Mercurial > hg > graal-compiler
annotate src/cpu/x86/vm/assembler_x86.hpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | ac637b7220d1 |
children | 2f644f85485d |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1503
diff
changeset
|
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1503
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1503
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1503
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef CPU_X86_VM_ASSEMBLER_X86_HPP |
26 #define CPU_X86_VM_ASSEMBLER_X86_HPP | |
27 | |
0 | 28 class BiasedLockingCounters; |
29 | |
30 // Contains all the definitions needed for x86 assembly code generation. | |
31 | |
32 // Calling convention | |
33 class Argument VALUE_OBJ_CLASS_SPEC { | |
34 public: | |
35 enum { | |
36 #ifdef _LP64 | |
37 #ifdef _WIN64 | |
38 n_int_register_parameters_c = 4, // rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) | |
39 n_float_register_parameters_c = 4, // xmm0 - xmm3 (c_farg0, c_farg1, ... ) | |
40 #else | |
41 n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) | |
42 n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... ) | |
43 #endif // _WIN64 | |
44 n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ... | |
45 n_float_register_parameters_j = 8 // j_farg0, j_farg1, ... | |
46 #else | |
47 n_register_parameters = 0 // 0 registers used to pass arguments | |
48 #endif // _LP64 | |
49 }; | |
50 }; | |
51 | |
52 | |
53 #ifdef _LP64 | |
54 // Symbolically name the register arguments used by the c calling convention. | |
55 // Windows is different from linux/solaris. So much for standards... | |
56 | |
57 #ifdef _WIN64 | |
58 | |
59 REGISTER_DECLARATION(Register, c_rarg0, rcx); | |
60 REGISTER_DECLARATION(Register, c_rarg1, rdx); | |
61 REGISTER_DECLARATION(Register, c_rarg2, r8); | |
62 REGISTER_DECLARATION(Register, c_rarg3, r9); | |
63 | |
304 | 64 REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); |
65 REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); | |
66 REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); | |
67 REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); | |
0 | 68 |
69 #else | |
70 | |
71 REGISTER_DECLARATION(Register, c_rarg0, rdi); | |
72 REGISTER_DECLARATION(Register, c_rarg1, rsi); | |
73 REGISTER_DECLARATION(Register, c_rarg2, rdx); | |
74 REGISTER_DECLARATION(Register, c_rarg3, rcx); | |
75 REGISTER_DECLARATION(Register, c_rarg4, r8); | |
76 REGISTER_DECLARATION(Register, c_rarg5, r9); | |
77 | |
304 | 78 REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0); |
79 REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1); | |
80 REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2); | |
81 REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3); | |
82 REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4); | |
83 REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5); | |
84 REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6); | |
85 REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7); | |
0 | 86 |
87 #endif // _WIN64 | |
88 | |
89 // Symbolically name the register arguments used by the Java calling convention. | |
90 // We have control over the convention for java so we can do what we please. | |
91 // What pleases us is to offset the java calling convention so that when | |
92 // we call a suitable jni method the arguments are lined up and we don't | |
93 // have to do little shuffling. A suitable jni method is non-static and a | |
94 // small number of arguments (two fewer args on windows) | |
95 // | |
96 // |-------------------------------------------------------| | |
97 // | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 | | |
98 // |-------------------------------------------------------| | |
99 // | rcx rdx r8 r9 rdi* rsi* | windows (* not a c_rarg) | |
100 // | rdi rsi rdx rcx r8 r9 | solaris/linux | |
101 // |-------------------------------------------------------| | |
102 // | j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 | | |
103 // |-------------------------------------------------------| | |
104 | |
105 REGISTER_DECLARATION(Register, j_rarg0, c_rarg1); | |
106 REGISTER_DECLARATION(Register, j_rarg1, c_rarg2); | |
107 REGISTER_DECLARATION(Register, j_rarg2, c_rarg3); | |
108 // Windows runs out of register args here | |
109 #ifdef _WIN64 | |
110 REGISTER_DECLARATION(Register, j_rarg3, rdi); | |
111 REGISTER_DECLARATION(Register, j_rarg4, rsi); | |
112 #else | |
113 REGISTER_DECLARATION(Register, j_rarg3, c_rarg4); | |
114 REGISTER_DECLARATION(Register, j_rarg4, c_rarg5); | |
115 #endif /* _WIN64 */ | |
116 REGISTER_DECLARATION(Register, j_rarg5, c_rarg0); | |
117 | |
304 | 118 REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0); |
119 REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1); | |
120 REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2); | |
121 REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3); | |
122 REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4); | |
123 REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5); | |
124 REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6); | |
125 REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7); | |
0 | 126 |
127 REGISTER_DECLARATION(Register, rscratch1, r10); // volatile | |
128 REGISTER_DECLARATION(Register, rscratch2, r11); // volatile | |
129 | |
304 | 130 REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved |
0 | 131 REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved |
132 | |
304 | 133 #else |
134 // rscratch1 will apear in 32bit code that is dead but of course must compile | |
135 // Using noreg ensures if the dead code is incorrectly live and executed it | |
136 // will cause an assertion failure | |
137 #define rscratch1 noreg | |
2002 | 138 #define rscratch2 noreg |
304 | 139 |
0 | 140 #endif // _LP64 |
141 | |
1564 | 142 // JSR 292 fixed register usages: |
143 REGISTER_DECLARATION(Register, rbp_mh_SP_save, rbp); | |
144 | |
0 | 145 // Address is an abstraction used to represent a memory location |
146 // using any of the amd64 addressing modes with one object. | |
147 // | |
148 // Note: A register location is represented via a Register, not | |
149 // via an address for efficiency & simplicity reasons. | |
150 | |
151 class ArrayAddress; | |
152 | |
153 class Address VALUE_OBJ_CLASS_SPEC { | |
154 public: | |
155 enum ScaleFactor { | |
156 no_scale = -1, | |
157 times_1 = 0, | |
158 times_2 = 1, | |
159 times_4 = 2, | |
304 | 160 times_8 = 3, |
161 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4) | |
0 | 162 }; |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
163 static ScaleFactor times(int size) { |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
164 assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size"); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
165 if (size == 8) return times_8; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
166 if (size == 4) return times_4; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
167 if (size == 2) return times_2; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
168 return times_1; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
169 } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
170 static int scale_size(ScaleFactor scale) { |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
171 assert(scale != no_scale, ""); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
172 assert(((1 << (int)times_1) == 1 && |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
173 (1 << (int)times_2) == 2 && |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
174 (1 << (int)times_4) == 4 && |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
175 (1 << (int)times_8) == 8), ""); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
176 return (1 << (int)scale); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
177 } |
0 | 178 |
179 private: | |
180 Register _base; | |
181 Register _index; | |
182 ScaleFactor _scale; | |
183 int _disp; | |
184 RelocationHolder _rspec; | |
185 | |
304 | 186 // Easily misused constructors make them private |
187 // %%% can we make these go away? | |
188 NOT_LP64(Address(address loc, RelocationHolder spec);) | |
189 Address(int disp, address loc, relocInfo::relocType rtype); | |
190 Address(int disp, address loc, RelocationHolder spec); | |
0 | 191 |
192 public: | |
304 | 193 |
194 int disp() { return _disp; } | |
0 | 195 // creation |
196 Address() | |
197 : _base(noreg), | |
198 _index(noreg), | |
199 _scale(no_scale), | |
200 _disp(0) { | |
201 } | |
202 | |
203 // No default displacement otherwise Register can be implicitly | |
204 // converted to 0(Register) which is quite a different animal. | |
205 | |
206 Address(Register base, int disp) | |
207 : _base(base), | |
208 _index(noreg), | |
209 _scale(no_scale), | |
210 _disp(disp) { | |
211 } | |
212 | |
213 Address(Register base, Register index, ScaleFactor scale, int disp = 0) | |
214 : _base (base), | |
215 _index(index), | |
216 _scale(scale), | |
217 _disp (disp) { | |
218 assert(!index->is_valid() == (scale == Address::no_scale), | |
219 "inconsistent address"); | |
220 } | |
221 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
222 Address(Register base, RegisterOrConstant index, ScaleFactor scale = times_1, int disp = 0) |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
223 : _base (base), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
224 _index(index.register_or_noreg()), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
225 _scale(scale), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
226 _disp (disp + (index.constant_or_zero() * scale_size(scale))) { |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
227 if (!index.is_register()) scale = Address::no_scale; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
228 assert(!_index->is_valid() == (scale == Address::no_scale), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
229 "inconsistent address"); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
230 } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
231 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
232 Address plus_disp(int disp) const { |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
233 Address a = (*this); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
234 a._disp += disp; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
235 return a; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
236 } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
237 |
0 | 238 // The following two overloads are used in connection with the |
239 // ByteSize type (see sizes.hpp). They simplify the use of | |
240 // ByteSize'd arguments in assembly code. Note that their equivalent | |
241 // for the optimized build are the member functions with int disp | |
242 // argument since ByteSize is mapped to an int type in that case. | |
243 // | |
244 // Note: DO NOT introduce similar overloaded functions for WordSize | |
245 // arguments as in the optimized mode, both ByteSize and WordSize | |
246 // are mapped to the same type and thus the compiler cannot make a | |
247 // distinction anymore (=> compiler errors). | |
248 | |
249 #ifdef ASSERT | |
250 Address(Register base, ByteSize disp) | |
251 : _base(base), | |
252 _index(noreg), | |
253 _scale(no_scale), | |
254 _disp(in_bytes(disp)) { | |
255 } | |
256 | |
257 Address(Register base, Register index, ScaleFactor scale, ByteSize disp) | |
258 : _base(base), | |
259 _index(index), | |
260 _scale(scale), | |
261 _disp(in_bytes(disp)) { | |
262 assert(!index->is_valid() == (scale == Address::no_scale), | |
263 "inconsistent address"); | |
264 } | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
265 |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
266 Address(Register base, RegisterOrConstant index, ScaleFactor scale, ByteSize disp) |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
267 : _base (base), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
268 _index(index.register_or_noreg()), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
269 _scale(scale), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
270 _disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) { |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
271 if (!index.is_register()) scale = Address::no_scale; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
272 assert(!_index->is_valid() == (scale == Address::no_scale), |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
273 "inconsistent address"); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
274 } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
275 |
0 | 276 #endif // ASSERT |
277 | |
278 // accessors | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
279 bool uses(Register reg) const { return _base == reg || _index == reg; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
280 Register base() const { return _base; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
281 Register index() const { return _index; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
282 ScaleFactor scale() const { return _scale; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
283 int disp() const { return _disp; } |
0 | 284 |
285 // Convert the raw encoding form into the form expected by the constructor for | |
286 // Address. An index of 4 (rsp) corresponds to having no index, so convert | |
287 // that to noreg for the Address constructor. | |
624 | 288 static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop); |
0 | 289 |
290 static Address make_array(ArrayAddress); | |
291 | |
292 private: | |
293 bool base_needs_rex() const { | |
294 return _base != noreg && _base->encoding() >= 8; | |
295 } | |
296 | |
297 bool index_needs_rex() const { | |
298 return _index != noreg &&_index->encoding() >= 8; | |
299 } | |
300 | |
301 relocInfo::relocType reloc() const { return _rspec.type(); } | |
302 | |
303 friend class Assembler; | |
304 friend class MacroAssembler; | |
305 friend class LIR_Assembler; // base/index/scale/disp | |
306 }; | |
307 | |
308 // | |
309 // AddressLiteral has been split out from Address because operands of this type | |
310 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out | |
311 // the few instructions that need to deal with address literals are unique and the | |
312 // MacroAssembler does not have to implement every instruction in the Assembler | |
313 // in order to search for address literals that may need special handling depending | |
314 // on the instruction and the platform. As small step on the way to merging i486/amd64 | |
315 // directories. | |
316 // | |
317 class AddressLiteral VALUE_OBJ_CLASS_SPEC { | |
318 friend class ArrayAddress; | |
319 RelocationHolder _rspec; | |
320 // Typically we use AddressLiterals we want to use their rval | |
321 // However in some situations we want the lval (effect address) of the item. | |
322 // We provide a special factory for making those lvals. | |
323 bool _is_lval; | |
324 | |
325 // If the target is far we'll need to load the ea of this to | |
326 // a register to reach it. Otherwise if near we can do rip | |
327 // relative addressing. | |
328 | |
329 address _target; | |
330 | |
331 protected: | |
332 // creation | |
333 AddressLiteral() | |
334 : _is_lval(false), | |
335 _target(NULL) | |
336 {} | |
337 | |
338 public: | |
339 | |
340 | |
341 AddressLiteral(address target, relocInfo::relocType rtype); | |
342 | |
343 AddressLiteral(address target, RelocationHolder const& rspec) | |
344 : _rspec(rspec), | |
345 _is_lval(false), | |
346 _target(target) | |
347 {} | |
348 | |
349 AddressLiteral addr() { | |
350 AddressLiteral ret = *this; | |
351 ret._is_lval = true; | |
352 return ret; | |
353 } | |
354 | |
355 | |
356 private: | |
357 | |
358 address target() { return _target; } | |
359 bool is_lval() { return _is_lval; } | |
360 | |
361 relocInfo::relocType reloc() const { return _rspec.type(); } | |
362 const RelocationHolder& rspec() const { return _rspec; } | |
363 | |
364 friend class Assembler; | |
365 friend class MacroAssembler; | |
366 friend class Address; | |
367 friend class LIR_Assembler; | |
368 }; | |
369 | |
370 // Convience classes | |
371 class RuntimeAddress: public AddressLiteral { | |
372 | |
373 public: | |
374 | |
375 RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {} | |
376 | |
377 }; | |
378 | |
379 class OopAddress: public AddressLiteral { | |
380 | |
381 public: | |
382 | |
383 OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){} | |
384 | |
385 }; | |
386 | |
387 class ExternalAddress: public AddressLiteral { | |
388 | |
389 public: | |
390 | |
391 ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){} | |
392 | |
393 }; | |
394 | |
395 class InternalAddress: public AddressLiteral { | |
396 | |
397 public: | |
398 | |
399 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {} | |
400 | |
401 }; | |
402 | |
403 // x86 can do array addressing as a single operation since disp can be an absolute | |
404 // address amd64 can't. We create a class that expresses the concept but does extra | |
405 // magic on amd64 to get the final result | |
406 | |
407 class ArrayAddress VALUE_OBJ_CLASS_SPEC { | |
408 private: | |
409 | |
410 AddressLiteral _base; | |
411 Address _index; | |
412 | |
413 public: | |
414 | |
415 ArrayAddress() {}; | |
416 ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {}; | |
417 AddressLiteral base() { return _base; } | |
418 Address index() { return _index; } | |
419 | |
420 }; | |
421 | |
304 | 422 const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize); |
0 | 423 |
424 // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction | |
425 // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write | |
426 // is what you get. The Assembler is generating code into a CodeBuffer. | |
427 | |
428 class Assembler : public AbstractAssembler { | |
429 friend class AbstractAssembler; // for the non-virtual hack | |
430 friend class LIR_Assembler; // as_Address() | |
304 | 431 friend class StubGenerator; |
0 | 432 |
433 public: | |
434 enum Condition { // The x86 condition codes used for conditional jumps/moves. | |
435 zero = 0x4, | |
436 notZero = 0x5, | |
437 equal = 0x4, | |
438 notEqual = 0x5, | |
439 less = 0xc, | |
440 lessEqual = 0xe, | |
441 greater = 0xf, | |
442 greaterEqual = 0xd, | |
443 below = 0x2, | |
444 belowEqual = 0x6, | |
445 above = 0x7, | |
446 aboveEqual = 0x3, | |
447 overflow = 0x0, | |
448 noOverflow = 0x1, | |
449 carrySet = 0x2, | |
450 carryClear = 0x3, | |
451 negative = 0x8, | |
452 positive = 0x9, | |
453 parity = 0xa, | |
454 noParity = 0xb | |
455 }; | |
456 | |
457 enum Prefix { | |
458 // segment overrides | |
459 CS_segment = 0x2e, | |
460 SS_segment = 0x36, | |
461 DS_segment = 0x3e, | |
462 ES_segment = 0x26, | |
463 FS_segment = 0x64, | |
464 GS_segment = 0x65, | |
465 | |
466 REX = 0x40, | |
467 | |
468 REX_B = 0x41, | |
469 REX_X = 0x42, | |
470 REX_XB = 0x43, | |
471 REX_R = 0x44, | |
472 REX_RB = 0x45, | |
473 REX_RX = 0x46, | |
474 REX_RXB = 0x47, | |
475 | |
476 REX_W = 0x48, | |
477 | |
478 REX_WB = 0x49, | |
479 REX_WX = 0x4A, | |
480 REX_WXB = 0x4B, | |
481 REX_WR = 0x4C, | |
482 REX_WRB = 0x4D, | |
483 REX_WRX = 0x4E, | |
484 REX_WRXB = 0x4F | |
485 }; | |
486 | |
487 enum WhichOperand { | |
488 // input to locate_operand, and format code for relocations | |
304 | 489 imm_operand = 0, // embedded 32-bit|64-bit immediate operand |
0 | 490 disp32_operand = 1, // embedded 32-bit displacement or address |
491 call32_operand = 2, // embedded 32-bit self-relative displacement | |
304 | 492 #ifndef _LP64 |
0 | 493 _WhichOperand_limit = 3 |
304 | 494 #else |
495 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop | |
496 _WhichOperand_limit = 4 | |
497 #endif | |
0 | 498 }; |
499 | |
304 | 500 |
501 | |
502 // NOTE: The general philopsophy of the declarations here is that 64bit versions | |
503 // of instructions are freely declared without the need for wrapping them an ifdef. | |
504 // (Some dangerous instructions are ifdef's out of inappropriate jvm's.) | |
505 // In the .cpp file the implementations are wrapped so that they are dropped out | |
506 // of the resulting jvm. This is done mostly to keep the footprint of KERNEL | |
507 // to the size it was prior to merging up the 32bit and 64bit assemblers. | |
508 // | |
509 // This does mean you'll get a linker/runtime error if you use a 64bit only instruction | |
510 // in a 32bit vm. This is somewhat unfortunate but keeps the ifdef noise down. | |
511 | |
512 private: | |
513 | |
514 | |
515 // 64bit prefixes | |
516 int prefix_and_encode(int reg_enc, bool byteinst = false); | |
517 int prefixq_and_encode(int reg_enc); | |
518 | |
519 int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); | |
520 int prefixq_and_encode(int dst_enc, int src_enc); | |
521 | |
522 void prefix(Register reg); | |
523 void prefix(Address adr); | |
524 void prefixq(Address adr); | |
525 | |
526 void prefix(Address adr, Register reg, bool byteinst = false); | |
527 void prefixq(Address adr, Register reg); | |
528 | |
529 void prefix(Address adr, XMMRegister reg); | |
530 | |
531 void prefetch_prefix(Address src); | |
532 | |
533 // Helper functions for groups of instructions | |
534 void emit_arith_b(int op1, int op2, Register dst, int imm8); | |
535 | |
536 void emit_arith(int op1, int op2, Register dst, int32_t imm32); | |
537 // only 32bit?? | |
538 void emit_arith(int op1, int op2, Register dst, jobject obj); | |
539 void emit_arith(int op1, int op2, Register dst, Register src); | |
540 | |
541 void emit_operand(Register reg, | |
542 Register base, Register index, Address::ScaleFactor scale, | |
543 int disp, | |
544 RelocationHolder const& rspec, | |
545 int rip_relative_correction = 0); | |
546 | |
547 void emit_operand(Register reg, Address adr, int rip_relative_correction = 0); | |
548 | |
549 // operands that only take the original 32bit registers | |
550 void emit_operand32(Register reg, Address adr); | |
551 | |
552 void emit_operand(XMMRegister reg, | |
553 Register base, Register index, Address::ScaleFactor scale, | |
554 int disp, | |
555 RelocationHolder const& rspec); | |
556 | |
557 void emit_operand(XMMRegister reg, Address adr); | |
558 | |
559 void emit_operand(MMXRegister reg, Address adr); | |
560 | |
561 // workaround gcc (3.2.1-7) bug | |
562 void emit_operand(Address adr, MMXRegister reg); | |
563 | |
564 | |
565 // Immediate-to-memory forms | |
566 void emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32); | |
567 | |
568 void emit_farith(int b1, int b2, int i); | |
569 | |
570 | |
571 protected: | |
572 #ifdef ASSERT | |
573 void check_relocation(RelocationHolder const& rspec, int format); | |
574 #endif | |
575 | |
576 inline void emit_long64(jlong x); | |
577 | |
578 void emit_data(jint data, relocInfo::relocType rtype, int format); | |
579 void emit_data(jint data, RelocationHolder const& rspec, int format); | |
580 void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); | |
581 void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); | |
582 | |
583 | |
584 bool reachable(AddressLiteral adr) NOT_LP64({ return true;}); | |
585 | |
586 // These are all easily abused and hence protected | |
587 | |
588 // 32BIT ONLY SECTION | |
589 #ifndef _LP64 | |
590 // Make these disappear in 64bit mode since they would never be correct | |
591 void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
592 void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
593 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
594 void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY |
304 | 595 void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY |
596 | |
597 void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
598 #else | |
599 // 64BIT ONLY SECTION | |
600 void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); // 64BIT ONLY | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
601 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
602 void cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
603 void cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
604 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
605 void mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
606 void mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec); |
304 | 607 #endif // _LP64 |
608 | |
609 // These are unique in that we are ensured by the caller that the 32bit | |
610 // relative in these instructions will always be able to reach the potentially | |
611 // 64bit address described by entry. Since they can take a 64bit address they | |
612 // don't have the 32 suffix like the other instructions in this class. | |
613 | |
614 void call_literal(address entry, RelocationHolder const& rspec); | |
615 void jmp_literal(address entry, RelocationHolder const& rspec); | |
616 | |
617 // Avoid using directly section | |
618 // Instructions in this section are actually usable by anyone without danger | |
619 // of failure but have performance issues that are addressed my enhanced | |
620 // instructions which will do the proper thing base on the particular cpu. | |
621 // We protect them because we don't trust you... | |
622 | |
623 // Don't use next inc() and dec() methods directly. INC & DEC instructions | |
624 // could cause a partial flag stall since they don't set CF flag. | |
625 // Use MacroAssembler::decrement() & MacroAssembler::increment() methods | |
626 // which call inc() & dec() or add() & sub() in accordance with | |
627 // the product flag UseIncDec value. | |
628 | |
629 void decl(Register dst); | |
630 void decl(Address dst); | |
631 void decq(Register dst); | |
632 void decq(Address dst); | |
633 | |
634 void incl(Register dst); | |
635 void incl(Address dst); | |
636 void incq(Register dst); | |
637 void incq(Address dst); | |
638 | |
639 // New cpus require use of movsd and movss to avoid partial register stall | |
640 // when loading from memory. But for old Opteron use movlpd instead of movsd. | |
641 // The selection is done in MacroAssembler::movdbl() and movflt(). | |
642 | |
643 // Move Scalar Single-Precision Floating-Point Values | |
644 void movss(XMMRegister dst, Address src); | |
645 void movss(XMMRegister dst, XMMRegister src); | |
646 void movss(Address dst, XMMRegister src); | |
647 | |
648 // Move Scalar Double-Precision Floating-Point Values | |
649 void movsd(XMMRegister dst, Address src); | |
650 void movsd(XMMRegister dst, XMMRegister src); | |
651 void movsd(Address dst, XMMRegister src); | |
652 void movlpd(XMMRegister dst, Address src); | |
653 | |
654 // New cpus require use of movaps and movapd to avoid partial register stall | |
655 // when moving between registers. | |
656 void movaps(XMMRegister dst, XMMRegister src); | |
657 void movapd(XMMRegister dst, XMMRegister src); | |
658 | |
659 // End avoid using directly | |
660 | |
661 | |
662 // Instruction prefixes | |
663 void prefix(Prefix p); | |
664 | |
0 | 665 public: |
666 | |
667 // Creation | |
668 Assembler(CodeBuffer* code) : AbstractAssembler(code) {} | |
669 | |
670 // Decoding | |
671 static address locate_operand(address inst, WhichOperand which); | |
672 static address locate_next_instruction(address inst); | |
673 | |
304 | 674 // Utilities |
675 | |
676 #ifdef _LP64 | |
677 static bool is_simm(int64_t x, int nbits) { return -( CONST64(1) << (nbits-1) ) <= x && x < ( CONST64(1) << (nbits-1) ); } | |
678 static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; } | |
679 #else | |
680 static bool is_simm(int32_t x, int nbits) { return -( 1 << (nbits-1) ) <= x && x < ( 1 << (nbits-1) ); } | |
681 static bool is_simm32(int32_t x) { return true; } | |
682 #endif // LP64 | |
683 | |
684 // Generic instructions | |
685 // Does 32bit or 64bit as needed for the platform. In some sense these | |
686 // belong in macro assembler but there is no need for both varieties to exist | |
687 | |
688 void lea(Register dst, Address src); | |
689 | |
690 void mov(Register dst, Register src); | |
691 | |
692 void pusha(); | |
693 void popa(); | |
694 | |
695 void pushf(); | |
696 void popf(); | |
697 | |
698 void push(int32_t imm32); | |
699 | |
700 void push(Register src); | |
701 | |
702 void pop(Register dst); | |
703 | |
704 // These are dummies to prevent surprise implicit conversions to Register | |
705 void push(void* v); | |
706 void pop(void* v); | |
707 | |
708 | |
709 // These do register sized moves/scans | |
710 void rep_mov(); | |
711 void rep_set(); | |
712 void repne_scan(); | |
713 #ifdef _LP64 | |
714 void repne_scanl(); | |
715 #endif | |
716 | |
717 // Vanilla instructions in lexical order | |
718 | |
719 void adcl(Register dst, int32_t imm32); | |
0 | 720 void adcl(Register dst, Address src); |
721 void adcl(Register dst, Register src); | |
722 | |
304 | 723 void adcq(Register dst, int32_t imm32); |
724 void adcq(Register dst, Address src); | |
725 void adcq(Register dst, Register src); | |
726 | |
727 | |
728 void addl(Address dst, int32_t imm32); | |
0 | 729 void addl(Address dst, Register src); |
304 | 730 void addl(Register dst, int32_t imm32); |
0 | 731 void addl(Register dst, Address src); |
732 void addl(Register dst, Register src); | |
733 | |
304 | 734 void addq(Address dst, int32_t imm32); |
735 void addq(Address dst, Register src); | |
736 void addq(Register dst, int32_t imm32); | |
737 void addq(Register dst, Address src); | |
738 void addq(Register dst, Register src); | |
739 | |
740 | |
0 | 741 void addr_nop_4(); |
742 void addr_nop_5(); | |
743 void addr_nop_7(); | |
744 void addr_nop_8(); | |
745 | |
304 | 746 // Add Scalar Double-Precision Floating-Point Values |
747 void addsd(XMMRegister dst, Address src); | |
748 void addsd(XMMRegister dst, XMMRegister src); | |
749 | |
750 // Add Scalar Single-Precision Floating-Point Values | |
751 void addss(XMMRegister dst, Address src); | |
752 void addss(XMMRegister dst, XMMRegister src); | |
753 | |
754 void andl(Register dst, int32_t imm32); | |
755 void andl(Register dst, Address src); | |
756 void andl(Register dst, Register src); | |
757 | |
758 void andq(Register dst, int32_t imm32); | |
759 void andq(Register dst, Address src); | |
760 void andq(Register dst, Register src); | |
761 | |
762 | |
763 // Bitwise Logical AND of Packed Double-Precision Floating-Point Values | |
764 void andpd(XMMRegister dst, Address src); | |
765 void andpd(XMMRegister dst, XMMRegister src); | |
766 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
767 void bsfl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
768 void bsrl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
769 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
770 #ifdef _LP64 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
771 void bsfq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
772 void bsrq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
773 #endif |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
774 |
304 | 775 void bswapl(Register reg); |
776 | |
777 void bswapq(Register reg); | |
778 | |
0 | 779 void call(Label& L, relocInfo::relocType rtype); |
780 void call(Register reg); // push pc; pc <- reg | |
781 void call(Address adr); // push pc; pc <- adr | |
782 | |
304 | 783 void cdql(); |
784 | |
785 void cdqq(); | |
786 | |
787 void cld() { emit_byte(0xfc); } | |
788 | |
789 void clflush(Address adr); | |
790 | |
791 void cmovl(Condition cc, Register dst, Register src); | |
792 void cmovl(Condition cc, Register dst, Address src); | |
793 | |
794 void cmovq(Condition cc, Register dst, Register src); | |
795 void cmovq(Condition cc, Register dst, Address src); | |
796 | |
797 | |
798 void cmpb(Address dst, int imm8); | |
799 | |
800 void cmpl(Address dst, int32_t imm32); | |
801 | |
802 void cmpl(Register dst, int32_t imm32); | |
803 void cmpl(Register dst, Register src); | |
804 void cmpl(Register dst, Address src); | |
805 | |
806 void cmpq(Address dst, int32_t imm32); | |
807 void cmpq(Address dst, Register src); | |
808 | |
809 void cmpq(Register dst, int32_t imm32); | |
810 void cmpq(Register dst, Register src); | |
811 void cmpq(Register dst, Address src); | |
812 | |
813 // these are dummies used to catch attempting to convert NULL to Register | |
814 void cmpl(Register dst, void* junk); // dummy | |
815 void cmpq(Register dst, void* junk); // dummy | |
816 | |
817 void cmpw(Address dst, int imm16); | |
818 | |
819 void cmpxchg8 (Address adr); | |
820 | |
821 void cmpxchgl(Register reg, Address adr); | |
822 | |
823 void cmpxchgq(Register reg, Address adr); | |
824 | |
825 // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS | |
826 void comisd(XMMRegister dst, Address src); | |
827 | |
828 // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS | |
829 void comiss(XMMRegister dst, Address src); | |
830 | |
831 // Identify processor type and features | |
832 void cpuid() { | |
833 emit_byte(0x0F); | |
834 emit_byte(0xA2); | |
835 } | |
836 | |
837 // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value | |
838 void cvtsd2ss(XMMRegister dst, XMMRegister src); | |
839 | |
840 // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value | |
841 void cvtsi2sdl(XMMRegister dst, Register src); | |
842 void cvtsi2sdq(XMMRegister dst, Register src); | |
843 | |
844 // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value | |
845 void cvtsi2ssl(XMMRegister dst, Register src); | |
846 void cvtsi2ssq(XMMRegister dst, Register src); | |
847 | |
848 // Convert Packed Signed Doubleword Integers to Packed Double-Precision Floating-Point Value | |
849 void cvtdq2pd(XMMRegister dst, XMMRegister src); | |
850 | |
851 // Convert Packed Signed Doubleword Integers to Packed Single-Precision Floating-Point Value | |
852 void cvtdq2ps(XMMRegister dst, XMMRegister src); | |
853 | |
854 // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value | |
855 void cvtss2sd(XMMRegister dst, XMMRegister src); | |
856 | |
857 // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer | |
858 void cvttsd2sil(Register dst, Address src); | |
859 void cvttsd2sil(Register dst, XMMRegister src); | |
860 void cvttsd2siq(Register dst, XMMRegister src); | |
861 | |
862 // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer | |
863 void cvttss2sil(Register dst, XMMRegister src); | |
864 void cvttss2siq(Register dst, XMMRegister src); | |
865 | |
866 // Divide Scalar Double-Precision Floating-Point Values | |
867 void divsd(XMMRegister dst, Address src); | |
868 void divsd(XMMRegister dst, XMMRegister src); | |
869 | |
870 // Divide Scalar Single-Precision Floating-Point Values | |
871 void divss(XMMRegister dst, Address src); | |
872 void divss(XMMRegister dst, XMMRegister src); | |
873 | |
874 void emms(); | |
875 | |
876 void fabs(); | |
877 | |
878 void fadd(int i); | |
879 | |
880 void fadd_d(Address src); | |
881 void fadd_s(Address src); | |
882 | |
883 // "Alternate" versions of x87 instructions place result down in FPU | |
884 // stack instead of on TOS | |
885 | |
886 void fadda(int i); // "alternate" fadd | |
887 void faddp(int i = 1); | |
888 | |
889 void fchs(); | |
890 | |
891 void fcom(int i); | |
892 | |
893 void fcomp(int i = 1); | |
894 void fcomp_d(Address src); | |
895 void fcomp_s(Address src); | |
896 | |
897 void fcompp(); | |
898 | |
899 void fcos(); | |
900 | |
901 void fdecstp(); | |
902 | |
903 void fdiv(int i); | |
904 void fdiv_d(Address src); | |
905 void fdivr_s(Address src); | |
906 void fdiva(int i); // "alternate" fdiv | |
907 void fdivp(int i = 1); | |
908 | |
909 void fdivr(int i); | |
910 void fdivr_d(Address src); | |
911 void fdiv_s(Address src); | |
912 | |
913 void fdivra(int i); // "alternate" reversed fdiv | |
914 | |
915 void fdivrp(int i = 1); | |
916 | |
917 void ffree(int i = 0); | |
918 | |
919 void fild_d(Address adr); | |
920 void fild_s(Address adr); | |
921 | |
922 void fincstp(); | |
923 | |
924 void finit(); | |
925 | |
926 void fist_s (Address adr); | |
927 void fistp_d(Address adr); | |
928 void fistp_s(Address adr); | |
929 | |
930 void fld1(); | |
931 | |
932 void fld_d(Address adr); | |
933 void fld_s(Address adr); | |
934 void fld_s(int index); | |
935 void fld_x(Address adr); // extended-precision (80-bit) format | |
936 | |
937 void fldcw(Address src); | |
938 | |
939 void fldenv(Address src); | |
940 | |
941 void fldlg2(); | |
942 | |
943 void fldln2(); | |
944 | |
945 void fldz(); | |
946 | |
947 void flog(); | |
948 void flog10(); | |
949 | |
950 void fmul(int i); | |
951 | |
952 void fmul_d(Address src); | |
953 void fmul_s(Address src); | |
954 | |
955 void fmula(int i); // "alternate" fmul | |
956 | |
957 void fmulp(int i = 1); | |
958 | |
959 void fnsave(Address dst); | |
960 | |
961 void fnstcw(Address src); | |
962 | |
963 void fnstsw_ax(); | |
964 | |
965 void fprem(); | |
966 void fprem1(); | |
967 | |
968 void frstor(Address src); | |
969 | |
970 void fsin(); | |
971 | |
972 void fsqrt(); | |
973 | |
974 void fst_d(Address adr); | |
975 void fst_s(Address adr); | |
976 | |
977 void fstp_d(Address adr); | |
978 void fstp_d(int index); | |
979 void fstp_s(Address adr); | |
980 void fstp_x(Address adr); // extended-precision (80-bit) format | |
981 | |
982 void fsub(int i); | |
983 void fsub_d(Address src); | |
984 void fsub_s(Address src); | |
985 | |
986 void fsuba(int i); // "alternate" fsub | |
987 | |
988 void fsubp(int i = 1); | |
989 | |
990 void fsubr(int i); | |
991 void fsubr_d(Address src); | |
992 void fsubr_s(Address src); | |
993 | |
994 void fsubra(int i); // "alternate" reversed fsub | |
995 | |
996 void fsubrp(int i = 1); | |
997 | |
998 void ftan(); | |
999 | |
1000 void ftst(); | |
1001 | |
1002 void fucomi(int i = 1); | |
1003 void fucomip(int i = 1); | |
1004 | |
1005 void fwait(); | |
1006 | |
1007 void fxch(int i = 1); | |
1008 | |
1009 void fxrstor(Address src); | |
1010 | |
1011 void fxsave(Address dst); | |
1012 | |
1013 void fyl2x(); | |
1014 | |
1015 void hlt(); | |
1016 | |
1017 void idivl(Register src); | |
1920 | 1018 void divl(Register src); // Unsigned division |
304 | 1019 |
1020 void idivq(Register src); | |
1021 | |
1022 void imull(Register dst, Register src); | |
1023 void imull(Register dst, Register src, int value); | |
1024 | |
1025 void imulq(Register dst, Register src); | |
1026 void imulq(Register dst, Register src, int value); | |
1027 | |
0 | 1028 |
1029 // jcc is the generic conditional branch generator to run- | |
1030 // time routines, jcc is used for branches to labels. jcc | |
1031 // takes a branch opcode (cc) and a label (L) and generates | |
1032 // either a backward branch or a forward branch and links it | |
1033 // to the label fixup chain. Usage: | |
1034 // | |
1035 // Label L; // unbound label | |
1036 // jcc(cc, L); // forward branch to unbound label | |
1037 // bind(L); // bind label to the current pc | |
1038 // jcc(cc, L); // backward branch to bound label | |
1039 // bind(L); // illegal: a label may be bound only once | |
1040 // | |
1041 // Note: The same Label can be used for forward and backward branches | |
1042 // but it may be bound only once. | |
1043 | |
1044 void jcc(Condition cc, Label& L, | |
1045 relocInfo::relocType rtype = relocInfo::none); | |
1046 | |
1047 // Conditional jump to a 8-bit offset to L. | |
1048 // WARNING: be very careful using this for forward jumps. If the label is | |
1049 // not bound within an 8-bit offset of this instruction, a run-time error | |
1050 // will occur. | |
1051 void jccb(Condition cc, Label& L); | |
1052 | |
304 | 1053 void jmp(Address entry); // pc <- entry |
1054 | |
1055 // Label operations & relative jumps (PPUM Appendix D) | |
1056 void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L | |
1057 | |
1058 void jmp(Register entry); // pc <- entry | |
1059 | |
1060 // Unconditional 8-bit offset jump to L. | |
1061 // WARNING: be very careful using this for forward jumps. If the label is | |
1062 // not bound within an 8-bit offset of this instruction, a run-time error | |
1063 // will occur. | |
1064 void jmpb(Label& L); | |
1065 | |
1066 void ldmxcsr( Address src ); | |
1067 | |
1068 void leal(Register dst, Address src); | |
1069 | |
1070 void leaq(Register dst, Address src); | |
1071 | |
1072 void lfence() { | |
1073 emit_byte(0x0F); | |
1074 emit_byte(0xAE); | |
1075 emit_byte(0xE8); | |
1076 } | |
1077 | |
1078 void lock(); | |
1079 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1080 void lzcntl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1081 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1082 #ifdef _LP64 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1083 void lzcntq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1084 #endif |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1085 |
304 | 1086 enum Membar_mask_bits { |
1087 StoreStore = 1 << 3, | |
1088 LoadStore = 1 << 2, | |
1089 StoreLoad = 1 << 1, | |
1090 LoadLoad = 1 << 0 | |
1091 }; | |
1092 | |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1093 // Serializes memory and blows flags |
304 | 1094 void membar(Membar_mask_bits order_constraint) { |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1095 if (os::is_MP()) { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1096 // We only have to handle StoreLoad |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1097 if (order_constraint & StoreLoad) { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1098 // All usable chips support "locked" instructions which suffice |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1099 // as barriers, and are much faster than the alternative of |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1100 // using cpuid instruction. We use here a locked add [esp],0. |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1101 // This is conveniently otherwise a no-op except for blowing |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1102 // flags. |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1103 // Any change to this code may need to revisit other places in |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1104 // the code where this idiom is used, in particular the |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1105 // orderAccess code. |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1106 lock(); |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1107 addl(Address(rsp, 0), 0);// Assert the lock# signal here |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1108 } |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1109 } |
304 | 1110 } |
1111 | |
1112 void mfence(); | |
1113 | |
1114 // Moves | |
1115 | |
1116 void mov64(Register dst, int64_t imm64); | |
1117 | |
1118 void movb(Address dst, Register src); | |
1119 void movb(Address dst, int imm8); | |
1120 void movb(Register dst, Address src); | |
1121 | |
1122 void movdl(XMMRegister dst, Register src); | |
1123 void movdl(Register dst, XMMRegister src); | |
1124 | |
1125 // Move Double Quadword | |
1126 void movdq(XMMRegister dst, Register src); | |
1127 void movdq(Register dst, XMMRegister src); | |
1128 | |
1129 // Move Aligned Double Quadword | |
1130 void movdqa(Address dst, XMMRegister src); | |
1131 void movdqa(XMMRegister dst, Address src); | |
1132 void movdqa(XMMRegister dst, XMMRegister src); | |
1133 | |
405 | 1134 // Move Unaligned Double Quadword |
1135 void movdqu(Address dst, XMMRegister src); | |
1136 void movdqu(XMMRegister dst, Address src); | |
1137 void movdqu(XMMRegister dst, XMMRegister src); | |
1138 | |
304 | 1139 void movl(Register dst, int32_t imm32); |
1140 void movl(Address dst, int32_t imm32); | |
1141 void movl(Register dst, Register src); | |
1142 void movl(Register dst, Address src); | |
1143 void movl(Address dst, Register src); | |
1144 | |
1145 // These dummies prevent using movl from converting a zero (like NULL) into Register | |
1146 // by giving the compiler two choices it can't resolve | |
1147 | |
1148 void movl(Address dst, void* junk); | |
1149 void movl(Register dst, void* junk); | |
1150 | |
1151 #ifdef _LP64 | |
1152 void movq(Register dst, Register src); | |
1153 void movq(Register dst, Address src); | |
1154 void movq(Address dst, Register src); | |
1155 #endif | |
1156 | |
1157 void movq(Address dst, MMXRegister src ); | |
1158 void movq(MMXRegister dst, Address src ); | |
1159 | |
1160 #ifdef _LP64 | |
1161 // These dummies prevent using movq from converting a zero (like NULL) into Register | |
1162 // by giving the compiler two choices it can't resolve | |
1163 | |
1164 void movq(Address dst, void* dummy); | |
1165 void movq(Register dst, void* dummy); | |
1166 #endif | |
1167 | |
1168 // Move Quadword | |
1169 void movq(Address dst, XMMRegister src); | |
1170 void movq(XMMRegister dst, Address src); | |
1171 | |
1172 void movsbl(Register dst, Address src); | |
1173 void movsbl(Register dst, Register src); | |
1174 | |
1175 #ifdef _LP64 | |
624 | 1176 void movsbq(Register dst, Address src); |
1177 void movsbq(Register dst, Register src); | |
1178 | |
304 | 1179 // Move signed 32bit immediate to 64bit extending sign |
1180 void movslq(Address dst, int32_t imm64); | |
1181 void movslq(Register dst, int32_t imm64); | |
1182 | |
1183 void movslq(Register dst, Address src); | |
1184 void movslq(Register dst, Register src); | |
1185 void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous | |
1186 #endif | |
1187 | |
1188 void movswl(Register dst, Address src); | |
1189 void movswl(Register dst, Register src); | |
1190 | |
624 | 1191 #ifdef _LP64 |
1192 void movswq(Register dst, Address src); | |
1193 void movswq(Register dst, Register src); | |
1194 #endif | |
1195 | |
304 | 1196 void movw(Address dst, int imm16); |
1197 void movw(Register dst, Address src); | |
1198 void movw(Address dst, Register src); | |
1199 | |
1200 void movzbl(Register dst, Address src); | |
1201 void movzbl(Register dst, Register src); | |
1202 | |
624 | 1203 #ifdef _LP64 |
1204 void movzbq(Register dst, Address src); | |
1205 void movzbq(Register dst, Register src); | |
1206 #endif | |
1207 | |
304 | 1208 void movzwl(Register dst, Address src); |
1209 void movzwl(Register dst, Register src); | |
1210 | |
624 | 1211 #ifdef _LP64 |
1212 void movzwq(Register dst, Address src); | |
1213 void movzwq(Register dst, Register src); | |
1214 #endif | |
1215 | |
304 | 1216 void mull(Address src); |
1217 void mull(Register src); | |
1218 | |
1219 // Multiply Scalar Double-Precision Floating-Point Values | |
1220 void mulsd(XMMRegister dst, Address src); | |
1221 void mulsd(XMMRegister dst, XMMRegister src); | |
1222 | |
1223 // Multiply Scalar Single-Precision Floating-Point Values | |
1224 void mulss(XMMRegister dst, Address src); | |
1225 void mulss(XMMRegister dst, XMMRegister src); | |
1226 | |
1227 void negl(Register dst); | |
1228 | |
1229 #ifdef _LP64 | |
1230 void negq(Register dst); | |
1231 #endif | |
1232 | |
1233 void nop(int i = 1); | |
1234 | |
1235 void notl(Register dst); | |
1236 | |
1237 #ifdef _LP64 | |
1238 void notq(Register dst); | |
1239 #endif | |
1240 | |
1241 void orl(Address dst, int32_t imm32); | |
1242 void orl(Register dst, int32_t imm32); | |
1243 void orl(Register dst, Address src); | |
1244 void orl(Register dst, Register src); | |
1245 | |
1246 void orq(Address dst, int32_t imm32); | |
1247 void orq(Register dst, int32_t imm32); | |
1248 void orq(Register dst, Address src); | |
1249 void orq(Register dst, Register src); | |
1250 | |
681 | 1251 // SSE4.2 string instructions |
1252 void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8); | |
1253 void pcmpestri(XMMRegister xmm1, Address src, int imm8); | |
1254 | |
1060 | 1255 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1256 void popl(Address dst); |
1060 | 1257 #endif |
304 | 1258 |
1259 #ifdef _LP64 | |
1260 void popq(Address dst); | |
1261 #endif | |
1262 | |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1263 void popcntl(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1264 void popcntl(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1265 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1266 #ifdef _LP64 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1267 void popcntq(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1268 void popcntq(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1269 #endif |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1270 |
304 | 1271 // Prefetches (SSE, SSE2, 3DNOW only) |
1272 | |
1273 void prefetchnta(Address src); | |
1274 void prefetchr(Address src); | |
1275 void prefetcht0(Address src); | |
1276 void prefetcht1(Address src); | |
1277 void prefetcht2(Address src); | |
1278 void prefetchw(Address src); | |
1279 | |
1280 // Shuffle Packed Doublewords | |
1281 void pshufd(XMMRegister dst, XMMRegister src, int mode); | |
1282 void pshufd(XMMRegister dst, Address src, int mode); | |
1283 | |
1284 // Shuffle Packed Low Words | |
1285 void pshuflw(XMMRegister dst, XMMRegister src, int mode); | |
1286 void pshuflw(XMMRegister dst, Address src, int mode); | |
1287 | |
1288 // Shift Right Logical Quadword Immediate | |
1289 void psrlq(XMMRegister dst, int shift); | |
1290 | |
681 | 1291 // Logical Compare Double Quadword |
1292 void ptest(XMMRegister dst, XMMRegister src); | |
1293 void ptest(XMMRegister dst, Address src); | |
1294 | |
304 | 1295 // Interleave Low Bytes |
1296 void punpcklbw(XMMRegister dst, XMMRegister src); | |
1297 | |
1060 | 1298 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1299 void pushl(Address src); |
1060 | 1300 #endif |
304 | 1301 |
1302 void pushq(Address src); | |
1303 | |
1304 // Xor Packed Byte Integer Values | |
1305 void pxor(XMMRegister dst, Address src); | |
1306 void pxor(XMMRegister dst, XMMRegister src); | |
1307 | |
1308 void rcll(Register dst, int imm8); | |
1309 | |
1310 void rclq(Register dst, int imm8); | |
1311 | |
1312 void ret(int imm16); | |
0 | 1313 |
1314 void sahf(); | |
1315 | |
304 | 1316 void sarl(Register dst, int imm8); |
1317 void sarl(Register dst); | |
1318 | |
1319 void sarq(Register dst, int imm8); | |
1320 void sarq(Register dst); | |
1321 | |
1322 void sbbl(Address dst, int32_t imm32); | |
1323 void sbbl(Register dst, int32_t imm32); | |
1324 void sbbl(Register dst, Address src); | |
1325 void sbbl(Register dst, Register src); | |
1326 | |
1327 void sbbq(Address dst, int32_t imm32); | |
1328 void sbbq(Register dst, int32_t imm32); | |
1329 void sbbq(Register dst, Address src); | |
1330 void sbbq(Register dst, Register src); | |
1331 | |
1332 void setb(Condition cc, Register dst); | |
1333 | |
1334 void shldl(Register dst, Register src); | |
1335 | |
1336 void shll(Register dst, int imm8); | |
1337 void shll(Register dst); | |
1338 | |
1339 void shlq(Register dst, int imm8); | |
1340 void shlq(Register dst); | |
1341 | |
1342 void shrdl(Register dst, Register src); | |
1343 | |
1344 void shrl(Register dst, int imm8); | |
1345 void shrl(Register dst); | |
1346 | |
1347 void shrq(Register dst, int imm8); | |
1348 void shrq(Register dst); | |
1349 | |
1350 void smovl(); // QQQ generic? | |
1351 | |
1352 // Compute Square Root of Scalar Double-Precision Floating-Point Value | |
1353 void sqrtsd(XMMRegister dst, Address src); | |
1354 void sqrtsd(XMMRegister dst, XMMRegister src); | |
1355 | |
1356 void std() { emit_byte(0xfd); } | |
1357 | |
1358 void stmxcsr( Address dst ); | |
1359 | |
1360 void subl(Address dst, int32_t imm32); | |
1361 void subl(Address dst, Register src); | |
1362 void subl(Register dst, int32_t imm32); | |
1363 void subl(Register dst, Address src); | |
1364 void subl(Register dst, Register src); | |
1365 | |
1366 void subq(Address dst, int32_t imm32); | |
1367 void subq(Address dst, Register src); | |
1368 void subq(Register dst, int32_t imm32); | |
1369 void subq(Register dst, Address src); | |
1370 void subq(Register dst, Register src); | |
1371 | |
1372 | |
1373 // Subtract Scalar Double-Precision Floating-Point Values | |
1374 void subsd(XMMRegister dst, Address src); | |
0 | 1375 void subsd(XMMRegister dst, XMMRegister src); |
1376 | |
304 | 1377 // Subtract Scalar Single-Precision Floating-Point Values |
1378 void subss(XMMRegister dst, Address src); | |
1379 void subss(XMMRegister dst, XMMRegister src); | |
1380 | |
1381 void testb(Register dst, int imm8); | |
1382 | |
1383 void testl(Register dst, int32_t imm32); | |
1384 void testl(Register dst, Register src); | |
1385 void testl(Register dst, Address src); | |
1386 | |
1387 void testq(Register dst, int32_t imm32); | |
1388 void testq(Register dst, Register src); | |
1389 | |
1390 | |
1391 // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS | |
1392 void ucomisd(XMMRegister dst, Address src); | |
0 | 1393 void ucomisd(XMMRegister dst, XMMRegister src); |
1394 | |
304 | 1395 // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS |
1396 void ucomiss(XMMRegister dst, Address src); | |
1397 void ucomiss(XMMRegister dst, XMMRegister src); | |
1398 | |
1399 void xaddl(Address dst, Register src); | |
1400 | |
1401 void xaddq(Address dst, Register src); | |
1402 | |
1403 void xchgl(Register reg, Address adr); | |
1404 void xchgl(Register dst, Register src); | |
1405 | |
1406 void xchgq(Register reg, Address adr); | |
1407 void xchgq(Register dst, Register src); | |
1408 | |
1409 void xorl(Register dst, int32_t imm32); | |
1410 void xorl(Register dst, Address src); | |
1411 void xorl(Register dst, Register src); | |
1412 | |
1413 void xorq(Register dst, Address src); | |
1414 void xorq(Register dst, Register src); | |
1415 | |
1416 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
1417 void xorpd(XMMRegister dst, Address src); | |
1418 void xorpd(XMMRegister dst, XMMRegister src); | |
1419 | |
1420 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
1421 void xorps(XMMRegister dst, Address src); | |
0 | 1422 void xorps(XMMRegister dst, XMMRegister src); |
304 | 1423 |
1424 void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 | |
0 | 1425 }; |
1426 | |
1427 | |
1428 // MacroAssembler extends Assembler by frequently used macros. | |
1429 // | |
1430 // Instructions for which a 'better' code sequence exists depending | |
1431 // on arguments should also go in here. | |
1432 | |
1433 class MacroAssembler: public Assembler { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1434 friend class LIR_Assembler; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1435 friend class Runtime1; // as_Address() |
0 | 1436 protected: |
1437 | |
1438 Address as_Address(AddressLiteral adr); | |
1439 Address as_Address(ArrayAddress adr); | |
1440 | |
1441 // Support for VM calls | |
1442 // | |
1443 // This is the base routine called by the different versions of call_VM_leaf. The interpreter | |
1444 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1445 // additional registers when doing a VM call). | |
1446 #ifdef CC_INTERP | |
1447 // c++ interpreter never wants to use interp_masm version of call_VM | |
1448 #define VIRTUAL | |
1449 #else | |
1450 #define VIRTUAL virtual | |
1451 #endif | |
1452 | |
1453 VIRTUAL void call_VM_leaf_base( | |
1454 address entry_point, // the entry point | |
1455 int number_of_arguments // the number of arguments to pop after the call | |
1456 ); | |
1457 | |
1458 // This is the base routine called by the different versions of call_VM. The interpreter | |
1459 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1460 // additional registers when doing a VM call). | |
1461 // | |
1462 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base | |
1463 // returns the register which contains the thread upon return. If a thread register has been | |
1464 // specified, the return value will correspond to that register. If no last_java_sp is specified | |
1465 // (noreg) than rsp will be used instead. | |
1466 VIRTUAL void call_VM_base( // returns the register containing the thread upon return | |
1467 Register oop_result, // where an oop-result ends up if any; use noreg otherwise | |
1468 Register java_thread, // the thread if computed before ; use noreg otherwise | |
1469 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise | |
1470 address entry_point, // the entry point | |
1471 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call | |
1472 bool check_exceptions // whether to check for pending exceptions after return | |
1473 ); | |
1474 | |
1475 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code. | |
1476 // The implementation is only non-empty for the InterpreterMacroAssembler, | |
1477 // as only the interpreter handles PopFrame and ForceEarlyReturn requests. | |
1478 virtual void check_and_handle_popframe(Register java_thread); | |
1479 virtual void check_and_handle_earlyret(Register java_thread); | |
1480 | |
1481 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true); | |
1482 | |
1483 // helpers for FPU flag access | |
1484 // tmp is a temporary register, if none is available use noreg | |
1485 void save_rax (Register tmp); | |
1486 void restore_rax(Register tmp); | |
1487 | |
1488 public: | |
1489 MacroAssembler(CodeBuffer* code) : Assembler(code) {} | |
1490 | |
1491 // Support for NULL-checks | |
1492 // | |
1493 // Generates code that causes a NULL OS exception if the content of reg is NULL. | |
1494 // If the accessed location is M[reg + offset] and the offset is known, provide the | |
1495 // offset. No explicit code generation is needed if the offset is within a certain | |
1496 // range (0 <= offset <= page_size). | |
1497 | |
1498 void null_check(Register reg, int offset = -1); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
71
diff
changeset
|
1499 static bool needs_explicit_null_check(intptr_t offset); |
0 | 1500 |
1501 // Required platform-specific helpers for Label::patch_instructions. | |
1502 // They _shadow_ the declarations in AbstractAssembler, which are undefined. | |
1503 void pd_patch_instruction(address branch, address target); | |
1504 #ifndef PRODUCT | |
1505 static void pd_print_patched_instruction(address branch); | |
1506 #endif | |
1507 | |
1508 // The following 4 methods return the offset of the appropriate move instruction | |
1509 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1510 // Support for fast byte/short loading with zero extension (depending on particular CPU) |
0 | 1511 int load_unsigned_byte(Register dst, Address src); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1512 int load_unsigned_short(Register dst, Address src); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1513 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1514 // Support for fast byte/short loading with sign extension (depending on particular CPU) |
0 | 1515 int load_signed_byte(Register dst, Address src); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1516 int load_signed_short(Register dst, Address src); |
0 | 1517 |
1518 // Support for sign-extension (hi:lo = extend_sign(lo)) | |
1519 void extend_sign(Register hi, Register lo); | |
1520 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1521 // Loading values by size and signed-ness |
1503 | 1522 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1523 |
0 | 1524 // Support for inc/dec with optimal instruction selection depending on value |
304 | 1525 |
1526 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } | |
1527 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } | |
1528 | |
1529 void decrementl(Address dst, int value = 1); | |
1530 void decrementl(Register reg, int value = 1); | |
1531 | |
1532 void decrementq(Register reg, int value = 1); | |
1533 void decrementq(Address dst, int value = 1); | |
1534 | |
1535 void incrementl(Address dst, int value = 1); | |
1536 void incrementl(Register reg, int value = 1); | |
1537 | |
1538 void incrementq(Register reg, int value = 1); | |
1539 void incrementq(Address dst, int value = 1); | |
1540 | |
0 | 1541 |
1542 // Support optimal SSE move instructions. | |
1543 void movflt(XMMRegister dst, XMMRegister src) { | |
1544 if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; } | |
1545 else { movss (dst, src); return; } | |
1546 } | |
1547 void movflt(XMMRegister dst, Address src) { movss(dst, src); } | |
1548 void movflt(XMMRegister dst, AddressLiteral src); | |
1549 void movflt(Address dst, XMMRegister src) { movss(dst, src); } | |
1550 | |
1551 void movdbl(XMMRegister dst, XMMRegister src) { | |
1552 if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; } | |
1553 else { movsd (dst, src); return; } | |
1554 } | |
1555 | |
1556 void movdbl(XMMRegister dst, AddressLiteral src); | |
1557 | |
1558 void movdbl(XMMRegister dst, Address src) { | |
1559 if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; } | |
1560 else { movlpd(dst, src); return; } | |
1561 } | |
1562 void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } | |
1563 | |
304 | 1564 void incrementl(AddressLiteral dst); |
1565 void incrementl(ArrayAddress dst); | |
0 | 1566 |
1567 // Alignment | |
1568 void align(int modulus); | |
1569 | |
1570 // Misc | |
1571 void fat_nop(); // 5 byte nop | |
1572 | |
1573 // Stack frame creation/removal | |
1574 void enter(); | |
1575 void leave(); | |
1576 | |
1577 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information) | |
1578 // The pointer will be loaded into the thread register. | |
1579 void get_thread(Register thread); | |
1580 | |
362 | 1581 |
0 | 1582 // Support for VM calls |
1583 // | |
1584 // It is imperative that all calls into the VM are handled via the call_VM macros. | |
1585 // They make sure that the stack linkage is setup correctly. call_VM's correspond | |
1586 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. | |
1587 | |
304 | 1588 |
1589 void call_VM(Register oop_result, | |
1590 address entry_point, | |
1591 bool check_exceptions = true); | |
1592 void call_VM(Register oop_result, | |
1593 address entry_point, | |
1594 Register arg_1, | |
1595 bool check_exceptions = true); | |
1596 void call_VM(Register oop_result, | |
1597 address entry_point, | |
1598 Register arg_1, Register arg_2, | |
1599 bool check_exceptions = true); | |
1600 void call_VM(Register oop_result, | |
1601 address entry_point, | |
1602 Register arg_1, Register arg_2, Register arg_3, | |
1603 bool check_exceptions = true); | |
1604 | |
1605 // Overloadings with last_Java_sp | |
1606 void call_VM(Register oop_result, | |
1607 Register last_java_sp, | |
1608 address entry_point, | |
1609 int number_of_arguments = 0, | |
1610 bool check_exceptions = true); | |
1611 void call_VM(Register oop_result, | |
1612 Register last_java_sp, | |
1613 address entry_point, | |
1614 Register arg_1, bool | |
1615 check_exceptions = true); | |
1616 void call_VM(Register oop_result, | |
1617 Register last_java_sp, | |
1618 address entry_point, | |
1619 Register arg_1, Register arg_2, | |
1620 bool check_exceptions = true); | |
1621 void call_VM(Register oop_result, | |
1622 Register last_java_sp, | |
1623 address entry_point, | |
1624 Register arg_1, Register arg_2, Register arg_3, | |
1625 bool check_exceptions = true); | |
1626 | |
1627 void call_VM_leaf(address entry_point, | |
1628 int number_of_arguments = 0); | |
1629 void call_VM_leaf(address entry_point, | |
1630 Register arg_1); | |
1631 void call_VM_leaf(address entry_point, | |
1632 Register arg_1, Register arg_2); | |
1633 void call_VM_leaf(address entry_point, | |
1634 Register arg_1, Register arg_2, Register arg_3); | |
0 | 1635 |
1636 // last Java Frame (fills frame anchor) | |
304 | 1637 void set_last_Java_frame(Register thread, |
1638 Register last_java_sp, | |
1639 Register last_java_fp, | |
1640 address last_java_pc); | |
1641 | |
1642 // thread in the default location (r15_thread on 64bit) | |
1643 void set_last_Java_frame(Register last_java_sp, | |
1644 Register last_java_fp, | |
1645 address last_java_pc); | |
1646 | |
0 | 1647 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); |
1648 | |
304 | 1649 // thread in the default location (r15_thread on 64bit) |
1650 void reset_last_Java_frame(bool clear_fp, bool clear_pc); | |
1651 | |
0 | 1652 // Stores |
1653 void store_check(Register obj); // store check for obj - register is destroyed afterwards | |
1654 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) | |
1655 | |
362 | 1656 void g1_write_barrier_pre(Register obj, |
1657 #ifndef _LP64 | |
1658 Register thread, | |
1659 #endif | |
1660 Register tmp, | |
1661 Register tmp2, | |
1662 bool tosca_live); | |
1663 void g1_write_barrier_post(Register store_addr, | |
1664 Register new_val, | |
1665 #ifndef _LP64 | |
1666 Register thread, | |
1667 #endif | |
1668 Register tmp, | |
1669 Register tmp2); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1670 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1671 |
0 | 1672 // split store_check(Register obj) to enhance instruction interleaving |
1673 void store_check_part_1(Register obj); | |
1674 void store_check_part_2(Register obj); | |
1675 | |
1676 // C 'boolean' to Java boolean: x == 0 ? 0 : 1 | |
1677 void c2bool(Register x); | |
1678 | |
1679 // C++ bool manipulation | |
1680 | |
1681 void movbool(Register dst, Address src); | |
1682 void movbool(Address dst, bool boolconst); | |
1683 void movbool(Address dst, Register src); | |
1684 void testbool(Register dst); | |
1685 | |
304 | 1686 // oop manipulations |
1687 void load_klass(Register dst, Register src); | |
1688 void store_klass(Register dst, Register src); | |
1689 | |
1846 | 1690 void load_heap_oop(Register dst, Address src); |
1691 void store_heap_oop(Address dst, Register src); | |
1692 | |
1693 // Used for storing NULL. All other oop constants should be | |
1694 // stored using routines that take a jobject. | |
1695 void store_heap_oop_null(Address dst); | |
1696 | |
304 | 1697 void load_prototype_header(Register dst, Register src); |
1698 | |
1699 #ifdef _LP64 | |
1700 void store_klass_gap(Register dst, Register src); | |
1701 | |
1047
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1702 // This dummy is to prevent a call to store_heap_oop from |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1703 // converting a zero (like NULL) into a Register by giving |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1704 // the compiler two choices it can't resolve |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1705 |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1706 void store_heap_oop(Address dst, void* dummy); |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1707 |
304 | 1708 void encode_heap_oop(Register r); |
1709 void decode_heap_oop(Register r); | |
1710 void encode_heap_oop_not_null(Register r); | |
1711 void decode_heap_oop_not_null(Register r); | |
1712 void encode_heap_oop_not_null(Register dst, Register src); | |
1713 void decode_heap_oop_not_null(Register dst, Register src); | |
1714 | |
1715 void set_narrow_oop(Register dst, jobject obj); | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1716 void set_narrow_oop(Address dst, jobject obj); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1717 void cmp_narrow_oop(Register dst, jobject obj); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
1718 void cmp_narrow_oop(Address dst, jobject obj); |
304 | 1719 |
1720 // if heap base register is used - reinit it with the correct value | |
1721 void reinit_heapbase(); | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1722 |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1723 DEBUG_ONLY(void verify_heapbase(const char* msg);) |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1724 |
304 | 1725 #endif // _LP64 |
1726 | |
1727 // Int division/remainder for Java | |
0 | 1728 // (as idivl, but checks for special case as described in JVM spec.) |
1729 // returns idivl instruction offset for implicit exception handling | |
1730 int corrected_idivl(Register reg); | |
1731 | |
304 | 1732 // Long division/remainder for Java |
1733 // (as idivq, but checks for special case as described in JVM spec.) | |
1734 // returns idivq instruction offset for implicit exception handling | |
1735 int corrected_idivq(Register reg); | |
1736 | |
0 | 1737 void int3(); |
1738 | |
304 | 1739 // Long operation macros for a 32bit cpu |
0 | 1740 // Long negation for Java |
1741 void lneg(Register hi, Register lo); | |
1742 | |
1743 // Long multiplication for Java | |
304 | 1744 // (destroys contents of eax, ebx, ecx and edx) |
0 | 1745 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y |
1746 | |
1747 // Long shifts for Java | |
1748 // (semantics as described in JVM spec.) | |
1749 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f) | |
1750 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f) | |
1751 | |
1752 // Long compare for Java | |
1753 // (semantics as described in JVM spec.) | |
1754 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y) | |
1755 | |
304 | 1756 |
1757 // misc | |
1758 | |
1759 // Sign extension | |
1760 void sign_extend_short(Register reg); | |
1761 void sign_extend_byte(Register reg); | |
1762 | |
1763 // Division by power of 2, rounding towards 0 | |
1764 void division_with_shift(Register reg, int shift_value); | |
1765 | |
0 | 1766 // Compares the top-most stack entries on the FPU stack and sets the eflags as follows: |
1767 // | |
1768 // CF (corresponds to C0) if x < y | |
1769 // PF (corresponds to C2) if unordered | |
1770 // ZF (corresponds to C3) if x = y | |
1771 // | |
1772 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1773 // tmp is a temporary register, if none is available use noreg (only matters for non-P6 code) | |
1774 void fcmp(Register tmp); | |
1775 // Variant of the above which allows y to be further down the stack | |
1776 // and which only pops x and y if specified. If pop_right is | |
1777 // specified then pop_left must also be specified. | |
1778 void fcmp(Register tmp, int index, bool pop_left, bool pop_right); | |
1779 | |
1780 // Floating-point comparison for Java | |
1781 // Compares the top-most stack entries on the FPU stack and stores the result in dst. | |
1782 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1783 // (semantics as described in JVM spec.) | |
1784 void fcmp2int(Register dst, bool unordered_is_less); | |
1785 // Variant of the above which allows y to be further down the stack | |
1786 // and which only pops x and y if specified. If pop_right is | |
1787 // specified then pop_left must also be specified. | |
1788 void fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right); | |
1789 | |
1790 // Floating-point remainder for Java (ST0 = ST0 fremr ST1, ST1 is empty afterwards) | |
1791 // tmp is a temporary register, if none is available use noreg | |
1792 void fremr(Register tmp); | |
1793 | |
1794 | |
1795 // same as fcmp2int, but using SSE2 | |
1796 void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1797 void cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1798 | |
1799 // Inlined sin/cos generator for Java; must not use CPU instruction | |
1800 // directly on Intel as it does not have high enough precision | |
1801 // outside of the range [-pi/4, pi/4]. Extra argument indicate the | |
1802 // number of FPU stack slots in use; all but the topmost will | |
1803 // require saving if a slow case is necessary. Assumes argument is | |
1804 // on FP TOS; result is on FP TOS. No cpu registers are changed by | |
1805 // this code. | |
1806 void trigfunc(char trig, int num_fpu_regs_in_use = 1); | |
1807 | |
1808 // branch to L if FPU flag C2 is set/not set | |
1809 // tmp is a temporary register, if none is available use noreg | |
1810 void jC2 (Register tmp, Label& L); | |
1811 void jnC2(Register tmp, Label& L); | |
1812 | |
1813 // Pop ST (ffree & fincstp combined) | |
1814 void fpop(); | |
1815 | |
1816 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack | |
1817 void push_fTOS(); | |
1818 | |
1819 // pops double TOS element from CPU stack and pushes on FPU stack | |
1820 void pop_fTOS(); | |
1821 | |
1822 void empty_FPU_stack(); | |
1823 | |
1824 void push_IU_state(); | |
1825 void pop_IU_state(); | |
1826 | |
1827 void push_FPU_state(); | |
1828 void pop_FPU_state(); | |
1829 | |
1830 void push_CPU_state(); | |
1831 void pop_CPU_state(); | |
1832 | |
1833 // Round up to a power of two | |
1834 void round_to(Register reg, int modulus); | |
1835 | |
1836 // Callee saved registers handling | |
1837 void push_callee_saved_registers(); | |
1838 void pop_callee_saved_registers(); | |
1839 | |
1840 // allocation | |
1841 void eden_allocate( | |
1842 Register obj, // result: pointer to object after successful allocation | |
1843 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1844 int con_size_in_bytes, // object size in bytes if known at compile time | |
1845 Register t1, // temp register | |
1846 Label& slow_case // continuation point if fast allocation fails | |
1847 ); | |
1848 void tlab_allocate( | |
1849 Register obj, // result: pointer to object after successful allocation | |
1850 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1851 int con_size_in_bytes, // object size in bytes if known at compile time | |
1852 Register t1, // temp register | |
1853 Register t2, // temp register | |
1854 Label& slow_case // continuation point if fast allocation fails | |
1855 ); | |
1856 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); | |
1857 | |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1858 // interface method calling |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1859 void lookup_interface_method(Register recv_klass, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1860 Register intf_klass, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1861 RegisterOrConstant itable_index, |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1862 Register method_result, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1863 Register scan_temp, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1864 Label& no_such_interface); |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1865 |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1866 // Test sub_klass against super_klass, with fast and slow paths. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1867 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1868 // The fast path produces a tri-state answer: yes / no / maybe-slow. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1869 // One of the three labels can be NULL, meaning take the fall-through. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1870 // If super_check_offset is -1, the value is loaded up from super_klass. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1871 // No registers are killed, except temp_reg. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1872 void check_klass_subtype_fast_path(Register sub_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1873 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1874 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1875 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1876 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1877 Label* L_slow_path, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1878 RegisterOrConstant super_check_offset = RegisterOrConstant(-1)); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1879 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1880 // The rest of the type check; must be wired to a corresponding fast path. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1881 // It does not repeat the fast path logic, so don't use it standalone. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1882 // The temp_reg and temp2_reg can be noreg, if no temps are available. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1883 // Updates the sub's secondary super cache as necessary. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1884 // If set_cond_codes, condition codes will be Z on success, NZ on failure. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1885 void check_klass_subtype_slow_path(Register sub_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1886 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1887 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1888 Register temp2_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1889 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1890 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1891 bool set_cond_codes = false); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1892 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1893 // Simplified, combined version, good for typical uses. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1894 // Falls through on failure. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1895 void check_klass_subtype(Register sub_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1896 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1897 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1898 Label& L_success); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1899 |
710 | 1900 // method handles (JSR 292) |
1901 void check_method_handle_type(Register mtype_reg, Register mh_reg, | |
1902 Register temp_reg, | |
1903 Label& wrong_method_type); | |
1904 void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, | |
1905 Register temp_reg); | |
1906 void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); | |
1907 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); | |
1908 | |
1909 | |
0 | 1910 //---- |
1911 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 | |
1912 | |
1913 // Debugging | |
304 | 1914 |
1915 // only if +VerifyOops | |
1916 void verify_oop(Register reg, const char* s = "broken oop"); | |
0 | 1917 void verify_oop_addr(Address addr, const char * s = "broken oop addr"); |
1918 | |
304 | 1919 // only if +VerifyFPU |
1920 void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); | |
1921 | |
1922 // prints msg, dumps registers and stops execution | |
1923 void stop(const char* msg); | |
1924 | |
1925 // prints msg and continues | |
1926 void warn(const char* msg); | |
1927 | |
1928 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); | |
1929 static void debug64(char* msg, int64_t pc, int64_t regs[]); | |
1930 | |
0 | 1931 void os_breakpoint(); |
304 | 1932 |
0 | 1933 void untested() { stop("untested"); } |
304 | 1934 |
1846 | 1935 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); } |
304 | 1936 |
0 | 1937 void should_not_reach_here() { stop("should not reach here"); } |
304 | 1938 |
0 | 1939 void print_CPU_state(); |
1940 | |
1941 // Stack overflow checking | |
1942 void bang_stack_with_offset(int offset) { | |
1943 // stack grows down, caller passes positive offset | |
1944 assert(offset > 0, "must bang with negative offset"); | |
1945 movl(Address(rsp, (-offset)), rax); | |
1946 } | |
1947 | |
1948 // Writes to stack successive pages until offset reached to check for | |
1949 // stack overflow + shadow pages. Also, clobbers tmp | |
1950 void bang_stack_size(Register size, Register tmp); | |
1951 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1952 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1953 Register tmp, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1954 int offset); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1955 |
0 | 1956 // Support for serializing memory accesses between threads |
1957 void serialize_memory(Register thread, Register tmp); | |
1958 | |
1959 void verify_tlab(); | |
1960 | |
1961 // Biased locking support | |
1962 // lock_reg and obj_reg must be loaded up with the appropriate values. | |
1963 // swap_reg must be rax, and is killed. | |
1964 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will | |
1965 // be killed; if not supplied, push/pop will be used internally to | |
1966 // allocate a temporary (inefficient, avoid if possible). | |
1967 // Optional slow case is for implementations (interpreter and C1) which branch to | |
1968 // slow case directly. Leaves condition codes set for C2's Fast_Lock node. | |
1969 // Returns offset of first potentially-faulting instruction for null | |
1970 // check info (currently consumed only by C1). If | |
1971 // swap_reg_contains_mark is true then returns -1 as it is assumed | |
1972 // the calling code has already passed any potential faults. | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
405
diff
changeset
|
1973 int biased_locking_enter(Register lock_reg, Register obj_reg, |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
405
diff
changeset
|
1974 Register swap_reg, Register tmp_reg, |
0 | 1975 bool swap_reg_contains_mark, |
1976 Label& done, Label* slow_case = NULL, | |
1977 BiasedLockingCounters* counters = NULL); | |
1978 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); | |
1979 | |
1980 | |
1981 Condition negate_condition(Condition cond); | |
1982 | |
1983 // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit | |
1984 // operands. In general the names are modified to avoid hiding the instruction in Assembler | |
1985 // so that we don't need to implement all the varieties in the Assembler with trivial wrappers | |
1986 // here in MacroAssembler. The major exception to this rule is call | |
1987 | |
1988 // Arithmetics | |
1989 | |
304 | 1990 |
1991 void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; } | |
1992 void addptr(Address dst, Register src); | |
1993 | |
1994 void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); } | |
1995 void addptr(Register dst, int32_t src); | |
1996 void addptr(Register dst, Register src); | |
1997 | |
1998 void andptr(Register dst, int32_t src); | |
1999 void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; } | |
2000 | |
2001 void cmp8(AddressLiteral src1, int imm); | |
2002 | |
2003 // renamed to drag out the casting of address to int32_t/intptr_t | |
0 | 2004 void cmp32(Register src1, int32_t imm); |
2005 | |
2006 void cmp32(AddressLiteral src1, int32_t imm); | |
2007 // compare reg - mem, or reg - &mem | |
2008 void cmp32(Register src1, AddressLiteral src2); | |
2009 | |
2010 void cmp32(Register src1, Address src2); | |
2011 | |
304 | 2012 #ifndef _LP64 |
2013 void cmpoop(Address dst, jobject obj); | |
2014 void cmpoop(Register dst, jobject obj); | |
2015 #endif // _LP64 | |
2016 | |
0 | 2017 // NOTE src2 must be the lval. This is NOT an mem-mem compare |
2018 void cmpptr(Address src1, AddressLiteral src2); | |
2019 | |
2020 void cmpptr(Register src1, AddressLiteral src2); | |
2021 | |
304 | 2022 void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } |
2023 void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2024 // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2025 | |
2026 void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2027 void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2028 | |
2029 // cmp64 to avoild hiding cmpq | |
2030 void cmp64(Register src1, AddressLiteral src); | |
2031 | |
2032 void cmpxchgptr(Register reg, Address adr); | |
2033 | |
2034 void locked_cmpxchgptr(Register reg, AddressLiteral adr); | |
2035 | |
2036 | |
2037 void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); } | |
2038 | |
2039 | |
2040 void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); } | |
2041 | |
2042 void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); } | |
2043 | |
2044 void shlptr(Register dst, int32_t shift); | |
2045 void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); } | |
2046 | |
2047 void shrptr(Register dst, int32_t shift); | |
2048 void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); } | |
2049 | |
2050 void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); } | |
2051 void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); } | |
2052 | |
2053 void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2054 | |
2055 void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2056 void subptr(Register dst, int32_t src); | |
2057 void subptr(Register dst, Register src); | |
2058 | |
2059 | |
2060 void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2061 void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2062 | |
2063 void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2064 void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2065 | |
2066 void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; } | |
2067 | |
2068 | |
0 | 2069 |
2070 // Helper functions for statistics gathering. | |
2071 // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. | |
2072 void cond_inc32(Condition cond, AddressLiteral counter_addr); | |
2073 // Unconditional atomic increment. | |
2074 void atomic_incl(AddressLiteral counter_addr); | |
2075 | |
2076 void lea(Register dst, AddressLiteral adr); | |
2077 void lea(Address dst, AddressLiteral adr); | |
304 | 2078 void lea(Register dst, Address adr) { Assembler::lea(dst, adr); } |
2079 | |
2080 void leal32(Register dst, Address src) { leal(dst, src); } | |
2081 | |
2082 void test32(Register src1, AddressLiteral src2); | |
2083 | |
2084 void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2085 void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2086 void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2087 | |
2088 void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } | |
2089 void testptr(Register src1, Register src2); | |
2090 | |
2091 void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
2092 void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
0 | 2093 |
2094 // Calls | |
2095 | |
2096 void call(Label& L, relocInfo::relocType rtype); | |
2097 void call(Register entry); | |
2098 | |
2099 // NOTE: this call tranfers to the effective address of entry NOT | |
2100 // the address contained by entry. This is because this is more natural | |
2101 // for jumps/calls. | |
2102 void call(AddressLiteral entry); | |
2103 | |
2104 // Jumps | |
2105 | |
2106 // NOTE: these jumps tranfer to the effective address of dst NOT | |
2107 // the address contained by dst. This is because this is more natural | |
2108 // for jumps/calls. | |
2109 void jump(AddressLiteral dst); | |
2110 void jump_cc(Condition cc, AddressLiteral dst); | |
2111 | |
2112 // 32bit can do a case table jump in one instruction but we no longer allow the base | |
2113 // to be installed in the Address class. This jump will tranfers to the address | |
2114 // contained in the location described by entry (not the address of entry) | |
2115 void jump(ArrayAddress entry); | |
2116 | |
2117 // Floating | |
2118 | |
2119 void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); } | |
2120 void andpd(XMMRegister dst, AddressLiteral src); | |
2121 | |
2122 void comiss(XMMRegister dst, Address src) { Assembler::comiss(dst, src); } | |
2123 void comiss(XMMRegister dst, AddressLiteral src); | |
2124 | |
2125 void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); } | |
2126 void comisd(XMMRegister dst, AddressLiteral src); | |
2127 | |
2128 void fldcw(Address src) { Assembler::fldcw(src); } | |
2129 void fldcw(AddressLiteral src); | |
2130 | |
2131 void fld_s(int index) { Assembler::fld_s(index); } | |
2132 void fld_s(Address src) { Assembler::fld_s(src); } | |
2133 void fld_s(AddressLiteral src); | |
2134 | |
2135 void fld_d(Address src) { Assembler::fld_d(src); } | |
2136 void fld_d(AddressLiteral src); | |
2137 | |
2138 void fld_x(Address src) { Assembler::fld_x(src); } | |
2139 void fld_x(AddressLiteral src); | |
2140 | |
2141 void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } | |
2142 void ldmxcsr(AddressLiteral src); | |
2143 | |
304 | 2144 private: |
2145 // these are private because users should be doing movflt/movdbl | |
2146 | |
0 | 2147 void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } |
2148 void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } | |
2149 void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } | |
2150 void movss(XMMRegister dst, AddressLiteral src); | |
2151 | |
304 | 2152 void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } |
2153 void movlpd(XMMRegister dst, AddressLiteral src); | |
2154 | |
2155 public: | |
2156 | |
0 | 2157 void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } |
2158 void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } | |
2159 void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } | |
2160 void movsd(XMMRegister dst, AddressLiteral src); | |
2161 | |
2162 void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); } | |
2163 void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); } | |
2164 void ucomiss(XMMRegister dst, AddressLiteral src); | |
2165 | |
2166 void ucomisd(XMMRegister dst, XMMRegister src) { Assembler::ucomisd(dst, src); } | |
2167 void ucomisd(XMMRegister dst, Address src) { Assembler::ucomisd(dst, src); } | |
2168 void ucomisd(XMMRegister dst, AddressLiteral src); | |
2169 | |
2170 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
2171 void xorpd(XMMRegister dst, XMMRegister src) { Assembler::xorpd(dst, src); } | |
2172 void xorpd(XMMRegister dst, Address src) { Assembler::xorpd(dst, src); } | |
2173 void xorpd(XMMRegister dst, AddressLiteral src); | |
2174 | |
2175 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
2176 void xorps(XMMRegister dst, XMMRegister src) { Assembler::xorps(dst, src); } | |
2177 void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); } | |
2178 void xorps(XMMRegister dst, AddressLiteral src); | |
2179 | |
2180 // Data | |
2181 | |
304 | 2182 void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } |
2183 | |
2184 void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } | |
2185 void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } | |
2186 | |
0 | 2187 void movoop(Register dst, jobject obj); |
2188 void movoop(Address dst, jobject obj); | |
2189 | |
2190 void movptr(ArrayAddress dst, Register src); | |
2191 // can this do an lea? | |
2192 void movptr(Register dst, ArrayAddress src); | |
2193 | |
304 | 2194 void movptr(Register dst, Address src); |
2195 | |
0 | 2196 void movptr(Register dst, AddressLiteral src); |
2197 | |
304 | 2198 void movptr(Register dst, intptr_t src); |
2199 void movptr(Register dst, Register src); | |
2200 void movptr(Address dst, intptr_t src); | |
2201 | |
2202 void movptr(Address dst, Register src); | |
2203 | |
2204 #ifdef _LP64 | |
2205 // Generally the next two are only used for moving NULL | |
2206 // Although there are situations in initializing the mark word where | |
2207 // they could be used. They are dangerous. | |
2208 | |
2209 // They only exist on LP64 so that int32_t and intptr_t are not the same | |
2210 // and we have ambiguous declarations. | |
2211 | |
2212 void movptr(Address dst, int32_t imm32); | |
2213 void movptr(Register dst, int32_t imm32); | |
2214 #endif // _LP64 | |
2215 | |
0 | 2216 // to avoid hiding movl |
2217 void mov32(AddressLiteral dst, Register src); | |
2218 void mov32(Register dst, AddressLiteral src); | |
304 | 2219 |
0 | 2220 // to avoid hiding movb |
2221 void movbyte(ArrayAddress dst, int src); | |
2222 | |
2223 // Can push value or effective address | |
2224 void pushptr(AddressLiteral src); | |
2225 | |
304 | 2226 void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); } |
2227 void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); } | |
2228 | |
2229 void pushoop(jobject obj); | |
2230 | |
2231 // sign extend as need a l to ptr sized element | |
2232 void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); } | |
2233 void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } | |
2234 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2235 // IndexOf strings. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2236 void string_indexof(Register str1, Register str2, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2237 Register cnt1, Register cnt2, Register result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2238 XMMRegister vec, Register tmp); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2239 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2240 // Compare strings. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2241 void string_compare(Register str1, Register str2, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2242 Register cnt1, Register cnt2, Register result, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2243 XMMRegister vec1, XMMRegister vec2); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2244 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2245 // Compare char[] arrays. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2246 void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2247 Register limit, Register result, Register chr, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2248 XMMRegister vec1, XMMRegister vec2); |
304 | 2249 |
1763 | 2250 // Fill primitive arrays |
2251 void generate_fill(BasicType t, bool aligned, | |
2252 Register to, Register value, Register count, | |
2253 Register rtmp, XMMRegister xtmp); | |
2254 | |
0 | 2255 #undef VIRTUAL |
2256 | |
2257 }; | |
2258 | |
2259 /** | |
2260 * class SkipIfEqual: | |
2261 * | |
2262 * Instantiating this class will result in assembly code being output that will | |
2263 * jump around any code emitted between the creation of the instance and it's | |
2264 * automatic destruction at the end of a scope block, depending on the value of | |
2265 * the flag passed to the constructor, which will be checked at run-time. | |
2266 */ | |
2267 class SkipIfEqual { | |
2268 private: | |
2269 MacroAssembler* _masm; | |
2270 Label _label; | |
2271 | |
2272 public: | |
2273 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); | |
2274 ~SkipIfEqual(); | |
2275 }; | |
2276 | |
2277 #ifdef ASSERT | |
2278 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; } | |
2279 #endif | |
1972 | 2280 |
2281 #endif // CPU_X86_VM_ASSEMBLER_X86_HPP |