133 }
134
135 void addmw(Address a, Register incr, Register scratch) {
136 ldrw(scratch, a);
137 addw(scratch, scratch, incr);
138 strw(scratch, a);
139 }
140
141 // Add constant to memory word
142 void addmw(Address a, int imm, Register scratch) {
143 ldrw(scratch, a);
144 if (imm > 0)
145 addw(scratch, scratch, (unsigned)imm);
146 else
147 subw(scratch, scratch, (unsigned)-imm);
148 strw(scratch, a);
149 }
150
151 void bind(Label& L) {
152 Assembler::bind(L);
153 code()->clear_last_membar();
154 }
155
156 void membar(Membar_mask_bits order_constraint);
157
158 // Frame creation and destruction shared between JITs.
159 void build_frame(int framesize);
160 void remove_frame(int framesize);
161
162 virtual void _call_Unimplemented(address call_site) {
163 mov(rscratch2, call_site);
164 haltsim();
165 }
166
167 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
168
169 virtual void notify(int type);
170
171 // aliases defined in AARCH64 spec
172
173 template<class T>
174 inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
175 // imm is limited to 12 bits.
176 inline void cmp(Register Rd, unsigned imm) { subs(zr, Rd, imm); }
177
1273 Register len, Register tmp0, Register tmp1, Register tmp2,
1274 Register tmp3);
1275 public:
1276 void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1277 Register zlen, Register tmp1, Register tmp2, Register tmp3,
1278 Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1279 void mul_add(Register out, Register in, Register offs, Register len, Register k);
1280 // ISB may be needed because of a safepoint
1281 void maybe_isb() { isb(); }
1282
1283 private:
1284 // Return the effective address r + (r1 << ext) + offset.
1285 // Uses rscratch2.
1286 Address offsetted_address(Register r, Register r1, Address::extend ext,
1287 int offset, int size);
1288
1289 private:
1290 // Returns an address on the stack which is reachable with a ldr/str of size
1291 // Uses rscratch2 if the address is not directly reachable
1292 Address spill_address(int size, int offset, Register tmp=rscratch2);
1293
1294 public:
1295 void spill(Register Rx, bool is64, int offset) {
1296 if (is64) {
1297 str(Rx, spill_address(8, offset));
1298 } else {
1299 strw(Rx, spill_address(4, offset));
1300 }
1301 }
1302 void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1303 str(Vx, T, spill_address(1 << (int)T, offset));
1304 }
1305 void unspill(Register Rx, bool is64, int offset) {
1306 if (is64) {
1307 ldr(Rx, spill_address(8, offset));
1308 } else {
1309 ldrw(Rx, spill_address(4, offset));
1310 }
1311 }
1312 void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
|
133 }
134
135 void addmw(Address a, Register incr, Register scratch) {
136 ldrw(scratch, a);
137 addw(scratch, scratch, incr);
138 strw(scratch, a);
139 }
140
141 // Add constant to memory word
142 void addmw(Address a, int imm, Register scratch) {
143 ldrw(scratch, a);
144 if (imm > 0)
145 addw(scratch, scratch, (unsigned)imm);
146 else
147 subw(scratch, scratch, (unsigned)-imm);
148 strw(scratch, a);
149 }
150
151 void bind(Label& L) {
152 Assembler::bind(L);
153 code()->clear_last_insn();
154 }
155
156 void membar(Membar_mask_bits order_constraint);
157
158 using Assembler::ldr;
159 using Assembler::str;
160
161 void ldr(Register Rx, const Address &adr);
162 void ldrw(Register Rw, const Address &adr);
163 void str(Register Rx, const Address &adr);
164 void strw(Register Rx, const Address &adr);
165
166 // Frame creation and destruction shared between JITs.
167 void build_frame(int framesize);
168 void remove_frame(int framesize);
169
170 virtual void _call_Unimplemented(address call_site) {
171 mov(rscratch2, call_site);
172 haltsim();
173 }
174
175 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
176
177 virtual void notify(int type);
178
179 // aliases defined in AARCH64 spec
180
181 template<class T>
182 inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
183 // imm is limited to 12 bits.
184 inline void cmp(Register Rd, unsigned imm) { subs(zr, Rd, imm); }
185
1281 Register len, Register tmp0, Register tmp1, Register tmp2,
1282 Register tmp3);
1283 public:
1284 void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1285 Register zlen, Register tmp1, Register tmp2, Register tmp3,
1286 Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1287 void mul_add(Register out, Register in, Register offs, Register len, Register k);
1288 // ISB may be needed because of a safepoint
1289 void maybe_isb() { isb(); }
1290
1291 private:
1292 // Return the effective address r + (r1 << ext) + offset.
1293 // Uses rscratch2.
1294 Address offsetted_address(Register r, Register r1, Address::extend ext,
1295 int offset, int size);
1296
1297 private:
1298 // Returns an address on the stack which is reachable with a ldr/str of size
1299 // Uses rscratch2 if the address is not directly reachable
1300 Address spill_address(int size, int offset, Register tmp=rscratch2);
1301
1302 bool merge_alignment_check(Register base, size_t size, long cur_offset, long prev_offset) const;
1303
1304 // Check whether two loads/stores can be merged into ldp/stp.
1305 bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
1306
1307 // Merge current load/store with previous load/store into ldp/stp.
1308 void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1309
1310 // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
1311 bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1312
1313 public:
1314 void spill(Register Rx, bool is64, int offset) {
1315 if (is64) {
1316 str(Rx, spill_address(8, offset));
1317 } else {
1318 strw(Rx, spill_address(4, offset));
1319 }
1320 }
1321 void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1322 str(Vx, T, spill_address(1 << (int)T, offset));
1323 }
1324 void unspill(Register Rx, bool is64, int offset) {
1325 if (is64) {
1326 ldr(Rx, spill_address(8, offset));
1327 } else {
1328 ldrw(Rx, spill_address(4, offset));
1329 }
1330 }
1331 void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
|