207 STDU_OPCODE_MASK = STD_OPCODE_MASK,
208 STDX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1),
209 STDUX_OPCODE_MASK = STDX_OPCODE_MASK,
210 STW_OPCODE_MASK = (63u << OPCODE_SHIFT),
211 STWU_OPCODE_MASK = STW_OPCODE_MASK,
212 STWX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1),
213 STWUX_OPCODE_MASK = STWX_OPCODE_MASK,
214 MTCTR_OPCODE_MASK = ~(31u << RS_SHIFT),
215 ORI_OPCODE_MASK = (63u << OPCODE_SHIFT),
216 ORIS_OPCODE_MASK = (63u << OPCODE_SHIFT),
217 RLDICR_OPCODE_MASK = (63u << OPCODE_SHIFT) | (7u << XO_27_29_SHIFT)
218 };
219
220 enum opcdxos {
221 ADD_OPCODE = (31u << OPCODE_SHIFT | 266u << 1),
222 ADDC_OPCODE = (31u << OPCODE_SHIFT | 10u << 1),
223 ADDI_OPCODE = (14u << OPCODE_SHIFT),
224 ADDIS_OPCODE = (15u << OPCODE_SHIFT),
225 ADDIC__OPCODE = (13u << OPCODE_SHIFT),
226 ADDE_OPCODE = (31u << OPCODE_SHIFT | 138u << 1),
227 SUBF_OPCODE = (31u << OPCODE_SHIFT | 40u << 1),
228 SUBFC_OPCODE = (31u << OPCODE_SHIFT | 8u << 1),
229 SUBFE_OPCODE = (31u << OPCODE_SHIFT | 136u << 1),
230 SUBFIC_OPCODE = (8u << OPCODE_SHIFT),
231 SUBFZE_OPCODE = (31u << OPCODE_SHIFT | 200u << 1),
232 DIVW_OPCODE = (31u << OPCODE_SHIFT | 491u << 1),
233 MULLW_OPCODE = (31u << OPCODE_SHIFT | 235u << 1),
234 MULHW_OPCODE = (31u << OPCODE_SHIFT | 75u << 1),
235 MULHWU_OPCODE = (31u << OPCODE_SHIFT | 11u << 1),
236 MULLI_OPCODE = (7u << OPCODE_SHIFT),
237 AND_OPCODE = (31u << OPCODE_SHIFT | 28u << 1),
238 ANDI_OPCODE = (28u << OPCODE_SHIFT),
239 ANDIS_OPCODE = (29u << OPCODE_SHIFT),
240 ANDC_OPCODE = (31u << OPCODE_SHIFT | 60u << 1),
241 ORC_OPCODE = (31u << OPCODE_SHIFT | 412u << 1),
242 OR_OPCODE = (31u << OPCODE_SHIFT | 444u << 1),
243 ORI_OPCODE = (24u << OPCODE_SHIFT),
244 ORIS_OPCODE = (25u << OPCODE_SHIFT),
245 XOR_OPCODE = (31u << OPCODE_SHIFT | 316u << 1),
246 XORI_OPCODE = (26u << OPCODE_SHIFT),
247 XORIS_OPCODE = (27u << OPCODE_SHIFT),
248
249 NEG_OPCODE = (31u << OPCODE_SHIFT | 104u << 1),
250
640 TABORTDCI_OPCODE = (31u << OPCODE_SHIFT | 878u << 1),
641 TSR_OPCODE = (31u << OPCODE_SHIFT | 750u << 1),
642 TCHECK_OPCODE = (31u << OPCODE_SHIFT | 718u << 1),
643
644 // Icache and dcache related instructions
645 DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1),
646 DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1),
647 DCBST_OPCODE = (31u << OPCODE_SHIFT | 54u << 1),
648 DCBF_OPCODE = (31u << OPCODE_SHIFT | 86u << 1),
649
650 DCBT_OPCODE = (31u << OPCODE_SHIFT | 278u << 1),
651 DCBTST_OPCODE = (31u << OPCODE_SHIFT | 246u << 1),
652 ICBI_OPCODE = (31u << OPCODE_SHIFT | 982u << 1),
653
654 // Instruction synchronization
655 ISYNC_OPCODE = (19u << OPCODE_SHIFT | 150u << 1),
656 // Memory barriers
657 SYNC_OPCODE = (31u << OPCODE_SHIFT | 598u << 1),
658 EIEIO_OPCODE = (31u << OPCODE_SHIFT | 854u << 1),
659
660 // Trap instructions
661 TDI_OPCODE = (2u << OPCODE_SHIFT),
662 TWI_OPCODE = (3u << OPCODE_SHIFT),
663 TD_OPCODE = (31u << OPCODE_SHIFT | 68u << 1),
664 TW_OPCODE = (31u << OPCODE_SHIFT | 4u << 1),
665
666 // Atomics.
667 LWARX_OPCODE = (31u << OPCODE_SHIFT | 20u << 1),
668 LDARX_OPCODE = (31u << OPCODE_SHIFT | 84u << 1),
669 STWCX_OPCODE = (31u << OPCODE_SHIFT | 150u << 1),
670 STDCX_OPCODE = (31u << OPCODE_SHIFT | 214u << 1)
671
672 };
673
674 // Trap instructions TO bits
675 enum trap_to_bits {
676 // single bits
677 traptoLessThanSigned = 1 << 4, // 0, left end
678 traptoGreaterThanSigned = 1 << 3,
679 traptoEqual = 1 << 2,
680 traptoLessThanUnsigned = 1 << 1,
681 traptoGreaterThanUnsigned = 1 << 0, // 4, right end
682
683 // compound ones
684 traptoUnconditional = (traptoLessThanSigned |
685 traptoGreaterThanSigned |
686 traptoEqual |
687 traptoLessThanUnsigned |
688 traptoGreaterThanUnsigned)
689 };
690
1154 inline void addis(Register d, Register a, int si16);
1155 private:
1156 inline void addi_r0ok( Register d, Register a, int si16);
1157 inline void addis_r0ok(Register d, Register a, int si16);
1158 public:
1159 inline void addic_( Register d, Register a, int si16);
1160 inline void subfic( Register d, Register a, int si16);
1161 inline void add( Register d, Register a, Register b);
1162 inline void add_( Register d, Register a, Register b);
1163 inline void subf( Register d, Register a, Register b); // d = b - a "Sub_from", as in ppc spec.
1164 inline void sub( Register d, Register a, Register b); // d = a - b Swap operands of subf for readability.
1165 inline void subf_( Register d, Register a, Register b);
1166 inline void addc( Register d, Register a, Register b);
1167 inline void addc_( Register d, Register a, Register b);
1168 inline void subfc( Register d, Register a, Register b);
1169 inline void subfc_( Register d, Register a, Register b);
1170 inline void adde( Register d, Register a, Register b);
1171 inline void adde_( Register d, Register a, Register b);
1172 inline void subfe( Register d, Register a, Register b);
1173 inline void subfe_( Register d, Register a, Register b);
1174 inline void neg( Register d, Register a);
1175 inline void neg_( Register d, Register a);
1176 inline void mulli( Register d, Register a, int si16);
1177 inline void mulld( Register d, Register a, Register b);
1178 inline void mulld_( Register d, Register a, Register b);
1179 inline void mullw( Register d, Register a, Register b);
1180 inline void mullw_( Register d, Register a, Register b);
1181 inline void mulhw( Register d, Register a, Register b);
1182 inline void mulhw_( Register d, Register a, Register b);
1183 inline void mulhd( Register d, Register a, Register b);
1184 inline void mulhd_( Register d, Register a, Register b);
1185 inline void mulhdu( Register d, Register a, Register b);
1186 inline void mulhdu_(Register d, Register a, Register b);
1187 inline void divd( Register d, Register a, Register b);
1188 inline void divd_( Register d, Register a, Register b);
1189 inline void divw( Register d, Register a, Register b);
1190 inline void divw_( Register d, Register a, Register b);
1191
1192 // extended mnemonics
1193 inline void li( Register d, int si16);
1194 inline void lis( Register d, int si16);
1195 inline void addir(Register d, int si16, Register a);
1196
1197 static bool is_addi(int x) {
1198 return ADDI_OPCODE == (x & ADDI_OPCODE_MASK);
1199 }
1200 static bool is_addis(int x) {
1201 return ADDIS_OPCODE == (x & ADDIS_OPCODE_MASK);
1202 }
1203 static bool is_bxx(int x) {
1204 return BXX_OPCODE == (x & BXX_OPCODE_MASK);
1205 }
1206 static bool is_b(int x) {
1207 return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 0;
1208 }
1209 static bool is_bl(int x) {
1210 return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 1;
1211 }
1286 inline void cmpl( ConditionRegister bf, int l, Register a, Register b);
1287
1288 public:
1289 // extended mnemonics of Compare Instructions
1290 inline void cmpwi( ConditionRegister crx, Register a, int si16);
1291 inline void cmpdi( ConditionRegister crx, Register a, int si16);
1292 inline void cmpw( ConditionRegister crx, Register a, Register b);
1293 inline void cmpd( ConditionRegister crx, Register a, Register b);
1294 inline void cmplwi(ConditionRegister crx, Register a, int ui16);
1295 inline void cmpldi(ConditionRegister crx, Register a, int ui16);
1296 inline void cmplw( ConditionRegister crx, Register a, Register b);
1297 inline void cmpld( ConditionRegister crx, Register a, Register b);
1298
1299 inline void isel( Register d, Register a, Register b, int bc);
1300 // Convenient version which takes: Condition register, Condition code and invert flag. Omit b to keep old value.
1301 inline void isel( Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b = noreg);
1302 // Set d = 0 if (cr.cc) equals 1, otherwise b.
1303 inline void isel_0( Register d, ConditionRegister cr, Condition cc, Register b = noreg);
1304
1305 // PPC 1, section 3.3.11, Fixed-Point Logical Instructions
1306 void andi( Register a, Register s, int ui16); // optimized version
1307 inline void andi_( Register a, Register s, int ui16);
1308 inline void andis_( Register a, Register s, int ui16);
1309 inline void ori( Register a, Register s, int ui16);
1310 inline void oris( Register a, Register s, int ui16);
1311 inline void xori( Register a, Register s, int ui16);
1312 inline void xoris( Register a, Register s, int ui16);
1313 inline void andr( Register a, Register s, Register b); // suffixed by 'r' as 'and' is C++ keyword
1314 inline void and_( Register a, Register s, Register b);
1315 // Turn or0(rx,rx,rx) into a nop and avoid that we accidently emit a
1316 // SMT-priority change instruction (see SMT instructions below).
1317 inline void or_unchecked(Register a, Register s, Register b);
1318 inline void orr( Register a, Register s, Register b); // suffixed by 'r' as 'or' is C++ keyword
1319 inline void or_( Register a, Register s, Register b);
1320 inline void xorr( Register a, Register s, Register b); // suffixed by 'r' as 'xor' is C++ keyword
1321 inline void xor_( Register a, Register s, Register b);
1322 inline void nand( Register a, Register s, Register b);
1323 inline void nand_( Register a, Register s, Register b);
1324 inline void nor( Register a, Register s, Register b);
1325 inline void nor_( Register a, Register s, Register b);
1326 inline void andc( Register a, Register s, Register b);
1671 //
1672 // - release orders Store|Store, (maps to lwsync)
1673 // Load|Store
1674 // - acquire orders Load|Store, (maps to lwsync)
1675 // Load|Load
1676 // - fence orders Store|Store, (maps to sync)
1677 // Load|Store,
1678 // Load|Load,
1679 // Store|Load
1680 //
1681 private:
1682 inline void sync(int l);
1683 public:
1684 inline void sync();
1685 inline void lwsync();
1686 inline void ptesync();
1687 inline void eieio();
1688 inline void isync();
1689 inline void elemental_membar(int e); // Elemental Memory Barriers (>=Power 8)
1690
1691 // atomics
1692 inline void lwarx_unchecked(Register d, Register a, Register b, int eh1 = 0);
1693 inline void ldarx_unchecked(Register d, Register a, Register b, int eh1 = 0);
1694 inline bool lxarx_hint_exclusive_access();
1695 inline void lwarx( Register d, Register a, Register b, bool hint_exclusive_access = false);
1696 inline void ldarx( Register d, Register a, Register b, bool hint_exclusive_access = false);
1697 inline void stwcx_( Register s, Register a, Register b);
1698 inline void stdcx_( Register s, Register a, Register b);
1699
1700 // Instructions for adjusting thread priority for simultaneous
1701 // multithreading (SMT) on Power5.
1702 private:
1703 inline void smt_prio_very_low();
1704 inline void smt_prio_medium_high();
1705 inline void smt_prio_high();
1706
1707 public:
1708 inline void smt_prio_low();
1709 inline void smt_prio_medium_low();
1710 inline void smt_prio_medium();
1711 // >= Power7
1712 inline void smt_yield();
1713 inline void smt_mdoio();
1714 inline void smt_mdoom();
1715
1716 // trap instructions
1717 inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur)
1718 // NOT FOR DIRECT USE!!
2037 inline void std( Register d, int si16);
2038
2039 // PPC 2, section 3.2.1 Instruction Cache Instructions
2040 inline void icbi( Register s2);
2041 // PPC 2, section 3.2.2 Data Cache Instructions
2042 //inlinevoid dcba( Register s2); // Instruction for embedded processor only.
2043 inline void dcbz( Register s2);
2044 inline void dcbst( Register s2);
2045 inline void dcbf( Register s2);
2046 // dcache read hint
2047 inline void dcbt( Register s2);
2048 inline void dcbtct( Register s2, int ct);
2049 inline void dcbtds( Register s2, int ds);
2050 // dcache write hint
2051 inline void dcbtst( Register s2);
2052 inline void dcbtstct(Register s2, int ct);
2053
2054 // Atomics: use ra0mem to disallow R0 as base.
2055 inline void lwarx_unchecked(Register d, Register b, int eh1);
2056 inline void ldarx_unchecked(Register d, Register b, int eh1);
2057 inline void lwarx( Register d, Register b, bool hint_exclusive_access);
2058 inline void ldarx( Register d, Register b, bool hint_exclusive_access);
2059 inline void stwcx_(Register s, Register b);
2060 inline void stdcx_(Register s, Register b);
2061 inline void lfs( FloatRegister d, int si16);
2062 inline void lfsx( FloatRegister d, Register b);
2063 inline void lfd( FloatRegister d, int si16);
2064 inline void lfdx( FloatRegister d, Register b);
2065 inline void stfs( FloatRegister s, int si16);
2066 inline void stfsx( FloatRegister s, Register b);
2067 inline void stfd( FloatRegister s, int si16);
2068 inline void stfdx( FloatRegister s, Register b);
2069 inline void lvebx( VectorRegister d, Register s2);
2070 inline void lvehx( VectorRegister d, Register s2);
2071 inline void lvewx( VectorRegister d, Register s2);
2072 inline void lvx( VectorRegister d, Register s2);
2073 inline void lvxl( VectorRegister d, Register s2);
2074 inline void stvebx(VectorRegister d, Register s2);
2075 inline void stvehx(VectorRegister d, Register s2);
2076 inline void stvewx(VectorRegister d, Register s2);
2077 inline void stvx( VectorRegister d, Register s2);
2078 inline void stvxl( VectorRegister d, Register s2);
2079 inline void lvsl( VectorRegister d, Register s2);
2080 inline void lvsr( VectorRegister d, Register s2);
2101 void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1);
2102
2103
2104 // Emit several instructions to load a 64 bit constant. This issues a fixed
2105 // instruction pattern so that the constant can be patched later on.
2106 enum {
2107 load_const_size = 5 * BytesPerInstWord
2108 };
2109 void load_const(Register d, long a, Register tmp = noreg);
2110 inline void load_const(Register d, void* a, Register tmp = noreg);
2111 inline void load_const(Register d, Label& L, Register tmp = noreg);
2112 inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg);
2113
2114 // Load a 64 bit constant, optimized, not identifyable.
2115 // Tmp can be used to increase ILP. Set return_simm16_rest = true to get a
2116 // 16 bit immediate offset. This is useful if the offset can be encoded in
2117 // a succeeding instruction.
2118 int load_const_optimized(Register d, long a, Register tmp = noreg, bool return_simm16_rest = false);
2119 inline int load_const_optimized(Register d, void* a, Register tmp = noreg, bool return_simm16_rest = false) {
2120 return load_const_optimized(d, (long)(unsigned long)a, tmp, return_simm16_rest);
2121 }
2122
2123 // Creation
2124 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
2125 #ifdef CHECK_DELAY
2126 delay_state = no_delay;
2127 #endif
2128 }
2129
2130 // Testing
2131 #ifndef PRODUCT
2132 void test_asm();
2133 #endif
2134 };
2135
2136
2137 #endif // CPU_PPC_VM_ASSEMBLER_PPC_HPP
|
207 STDU_OPCODE_MASK = STD_OPCODE_MASK,
208 STDX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1),
209 STDUX_OPCODE_MASK = STDX_OPCODE_MASK,
210 STW_OPCODE_MASK = (63u << OPCODE_SHIFT),
211 STWU_OPCODE_MASK = STW_OPCODE_MASK,
212 STWX_OPCODE_MASK = (63u << OPCODE_SHIFT) | (1023u << 1),
213 STWUX_OPCODE_MASK = STWX_OPCODE_MASK,
214 MTCTR_OPCODE_MASK = ~(31u << RS_SHIFT),
215 ORI_OPCODE_MASK = (63u << OPCODE_SHIFT),
216 ORIS_OPCODE_MASK = (63u << OPCODE_SHIFT),
217 RLDICR_OPCODE_MASK = (63u << OPCODE_SHIFT) | (7u << XO_27_29_SHIFT)
218 };
219
220 enum opcdxos {
221 ADD_OPCODE = (31u << OPCODE_SHIFT | 266u << 1),
222 ADDC_OPCODE = (31u << OPCODE_SHIFT | 10u << 1),
223 ADDI_OPCODE = (14u << OPCODE_SHIFT),
224 ADDIS_OPCODE = (15u << OPCODE_SHIFT),
225 ADDIC__OPCODE = (13u << OPCODE_SHIFT),
226 ADDE_OPCODE = (31u << OPCODE_SHIFT | 138u << 1),
227 ADDME_OPCODE = (31u << OPCODE_SHIFT | 234u << 1),
228 ADDZE_OPCODE = (31u << OPCODE_SHIFT | 202u << 1),
229 SUBF_OPCODE = (31u << OPCODE_SHIFT | 40u << 1),
230 SUBFC_OPCODE = (31u << OPCODE_SHIFT | 8u << 1),
231 SUBFE_OPCODE = (31u << OPCODE_SHIFT | 136u << 1),
232 SUBFIC_OPCODE = (8u << OPCODE_SHIFT),
233 SUBFME_OPCODE = (31u << OPCODE_SHIFT | 232u << 1),
234 SUBFZE_OPCODE = (31u << OPCODE_SHIFT | 200u << 1),
235 DIVW_OPCODE = (31u << OPCODE_SHIFT | 491u << 1),
236 MULLW_OPCODE = (31u << OPCODE_SHIFT | 235u << 1),
237 MULHW_OPCODE = (31u << OPCODE_SHIFT | 75u << 1),
238 MULHWU_OPCODE = (31u << OPCODE_SHIFT | 11u << 1),
239 MULLI_OPCODE = (7u << OPCODE_SHIFT),
240 AND_OPCODE = (31u << OPCODE_SHIFT | 28u << 1),
241 ANDI_OPCODE = (28u << OPCODE_SHIFT),
242 ANDIS_OPCODE = (29u << OPCODE_SHIFT),
243 ANDC_OPCODE = (31u << OPCODE_SHIFT | 60u << 1),
244 ORC_OPCODE = (31u << OPCODE_SHIFT | 412u << 1),
245 OR_OPCODE = (31u << OPCODE_SHIFT | 444u << 1),
246 ORI_OPCODE = (24u << OPCODE_SHIFT),
247 ORIS_OPCODE = (25u << OPCODE_SHIFT),
248 XOR_OPCODE = (31u << OPCODE_SHIFT | 316u << 1),
249 XORI_OPCODE = (26u << OPCODE_SHIFT),
250 XORIS_OPCODE = (27u << OPCODE_SHIFT),
251
252 NEG_OPCODE = (31u << OPCODE_SHIFT | 104u << 1),
253
643 TABORTDCI_OPCODE = (31u << OPCODE_SHIFT | 878u << 1),
644 TSR_OPCODE = (31u << OPCODE_SHIFT | 750u << 1),
645 TCHECK_OPCODE = (31u << OPCODE_SHIFT | 718u << 1),
646
647 // Icache and dcache related instructions
648 DCBA_OPCODE = (31u << OPCODE_SHIFT | 758u << 1),
649 DCBZ_OPCODE = (31u << OPCODE_SHIFT | 1014u << 1),
650 DCBST_OPCODE = (31u << OPCODE_SHIFT | 54u << 1),
651 DCBF_OPCODE = (31u << OPCODE_SHIFT | 86u << 1),
652
653 DCBT_OPCODE = (31u << OPCODE_SHIFT | 278u << 1),
654 DCBTST_OPCODE = (31u << OPCODE_SHIFT | 246u << 1),
655 ICBI_OPCODE = (31u << OPCODE_SHIFT | 982u << 1),
656
657 // Instruction synchronization
658 ISYNC_OPCODE = (19u << OPCODE_SHIFT | 150u << 1),
659 // Memory barriers
660 SYNC_OPCODE = (31u << OPCODE_SHIFT | 598u << 1),
661 EIEIO_OPCODE = (31u << OPCODE_SHIFT | 854u << 1),
662
663 // Wait instructions for polling.
664 WAIT_OPCODE = (31u << OPCODE_SHIFT | 62u << 1),
665
666 // Trap instructions
667 TDI_OPCODE = (2u << OPCODE_SHIFT),
668 TWI_OPCODE = (3u << OPCODE_SHIFT),
669 TD_OPCODE = (31u << OPCODE_SHIFT | 68u << 1),
670 TW_OPCODE = (31u << OPCODE_SHIFT | 4u << 1),
671
672 // Atomics.
673 LWARX_OPCODE = (31u << OPCODE_SHIFT | 20u << 1),
674 LDARX_OPCODE = (31u << OPCODE_SHIFT | 84u << 1),
675 LQARX_OPCODE = (31u << OPCODE_SHIFT | 276u << 1),
676 STWCX_OPCODE = (31u << OPCODE_SHIFT | 150u << 1),
677 STDCX_OPCODE = (31u << OPCODE_SHIFT | 214u << 1),
678 STQCX_OPCODE = (31u << OPCODE_SHIFT | 182u << 1)
679
680 };
681
682 // Trap instructions TO bits
683 enum trap_to_bits {
684 // single bits
685 traptoLessThanSigned = 1 << 4, // 0, left end
686 traptoGreaterThanSigned = 1 << 3,
687 traptoEqual = 1 << 2,
688 traptoLessThanUnsigned = 1 << 1,
689 traptoGreaterThanUnsigned = 1 << 0, // 4, right end
690
691 // compound ones
692 traptoUnconditional = (traptoLessThanSigned |
693 traptoGreaterThanSigned |
694 traptoEqual |
695 traptoLessThanUnsigned |
696 traptoGreaterThanUnsigned)
697 };
698
1162 inline void addis(Register d, Register a, int si16);
1163 private:
1164 inline void addi_r0ok( Register d, Register a, int si16);
1165 inline void addis_r0ok(Register d, Register a, int si16);
1166 public:
1167 inline void addic_( Register d, Register a, int si16);
1168 inline void subfic( Register d, Register a, int si16);
1169 inline void add( Register d, Register a, Register b);
1170 inline void add_( Register d, Register a, Register b);
1171 inline void subf( Register d, Register a, Register b); // d = b - a "Sub_from", as in ppc spec.
1172 inline void sub( Register d, Register a, Register b); // d = a - b Swap operands of subf for readability.
1173 inline void subf_( Register d, Register a, Register b);
1174 inline void addc( Register d, Register a, Register b);
1175 inline void addc_( Register d, Register a, Register b);
1176 inline void subfc( Register d, Register a, Register b);
1177 inline void subfc_( Register d, Register a, Register b);
1178 inline void adde( Register d, Register a, Register b);
1179 inline void adde_( Register d, Register a, Register b);
1180 inline void subfe( Register d, Register a, Register b);
1181 inline void subfe_( Register d, Register a, Register b);
1182 inline void addme( Register d, Register a);
1183 inline void addme_( Register d, Register a);
1184 inline void subfme( Register d, Register a);
1185 inline void subfme_(Register d, Register a);
1186 inline void addze( Register d, Register a);
1187 inline void addze_( Register d, Register a);
1188 inline void subfze( Register d, Register a);
1189 inline void subfze_(Register d, Register a);
1190 inline void neg( Register d, Register a);
1191 inline void neg_( Register d, Register a);
1192 inline void mulli( Register d, Register a, int si16);
1193 inline void mulld( Register d, Register a, Register b);
1194 inline void mulld_( Register d, Register a, Register b);
1195 inline void mullw( Register d, Register a, Register b);
1196 inline void mullw_( Register d, Register a, Register b);
1197 inline void mulhw( Register d, Register a, Register b);
1198 inline void mulhw_( Register d, Register a, Register b);
1199 inline void mulhd( Register d, Register a, Register b);
1200 inline void mulhd_( Register d, Register a, Register b);
1201 inline void mulhdu( Register d, Register a, Register b);
1202 inline void mulhdu_(Register d, Register a, Register b);
1203 inline void divd( Register d, Register a, Register b);
1204 inline void divd_( Register d, Register a, Register b);
1205 inline void divw( Register d, Register a, Register b);
1206 inline void divw_( Register d, Register a, Register b);
1207
1208 // Fixed-Point Arithmetic Instructions with Overflow detection
1209 inline void addo( Register d, Register a, Register b);
1210 inline void addo_( Register d, Register a, Register b);
1211 inline void subfo( Register d, Register a, Register b);
1212 inline void subfo_( Register d, Register a, Register b);
1213 inline void addco( Register d, Register a, Register b);
1214 inline void addco_( Register d, Register a, Register b);
1215 inline void subfco( Register d, Register a, Register b);
1216 inline void subfco_( Register d, Register a, Register b);
1217 inline void addeo( Register d, Register a, Register b);
1218 inline void addeo_( Register d, Register a, Register b);
1219 inline void subfeo( Register d, Register a, Register b);
1220 inline void subfeo_( Register d, Register a, Register b);
1221 inline void addmeo( Register d, Register a);
1222 inline void addmeo_( Register d, Register a);
1223 inline void subfmeo( Register d, Register a);
1224 inline void subfmeo_(Register d, Register a);
1225 inline void addzeo( Register d, Register a);
1226 inline void addzeo_( Register d, Register a);
1227 inline void subfzeo( Register d, Register a);
1228 inline void subfzeo_(Register d, Register a);
1229 inline void nego( Register d, Register a);
1230 inline void nego_( Register d, Register a);
1231 inline void mulldo( Register d, Register a, Register b);
1232 inline void mulldo_( Register d, Register a, Register b);
1233 inline void mullwo( Register d, Register a, Register b);
1234 inline void mullwo_( Register d, Register a, Register b);
1235 inline void divdo( Register d, Register a, Register b);
1236 inline void divdo_( Register d, Register a, Register b);
1237 inline void divwo( Register d, Register a, Register b);
1238 inline void divwo_( Register d, Register a, Register b);
1239
1240 // extended mnemonics
1241 inline void li( Register d, int si16);
1242 inline void lis( Register d, int si16);
1243 inline void addir(Register d, int si16, Register a);
1244
1245 static bool is_addi(int x) {
1246 return ADDI_OPCODE == (x & ADDI_OPCODE_MASK);
1247 }
1248 static bool is_addis(int x) {
1249 return ADDIS_OPCODE == (x & ADDIS_OPCODE_MASK);
1250 }
1251 static bool is_bxx(int x) {
1252 return BXX_OPCODE == (x & BXX_OPCODE_MASK);
1253 }
1254 static bool is_b(int x) {
1255 return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 0;
1256 }
1257 static bool is_bl(int x) {
1258 return BXX_OPCODE == (x & BXX_OPCODE_MASK) && inv_lk_field(x) == 1;
1259 }
1334 inline void cmpl( ConditionRegister bf, int l, Register a, Register b);
1335
1336 public:
1337 // extended mnemonics of Compare Instructions
1338 inline void cmpwi( ConditionRegister crx, Register a, int si16);
1339 inline void cmpdi( ConditionRegister crx, Register a, int si16);
1340 inline void cmpw( ConditionRegister crx, Register a, Register b);
1341 inline void cmpd( ConditionRegister crx, Register a, Register b);
1342 inline void cmplwi(ConditionRegister crx, Register a, int ui16);
1343 inline void cmpldi(ConditionRegister crx, Register a, int ui16);
1344 inline void cmplw( ConditionRegister crx, Register a, Register b);
1345 inline void cmpld( ConditionRegister crx, Register a, Register b);
1346
1347 inline void isel( Register d, Register a, Register b, int bc);
1348 // Convenient version which takes: Condition register, Condition code and invert flag. Omit b to keep old value.
1349 inline void isel( Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b = noreg);
1350 // Set d = 0 if (cr.cc) equals 1, otherwise b.
1351 inline void isel_0( Register d, ConditionRegister cr, Condition cc, Register b = noreg);
1352
1353 // PPC 1, section 3.3.11, Fixed-Point Logical Instructions
1354 void andi( Register a, Register s, long ui16); // optimized version
1355 inline void andi_( Register a, Register s, int ui16);
1356 inline void andis_( Register a, Register s, int ui16);
1357 inline void ori( Register a, Register s, int ui16);
1358 inline void oris( Register a, Register s, int ui16);
1359 inline void xori( Register a, Register s, int ui16);
1360 inline void xoris( Register a, Register s, int ui16);
1361 inline void andr( Register a, Register s, Register b); // suffixed by 'r' as 'and' is C++ keyword
1362 inline void and_( Register a, Register s, Register b);
1363 // Turn or0(rx,rx,rx) into a nop and avoid that we accidently emit a
1364 // SMT-priority change instruction (see SMT instructions below).
1365 inline void or_unchecked(Register a, Register s, Register b);
1366 inline void orr( Register a, Register s, Register b); // suffixed by 'r' as 'or' is C++ keyword
1367 inline void or_( Register a, Register s, Register b);
1368 inline void xorr( Register a, Register s, Register b); // suffixed by 'r' as 'xor' is C++ keyword
1369 inline void xor_( Register a, Register s, Register b);
1370 inline void nand( Register a, Register s, Register b);
1371 inline void nand_( Register a, Register s, Register b);
1372 inline void nor( Register a, Register s, Register b);
1373 inline void nor_( Register a, Register s, Register b);
1374 inline void andc( Register a, Register s, Register b);
1719 //
1720 // - release orders Store|Store, (maps to lwsync)
1721 // Load|Store
1722 // - acquire orders Load|Store, (maps to lwsync)
1723 // Load|Load
1724 // - fence orders Store|Store, (maps to sync)
1725 // Load|Store,
1726 // Load|Load,
1727 // Store|Load
1728 //
1729 private:
1730 inline void sync(int l);
1731 public:
1732 inline void sync();
1733 inline void lwsync();
1734 inline void ptesync();
1735 inline void eieio();
1736 inline void isync();
1737 inline void elemental_membar(int e); // Elemental Memory Barriers (>=Power 8)
1738
1739 // Wait instructions for polling. Attention: May result in SIGILL.
1740 inline void wait();
1741 inline void waitrsv(); // >=Power7
1742
1743 // atomics
1744 inline void lwarx_unchecked(Register d, Register a, Register b, int eh1 = 0);
1745 inline void ldarx_unchecked(Register d, Register a, Register b, int eh1 = 0);
1746 inline void lqarx_unchecked(Register d, Register a, Register b, int eh1 = 0);
1747 inline bool lxarx_hint_exclusive_access();
1748 inline void lwarx( Register d, Register a, Register b, bool hint_exclusive_access = false);
1749 inline void ldarx( Register d, Register a, Register b, bool hint_exclusive_access = false);
1750 inline void lqarx( Register d, Register a, Register b, bool hint_exclusive_access = false);
1751 inline void stwcx_( Register s, Register a, Register b);
1752 inline void stdcx_( Register s, Register a, Register b);
1753 inline void stqcx_( Register s, Register a, Register b);
1754
1755 // Instructions for adjusting thread priority for simultaneous
1756 // multithreading (SMT) on Power5.
1757 private:
1758 inline void smt_prio_very_low();
1759 inline void smt_prio_medium_high();
1760 inline void smt_prio_high();
1761
1762 public:
1763 inline void smt_prio_low();
1764 inline void smt_prio_medium_low();
1765 inline void smt_prio_medium();
1766 // >= Power7
1767 inline void smt_yield();
1768 inline void smt_mdoio();
1769 inline void smt_mdoom();
1770
1771 // trap instructions
1772 inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur)
1773 // NOT FOR DIRECT USE!!
2092 inline void std( Register d, int si16);
2093
2094 // PPC 2, section 3.2.1 Instruction Cache Instructions
2095 inline void icbi( Register s2);
2096 // PPC 2, section 3.2.2 Data Cache Instructions
2097 //inlinevoid dcba( Register s2); // Instruction for embedded processor only.
2098 inline void dcbz( Register s2);
2099 inline void dcbst( Register s2);
2100 inline void dcbf( Register s2);
2101 // dcache read hint
2102 inline void dcbt( Register s2);
2103 inline void dcbtct( Register s2, int ct);
2104 inline void dcbtds( Register s2, int ds);
2105 // dcache write hint
2106 inline void dcbtst( Register s2);
2107 inline void dcbtstct(Register s2, int ct);
2108
2109 // Atomics: use ra0mem to disallow R0 as base.
2110 inline void lwarx_unchecked(Register d, Register b, int eh1);
2111 inline void ldarx_unchecked(Register d, Register b, int eh1);
2112 inline void lqarx_unchecked(Register d, Register b, int eh1);
2113 inline void lwarx( Register d, Register b, bool hint_exclusive_access);
2114 inline void ldarx( Register d, Register b, bool hint_exclusive_access);
2115 inline void lqarx( Register d, Register b, bool hint_exclusive_access);
2116 inline void stwcx_(Register s, Register b);
2117 inline void stdcx_(Register s, Register b);
2118 inline void stqcx_(Register s, Register b);
2119 inline void lfs( FloatRegister d, int si16);
2120 inline void lfsx( FloatRegister d, Register b);
2121 inline void lfd( FloatRegister d, int si16);
2122 inline void lfdx( FloatRegister d, Register b);
2123 inline void stfs( FloatRegister s, int si16);
2124 inline void stfsx( FloatRegister s, Register b);
2125 inline void stfd( FloatRegister s, int si16);
2126 inline void stfdx( FloatRegister s, Register b);
2127 inline void lvebx( VectorRegister d, Register s2);
2128 inline void lvehx( VectorRegister d, Register s2);
2129 inline void lvewx( VectorRegister d, Register s2);
2130 inline void lvx( VectorRegister d, Register s2);
2131 inline void lvxl( VectorRegister d, Register s2);
2132 inline void stvebx(VectorRegister d, Register s2);
2133 inline void stvehx(VectorRegister d, Register s2);
2134 inline void stvewx(VectorRegister d, Register s2);
2135 inline void stvx( VectorRegister d, Register s2);
2136 inline void stvxl( VectorRegister d, Register s2);
2137 inline void lvsl( VectorRegister d, Register s2);
2138 inline void lvsr( VectorRegister d, Register s2);
2159 void cmpd(ConditionRegister d, RegisterOrConstant roc, Register s1);
2160
2161
2162 // Emit several instructions to load a 64 bit constant. This issues a fixed
2163 // instruction pattern so that the constant can be patched later on.
2164 enum {
2165 load_const_size = 5 * BytesPerInstWord
2166 };
2167 void load_const(Register d, long a, Register tmp = noreg);
2168 inline void load_const(Register d, void* a, Register tmp = noreg);
2169 inline void load_const(Register d, Label& L, Register tmp = noreg);
2170 inline void load_const(Register d, AddressLiteral& a, Register tmp = noreg);
2171
2172 // Load a 64 bit constant, optimized, not identifyable.
2173 // Tmp can be used to increase ILP. Set return_simm16_rest = true to get a
2174 // 16 bit immediate offset. This is useful if the offset can be encoded in
2175 // a succeeding instruction.
2176 int load_const_optimized(Register d, long a, Register tmp = noreg, bool return_simm16_rest = false);
2177 inline int load_const_optimized(Register d, void* a, Register tmp = noreg, bool return_simm16_rest = false) {
2178 return load_const_optimized(d, (long)(unsigned long)a, tmp, return_simm16_rest);
2179 }
2180
2181 // If return_simm16_rest, the return value needs to get added afterwards.
2182 int add_const_optimized(Register d, Register s, long x, Register tmp = R0, bool return_simm16_rest = false);
2183 inline int add_const_optimized(Register d, Register s, void* a, Register tmp = R0, bool return_simm16_rest = false) {
2184 return add_const_optimized(d, s, (long)(unsigned long)a, tmp, return_simm16_rest);
2185 }
2186
2187 // If return_simm16_rest, the return value needs to get added afterwards.
2188 inline int sub_const_optimized(Register d, Register s, long x, Register tmp = R0, bool return_simm16_rest = false) {
2189 return add_const_optimized(d, s, -x, tmp, return_simm16_rest);
2190 }
2191 inline int sub_const_optimized(Register d, Register s, void* a, Register tmp = R0, bool return_simm16_rest = false) {
2192 return sub_const_optimized(d, s, (long)(unsigned long)a, tmp, return_simm16_rest);
2193 }
2194
2195 // Creation
2196 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
2197 #ifdef CHECK_DELAY
2198 delay_state = no_delay;
2199 #endif
2200 }
2201
2202 // Testing
2203 #ifndef PRODUCT
2204 void test_asm();
2205 #endif
2206 };
2207
2208
2209 #endif // CPU_PPC_VM_ASSEMBLER_PPC_HPP
|