Mercurial > hg > graal-compiler
comparison src/cpu/ppc/vm/assembler_ppc.hpp @ 14445:67fa91961822
8029940: PPC64 (part 122): C2 compiler port
Reviewed-by: kvn
author | goetz |
---|---|
date | Wed, 11 Dec 2013 00:06:11 +0100 |
parents | ec28f9c041ff |
children | e5e8aa897002 |
comparison
equal
deleted
inserted
replaced
14444:492e67693373 | 14445:67fa91961822 |
---|---|
96 public: | 96 public: |
97 enum { | 97 enum { |
98 // Only 8 registers may contain integer parameters. | 98 // Only 8 registers may contain integer parameters. |
99 n_register_parameters = 8, | 99 n_register_parameters = 8, |
100 // Can have up to 8 floating registers. | 100 // Can have up to 8 floating registers. |
101 n_float_register_parameters = 8 | 101 n_float_register_parameters = 8, |
102 | |
103 // PPC C calling conventions. | |
104 // The first eight arguments are passed in int regs if they are int. | |
105 n_int_register_parameters_c = 8, | |
106 // The first thirteen float arguments are passed in float regs. | |
107 n_float_register_parameters_c = 13, | |
108 // Only the first 8 parameters are not placed on the stack. Aix disassembly | |
109 // shows that xlC places all float args after argument 8 on the stack AND | |
110 // in a register. This is not documented, but we follow this convention, too. | |
111 n_regs_not_on_stack_c = 8, | |
102 }; | 112 }; |
103 // creation | 113 // creation |
104 Argument(int number) : _number(number) {} | 114 Argument(int number) : _number(number) {} |
105 | 115 |
106 int number() const { return _number; } | 116 int number() const { return _number; } |
660 bcondCRbiIs1_bhintNoHint = bcondCRbiIs1 | bhintatNoHint, | 670 bcondCRbiIs1_bhintNoHint = bcondCRbiIs1 | bhintatNoHint, |
661 bcondCRbiIs1_bhintIsNotTaken = bcondCRbiIs1 | bhintatIsNotTaken, | 671 bcondCRbiIs1_bhintIsNotTaken = bcondCRbiIs1 | bhintatIsNotTaken, |
662 bcondCRbiIs1_bhintIsTaken = bcondCRbiIs1 | bhintatIsTaken, | 672 bcondCRbiIs1_bhintIsTaken = bcondCRbiIs1 | bhintatIsTaken, |
663 }; | 673 }; |
664 | 674 |
675 // Elemental Memory Barriers (>=Power 8) | |
676 enum Elemental_Membar_mask_bits { | |
677 StoreStore = 1 << 0, | |
678 StoreLoad = 1 << 1, | |
679 LoadStore = 1 << 2, | |
680 LoadLoad = 1 << 3 | |
681 }; | |
682 | |
665 // Branch prediction hints. | 683 // Branch prediction hints. |
666 inline static int add_bhint_to_boint(const int bhint, const int boint) { | 684 inline static int add_bhint_to_boint(const int bhint, const int boint) { |
667 switch (boint) { | 685 switch (boint) { |
668 case bcondCRbiIs0: | 686 case bcondCRbiIs0: |
669 case bcondCRbiIs1: | 687 case bcondCRbiIs1: |
751 public: | 769 public: |
752 // Helper functions for groups of instructions | 770 // Helper functions for groups of instructions |
753 | 771 |
754 enum Predict { pt = 1, pn = 0 }; // pt = predict taken | 772 enum Predict { pt = 1, pn = 0 }; // pt = predict taken |
755 | 773 |
756 enum Membar_mask_bits { // page 184, v9 | |
757 StoreStore = 1 << 3, | |
758 LoadStore = 1 << 2, | |
759 StoreLoad = 1 << 1, | |
760 LoadLoad = 1 << 0, | |
761 | |
762 Sync = 1 << 6, | |
763 MemIssue = 1 << 5, | |
764 Lookaside = 1 << 4 | |
765 }; | |
766 | |
767 // instruction must start at passed address | 774 // instruction must start at passed address |
768 static int instr_len(unsigned char *instr) { return BytesPerInstWord; } | 775 static int instr_len(unsigned char *instr) { return BytesPerInstWord; } |
769 | 776 |
770 // instruction must be left-justified in argument | 777 // instruction must be left-justified in argument |
771 static int instr_len(unsigned long instr) { return BytesPerInstWord; } | 778 static int instr_len(unsigned long instr) { return BytesPerInstWord; } |
873 | 880 |
874 #define inv_opp_u_field(x, hi_bit, lo_bit) inv_u_field(x, 31-(lo_bit), 31-(hi_bit)) | 881 #define inv_opp_u_field(x, hi_bit, lo_bit) inv_u_field(x, 31-(lo_bit), 31-(hi_bit)) |
875 #define inv_opp_s_field(x, hi_bit, lo_bit) inv_s_field_ppc(x, 31-(lo_bit), 31-(hi_bit)) | 882 #define inv_opp_s_field(x, hi_bit, lo_bit) inv_s_field_ppc(x, 31-(lo_bit), 31-(hi_bit)) |
876 // Extract instruction fields from instruction words. | 883 // Extract instruction fields from instruction words. |
877 public: | 884 public: |
878 static int inv_ra_field(int x) { return inv_opp_u_field(x, 15, 11); } | 885 static int inv_ra_field(int x) { return inv_opp_u_field(x, 15, 11); } |
879 static int inv_rb_field(int x) { return inv_opp_u_field(x, 20, 16); } | 886 static int inv_rb_field(int x) { return inv_opp_u_field(x, 20, 16); } |
880 static int inv_rt_field(int x) { return inv_opp_u_field(x, 10, 6); } | 887 static int inv_rt_field(int x) { return inv_opp_u_field(x, 10, 6); } |
881 static int inv_rs_field(int x) { return inv_opp_u_field(x, 10, 6); } | 888 static int inv_rta_field(int x) { return inv_opp_u_field(x, 15, 11); } |
889 static int inv_rs_field(int x) { return inv_opp_u_field(x, 10, 6); } | |
882 // Ds uses opp_s_field(x, 31, 16), but lowest 2 bits must be 0. | 890 // Ds uses opp_s_field(x, 31, 16), but lowest 2 bits must be 0. |
883 // Inv_ds_field uses range (x, 29, 16) but shifts by 2 to ensure that lowest bits are 0. | 891 // Inv_ds_field uses range (x, 29, 16) but shifts by 2 to ensure that lowest bits are 0. |
884 static int inv_ds_field(int x) { return inv_opp_s_field(x, 29, 16) << 2; } | 892 static int inv_ds_field(int x) { return inv_opp_s_field(x, 29, 16) << 2; } |
885 static int inv_d1_field(int x) { return inv_opp_s_field(x, 31, 16); } | 893 static int inv_d1_field(int x) { return inv_opp_s_field(x, 31, 16); } |
886 static int inv_si_field(int x) { return inv_opp_s_field(x, 31, 16); } | 894 static int inv_si_field(int x) { return inv_opp_s_field(x, 31, 16); } |
887 static int inv_to_field(int x) { return inv_opp_u_field(x, 10, 6); } | 895 static int inv_to_field(int x) { return inv_opp_u_field(x, 10, 6); } |
888 static int inv_lk_field(int x) { return inv_opp_u_field(x, 31, 31); } | 896 static int inv_lk_field(int x) { return inv_opp_u_field(x, 31, 31); } |
889 static int inv_bo_field(int x) { return inv_opp_u_field(x, 10, 6); } | 897 static int inv_bo_field(int x) { return inv_opp_u_field(x, 10, 6); } |
890 static int inv_bi_field(int x) { return inv_opp_u_field(x, 15, 11); } | 898 static int inv_bi_field(int x) { return inv_opp_u_field(x, 15, 11); } |
891 | 899 |
892 #define opp_u_field(x, hi_bit, lo_bit) u_field(x, 31-(lo_bit), 31-(hi_bit)) | 900 #define opp_u_field(x, hi_bit, lo_bit) u_field(x, 31-(lo_bit), 31-(hi_bit)) |
893 #define opp_s_field(x, hi_bit, lo_bit) s_field(x, 31-(lo_bit), 31-(hi_bit)) | 901 #define opp_s_field(x, hi_bit, lo_bit) s_field(x, 31-(lo_bit), 31-(hi_bit)) |
894 | 902 |
895 // instruction fields | 903 // instruction fields |
923 static int frt( int x) { return opp_u_field(x, 10, 6); } | 931 static int frt( int x) { return opp_u_field(x, 10, 6); } |
924 static int fxm( int x) { return opp_u_field(x, 19, 12); } | 932 static int fxm( int x) { return opp_u_field(x, 19, 12); } |
925 static int l10( int x) { return opp_u_field(x, 10, 10); } | 933 static int l10( int x) { return opp_u_field(x, 10, 10); } |
926 static int l15( int x) { return opp_u_field(x, 15, 15); } | 934 static int l15( int x) { return opp_u_field(x, 15, 15); } |
927 static int l910( int x) { return opp_u_field(x, 10, 9); } | 935 static int l910( int x) { return opp_u_field(x, 10, 9); } |
936 static int e1215( int x) { return opp_u_field(x, 15, 12); } | |
928 static int lev( int x) { return opp_u_field(x, 26, 20); } | 937 static int lev( int x) { return opp_u_field(x, 26, 20); } |
929 static int li( int x) { return opp_s_field(x, 29, 6); } | 938 static int li( int x) { return opp_s_field(x, 29, 6); } |
930 static int lk( int x) { return opp_u_field(x, 31, 31); } | 939 static int lk( int x) { return opp_u_field(x, 31, 31); } |
931 static int mb2125( int x) { return opp_u_field(x, 25, 21); } | 940 static int mb2125( int x) { return opp_u_field(x, 25, 21); } |
932 static int me2630( int x) { return opp_u_field(x, 30, 26); } | 941 static int me2630( int x) { return opp_u_field(x, 30, 26); } |
958 static int si( int x) { return opp_s_field(x, 31, 16); } | 967 static int si( int x) { return opp_s_field(x, 31, 16); } |
959 static int spr( int x) { return opp_u_field(x, 20, 11); } | 968 static int spr( int x) { return opp_u_field(x, 20, 11); } |
960 static int sr( int x) { return opp_u_field(x, 15, 12); } | 969 static int sr( int x) { return opp_u_field(x, 15, 12); } |
961 static int tbr( int x) { return opp_u_field(x, 20, 11); } | 970 static int tbr( int x) { return opp_u_field(x, 20, 11); } |
962 static int th( int x) { return opp_u_field(x, 10, 7); } | 971 static int th( int x) { return opp_u_field(x, 10, 7); } |
963 static int thct( int x) { assert((x&8)==0, "must be valid cache specification"); return th(x); } | 972 static int thct( int x) { assert((x&8) == 0, "must be valid cache specification"); return th(x); } |
964 static int thds( int x) { assert((x&8)==8, "must be valid stream specification"); return th(x); } | 973 static int thds( int x) { assert((x&8) == 8, "must be valid stream specification"); return th(x); } |
965 static int to( int x) { return opp_u_field(x, 10, 6); } | 974 static int to( int x) { return opp_u_field(x, 10, 6); } |
966 static int u( int x) { return opp_u_field(x, 19, 16); } | 975 static int u( int x) { return opp_u_field(x, 19, 16); } |
967 static int ui( int x) { return opp_u_field(x, 31, 16); } | 976 static int ui( int x) { return opp_u_field(x, 31, 16); } |
968 | 977 |
969 // support vector instructions for >= Power6 | 978 // Support vector instructions for >= Power6. |
970 static int vra( int x) { return opp_u_field(x, 15, 11); } | 979 static int vra( int x) { return opp_u_field(x, 15, 11); } |
971 static int vrb( int x) { return opp_u_field(x, 20, 16); } | 980 static int vrb( int x) { return opp_u_field(x, 20, 16); } |
972 static int vrc( int x) { return opp_u_field(x, 25, 21); } | 981 static int vrc( int x) { return opp_u_field(x, 25, 21); } |
973 static int vrs( int x) { return opp_u_field(x, 10, 6); } | 982 static int vrs( int x) { return opp_u_field(x, 10, 6); } |
974 static int vrt( int x) { return opp_u_field(x, 10, 6); } | 983 static int vrt( int x) { return opp_u_field(x, 10, 6); } |
1088 public: | 1097 public: |
1089 inline void addic_( Register d, Register a, int si16); | 1098 inline void addic_( Register d, Register a, int si16); |
1090 inline void subfic( Register d, Register a, int si16); | 1099 inline void subfic( Register d, Register a, int si16); |
1091 inline void add( Register d, Register a, Register b); | 1100 inline void add( Register d, Register a, Register b); |
1092 inline void add_( Register d, Register a, Register b); | 1101 inline void add_( Register d, Register a, Register b); |
1093 inline void subf( Register d, Register a, Register b); | 1102 inline void subf( Register d, Register a, Register b); // d = b - a "Sub_from", as in ppc spec. |
1094 inline void sub( Register d, Register a, Register b); | 1103 inline void sub( Register d, Register a, Register b); // d = a - b Swap operands of subf for readability. |
1095 inline void subf_( Register d, Register a, Register b); | 1104 inline void subf_( Register d, Register a, Register b); |
1096 inline void addc( Register d, Register a, Register b); | 1105 inline void addc( Register d, Register a, Register b); |
1097 inline void addc_( Register d, Register a, Register b); | 1106 inline void addc_( Register d, Register a, Register b); |
1098 inline void subfc( Register d, Register a, Register b); | 1107 inline void subfc( Register d, Register a, Register b); |
1099 inline void subfc_( Register d, Register a, Register b); | 1108 inline void subfc_( Register d, Register a, Register b); |
1202 static bool is_nop(int x) { | 1211 static bool is_nop(int x) { |
1203 return x == 0x60000000; | 1212 return x == 0x60000000; |
1204 } | 1213 } |
1205 // endgroup opcode for Power6 | 1214 // endgroup opcode for Power6 |
1206 static bool is_endgroup(int x) { | 1215 static bool is_endgroup(int x) { |
1207 return is_ori(x) && inv_ra_field(x)==1 && inv_rs_field(x)==1 && inv_d1_field(x)==0; | 1216 return is_ori(x) && inv_ra_field(x) == 1 && inv_rs_field(x) == 1 && inv_d1_field(x) == 0; |
1208 } | 1217 } |
1209 | 1218 |
1210 | 1219 |
1211 private: | 1220 private: |
1212 // PPC 1, section 3.3.9, Fixed-Point Compare Instructions | 1221 // PPC 1, section 3.3.9, Fixed-Point Compare Instructions |
1225 inline void cmpldi(ConditionRegister crx, Register a, int ui16); | 1234 inline void cmpldi(ConditionRegister crx, Register a, int ui16); |
1226 inline void cmplw( ConditionRegister crx, Register a, Register b); | 1235 inline void cmplw( ConditionRegister crx, Register a, Register b); |
1227 inline void cmpld( ConditionRegister crx, Register a, Register b); | 1236 inline void cmpld( ConditionRegister crx, Register a, Register b); |
1228 | 1237 |
1229 inline void isel( Register d, Register a, Register b, int bc); | 1238 inline void isel( Register d, Register a, Register b, int bc); |
1239 // Convenient version which takes: Condition register, Condition code and invert flag. Omit b to keep old value. | |
1240 inline void isel( Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b = noreg); | |
1241 // Set d = 0 if (cr.cc) equals 1, otherwise b. | |
1242 inline void isel_0( Register d, ConditionRegister cr, Condition cc, Register b = noreg); | |
1230 | 1243 |
1231 // PPC 1, section 3.3.11, Fixed-Point Logical Instructions | 1244 // PPC 1, section 3.3.11, Fixed-Point Logical Instructions |
1232 void andi( Register a, Register s, int ui16); // optimized version | 1245 void andi( Register a, Register s, int ui16); // optimized version |
1233 inline void andi_( Register a, Register s, int ui16); | 1246 inline void andi_( Register a, Register s, int ui16); |
1234 inline void andis_( Register a, Register s, int ui16); | 1247 inline void andis_( Register a, Register s, int ui16); |
1235 inline void ori( Register a, Register s, int ui16); | 1248 inline void ori( Register a, Register s, int ui16); |
1236 inline void oris( Register a, Register s, int ui16); | 1249 inline void oris( Register a, Register s, int ui16); |
1237 inline void xori( Register a, Register s, int ui16); | 1250 inline void xori( Register a, Register s, int ui16); |
1551 inline void sync(); | 1564 inline void sync(); |
1552 inline void lwsync(); | 1565 inline void lwsync(); |
1553 inline void ptesync(); | 1566 inline void ptesync(); |
1554 inline void eieio(); | 1567 inline void eieio(); |
1555 inline void isync(); | 1568 inline void isync(); |
1556 | 1569 inline void elemental_membar(int e); // Elemental Memory Barriers (>=Power 8) |
1557 inline void release(); | |
1558 inline void acquire(); | |
1559 inline void fence(); | |
1560 | 1570 |
1561 // atomics | 1571 // atomics |
1562 inline void lwarx_unchecked(Register d, Register a, Register b, int eh1 = 0); | 1572 inline void lwarx_unchecked(Register d, Register a, Register b, int eh1 = 0); |
1563 inline void ldarx_unchecked(Register d, Register a, Register b, int eh1 = 0); | 1573 inline void ldarx_unchecked(Register d, Register a, Register b, int eh1 = 0); |
1564 inline bool lxarx_hint_exclusive_access(); | 1574 inline bool lxarx_hint_exclusive_access(); |
1936 inline void load_const(Register d, void* a, Register tmp = noreg); | 1946 inline void load_const(Register d, void* a, Register tmp = noreg); |
1937 inline void load_const(Register d, Label& L, Register tmp = noreg); | 1947 inline void load_const(Register d, Label& L, Register tmp = noreg); |
1938 inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg); | 1948 inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg); |
1939 | 1949 |
1940 // Load a 64 bit constant, optimized, not identifyable. | 1950 // Load a 64 bit constant, optimized, not identifyable. |
1941 // Tmp can be used to increase ILP. Set return_simm16_rest=true to get a | 1951 // Tmp can be used to increase ILP. Set return_simm16_rest = true to get a |
1942 // 16 bit immediate offset. This is useful if the offset can be encoded in | 1952 // 16 bit immediate offset. This is useful if the offset can be encoded in |
1943 // a succeeding instruction. | 1953 // a succeeding instruction. |
1944 int load_const_optimized(Register d, long a, Register tmp = noreg, bool return_simm16_rest = false); | 1954 int load_const_optimized(Register d, long a, Register tmp = noreg, bool return_simm16_rest = false); |
1945 inline int load_const_optimized(Register d, void* a, Register tmp = noreg, bool return_simm16_rest = false) { | 1955 inline int load_const_optimized(Register d, void* a, Register tmp = noreg, bool return_simm16_rest = false) { |
1946 return load_const_optimized(d, (long)(unsigned long)a, tmp, return_simm16_rest); | 1956 return load_const_optimized(d, (long)(unsigned long)a, tmp, return_simm16_rest); |