Mercurial > hg > truffle
annotate src/cpu/x86/vm/assembler_x86.hpp @ 3249:e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes
author | johnc |
---|---|
date | Thu, 07 Apr 2011 09:53:20 -0700 |
parents | 41d4973cf100 |
children | 92add02409c9 |
rev | line source |
---|---|
0 | 1 /* |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
677 static bool is_simm(int64_t x, int nbits) { return -(CONST64(1) << (nbits-1)) <= x && |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
678 x < (CONST64(1) << (nbits-1)); } |
304 | 679 static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; } |
680 #else | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
681 static bool is_simm(int32_t x, int nbits) { return -(1 << (nbits-1)) <= x && |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
682 x < (1 << (nbits-1)); } |
304 | 683 static bool is_simm32(int32_t x) { return true; } |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
684 #endif // _LP64 |
304 | 685 |
686 // Generic instructions | |
687 // Does 32bit or 64bit as needed for the platform. In some sense these | |
688 // belong in macro assembler but there is no need for both varieties to exist | |
689 | |
690 void lea(Register dst, Address src); | |
691 | |
692 void mov(Register dst, Register src); | |
693 | |
694 void pusha(); | |
695 void popa(); | |
696 | |
697 void pushf(); | |
698 void popf(); | |
699 | |
700 void push(int32_t imm32); | |
701 | |
702 void push(Register src); | |
703 | |
704 void pop(Register dst); | |
705 | |
706 // These are dummies to prevent surprise implicit conversions to Register | |
707 void push(void* v); | |
708 void pop(void* v); | |
709 | |
710 // These do register sized moves/scans | |
711 void rep_mov(); | |
712 void rep_set(); | |
713 void repne_scan(); | |
714 #ifdef _LP64 | |
715 void repne_scanl(); | |
716 #endif | |
717 | |
718 // Vanilla instructions in lexical order | |
719 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
720 void adcl(Address dst, int32_t imm32); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
721 void adcl(Address dst, Register src); |
304 | 722 void adcl(Register dst, int32_t imm32); |
0 | 723 void adcl(Register dst, Address src); |
724 void adcl(Register dst, Register src); | |
725 | |
304 | 726 void adcq(Register dst, int32_t imm32); |
727 void adcq(Register dst, Address src); | |
728 void adcq(Register dst, Register src); | |
729 | |
730 void addl(Address dst, int32_t imm32); | |
0 | 731 void addl(Address dst, Register src); |
304 | 732 void addl(Register dst, int32_t imm32); |
0 | 733 void addl(Register dst, Address src); |
734 void addl(Register dst, Register src); | |
735 | |
304 | 736 void addq(Address dst, int32_t imm32); |
737 void addq(Address dst, Register src); | |
738 void addq(Register dst, int32_t imm32); | |
739 void addq(Register dst, Address src); | |
740 void addq(Register dst, Register src); | |
741 | |
0 | 742 void addr_nop_4(); |
743 void addr_nop_5(); | |
744 void addr_nop_7(); | |
745 void addr_nop_8(); | |
746 | |
304 | 747 // Add Scalar Double-Precision Floating-Point Values |
748 void addsd(XMMRegister dst, Address src); | |
749 void addsd(XMMRegister dst, XMMRegister src); | |
750 | |
751 // Add Scalar Single-Precision Floating-Point Values | |
752 void addss(XMMRegister dst, Address src); | |
753 void addss(XMMRegister dst, XMMRegister src); | |
754 | |
755 void andl(Register dst, int32_t imm32); | |
756 void andl(Register dst, Address src); | |
757 void andl(Register dst, Register src); | |
758 | |
759 void andq(Register dst, int32_t imm32); | |
760 void andq(Register dst, Address src); | |
761 void andq(Register dst, Register src); | |
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); | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1124 void movdl(XMMRegister dst, Address src); |
304 | 1125 |
1126 // Move Double Quadword | |
1127 void movdq(XMMRegister dst, Register src); | |
1128 void movdq(Register dst, XMMRegister src); | |
1129 | |
1130 // Move Aligned Double Quadword | |
1131 void movdqa(Address dst, XMMRegister src); | |
1132 void movdqa(XMMRegister dst, Address src); | |
1133 void movdqa(XMMRegister dst, XMMRegister src); | |
1134 | |
405 | 1135 // Move Unaligned Double Quadword |
1136 void movdqu(Address dst, XMMRegister src); | |
1137 void movdqu(XMMRegister dst, Address src); | |
1138 void movdqu(XMMRegister dst, XMMRegister src); | |
1139 | |
304 | 1140 void movl(Register dst, int32_t imm32); |
1141 void movl(Address dst, int32_t imm32); | |
1142 void movl(Register dst, Register src); | |
1143 void movl(Register dst, Address src); | |
1144 void movl(Address dst, Register src); | |
1145 | |
1146 // These dummies prevent using movl from converting a zero (like NULL) into Register | |
1147 // by giving the compiler two choices it can't resolve | |
1148 | |
1149 void movl(Address dst, void* junk); | |
1150 void movl(Register dst, void* junk); | |
1151 | |
1152 #ifdef _LP64 | |
1153 void movq(Register dst, Register src); | |
1154 void movq(Register dst, Address src); | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1155 void movq(Address dst, Register src); |
304 | 1156 #endif |
1157 | |
1158 void movq(Address dst, MMXRegister src ); | |
1159 void movq(MMXRegister dst, Address src ); | |
1160 | |
1161 #ifdef _LP64 | |
1162 // These dummies prevent using movq from converting a zero (like NULL) into Register | |
1163 // by giving the compiler two choices it can't resolve | |
1164 | |
1165 void movq(Address dst, void* dummy); | |
1166 void movq(Register dst, void* dummy); | |
1167 #endif | |
1168 | |
1169 // Move Quadword | |
1170 void movq(Address dst, XMMRegister src); | |
1171 void movq(XMMRegister dst, Address src); | |
1172 | |
1173 void movsbl(Register dst, Address src); | |
1174 void movsbl(Register dst, Register src); | |
1175 | |
1176 #ifdef _LP64 | |
624 | 1177 void movsbq(Register dst, Address src); |
1178 void movsbq(Register dst, Register src); | |
1179 | |
304 | 1180 // Move signed 32bit immediate to 64bit extending sign |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1181 void movslq(Address dst, int32_t imm64); |
304 | 1182 void movslq(Register dst, int32_t imm64); |
1183 | |
1184 void movslq(Register dst, Address src); | |
1185 void movslq(Register dst, Register src); | |
1186 void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous | |
1187 #endif | |
1188 | |
1189 void movswl(Register dst, Address src); | |
1190 void movswl(Register dst, Register src); | |
1191 | |
624 | 1192 #ifdef _LP64 |
1193 void movswq(Register dst, Address src); | |
1194 void movswq(Register dst, Register src); | |
1195 #endif | |
1196 | |
304 | 1197 void movw(Address dst, int imm16); |
1198 void movw(Register dst, Address src); | |
1199 void movw(Address dst, Register src); | |
1200 | |
1201 void movzbl(Register dst, Address src); | |
1202 void movzbl(Register dst, Register src); | |
1203 | |
624 | 1204 #ifdef _LP64 |
1205 void movzbq(Register dst, Address src); | |
1206 void movzbq(Register dst, Register src); | |
1207 #endif | |
1208 | |
304 | 1209 void movzwl(Register dst, Address src); |
1210 void movzwl(Register dst, Register src); | |
1211 | |
624 | 1212 #ifdef _LP64 |
1213 void movzwq(Register dst, Address src); | |
1214 void movzwq(Register dst, Register src); | |
1215 #endif | |
1216 | |
304 | 1217 void mull(Address src); |
1218 void mull(Register src); | |
1219 | |
1220 // Multiply Scalar Double-Precision Floating-Point Values | |
1221 void mulsd(XMMRegister dst, Address src); | |
1222 void mulsd(XMMRegister dst, XMMRegister src); | |
1223 | |
1224 // Multiply Scalar Single-Precision Floating-Point Values | |
1225 void mulss(XMMRegister dst, Address src); | |
1226 void mulss(XMMRegister dst, XMMRegister src); | |
1227 | |
1228 void negl(Register dst); | |
1229 | |
1230 #ifdef _LP64 | |
1231 void negq(Register dst); | |
1232 #endif | |
1233 | |
1234 void nop(int i = 1); | |
1235 | |
1236 void notl(Register dst); | |
1237 | |
1238 #ifdef _LP64 | |
1239 void notq(Register dst); | |
1240 #endif | |
1241 | |
1242 void orl(Address dst, int32_t imm32); | |
1243 void orl(Register dst, int32_t imm32); | |
1244 void orl(Register dst, Address src); | |
1245 void orl(Register dst, Register src); | |
1246 | |
1247 void orq(Address dst, int32_t imm32); | |
1248 void orq(Register dst, int32_t imm32); | |
1249 void orq(Register dst, Address src); | |
1250 void orq(Register dst, Register src); | |
1251 | |
681 | 1252 // SSE4.2 string instructions |
1253 void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8); | |
1254 void pcmpestri(XMMRegister xmm1, Address src, int imm8); | |
1255 | |
1060 | 1256 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1257 void popl(Address dst); |
1060 | 1258 #endif |
304 | 1259 |
1260 #ifdef _LP64 | |
1261 void popq(Address dst); | |
1262 #endif | |
1263 | |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1264 void popcntl(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1265 void popcntl(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1266 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1267 #ifdef _LP64 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1268 void popcntq(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1269 void popcntq(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1270 #endif |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1271 |
304 | 1272 // Prefetches (SSE, SSE2, 3DNOW only) |
1273 | |
1274 void prefetchnta(Address src); | |
1275 void prefetchr(Address src); | |
1276 void prefetcht0(Address src); | |
1277 void prefetcht1(Address src); | |
1278 void prefetcht2(Address src); | |
1279 void prefetchw(Address src); | |
1280 | |
2262 | 1281 // POR - Bitwise logical OR |
1282 void por(XMMRegister dst, XMMRegister src); | |
1283 | |
304 | 1284 // Shuffle Packed Doublewords |
1285 void pshufd(XMMRegister dst, XMMRegister src, int mode); | |
1286 void pshufd(XMMRegister dst, Address src, int mode); | |
1287 | |
1288 // Shuffle Packed Low Words | |
1289 void pshuflw(XMMRegister dst, XMMRegister src, int mode); | |
1290 void pshuflw(XMMRegister dst, Address src, int mode); | |
1291 | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1292 // Shift Right by bits Logical Quadword Immediate |
304 | 1293 void psrlq(XMMRegister dst, int shift); |
1294 | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1295 // Shift Right by bytes Logical DoubleQuadword Immediate |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1296 void psrldq(XMMRegister dst, int shift); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1297 |
681 | 1298 // Logical Compare Double Quadword |
1299 void ptest(XMMRegister dst, XMMRegister src); | |
1300 void ptest(XMMRegister dst, Address src); | |
1301 | |
304 | 1302 // Interleave Low Bytes |
1303 void punpcklbw(XMMRegister dst, XMMRegister src); | |
1304 | |
1060 | 1305 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1306 void pushl(Address src); |
1060 | 1307 #endif |
304 | 1308 |
1309 void pushq(Address src); | |
1310 | |
1311 // Xor Packed Byte Integer Values | |
1312 void pxor(XMMRegister dst, Address src); | |
1313 void pxor(XMMRegister dst, XMMRegister src); | |
1314 | |
1315 void rcll(Register dst, int imm8); | |
1316 | |
1317 void rclq(Register dst, int imm8); | |
1318 | |
1319 void ret(int imm16); | |
0 | 1320 |
1321 void sahf(); | |
1322 | |
304 | 1323 void sarl(Register dst, int imm8); |
1324 void sarl(Register dst); | |
1325 | |
1326 void sarq(Register dst, int imm8); | |
1327 void sarq(Register dst); | |
1328 | |
1329 void sbbl(Address dst, int32_t imm32); | |
1330 void sbbl(Register dst, int32_t imm32); | |
1331 void sbbl(Register dst, Address src); | |
1332 void sbbl(Register dst, Register src); | |
1333 | |
1334 void sbbq(Address dst, int32_t imm32); | |
1335 void sbbq(Register dst, int32_t imm32); | |
1336 void sbbq(Register dst, Address src); | |
1337 void sbbq(Register dst, Register src); | |
1338 | |
1339 void setb(Condition cc, Register dst); | |
1340 | |
1341 void shldl(Register dst, Register src); | |
1342 | |
1343 void shll(Register dst, int imm8); | |
1344 void shll(Register dst); | |
1345 | |
1346 void shlq(Register dst, int imm8); | |
1347 void shlq(Register dst); | |
1348 | |
1349 void shrdl(Register dst, Register src); | |
1350 | |
1351 void shrl(Register dst, int imm8); | |
1352 void shrl(Register dst); | |
1353 | |
1354 void shrq(Register dst, int imm8); | |
1355 void shrq(Register dst); | |
1356 | |
1357 void smovl(); // QQQ generic? | |
1358 | |
1359 // Compute Square Root of Scalar Double-Precision Floating-Point Value | |
1360 void sqrtsd(XMMRegister dst, Address src); | |
1361 void sqrtsd(XMMRegister dst, XMMRegister src); | |
1362 | |
2008 | 1363 // Compute Square Root of Scalar Single-Precision Floating-Point Value |
1364 void sqrtss(XMMRegister dst, Address src); | |
1365 void sqrtss(XMMRegister dst, XMMRegister src); | |
1366 | |
304 | 1367 void std() { emit_byte(0xfd); } |
1368 | |
1369 void stmxcsr( Address dst ); | |
1370 | |
1371 void subl(Address dst, int32_t imm32); | |
1372 void subl(Address dst, Register src); | |
1373 void subl(Register dst, int32_t imm32); | |
1374 void subl(Register dst, Address src); | |
1375 void subl(Register dst, Register src); | |
1376 | |
1377 void subq(Address dst, int32_t imm32); | |
1378 void subq(Address dst, Register src); | |
1379 void subq(Register dst, int32_t imm32); | |
1380 void subq(Register dst, Address src); | |
1381 void subq(Register dst, Register src); | |
1382 | |
1383 | |
1384 // Subtract Scalar Double-Precision Floating-Point Values | |
1385 void subsd(XMMRegister dst, Address src); | |
0 | 1386 void subsd(XMMRegister dst, XMMRegister src); |
1387 | |
304 | 1388 // Subtract Scalar Single-Precision Floating-Point Values |
1389 void subss(XMMRegister dst, Address src); | |
1390 void subss(XMMRegister dst, XMMRegister src); | |
1391 | |
1392 void testb(Register dst, int imm8); | |
1393 | |
1394 void testl(Register dst, int32_t imm32); | |
1395 void testl(Register dst, Register src); | |
1396 void testl(Register dst, Address src); | |
1397 | |
1398 void testq(Register dst, int32_t imm32); | |
1399 void testq(Register dst, Register src); | |
1400 | |
1401 | |
1402 // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS | |
1403 void ucomisd(XMMRegister dst, Address src); | |
0 | 1404 void ucomisd(XMMRegister dst, XMMRegister src); |
1405 | |
304 | 1406 // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS |
1407 void ucomiss(XMMRegister dst, Address src); | |
1408 void ucomiss(XMMRegister dst, XMMRegister src); | |
1409 | |
1410 void xaddl(Address dst, Register src); | |
1411 | |
1412 void xaddq(Address dst, Register src); | |
1413 | |
1414 void xchgl(Register reg, Address adr); | |
1415 void xchgl(Register dst, Register src); | |
1416 | |
1417 void xchgq(Register reg, Address adr); | |
1418 void xchgq(Register dst, Register src); | |
1419 | |
1420 void xorl(Register dst, int32_t imm32); | |
1421 void xorl(Register dst, Address src); | |
1422 void xorl(Register dst, Register src); | |
1423 | |
1424 void xorq(Register dst, Address src); | |
1425 void xorq(Register dst, Register src); | |
1426 | |
1427 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
1428 void xorpd(XMMRegister dst, Address src); | |
1429 void xorpd(XMMRegister dst, XMMRegister src); | |
1430 | |
1431 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
1432 void xorps(XMMRegister dst, Address src); | |
0 | 1433 void xorps(XMMRegister dst, XMMRegister src); |
304 | 1434 |
1435 void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 | |
0 | 1436 }; |
1437 | |
1438 | |
1439 // MacroAssembler extends Assembler by frequently used macros. | |
1440 // | |
1441 // Instructions for which a 'better' code sequence exists depending | |
1442 // on arguments should also go in here. | |
1443 | |
1444 class MacroAssembler: public Assembler { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1445 friend class LIR_Assembler; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1446 friend class Runtime1; // as_Address() |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1447 |
0 | 1448 protected: |
1449 | |
1450 Address as_Address(AddressLiteral adr); | |
1451 Address as_Address(ArrayAddress adr); | |
1452 | |
1453 // Support for VM calls | |
1454 // | |
1455 // This is the base routine called by the different versions of call_VM_leaf. The interpreter | |
1456 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1457 // additional registers when doing a VM call). | |
1458 #ifdef CC_INTERP | |
1459 // c++ interpreter never wants to use interp_masm version of call_VM | |
1460 #define VIRTUAL | |
1461 #else | |
1462 #define VIRTUAL virtual | |
1463 #endif | |
1464 | |
1465 VIRTUAL void call_VM_leaf_base( | |
1466 address entry_point, // the entry point | |
1467 int number_of_arguments // the number of arguments to pop after the call | |
1468 ); | |
1469 | |
1470 // This is the base routine called by the different versions of call_VM. The interpreter | |
1471 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1472 // additional registers when doing a VM call). | |
1473 // | |
1474 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base | |
1475 // returns the register which contains the thread upon return. If a thread register has been | |
1476 // specified, the return value will correspond to that register. If no last_java_sp is specified | |
1477 // (noreg) than rsp will be used instead. | |
1478 VIRTUAL void call_VM_base( // returns the register containing the thread upon return | |
1479 Register oop_result, // where an oop-result ends up if any; use noreg otherwise | |
1480 Register java_thread, // the thread if computed before ; use noreg otherwise | |
1481 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise | |
1482 address entry_point, // the entry point | |
1483 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call | |
1484 bool check_exceptions // whether to check for pending exceptions after return | |
1485 ); | |
1486 | |
1487 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code. | |
1488 // The implementation is only non-empty for the InterpreterMacroAssembler, | |
1489 // as only the interpreter handles PopFrame and ForceEarlyReturn requests. | |
1490 virtual void check_and_handle_popframe(Register java_thread); | |
1491 virtual void check_and_handle_earlyret(Register java_thread); | |
1492 | |
1493 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true); | |
1494 | |
1495 // helpers for FPU flag access | |
1496 // tmp is a temporary register, if none is available use noreg | |
1497 void save_rax (Register tmp); | |
1498 void restore_rax(Register tmp); | |
1499 | |
1500 public: | |
1501 MacroAssembler(CodeBuffer* code) : Assembler(code) {} | |
1502 | |
1503 // Support for NULL-checks | |
1504 // | |
1505 // Generates code that causes a NULL OS exception if the content of reg is NULL. | |
1506 // If the accessed location is M[reg + offset] and the offset is known, provide the | |
1507 // offset. No explicit code generation is needed if the offset is within a certain | |
1508 // range (0 <= offset <= page_size). | |
1509 | |
1510 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
|
1511 static bool needs_explicit_null_check(intptr_t offset); |
0 | 1512 |
1513 // Required platform-specific helpers for Label::patch_instructions. | |
1514 // They _shadow_ the declarations in AbstractAssembler, which are undefined. | |
1515 void pd_patch_instruction(address branch, address target); | |
1516 #ifndef PRODUCT | |
1517 static void pd_print_patched_instruction(address branch); | |
1518 #endif | |
1519 | |
1520 // The following 4 methods return the offset of the appropriate move instruction | |
1521 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1522 // Support for fast byte/short loading with zero extension (depending on particular CPU) |
0 | 1523 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
|
1524 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
|
1525 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1526 // Support for fast byte/short loading with sign extension (depending on particular CPU) |
0 | 1527 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
|
1528 int load_signed_short(Register dst, Address src); |
0 | 1529 |
1530 // Support for sign-extension (hi:lo = extend_sign(lo)) | |
1531 void extend_sign(Register hi, Register lo); | |
1532 | |
2258
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2100
diff
changeset
|
1533 // Load and store values by size and signed-ness |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2100
diff
changeset
|
1534 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg); |
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2100
diff
changeset
|
1535 void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1536 |
0 | 1537 // Support for inc/dec with optimal instruction selection depending on value |
304 | 1538 |
1539 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } | |
1540 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } | |
1541 | |
1542 void decrementl(Address dst, int value = 1); | |
1543 void decrementl(Register reg, int value = 1); | |
1544 | |
1545 void decrementq(Register reg, int value = 1); | |
1546 void decrementq(Address dst, int value = 1); | |
1547 | |
1548 void incrementl(Address dst, int value = 1); | |
1549 void incrementl(Register reg, int value = 1); | |
1550 | |
1551 void incrementq(Register reg, int value = 1); | |
1552 void incrementq(Address dst, int value = 1); | |
1553 | |
0 | 1554 |
1555 // Support optimal SSE move instructions. | |
1556 void movflt(XMMRegister dst, XMMRegister src) { | |
1557 if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; } | |
1558 else { movss (dst, src); return; } | |
1559 } | |
1560 void movflt(XMMRegister dst, Address src) { movss(dst, src); } | |
1561 void movflt(XMMRegister dst, AddressLiteral src); | |
1562 void movflt(Address dst, XMMRegister src) { movss(dst, src); } | |
1563 | |
1564 void movdbl(XMMRegister dst, XMMRegister src) { | |
1565 if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; } | |
1566 else { movsd (dst, src); return; } | |
1567 } | |
1568 | |
1569 void movdbl(XMMRegister dst, AddressLiteral src); | |
1570 | |
1571 void movdbl(XMMRegister dst, Address src) { | |
1572 if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; } | |
1573 else { movlpd(dst, src); return; } | |
1574 } | |
1575 void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } | |
1576 | |
304 | 1577 void incrementl(AddressLiteral dst); |
1578 void incrementl(ArrayAddress dst); | |
0 | 1579 |
1580 // Alignment | |
1581 void align(int modulus); | |
1582 | |
1583 // Misc | |
1584 void fat_nop(); // 5 byte nop | |
1585 | |
1586 // Stack frame creation/removal | |
1587 void enter(); | |
1588 void leave(); | |
1589 | |
1590 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information) | |
1591 // The pointer will be loaded into the thread register. | |
1592 void get_thread(Register thread); | |
1593 | |
362 | 1594 |
0 | 1595 // Support for VM calls |
1596 // | |
1597 // It is imperative that all calls into the VM are handled via the call_VM macros. | |
1598 // They make sure that the stack linkage is setup correctly. call_VM's correspond | |
1599 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. | |
1600 | |
304 | 1601 |
1602 void call_VM(Register oop_result, | |
1603 address entry_point, | |
1604 bool check_exceptions = true); | |
1605 void call_VM(Register oop_result, | |
1606 address entry_point, | |
1607 Register arg_1, | |
1608 bool check_exceptions = true); | |
1609 void call_VM(Register oop_result, | |
1610 address entry_point, | |
1611 Register arg_1, Register arg_2, | |
1612 bool check_exceptions = true); | |
1613 void call_VM(Register oop_result, | |
1614 address entry_point, | |
1615 Register arg_1, Register arg_2, Register arg_3, | |
1616 bool check_exceptions = true); | |
1617 | |
1618 // Overloadings with last_Java_sp | |
1619 void call_VM(Register oop_result, | |
1620 Register last_java_sp, | |
1621 address entry_point, | |
1622 int number_of_arguments = 0, | |
1623 bool check_exceptions = true); | |
1624 void call_VM(Register oop_result, | |
1625 Register last_java_sp, | |
1626 address entry_point, | |
1627 Register arg_1, bool | |
1628 check_exceptions = true); | |
1629 void call_VM(Register oop_result, | |
1630 Register last_java_sp, | |
1631 address entry_point, | |
1632 Register arg_1, Register arg_2, | |
1633 bool check_exceptions = true); | |
1634 void call_VM(Register oop_result, | |
1635 Register last_java_sp, | |
1636 address entry_point, | |
1637 Register arg_1, Register arg_2, Register arg_3, | |
1638 bool check_exceptions = true); | |
1639 | |
1640 void call_VM_leaf(address entry_point, | |
1641 int number_of_arguments = 0); | |
1642 void call_VM_leaf(address entry_point, | |
1643 Register arg_1); | |
1644 void call_VM_leaf(address entry_point, | |
1645 Register arg_1, Register arg_2); | |
1646 void call_VM_leaf(address entry_point, | |
1647 Register arg_1, Register arg_2, Register arg_3); | |
0 | 1648 |
1649 // last Java Frame (fills frame anchor) | |
304 | 1650 void set_last_Java_frame(Register thread, |
1651 Register last_java_sp, | |
1652 Register last_java_fp, | |
1653 address last_java_pc); | |
1654 | |
1655 // thread in the default location (r15_thread on 64bit) | |
1656 void set_last_Java_frame(Register last_java_sp, | |
1657 Register last_java_fp, | |
1658 address last_java_pc); | |
1659 | |
0 | 1660 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); |
1661 | |
304 | 1662 // thread in the default location (r15_thread on 64bit) |
1663 void reset_last_Java_frame(bool clear_fp, bool clear_pc); | |
1664 | |
0 | 1665 // Stores |
1666 void store_check(Register obj); // store check for obj - register is destroyed afterwards | |
1667 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) | |
1668 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1669 #ifndef SERIALGC |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1670 |
362 | 1671 void g1_write_barrier_pre(Register obj, |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1672 Register pre_val, |
362 | 1673 Register thread, |
1674 Register tmp, | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1675 bool tosca_live, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1676 bool expand_call); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1677 |
362 | 1678 void g1_write_barrier_post(Register store_addr, |
1679 Register new_val, | |
1680 Register thread, | |
1681 Register tmp, | |
1682 Register tmp2); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1683 |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2320
diff
changeset
|
1684 #endif // SERIALGC |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1685 |
0 | 1686 // split store_check(Register obj) to enhance instruction interleaving |
1687 void store_check_part_1(Register obj); | |
1688 void store_check_part_2(Register obj); | |
1689 | |
1690 // C 'boolean' to Java boolean: x == 0 ? 0 : 1 | |
1691 void c2bool(Register x); | |
1692 | |
1693 // C++ bool manipulation | |
1694 | |
1695 void movbool(Register dst, Address src); | |
1696 void movbool(Address dst, bool boolconst); | |
1697 void movbool(Address dst, Register src); | |
1698 void testbool(Register dst); | |
1699 | |
304 | 1700 // oop manipulations |
1701 void load_klass(Register dst, Register src); | |
1702 void store_klass(Register dst, Register src); | |
1703 | |
1846 | 1704 void load_heap_oop(Register dst, Address src); |
1705 void store_heap_oop(Address dst, Register src); | |
1706 | |
1707 // Used for storing NULL. All other oop constants should be | |
1708 // stored using routines that take a jobject. | |
1709 void store_heap_oop_null(Address dst); | |
1710 | |
304 | 1711 void load_prototype_header(Register dst, Register src); |
1712 | |
1713 #ifdef _LP64 | |
1714 void store_klass_gap(Register dst, Register src); | |
1715 | |
1047
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1716 // 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
|
1717 // 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
|
1718 // the compiler two choices it can't resolve |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1719 |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1720 void store_heap_oop(Address dst, void* dummy); |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1721 |
304 | 1722 void encode_heap_oop(Register r); |
1723 void decode_heap_oop(Register r); | |
1724 void encode_heap_oop_not_null(Register r); | |
1725 void decode_heap_oop_not_null(Register r); | |
1726 void encode_heap_oop_not_null(Register dst, Register src); | |
1727 void decode_heap_oop_not_null(Register dst, Register src); | |
1728 | |
1729 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
|
1730 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
|
1731 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
|
1732 void cmp_narrow_oop(Address dst, jobject obj); |
304 | 1733 |
1734 // if heap base register is used - reinit it with the correct value | |
1735 void reinit_heapbase(); | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1736 |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1737 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
|
1738 |
304 | 1739 #endif // _LP64 |
1740 | |
1741 // Int division/remainder for Java | |
0 | 1742 // (as idivl, but checks for special case as described in JVM spec.) |
1743 // returns idivl instruction offset for implicit exception handling | |
1744 int corrected_idivl(Register reg); | |
1745 | |
304 | 1746 // Long division/remainder for Java |
1747 // (as idivq, but checks for special case as described in JVM spec.) | |
1748 // returns idivq instruction offset for implicit exception handling | |
1749 int corrected_idivq(Register reg); | |
1750 | |
0 | 1751 void int3(); |
1752 | |
304 | 1753 // Long operation macros for a 32bit cpu |
0 | 1754 // Long negation for Java |
1755 void lneg(Register hi, Register lo); | |
1756 | |
1757 // Long multiplication for Java | |
304 | 1758 // (destroys contents of eax, ebx, ecx and edx) |
0 | 1759 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y |
1760 | |
1761 // Long shifts for Java | |
1762 // (semantics as described in JVM spec.) | |
1763 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f) | |
1764 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f) | |
1765 | |
1766 // Long compare for Java | |
1767 // (semantics as described in JVM spec.) | |
1768 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y) | |
1769 | |
304 | 1770 |
1771 // misc | |
1772 | |
1773 // Sign extension | |
1774 void sign_extend_short(Register reg); | |
1775 void sign_extend_byte(Register reg); | |
1776 | |
1777 // Division by power of 2, rounding towards 0 | |
1778 void division_with_shift(Register reg, int shift_value); | |
1779 | |
0 | 1780 // Compares the top-most stack entries on the FPU stack and sets the eflags as follows: |
1781 // | |
1782 // CF (corresponds to C0) if x < y | |
1783 // PF (corresponds to C2) if unordered | |
1784 // ZF (corresponds to C3) if x = y | |
1785 // | |
1786 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1787 // tmp is a temporary register, if none is available use noreg (only matters for non-P6 code) | |
1788 void fcmp(Register tmp); | |
1789 // Variant of the above which allows y to be further down the stack | |
1790 // and which only pops x and y if specified. If pop_right is | |
1791 // specified then pop_left must also be specified. | |
1792 void fcmp(Register tmp, int index, bool pop_left, bool pop_right); | |
1793 | |
1794 // Floating-point comparison for Java | |
1795 // Compares the top-most stack entries on the FPU stack and stores the result in dst. | |
1796 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1797 // (semantics as described in JVM spec.) | |
1798 void fcmp2int(Register dst, bool unordered_is_less); | |
1799 // Variant of the above which allows y to be further down the stack | |
1800 // and which only pops x and y if specified. If pop_right is | |
1801 // specified then pop_left must also be specified. | |
1802 void fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right); | |
1803 | |
1804 // Floating-point remainder for Java (ST0 = ST0 fremr ST1, ST1 is empty afterwards) | |
1805 // tmp is a temporary register, if none is available use noreg | |
1806 void fremr(Register tmp); | |
1807 | |
1808 | |
1809 // same as fcmp2int, but using SSE2 | |
1810 void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1811 void cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1812 | |
1813 // Inlined sin/cos generator for Java; must not use CPU instruction | |
1814 // directly on Intel as it does not have high enough precision | |
1815 // outside of the range [-pi/4, pi/4]. Extra argument indicate the | |
1816 // number of FPU stack slots in use; all but the topmost will | |
1817 // require saving if a slow case is necessary. Assumes argument is | |
1818 // on FP TOS; result is on FP TOS. No cpu registers are changed by | |
1819 // this code. | |
1820 void trigfunc(char trig, int num_fpu_regs_in_use = 1); | |
1821 | |
1822 // branch to L if FPU flag C2 is set/not set | |
1823 // tmp is a temporary register, if none is available use noreg | |
1824 void jC2 (Register tmp, Label& L); | |
1825 void jnC2(Register tmp, Label& L); | |
1826 | |
1827 // Pop ST (ffree & fincstp combined) | |
1828 void fpop(); | |
1829 | |
1830 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack | |
1831 void push_fTOS(); | |
1832 | |
1833 // pops double TOS element from CPU stack and pushes on FPU stack | |
1834 void pop_fTOS(); | |
1835 | |
1836 void empty_FPU_stack(); | |
1837 | |
1838 void push_IU_state(); | |
1839 void pop_IU_state(); | |
1840 | |
1841 void push_FPU_state(); | |
1842 void pop_FPU_state(); | |
1843 | |
1844 void push_CPU_state(); | |
1845 void pop_CPU_state(); | |
1846 | |
1847 // Round up to a power of two | |
1848 void round_to(Register reg, int modulus); | |
1849 | |
1850 // Callee saved registers handling | |
1851 void push_callee_saved_registers(); | |
1852 void pop_callee_saved_registers(); | |
1853 | |
1854 // allocation | |
1855 void eden_allocate( | |
1856 Register obj, // result: pointer to object after successful allocation | |
1857 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1858 int con_size_in_bytes, // object size in bytes if known at compile time | |
1859 Register t1, // temp register | |
1860 Label& slow_case // continuation point if fast allocation fails | |
1861 ); | |
1862 void tlab_allocate( | |
1863 Register obj, // result: pointer to object after successful allocation | |
1864 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1865 int con_size_in_bytes, // object size in bytes if known at compile time | |
1866 Register t1, // temp register | |
1867 Register t2, // temp register | |
1868 Label& slow_case // continuation point if fast allocation fails | |
1869 ); | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1870 Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1871 void incr_allocated_bytes(Register thread, |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1872 Register var_size_in_bytes, int con_size_in_bytes, |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1873 Register t1 = noreg); |
0 | 1874 |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1875 // interface method calling |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1876 void lookup_interface_method(Register recv_klass, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1877 Register intf_klass, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1878 RegisterOrConstant itable_index, |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1879 Register method_result, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1880 Register scan_temp, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1881 Label& no_such_interface); |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1882 |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1883 // 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
|
1884 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1885 // 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
|
1886 // 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
|
1887 // 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
|
1888 // No registers are killed, except temp_reg. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1889 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
|
1890 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1891 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1892 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1893 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1894 Label* L_slow_path, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1895 RegisterOrConstant super_check_offset = RegisterOrConstant(-1)); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1896 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1897 // 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
|
1898 // 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
|
1899 // 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
|
1900 // 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
|
1901 // 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
|
1902 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
|
1903 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1904 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1905 Register temp2_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1906 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1907 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1908 bool set_cond_codes = false); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1909 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1910 // Simplified, combined version, good for typical uses. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1911 // Falls through on failure. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1912 void check_klass_subtype(Register sub_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1913 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1914 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1915 Label& L_success); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1916 |
710 | 1917 // method handles (JSR 292) |
1918 void check_method_handle_type(Register mtype_reg, Register mh_reg, | |
1919 Register temp_reg, | |
1920 Label& wrong_method_type); | |
1921 void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, | |
1922 Register temp_reg); | |
1923 void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); | |
1924 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); | |
1925 | |
1926 | |
0 | 1927 //---- |
1928 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 | |
1929 | |
1930 // Debugging | |
304 | 1931 |
1932 // only if +VerifyOops | |
1933 void verify_oop(Register reg, const char* s = "broken oop"); | |
0 | 1934 void verify_oop_addr(Address addr, const char * s = "broken oop addr"); |
1935 | |
304 | 1936 // only if +VerifyFPU |
1937 void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); | |
1938 | |
1939 // prints msg, dumps registers and stops execution | |
1940 void stop(const char* msg); | |
1941 | |
1942 // prints msg and continues | |
1943 void warn(const char* msg); | |
1944 | |
1945 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); | |
1946 static void debug64(char* msg, int64_t pc, int64_t regs[]); | |
1947 | |
0 | 1948 void os_breakpoint(); |
304 | 1949 |
0 | 1950 void untested() { stop("untested"); } |
304 | 1951 |
1846 | 1952 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); } |
304 | 1953 |
0 | 1954 void should_not_reach_here() { stop("should not reach here"); } |
304 | 1955 |
0 | 1956 void print_CPU_state(); |
1957 | |
1958 // Stack overflow checking | |
1959 void bang_stack_with_offset(int offset) { | |
1960 // stack grows down, caller passes positive offset | |
1961 assert(offset > 0, "must bang with negative offset"); | |
1962 movl(Address(rsp, (-offset)), rax); | |
1963 } | |
1964 | |
1965 // Writes to stack successive pages until offset reached to check for | |
1966 // stack overflow + shadow pages. Also, clobbers tmp | |
1967 void bang_stack_size(Register size, Register tmp); | |
1968 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1969 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1970 Register tmp, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1971 int offset); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1972 |
0 | 1973 // Support for serializing memory accesses between threads |
1974 void serialize_memory(Register thread, Register tmp); | |
1975 | |
1976 void verify_tlab(); | |
1977 | |
1978 // Biased locking support | |
1979 // lock_reg and obj_reg must be loaded up with the appropriate values. | |
1980 // swap_reg must be rax, and is killed. | |
1981 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will | |
1982 // be killed; if not supplied, push/pop will be used internally to | |
1983 // allocate a temporary (inefficient, avoid if possible). | |
1984 // Optional slow case is for implementations (interpreter and C1) which branch to | |
1985 // slow case directly. Leaves condition codes set for C2's Fast_Lock node. | |
1986 // Returns offset of first potentially-faulting instruction for null | |
1987 // check info (currently consumed only by C1). If | |
1988 // swap_reg_contains_mark is true then returns -1 as it is assumed | |
1989 // 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
|
1990 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
|
1991 Register swap_reg, Register tmp_reg, |
0 | 1992 bool swap_reg_contains_mark, |
1993 Label& done, Label* slow_case = NULL, | |
1994 BiasedLockingCounters* counters = NULL); | |
1995 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); | |
1996 | |
1997 | |
1998 Condition negate_condition(Condition cond); | |
1999 | |
2000 // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit | |
2001 // operands. In general the names are modified to avoid hiding the instruction in Assembler | |
2002 // so that we don't need to implement all the varieties in the Assembler with trivial wrappers | |
2003 // here in MacroAssembler. The major exception to this rule is call | |
2004 | |
2005 // Arithmetics | |
2006 | |
304 | 2007 |
2008 void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; } | |
2009 void addptr(Address dst, Register src); | |
2010 | |
2011 void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); } | |
2012 void addptr(Register dst, int32_t src); | |
2013 void addptr(Register dst, Register src); | |
2014 | |
2015 void andptr(Register dst, int32_t src); | |
2016 void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; } | |
2017 | |
2018 void cmp8(AddressLiteral src1, int imm); | |
2019 | |
2020 // renamed to drag out the casting of address to int32_t/intptr_t | |
0 | 2021 void cmp32(Register src1, int32_t imm); |
2022 | |
2023 void cmp32(AddressLiteral src1, int32_t imm); | |
2024 // compare reg - mem, or reg - &mem | |
2025 void cmp32(Register src1, AddressLiteral src2); | |
2026 | |
2027 void cmp32(Register src1, Address src2); | |
2028 | |
304 | 2029 #ifndef _LP64 |
2030 void cmpoop(Address dst, jobject obj); | |
2031 void cmpoop(Register dst, jobject obj); | |
2032 #endif // _LP64 | |
2033 | |
0 | 2034 // NOTE src2 must be the lval. This is NOT an mem-mem compare |
2035 void cmpptr(Address src1, AddressLiteral src2); | |
2036 | |
2037 void cmpptr(Register src1, AddressLiteral src2); | |
2038 | |
304 | 2039 void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } |
2040 void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2041 // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2042 | |
2043 void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2044 void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2045 | |
2046 // cmp64 to avoild hiding cmpq | |
2047 void cmp64(Register src1, AddressLiteral src); | |
2048 | |
2049 void cmpxchgptr(Register reg, Address adr); | |
2050 | |
2051 void locked_cmpxchgptr(Register reg, AddressLiteral adr); | |
2052 | |
2053 | |
2054 void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); } | |
2055 | |
2056 | |
2057 void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); } | |
2058 | |
2059 void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); } | |
2060 | |
2061 void shlptr(Register dst, int32_t shift); | |
2062 void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); } | |
2063 | |
2064 void shrptr(Register dst, int32_t shift); | |
2065 void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); } | |
2066 | |
2067 void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); } | |
2068 void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); } | |
2069 | |
2070 void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2071 | |
2072 void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2073 void subptr(Register dst, int32_t src); | |
2074 void subptr(Register dst, Register src); | |
2075 | |
2076 | |
2077 void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2078 void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2079 | |
2080 void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2081 void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2082 | |
2083 void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; } | |
2084 | |
2085 | |
0 | 2086 |
2087 // Helper functions for statistics gathering. | |
2088 // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. | |
2089 void cond_inc32(Condition cond, AddressLiteral counter_addr); | |
2090 // Unconditional atomic increment. | |
2091 void atomic_incl(AddressLiteral counter_addr); | |
2092 | |
2093 void lea(Register dst, AddressLiteral adr); | |
2094 void lea(Address dst, AddressLiteral adr); | |
304 | 2095 void lea(Register dst, Address adr) { Assembler::lea(dst, adr); } |
2096 | |
2097 void leal32(Register dst, Address src) { leal(dst, src); } | |
2098 | |
2099 void test32(Register src1, AddressLiteral src2); | |
2100 | |
2101 void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2102 void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2103 void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2104 | |
2105 void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } | |
2106 void testptr(Register src1, Register src2); | |
2107 | |
2108 void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
2109 void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
0 | 2110 |
2111 // Calls | |
2112 | |
2113 void call(Label& L, relocInfo::relocType rtype); | |
2114 void call(Register entry); | |
2115 | |
2116 // NOTE: this call tranfers to the effective address of entry NOT | |
2117 // the address contained by entry. This is because this is more natural | |
2118 // for jumps/calls. | |
2119 void call(AddressLiteral entry); | |
2120 | |
2121 // Jumps | |
2122 | |
2123 // NOTE: these jumps tranfer to the effective address of dst NOT | |
2124 // the address contained by dst. This is because this is more natural | |
2125 // for jumps/calls. | |
2126 void jump(AddressLiteral dst); | |
2127 void jump_cc(Condition cc, AddressLiteral dst); | |
2128 | |
2129 // 32bit can do a case table jump in one instruction but we no longer allow the base | |
2130 // to be installed in the Address class. This jump will tranfers to the address | |
2131 // contained in the location described by entry (not the address of entry) | |
2132 void jump(ArrayAddress entry); | |
2133 | |
2134 // Floating | |
2135 | |
2136 void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); } | |
2137 void andpd(XMMRegister dst, AddressLiteral src); | |
2138 | |
2139 void comiss(XMMRegister dst, Address src) { Assembler::comiss(dst, src); } | |
2140 void comiss(XMMRegister dst, AddressLiteral src); | |
2141 | |
2142 void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); } | |
2143 void comisd(XMMRegister dst, AddressLiteral src); | |
2144 | |
2008 | 2145 void fadd_s(Address src) { Assembler::fadd_s(src); } |
2146 void fadd_s(AddressLiteral src) { Assembler::fadd_s(as_Address(src)); } | |
2147 | |
0 | 2148 void fldcw(Address src) { Assembler::fldcw(src); } |
2149 void fldcw(AddressLiteral src); | |
2150 | |
2151 void fld_s(int index) { Assembler::fld_s(index); } | |
2152 void fld_s(Address src) { Assembler::fld_s(src); } | |
2153 void fld_s(AddressLiteral src); | |
2154 | |
2155 void fld_d(Address src) { Assembler::fld_d(src); } | |
2156 void fld_d(AddressLiteral src); | |
2157 | |
2158 void fld_x(Address src) { Assembler::fld_x(src); } | |
2159 void fld_x(AddressLiteral src); | |
2160 | |
2008 | 2161 void fmul_s(Address src) { Assembler::fmul_s(src); } |
2162 void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); } | |
2163 | |
0 | 2164 void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } |
2165 void ldmxcsr(AddressLiteral src); | |
2166 | |
304 | 2167 private: |
2168 // these are private because users should be doing movflt/movdbl | |
2169 | |
0 | 2170 void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } |
2171 void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } | |
2172 void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } | |
2173 void movss(XMMRegister dst, AddressLiteral src); | |
2174 | |
304 | 2175 void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } |
2176 void movlpd(XMMRegister dst, AddressLiteral src); | |
2177 | |
2178 public: | |
2179 | |
2008 | 2180 void addsd(XMMRegister dst, XMMRegister src) { Assembler::addsd(dst, src); } |
2181 void addsd(XMMRegister dst, Address src) { Assembler::addsd(dst, src); } | |
2182 void addsd(XMMRegister dst, AddressLiteral src) { Assembler::addsd(dst, as_Address(src)); } | |
2183 | |
2184 void addss(XMMRegister dst, XMMRegister src) { Assembler::addss(dst, src); } | |
2185 void addss(XMMRegister dst, Address src) { Assembler::addss(dst, src); } | |
2186 void addss(XMMRegister dst, AddressLiteral src) { Assembler::addss(dst, as_Address(src)); } | |
2187 | |
2188 void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); } | |
2189 void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); } | |
2190 void divsd(XMMRegister dst, AddressLiteral src) { Assembler::divsd(dst, as_Address(src)); } | |
2191 | |
2192 void divss(XMMRegister dst, XMMRegister src) { Assembler::divss(dst, src); } | |
2193 void divss(XMMRegister dst, Address src) { Assembler::divss(dst, src); } | |
2194 void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); } | |
2195 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
2196 void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
2197 void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
2198 void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } |
2008 | 2199 void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); } |
2200 | |
2201 void mulsd(XMMRegister dst, XMMRegister src) { Assembler::mulsd(dst, src); } | |
2202 void mulsd(XMMRegister dst, Address src) { Assembler::mulsd(dst, src); } | |
2203 void mulsd(XMMRegister dst, AddressLiteral src) { Assembler::mulsd(dst, as_Address(src)); } | |
2204 | |
2205 void mulss(XMMRegister dst, XMMRegister src) { Assembler::mulss(dst, src); } | |
2206 void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); } | |
2207 void mulss(XMMRegister dst, AddressLiteral src) { Assembler::mulss(dst, as_Address(src)); } | |
2208 | |
2209 void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); } | |
2210 void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); } | |
2211 void sqrtsd(XMMRegister dst, AddressLiteral src) { Assembler::sqrtsd(dst, as_Address(src)); } | |
2212 | |
2213 void sqrtss(XMMRegister dst, XMMRegister src) { Assembler::sqrtss(dst, src); } | |
2214 void sqrtss(XMMRegister dst, Address src) { Assembler::sqrtss(dst, src); } | |
2215 void sqrtss(XMMRegister dst, AddressLiteral src) { Assembler::sqrtss(dst, as_Address(src)); } | |
2216 | |
2217 void subsd(XMMRegister dst, XMMRegister src) { Assembler::subsd(dst, src); } | |
2218 void subsd(XMMRegister dst, Address src) { Assembler::subsd(dst, src); } | |
2219 void subsd(XMMRegister dst, AddressLiteral src) { Assembler::subsd(dst, as_Address(src)); } | |
2220 | |
2221 void subss(XMMRegister dst, XMMRegister src) { Assembler::subss(dst, src); } | |
2222 void subss(XMMRegister dst, Address src) { Assembler::subss(dst, src); } | |
2223 void subss(XMMRegister dst, AddressLiteral src) { Assembler::subss(dst, as_Address(src)); } | |
0 | 2224 |
2225 void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); } | |
2226 void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); } | |
2227 void ucomiss(XMMRegister dst, AddressLiteral src); | |
2228 | |
2229 void ucomisd(XMMRegister dst, XMMRegister src) { Assembler::ucomisd(dst, src); } | |
2230 void ucomisd(XMMRegister dst, Address src) { Assembler::ucomisd(dst, src); } | |
2231 void ucomisd(XMMRegister dst, AddressLiteral src); | |
2232 | |
2233 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
2234 void xorpd(XMMRegister dst, XMMRegister src) { Assembler::xorpd(dst, src); } | |
2235 void xorpd(XMMRegister dst, Address src) { Assembler::xorpd(dst, src); } | |
2236 void xorpd(XMMRegister dst, AddressLiteral src); | |
2237 | |
2238 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
2239 void xorps(XMMRegister dst, XMMRegister src) { Assembler::xorps(dst, src); } | |
2240 void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); } | |
2241 void xorps(XMMRegister dst, AddressLiteral src); | |
2242 | |
2243 // Data | |
2244 | |
304 | 2245 void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } |
2246 | |
2247 void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } | |
2248 void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); } | |
2249 | |
0 | 2250 void movoop(Register dst, jobject obj); |
2251 void movoop(Address dst, jobject obj); | |
2252 | |
2253 void movptr(ArrayAddress dst, Register src); | |
2254 // can this do an lea? | |
2255 void movptr(Register dst, ArrayAddress src); | |
2256 | |
304 | 2257 void movptr(Register dst, Address src); |
2258 | |
0 | 2259 void movptr(Register dst, AddressLiteral src); |
2260 | |
304 | 2261 void movptr(Register dst, intptr_t src); |
2262 void movptr(Register dst, Register src); | |
2263 void movptr(Address dst, intptr_t src); | |
2264 | |
2265 void movptr(Address dst, Register src); | |
2266 | |
2267 #ifdef _LP64 | |
2268 // Generally the next two are only used for moving NULL | |
2269 // Although there are situations in initializing the mark word where | |
2270 // they could be used. They are dangerous. | |
2271 | |
2272 // They only exist on LP64 so that int32_t and intptr_t are not the same | |
2273 // and we have ambiguous declarations. | |
2274 | |
2275 void movptr(Address dst, int32_t imm32); | |
2276 void movptr(Register dst, int32_t imm32); | |
2277 #endif // _LP64 | |
2278 | |
0 | 2279 // to avoid hiding movl |
2280 void mov32(AddressLiteral dst, Register src); | |
2281 void mov32(Register dst, AddressLiteral src); | |
304 | 2282 |
0 | 2283 // to avoid hiding movb |
2284 void movbyte(ArrayAddress dst, int src); | |
2285 | |
2286 // Can push value or effective address | |
2287 void pushptr(AddressLiteral src); | |
2288 | |
304 | 2289 void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); } |
2290 void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); } | |
2291 | |
2292 void pushoop(jobject obj); | |
2293 | |
2294 // sign extend as need a l to ptr sized element | |
2295 void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); } | |
2296 void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } | |
2297 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2298 // IndexOf strings. |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2299 // Small strings are loaded through stack if they cross page boundary. |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2300 void string_indexof(Register str1, Register str2, |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2301 Register cnt1, Register cnt2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2302 int int_cnt2, Register result, |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2303 XMMRegister vec, Register tmp); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2304 |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2305 // IndexOf for constant substrings with size >= 8 elements |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2306 // which don't need to be loaded through stack. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2307 void string_indexofC8(Register str1, Register str2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2308 Register cnt1, Register cnt2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2309 int int_cnt2, Register result, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2310 XMMRegister vec, Register tmp); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2311 |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2312 // Smallest code: we don't need to load through stack, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2313 // check string tail. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2314 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2315 // Compare strings. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2316 void string_compare(Register str1, Register str2, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2317 Register cnt1, Register cnt2, Register result, |
2262 | 2318 XMMRegister vec1); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2319 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2320 // Compare char[] arrays. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2321 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
|
2322 Register limit, Register result, Register chr, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2323 XMMRegister vec1, XMMRegister vec2); |
304 | 2324 |
1763 | 2325 // Fill primitive arrays |
2326 void generate_fill(BasicType t, bool aligned, | |
2327 Register to, Register value, Register count, | |
2328 Register rtmp, XMMRegister xtmp); | |
2329 | |
0 | 2330 #undef VIRTUAL |
2331 | |
2332 }; | |
2333 | |
2334 /** | |
2335 * class SkipIfEqual: | |
2336 * | |
2337 * Instantiating this class will result in assembly code being output that will | |
2338 * jump around any code emitted between the creation of the instance and it's | |
2339 * automatic destruction at the end of a scope block, depending on the value of | |
2340 * the flag passed to the constructor, which will be checked at run-time. | |
2341 */ | |
2342 class SkipIfEqual { | |
2343 private: | |
2344 MacroAssembler* _masm; | |
2345 Label _label; | |
2346 | |
2347 public: | |
2348 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); | |
2349 ~SkipIfEqual(); | |
2350 }; | |
2351 | |
2352 #ifdef ASSERT | |
2353 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; } | |
2354 #endif | |
1972 | 2355 |
2356 #endif // CPU_X86_VM_ASSEMBLER_X86_HPP |