Mercurial > hg > truffle
comparison src/cpu/x86/vm/assembler_x86.hpp @ 625:2f2f54ed12ce
Merge
author | kvn |
---|---|
date | Tue, 10 Mar 2009 08:52:16 -0700 |
parents | 337400e7a5dd |
children | 660978a2a31a |
comparison
equal
deleted
inserted
replaced
620:bcedf688d882 | 625:2f2f54ed12ce |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
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; } |
234 int disp() const { return _disp; } | 276 int disp() const { return _disp; } |
235 | 277 |
236 // Convert the raw encoding form into the form expected by the constructor for | 278 // Convert the raw encoding form into the form expected by the constructor for |
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, bool disp_is_oop); |
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 } |
1095 | 1136 |
1096 void movsbl(Register dst, Address src); | 1137 void movsbl(Register dst, Address src); |
1097 void movsbl(Register dst, Register src); | 1138 void movsbl(Register dst, Register src); |
1098 | 1139 |
1099 #ifdef _LP64 | 1140 #ifdef _LP64 |
1141 void movsbq(Register dst, Address src); | |
1142 void movsbq(Register dst, Register src); | |
1143 | |
1100 // Move signed 32bit immediate to 64bit extending sign | 1144 // Move signed 32bit immediate to 64bit extending sign |
1101 void movslq(Address dst, int32_t imm64); | 1145 void movslq(Address dst, int32_t imm64); |
1102 void movslq(Register dst, int32_t imm64); | 1146 void movslq(Register dst, int32_t imm64); |
1103 | 1147 |
1104 void movslq(Register dst, Address src); | 1148 void movslq(Register dst, Address src); |
1107 #endif | 1151 #endif |
1108 | 1152 |
1109 void movswl(Register dst, Address src); | 1153 void movswl(Register dst, Address src); |
1110 void movswl(Register dst, Register src); | 1154 void movswl(Register dst, Register src); |
1111 | 1155 |
1156 #ifdef _LP64 | |
1157 void movswq(Register dst, Address src); | |
1158 void movswq(Register dst, Register src); | |
1159 #endif | |
1160 | |
1112 void movw(Address dst, int imm16); | 1161 void movw(Address dst, int imm16); |
1113 void movw(Register dst, Address src); | 1162 void movw(Register dst, Address src); |
1114 void movw(Address dst, Register src); | 1163 void movw(Address dst, Register src); |
1115 | 1164 |
1116 void movzbl(Register dst, Address src); | 1165 void movzbl(Register dst, Address src); |
1117 void movzbl(Register dst, Register src); | 1166 void movzbl(Register dst, Register src); |
1118 | 1167 |
1168 #ifdef _LP64 | |
1169 void movzbq(Register dst, Address src); | |
1170 void movzbq(Register dst, Register src); | |
1171 #endif | |
1172 | |
1119 void movzwl(Register dst, Address src); | 1173 void movzwl(Register dst, Address src); |
1120 void movzwl(Register dst, Register src); | 1174 void movzwl(Register dst, Register src); |
1175 | |
1176 #ifdef _LP64 | |
1177 void movzwq(Register dst, Address src); | |
1178 void movzwq(Register dst, Register src); | |
1179 #endif | |
1121 | 1180 |
1122 void mull(Address src); | 1181 void mull(Address src); |
1123 void mull(Register src); | 1182 void mull(Register src); |
1124 | 1183 |
1125 // Multiply Scalar Double-Precision Floating-Point Values | 1184 // Multiply Scalar Double-Precision Floating-Point Values |
1391 static void pd_print_patched_instruction(address branch); | 1450 static void pd_print_patched_instruction(address branch); |
1392 #endif | 1451 #endif |
1393 | 1452 |
1394 // The following 4 methods return the offset of the appropriate move instruction | 1453 // The following 4 methods return the offset of the appropriate move instruction |
1395 | 1454 |
1396 // Support for fast byte/word loading with zero extension (depending on particular CPU) | 1455 // Support for fast byte/short loading with zero extension (depending on particular CPU) |
1397 int load_unsigned_byte(Register dst, Address src); | 1456 int load_unsigned_byte(Register dst, Address src); |
1398 int load_unsigned_word(Register dst, Address src); | 1457 int load_unsigned_short(Register dst, Address src); |
1399 | 1458 |
1400 // Support for fast byte/word loading with sign extension (depending on particular CPU) | 1459 // Support for fast byte/short loading with sign extension (depending on particular CPU) |
1401 int load_signed_byte(Register dst, Address src); | 1460 int load_signed_byte(Register dst, Address src); |
1402 int load_signed_word(Register dst, Address src); | 1461 int load_signed_short(Register dst, Address src); |
1403 | 1462 |
1404 // Support for sign-extension (hi:lo = extend_sign(lo)) | 1463 // Support for sign-extension (hi:lo = extend_sign(lo)) |
1405 void extend_sign(Register hi, Register lo); | 1464 void extend_sign(Register hi, Register lo); |
1465 | |
1466 // Loading values by size and signed-ness | |
1467 void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed); | |
1406 | 1468 |
1407 // Support for inc/dec with optimal instruction selection depending on value | 1469 // Support for inc/dec with optimal instruction selection depending on value |
1408 | 1470 |
1409 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } | 1471 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)) ; } | 1472 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } |
1719 Register t2, // temp register | 1781 Register t2, // temp register |
1720 Label& slow_case // continuation point if fast allocation fails | 1782 Label& slow_case // continuation point if fast allocation fails |
1721 ); | 1783 ); |
1722 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); | 1784 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); |
1723 | 1785 |
1786 // interface method calling | |
1787 void lookup_interface_method(Register recv_klass, | |
1788 Register intf_klass, | |
1789 RegisterConstant itable_index, | |
1790 Register method_result, | |
1791 Register scan_temp, | |
1792 Label& no_such_interface); | |
1793 | |
1724 //---- | 1794 //---- |
1725 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 | 1795 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 |
1726 | 1796 |
1727 // Debugging | 1797 // Debugging |
1728 | 1798 |
1760 } | 1830 } |
1761 | 1831 |
1762 // Writes to stack successive pages until offset reached to check for | 1832 // Writes to stack successive pages until offset reached to check for |
1763 // stack overflow + shadow pages. Also, clobbers tmp | 1833 // stack overflow + shadow pages. Also, clobbers tmp |
1764 void bang_stack_size(Register size, Register tmp); | 1834 void bang_stack_size(Register size, Register tmp); |
1835 | |
1836 virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr, | |
1837 Register tmp, | |
1838 int offset); | |
1765 | 1839 |
1766 // Support for serializing memory accesses between threads | 1840 // Support for serializing memory accesses between threads |
1767 void serialize_memory(Register thread, Register tmp); | 1841 void serialize_memory(Register thread, Register tmp); |
1768 | 1842 |
1769 void verify_tlab(); | 1843 void verify_tlab(); |