451
452 inline void movw(Register dst, u_int32_t imm32)
453 {
454 mov_immediate32(dst, imm32);
455 }
456
457 inline void mov(Register dst, long l)
458 {
459 mov(dst, (u_int64_t)l);
460 }
461
462 inline void mov(Register dst, int i)
463 {
464 mov(dst, (long)i);
465 }
466
467 void movptr(Register r, uintptr_t imm64);
468
469 void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
470
471 // macro instructions for accessing and updating floating point
472 // status register
473 //
474 // FPSR : op1 == 011
475 // CRn == 0100
476 // CRm == 0100
477 // op2 == 001
478
479 inline void get_fpsr(Register reg)
480 {
481 mrs(0b11, 0b0100, 0b0100, 0b001, reg);
482 }
483
484 inline void set_fpsr(Register reg)
485 {
486 msr(0b011, 0b0100, 0b0100, 0b001, reg);
487 }
488
489 inline void clear_fpsr()
490 {
1144 Register carry, Register product,
1145 Register idx, Register kdx);
1146 void multiply_128_x_128_loop(Register y, Register z,
1147 Register carry, Register carry2,
1148 Register idx, Register jdx,
1149 Register yz_idx1, Register yz_idx2,
1150 Register tmp, Register tmp3, Register tmp4,
1151 Register tmp7, Register product_hi);
1152 public:
1153 void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1154 Register zlen, Register tmp1, Register tmp2, Register tmp3,
1155 Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1156 // ISB may be needed because of a safepoint
1157 void maybe_isb() { isb(); }
1158
1159 private:
1160 // Return the effective address r + (r1 << ext) + offset.
1161 // Uses rscratch2.
1162 Address offsetted_address(Register r, Register r1, Address::extend ext,
1163 int offset, int size);
1164 };
1165
1166 #ifdef ASSERT
1167 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1168 #endif
1169
1170 /**
1171 * class SkipIfEqual:
1172 *
1173 * Instantiating this class will result in assembly code being output that will
1174 * jump around any code emitted between the creation of the instance and it's
1175 * automatic destruction at the end of a scope block, depending on the value of
1176 * the flag passed to the constructor, which will be checked at run-time.
1177 */
1178 class SkipIfEqual {
1179 private:
1180 MacroAssembler* _masm;
1181 Label _label;
1182
1183 public:
|
451
452 inline void movw(Register dst, u_int32_t imm32)
453 {
454 mov_immediate32(dst, imm32);
455 }
456
457 inline void mov(Register dst, long l)
458 {
459 mov(dst, (u_int64_t)l);
460 }
461
462 inline void mov(Register dst, int i)
463 {
464 mov(dst, (long)i);
465 }
466
467 void movptr(Register r, uintptr_t imm64);
468
469 void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
470
471 void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
472 orr(Vd, T, Vn, Vn);
473 }
474
475 // macro instructions for accessing and updating floating point
476 // status register
477 //
478 // FPSR : op1 == 011
479 // CRn == 0100
480 // CRm == 0100
481 // op2 == 001
482
483 inline void get_fpsr(Register reg)
484 {
485 mrs(0b11, 0b0100, 0b0100, 0b001, reg);
486 }
487
488 inline void set_fpsr(Register reg)
489 {
490 msr(0b011, 0b0100, 0b0100, 0b001, reg);
491 }
492
493 inline void clear_fpsr()
494 {
1148 Register carry, Register product,
1149 Register idx, Register kdx);
1150 void multiply_128_x_128_loop(Register y, Register z,
1151 Register carry, Register carry2,
1152 Register idx, Register jdx,
1153 Register yz_idx1, Register yz_idx2,
1154 Register tmp, Register tmp3, Register tmp4,
1155 Register tmp7, Register product_hi);
1156 public:
1157 void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1158 Register zlen, Register tmp1, Register tmp2, Register tmp3,
1159 Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1160 // ISB may be needed because of a safepoint
1161 void maybe_isb() { isb(); }
1162
1163 private:
1164 // Return the effective address r + (r1 << ext) + offset.
1165 // Uses rscratch2.
1166 Address offsetted_address(Register r, Register r1, Address::extend ext,
1167 int offset, int size);
1168
1169 private:
1170 // Returns an address on the stack which is reachable with a ldr/str of size
1171 // Uses rscratch2 if the address is not directly reachable
1172 Address spill_address(int size, int offset, Register tmp=rscratch2);
1173
1174 public:
1175 void spill(Register Rx, bool is64, int offset) {
1176 if (is64) {
1177 str(Rx, spill_address(8, offset));
1178 } else {
1179 strw(Rx, spill_address(4, offset));
1180 }
1181 }
1182 void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1183 str(Vx, T, spill_address(1 << (int)T, offset));
1184 }
1185 void unspill(Register Rx, bool is64, int offset) {
1186 if (is64) {
1187 ldr(Rx, spill_address(8, offset));
1188 } else {
1189 ldrw(Rx, spill_address(4, offset));
1190 }
1191 }
1192 void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1193 ldr(Vx, T, spill_address(1 << (int)T, offset));
1194 }
1195 void spill_copy128(int src_offset, int dst_offset,
1196 Register tmp1=rscratch1, Register tmp2=rscratch2) {
1197 if (src_offset < 512 && (src_offset & 7) == 0 &&
1198 dst_offset < 512 && (dst_offset & 7) == 0) {
1199 ldp(tmp1, tmp2, Address(sp, src_offset));
1200 stp(tmp1, tmp2, Address(sp, dst_offset));
1201 } else {
1202 unspill(tmp1, true, src_offset);
1203 spill(tmp1, true, dst_offset);
1204 unspill(tmp1, true, src_offset+8);
1205 spill(tmp1, true, dst_offset+8);
1206 }
1207 }
1208 };
1209
1210 #ifdef ASSERT
1211 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1212 #endif
1213
1214 /**
1215 * class SkipIfEqual:
1216 *
1217 * Instantiating this class will result in assembly code being output that will
1218 * jump around any code emitted between the creation of the instance and it's
1219 * automatic destruction at the end of a scope block, depending on the value of
1220 * the flag passed to the constructor, which will be checked at run-time.
1221 */
1222 class SkipIfEqual {
1223 private:
1224 MacroAssembler* _masm;
1225 Label _label;
1226
1227 public:
|