comparison src/cpu/x86/vm/assembler_x86.hpp @ 622:56aae7be60d4

6812678: macro assembler needs delayed binding of a few constants (for 6655638) Summary: minor assembler enhancements preparing for method handles Reviewed-by: kvn
author jrose
date Wed, 04 Mar 2009 09:58:39 -0800
parents a1980da045cc
children 9adddb8c0fc8
comparison
equal deleted inserted replaced
621:19f25e603e7b 622:56aae7be60d4
151 times_2 = 1, 151 times_2 = 1,
152 times_4 = 2, 152 times_4 = 2,
153 times_8 = 3, 153 times_8 = 3,
154 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4) 154 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
155 }; 155 };
156 static ScaleFactor times(int size) {
157 assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
158 if (size == 8) return times_8;
159 if (size == 4) return times_4;
160 if (size == 2) return times_2;
161 return times_1;
162 }
163 static int scale_size(ScaleFactor scale) {
164 assert(scale != no_scale, "");
165 assert(((1 << (int)times_1) == 1 &&
166 (1 << (int)times_2) == 2 &&
167 (1 << (int)times_4) == 4 &&
168 (1 << (int)times_8) == 8), "");
169 return (1 << (int)scale);
170 }
156 171
157 private: 172 private:
158 Register _base; 173 Register _base;
159 Register _index; 174 Register _index;
160 ScaleFactor _scale; 175 ScaleFactor _scale;
193 _index(index), 208 _index(index),
194 _scale(scale), 209 _scale(scale),
195 _disp (disp) { 210 _disp (disp) {
196 assert(!index->is_valid() == (scale == Address::no_scale), 211 assert(!index->is_valid() == (scale == Address::no_scale),
197 "inconsistent address"); 212 "inconsistent address");
213 }
214
215 Address(Register base, RegisterConstant index, ScaleFactor scale = times_1, int disp = 0)
216 : _base (base),
217 _index(index.register_or_noreg()),
218 _scale(scale),
219 _disp (disp + (index.constant_or_zero() * scale_size(scale))) {
220 if (!index.is_register()) scale = Address::no_scale;
221 assert(!_index->is_valid() == (scale == Address::no_scale),
222 "inconsistent address");
223 }
224
225 Address plus_disp(int disp) const {
226 Address a = (*this);
227 a._disp += disp;
228 return a;
198 } 229 }
199 230
200 // The following two overloads are used in connection with the 231 // The following two overloads are used in connection with the
201 // ByteSize type (see sizes.hpp). They simplify the use of 232 // ByteSize type (see sizes.hpp). They simplify the use of
202 // ByteSize'd arguments in assembly code. Note that their equivalent 233 // ByteSize'd arguments in assembly code. Note that their equivalent
222 _scale(scale), 253 _scale(scale),
223 _disp(in_bytes(disp)) { 254 _disp(in_bytes(disp)) {
224 assert(!index->is_valid() == (scale == Address::no_scale), 255 assert(!index->is_valid() == (scale == Address::no_scale),
225 "inconsistent address"); 256 "inconsistent address");
226 } 257 }
258
259 Address(Register base, RegisterConstant index, ScaleFactor scale, ByteSize disp)
260 : _base (base),
261 _index(index.register_or_noreg()),
262 _scale(scale),
263 _disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) {
264 if (!index.is_register()) scale = Address::no_scale;
265 assert(!_index->is_valid() == (scale == Address::no_scale),
266 "inconsistent address");
267 }
268
227 #endif // ASSERT 269 #endif // ASSERT
228 270
229 // accessors 271 // accessors
230 bool uses(Register reg) const { return _base == reg || _index == reg; } 272 bool uses(Register reg) const { return _base == reg || _index == reg; }
231 Register base() const { return _base; } 273 Register base() const { return _base; }
237 // Address. An index of 4 (rsp) corresponds to having no index, so convert 279 // Address. An index of 4 (rsp) corresponds to having no index, so convert
238 // that to noreg for the Address constructor. 280 // that to noreg for the Address constructor.
239 static Address make_raw(int base, int index, int scale, int disp); 281 static Address make_raw(int base, int index, int scale, int disp);
240 282
241 static Address make_array(ArrayAddress); 283 static Address make_array(ArrayAddress);
242
243 284
244 private: 285 private:
245 bool base_needs_rex() const { 286 bool base_needs_rex() const {
246 return _base != noreg && _base->encoding() >= 8; 287 return _base != noreg && _base->encoding() >= 8;
247 } 288 }
1391 static void pd_print_patched_instruction(address branch); 1432 static void pd_print_patched_instruction(address branch);
1392 #endif 1433 #endif
1393 1434
1394 // The following 4 methods return the offset of the appropriate move instruction 1435 // The following 4 methods return the offset of the appropriate move instruction
1395 1436
1396 // Support for fast byte/word loading with zero extension (depending on particular CPU) 1437 // Support for fast byte/short loading with zero extension (depending on particular CPU)
1397 int load_unsigned_byte(Register dst, Address src); 1438 int load_unsigned_byte(Register dst, Address src);
1398 int load_unsigned_word(Register dst, Address src); 1439 int load_unsigned_short(Register dst, Address src);
1399 1440
1400 // Support for fast byte/word loading with sign extension (depending on particular CPU) 1441 // Support for fast byte/short loading with sign extension (depending on particular CPU)
1401 int load_signed_byte(Register dst, Address src); 1442 int load_signed_byte(Register dst, Address src);
1402 int load_signed_word(Register dst, Address src); 1443 int load_signed_short(Register dst, Address src);
1403 1444
1404 // Support for sign-extension (hi:lo = extend_sign(lo)) 1445 // Support for sign-extension (hi:lo = extend_sign(lo))
1405 void extend_sign(Register hi, Register lo); 1446 void extend_sign(Register hi, Register lo);
1447
1448 // Loading values by size and signed-ness
1449 void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed);
1406 1450
1407 // Support for inc/dec with optimal instruction selection depending on value 1451 // Support for inc/dec with optimal instruction selection depending on value
1408 1452
1409 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } 1453 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
1410 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } 1454 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; }
1761 1805
1762 // Writes to stack successive pages until offset reached to check for 1806 // Writes to stack successive pages until offset reached to check for
1763 // stack overflow + shadow pages. Also, clobbers tmp 1807 // stack overflow + shadow pages. Also, clobbers tmp
1764 void bang_stack_size(Register size, Register tmp); 1808 void bang_stack_size(Register size, Register tmp);
1765 1809
1810 virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr,
1811 Register tmp,
1812 int offset);
1813
1766 // Support for serializing memory accesses between threads 1814 // Support for serializing memory accesses between threads
1767 void serialize_memory(Register thread, Register tmp); 1815 void serialize_memory(Register thread, Register tmp);
1768 1816
1769 void verify_tlab(); 1817 void verify_tlab();
1770 1818