Mercurial > hg > truffle
annotate src/cpu/x86/vm/assembler_x86.hpp @ 3101:6ccb95c97e6d
IdealGraphVisualizer: Work around a problem with JSplitPane and the NetBeans editor: setDividerLocation() doesn't work when the split pane has not been layouted and painted yet. JSplitPane then initially uses a tiny width for the left editor component, which causes the editor to calculate invalid offsets and constantly throw exceptions, particularly on mouse events. Thus, defer adding the two components and setting the divider's location.
author | Peter Hofer <peter.hofer@jku.at> |
---|---|
date | Thu, 30 Jun 2011 12:17:27 +0200 |
parents | d86923d96dca |
children | 5d046bf49ce7 |
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 { | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
388 private: |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
389 static relocInfo::relocType reloc_for_target(address target) { |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
390 // Sometimes ExternalAddress is used for values which aren't |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
391 // exactly addresses, like the card table base. |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
392 // external_word_type can't be used for values in the first page |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
393 // so just skip the reloc in that case. |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
394 return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none; |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
395 } |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
396 |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
397 public: |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
398 |
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2415
diff
changeset
|
399 ExternalAddress(address target) : AddressLiteral(target, reloc_for_target(target)) {} |
0 | 400 |
401 }; | |
402 | |
403 class InternalAddress: public AddressLiteral { | |
404 | |
405 public: | |
406 | |
407 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {} | |
408 | |
409 }; | |
410 | |
411 // x86 can do array addressing as a single operation since disp can be an absolute | |
412 // address amd64 can't. We create a class that expresses the concept but does extra | |
413 // magic on amd64 to get the final result | |
414 | |
415 class ArrayAddress VALUE_OBJ_CLASS_SPEC { | |
416 private: | |
417 | |
418 AddressLiteral _base; | |
419 Address _index; | |
420 | |
421 public: | |
422 | |
423 ArrayAddress() {}; | |
424 ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {}; | |
425 AddressLiteral base() { return _base; } | |
426 Address index() { return _index; } | |
427 | |
428 }; | |
429 | |
304 | 430 const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize); |
0 | 431 |
432 // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction | |
433 // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write | |
434 // is what you get. The Assembler is generating code into a CodeBuffer. | |
435 | |
436 class Assembler : public AbstractAssembler { | |
437 friend class AbstractAssembler; // for the non-virtual hack | |
438 friend class LIR_Assembler; // as_Address() | |
304 | 439 friend class StubGenerator; |
0 | 440 |
441 public: | |
442 enum Condition { // The x86 condition codes used for conditional jumps/moves. | |
443 zero = 0x4, | |
444 notZero = 0x5, | |
445 equal = 0x4, | |
446 notEqual = 0x5, | |
447 less = 0xc, | |
448 lessEqual = 0xe, | |
449 greater = 0xf, | |
450 greaterEqual = 0xd, | |
451 below = 0x2, | |
452 belowEqual = 0x6, | |
453 above = 0x7, | |
454 aboveEqual = 0x3, | |
455 overflow = 0x0, | |
456 noOverflow = 0x1, | |
457 carrySet = 0x2, | |
458 carryClear = 0x3, | |
459 negative = 0x8, | |
460 positive = 0x9, | |
461 parity = 0xa, | |
462 noParity = 0xb | |
463 }; | |
464 | |
465 enum Prefix { | |
466 // segment overrides | |
467 CS_segment = 0x2e, | |
468 SS_segment = 0x36, | |
469 DS_segment = 0x3e, | |
470 ES_segment = 0x26, | |
471 FS_segment = 0x64, | |
472 GS_segment = 0x65, | |
473 | |
474 REX = 0x40, | |
475 | |
476 REX_B = 0x41, | |
477 REX_X = 0x42, | |
478 REX_XB = 0x43, | |
479 REX_R = 0x44, | |
480 REX_RB = 0x45, | |
481 REX_RX = 0x46, | |
482 REX_RXB = 0x47, | |
483 | |
484 REX_W = 0x48, | |
485 | |
486 REX_WB = 0x49, | |
487 REX_WX = 0x4A, | |
488 REX_WXB = 0x4B, | |
489 REX_WR = 0x4C, | |
490 REX_WRB = 0x4D, | |
491 REX_WRX = 0x4E, | |
492 REX_WRXB = 0x4F | |
493 }; | |
494 | |
495 enum WhichOperand { | |
496 // input to locate_operand, and format code for relocations | |
304 | 497 imm_operand = 0, // embedded 32-bit|64-bit immediate operand |
0 | 498 disp32_operand = 1, // embedded 32-bit displacement or address |
499 call32_operand = 2, // embedded 32-bit self-relative displacement | |
304 | 500 #ifndef _LP64 |
0 | 501 _WhichOperand_limit = 3 |
304 | 502 #else |
503 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop | |
504 _WhichOperand_limit = 4 | |
505 #endif | |
0 | 506 }; |
507 | |
304 | 508 |
509 | |
510 // NOTE: The general philopsophy of the declarations here is that 64bit versions | |
511 // of instructions are freely declared without the need for wrapping them an ifdef. | |
512 // (Some dangerous instructions are ifdef's out of inappropriate jvm's.) | |
513 // In the .cpp file the implementations are wrapped so that they are dropped out | |
514 // of the resulting jvm. This is done mostly to keep the footprint of KERNEL | |
515 // to the size it was prior to merging up the 32bit and 64bit assemblers. | |
516 // | |
517 // This does mean you'll get a linker/runtime error if you use a 64bit only instruction | |
518 // in a 32bit vm. This is somewhat unfortunate but keeps the ifdef noise down. | |
519 | |
520 private: | |
521 | |
522 | |
523 // 64bit prefixes | |
524 int prefix_and_encode(int reg_enc, bool byteinst = false); | |
525 int prefixq_and_encode(int reg_enc); | |
526 | |
527 int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false); | |
528 int prefixq_and_encode(int dst_enc, int src_enc); | |
529 | |
530 void prefix(Register reg); | |
531 void prefix(Address adr); | |
532 void prefixq(Address adr); | |
533 | |
534 void prefix(Address adr, Register reg, bool byteinst = false); | |
535 void prefixq(Address adr, Register reg); | |
536 | |
537 void prefix(Address adr, XMMRegister reg); | |
538 | |
539 void prefetch_prefix(Address src); | |
540 | |
541 // Helper functions for groups of instructions | |
542 void emit_arith_b(int op1, int op2, Register dst, int imm8); | |
543 | |
544 void emit_arith(int op1, int op2, Register dst, int32_t imm32); | |
545 // only 32bit?? | |
546 void emit_arith(int op1, int op2, Register dst, jobject obj); | |
547 void emit_arith(int op1, int op2, Register dst, Register src); | |
548 | |
549 void emit_operand(Register reg, | |
550 Register base, Register index, Address::ScaleFactor scale, | |
551 int disp, | |
552 RelocationHolder const& rspec, | |
553 int rip_relative_correction = 0); | |
554 | |
555 void emit_operand(Register reg, Address adr, int rip_relative_correction = 0); | |
556 | |
557 // operands that only take the original 32bit registers | |
558 void emit_operand32(Register reg, Address adr); | |
559 | |
560 void emit_operand(XMMRegister reg, | |
561 Register base, Register index, Address::ScaleFactor scale, | |
562 int disp, | |
563 RelocationHolder const& rspec); | |
564 | |
565 void emit_operand(XMMRegister reg, Address adr); | |
566 | |
567 void emit_operand(MMXRegister reg, Address adr); | |
568 | |
569 // workaround gcc (3.2.1-7) bug | |
570 void emit_operand(Address adr, MMXRegister reg); | |
571 | |
572 | |
573 // Immediate-to-memory forms | |
574 void emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32); | |
575 | |
576 void emit_farith(int b1, int b2, int i); | |
577 | |
578 | |
579 protected: | |
580 #ifdef ASSERT | |
581 void check_relocation(RelocationHolder const& rspec, int format); | |
582 #endif | |
583 | |
584 inline void emit_long64(jlong x); | |
585 | |
586 void emit_data(jint data, relocInfo::relocType rtype, int format); | |
587 void emit_data(jint data, RelocationHolder const& rspec, int format); | |
588 void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); | |
589 void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); | |
590 | |
591 bool reachable(AddressLiteral adr) NOT_LP64({ return true;}); | |
592 | |
593 // These are all easily abused and hence protected | |
594 | |
595 // 32BIT ONLY SECTION | |
596 #ifndef _LP64 | |
597 // Make these disappear in 64bit mode since they would never be correct | |
598 void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
599 void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
600 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
601 void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY |
304 | 602 void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY |
603 | |
604 void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY | |
605 #else | |
606 // 64BIT ONLY SECTION | |
607 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
|
608 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
609 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
|
610 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
|
611 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
624
diff
changeset
|
612 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
|
613 void mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec); |
304 | 614 #endif // _LP64 |
615 | |
616 // These are unique in that we are ensured by the caller that the 32bit | |
617 // relative in these instructions will always be able to reach the potentially | |
618 // 64bit address described by entry. Since they can take a 64bit address they | |
619 // don't have the 32 suffix like the other instructions in this class. | |
620 | |
621 void call_literal(address entry, RelocationHolder const& rspec); | |
622 void jmp_literal(address entry, RelocationHolder const& rspec); | |
623 | |
624 // Avoid using directly section | |
625 // Instructions in this section are actually usable by anyone without danger | |
626 // of failure but have performance issues that are addressed my enhanced | |
627 // instructions which will do the proper thing base on the particular cpu. | |
628 // We protect them because we don't trust you... | |
629 | |
630 // Don't use next inc() and dec() methods directly. INC & DEC instructions | |
631 // could cause a partial flag stall since they don't set CF flag. | |
632 // Use MacroAssembler::decrement() & MacroAssembler::increment() methods | |
633 // which call inc() & dec() or add() & sub() in accordance with | |
634 // the product flag UseIncDec value. | |
635 | |
636 void decl(Register dst); | |
637 void decl(Address dst); | |
638 void decq(Register dst); | |
639 void decq(Address dst); | |
640 | |
641 void incl(Register dst); | |
642 void incl(Address dst); | |
643 void incq(Register dst); | |
644 void incq(Address dst); | |
645 | |
646 // New cpus require use of movsd and movss to avoid partial register stall | |
647 // when loading from memory. But for old Opteron use movlpd instead of movsd. | |
648 // The selection is done in MacroAssembler::movdbl() and movflt(). | |
649 | |
650 // Move Scalar Single-Precision Floating-Point Values | |
651 void movss(XMMRegister dst, Address src); | |
652 void movss(XMMRegister dst, XMMRegister src); | |
653 void movss(Address dst, XMMRegister src); | |
654 | |
655 // Move Scalar Double-Precision Floating-Point Values | |
656 void movsd(XMMRegister dst, Address src); | |
657 void movsd(XMMRegister dst, XMMRegister src); | |
658 void movsd(Address dst, XMMRegister src); | |
659 void movlpd(XMMRegister dst, Address src); | |
660 | |
661 // New cpus require use of movaps and movapd to avoid partial register stall | |
662 // when moving between registers. | |
663 void movaps(XMMRegister dst, XMMRegister src); | |
664 void movapd(XMMRegister dst, XMMRegister src); | |
665 | |
666 // End avoid using directly | |
667 | |
668 | |
669 // Instruction prefixes | |
670 void prefix(Prefix p); | |
671 | |
0 | 672 public: |
673 | |
674 // Creation | |
675 Assembler(CodeBuffer* code) : AbstractAssembler(code) {} | |
676 | |
677 // Decoding | |
678 static address locate_operand(address inst, WhichOperand which); | |
679 static address locate_next_instruction(address inst); | |
680 | |
304 | 681 // Utilities |
682 | |
683 #ifdef _LP64 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
684 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
|
685 x < (CONST64(1) << (nbits-1)); } |
304 | 686 static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; } |
687 #else | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
688 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
|
689 x < (1 << (nbits-1)); } |
304 | 690 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
|
691 #endif // _LP64 |
304 | 692 |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
693 static bool is_polling_page_far() NOT_LP64({ return false;}); |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
694 |
304 | 695 // Generic instructions |
696 // Does 32bit or 64bit as needed for the platform. In some sense these | |
697 // belong in macro assembler but there is no need for both varieties to exist | |
698 | |
699 void lea(Register dst, Address src); | |
700 | |
701 void mov(Register dst, Register src); | |
702 | |
703 void pusha(); | |
704 void popa(); | |
705 | |
706 void pushf(); | |
707 void popf(); | |
708 | |
709 void push(int32_t imm32); | |
710 | |
711 void push(Register src); | |
712 | |
713 void pop(Register dst); | |
714 | |
715 // These are dummies to prevent surprise implicit conversions to Register | |
716 void push(void* v); | |
717 void pop(void* v); | |
718 | |
719 // These do register sized moves/scans | |
720 void rep_mov(); | |
721 void rep_set(); | |
722 void repne_scan(); | |
723 #ifdef _LP64 | |
724 void repne_scanl(); | |
725 #endif | |
726 | |
727 // Vanilla instructions in lexical order | |
728 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
729 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
|
730 void adcl(Address dst, Register src); |
304 | 731 void adcl(Register dst, int32_t imm32); |
0 | 732 void adcl(Register dst, Address src); |
733 void adcl(Register dst, Register src); | |
734 | |
304 | 735 void adcq(Register dst, int32_t imm32); |
736 void adcq(Register dst, Address src); | |
737 void adcq(Register dst, Register src); | |
738 | |
739 void addl(Address dst, int32_t imm32); | |
0 | 740 void addl(Address dst, Register src); |
304 | 741 void addl(Register dst, int32_t imm32); |
0 | 742 void addl(Register dst, Address src); |
743 void addl(Register dst, Register src); | |
744 | |
304 | 745 void addq(Address dst, int32_t imm32); |
746 void addq(Address dst, Register src); | |
747 void addq(Register dst, int32_t imm32); | |
748 void addq(Register dst, Address src); | |
749 void addq(Register dst, Register src); | |
750 | |
0 | 751 void addr_nop_4(); |
752 void addr_nop_5(); | |
753 void addr_nop_7(); | |
754 void addr_nop_8(); | |
755 | |
304 | 756 // Add Scalar Double-Precision Floating-Point Values |
757 void addsd(XMMRegister dst, Address src); | |
758 void addsd(XMMRegister dst, XMMRegister src); | |
759 | |
760 // Add Scalar Single-Precision Floating-Point Values | |
761 void addss(XMMRegister dst, Address src); | |
762 void addss(XMMRegister dst, XMMRegister src); | |
763 | |
764 void andl(Register dst, int32_t imm32); | |
765 void andl(Register dst, Address src); | |
766 void andl(Register dst, Register src); | |
767 | |
768 void andq(Register dst, int32_t imm32); | |
769 void andq(Register dst, Address src); | |
770 void andq(Register dst, Register src); | |
771 | |
772 // Bitwise Logical AND of Packed Double-Precision Floating-Point Values | |
773 void andpd(XMMRegister dst, Address src); | |
774 void andpd(XMMRegister dst, XMMRegister src); | |
775 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
776 void bsfl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
777 void bsrl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
778 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
779 #ifdef _LP64 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
780 void bsfq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
781 void bsrq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
782 #endif |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
783 |
304 | 784 void bswapl(Register reg); |
785 | |
786 void bswapq(Register reg); | |
787 | |
0 | 788 void call(Label& L, relocInfo::relocType rtype); |
789 void call(Register reg); // push pc; pc <- reg | |
790 void call(Address adr); // push pc; pc <- adr | |
791 | |
304 | 792 void cdql(); |
793 | |
794 void cdqq(); | |
795 | |
796 void cld() { emit_byte(0xfc); } | |
797 | |
798 void clflush(Address adr); | |
799 | |
800 void cmovl(Condition cc, Register dst, Register src); | |
801 void cmovl(Condition cc, Register dst, Address src); | |
802 | |
803 void cmovq(Condition cc, Register dst, Register src); | |
804 void cmovq(Condition cc, Register dst, Address src); | |
805 | |
806 | |
807 void cmpb(Address dst, int imm8); | |
808 | |
809 void cmpl(Address dst, int32_t imm32); | |
810 | |
811 void cmpl(Register dst, int32_t imm32); | |
812 void cmpl(Register dst, Register src); | |
813 void cmpl(Register dst, Address src); | |
814 | |
815 void cmpq(Address dst, int32_t imm32); | |
816 void cmpq(Address dst, Register src); | |
817 | |
818 void cmpq(Register dst, int32_t imm32); | |
819 void cmpq(Register dst, Register src); | |
820 void cmpq(Register dst, Address src); | |
821 | |
822 // these are dummies used to catch attempting to convert NULL to Register | |
823 void cmpl(Register dst, void* junk); // dummy | |
824 void cmpq(Register dst, void* junk); // dummy | |
825 | |
826 void cmpw(Address dst, int imm16); | |
827 | |
828 void cmpxchg8 (Address adr); | |
829 | |
830 void cmpxchgl(Register reg, Address adr); | |
831 | |
832 void cmpxchgq(Register reg, Address adr); | |
833 | |
834 // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS | |
835 void comisd(XMMRegister dst, Address src); | |
836 | |
837 // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS | |
838 void comiss(XMMRegister dst, Address src); | |
839 | |
840 // Identify processor type and features | |
841 void cpuid() { | |
842 emit_byte(0x0F); | |
843 emit_byte(0xA2); | |
844 } | |
845 | |
846 // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value | |
847 void cvtsd2ss(XMMRegister dst, XMMRegister src); | |
848 | |
849 // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value | |
850 void cvtsi2sdl(XMMRegister dst, Register src); | |
851 void cvtsi2sdq(XMMRegister dst, Register src); | |
852 | |
853 // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value | |
854 void cvtsi2ssl(XMMRegister dst, Register src); | |
855 void cvtsi2ssq(XMMRegister dst, Register src); | |
856 | |
857 // Convert Packed Signed Doubleword Integers to Packed Double-Precision Floating-Point Value | |
858 void cvtdq2pd(XMMRegister dst, XMMRegister src); | |
859 | |
860 // Convert Packed Signed Doubleword Integers to Packed Single-Precision Floating-Point Value | |
861 void cvtdq2ps(XMMRegister dst, XMMRegister src); | |
862 | |
863 // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value | |
864 void cvtss2sd(XMMRegister dst, XMMRegister src); | |
865 | |
866 // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer | |
867 void cvttsd2sil(Register dst, Address src); | |
868 void cvttsd2sil(Register dst, XMMRegister src); | |
869 void cvttsd2siq(Register dst, XMMRegister src); | |
870 | |
871 // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer | |
872 void cvttss2sil(Register dst, XMMRegister src); | |
873 void cvttss2siq(Register dst, XMMRegister src); | |
874 | |
875 // Divide Scalar Double-Precision Floating-Point Values | |
876 void divsd(XMMRegister dst, Address src); | |
877 void divsd(XMMRegister dst, XMMRegister src); | |
878 | |
879 // Divide Scalar Single-Precision Floating-Point Values | |
880 void divss(XMMRegister dst, Address src); | |
881 void divss(XMMRegister dst, XMMRegister src); | |
882 | |
883 void emms(); | |
884 | |
885 void fabs(); | |
886 | |
887 void fadd(int i); | |
888 | |
889 void fadd_d(Address src); | |
890 void fadd_s(Address src); | |
891 | |
892 // "Alternate" versions of x87 instructions place result down in FPU | |
893 // stack instead of on TOS | |
894 | |
895 void fadda(int i); // "alternate" fadd | |
896 void faddp(int i = 1); | |
897 | |
898 void fchs(); | |
899 | |
900 void fcom(int i); | |
901 | |
902 void fcomp(int i = 1); | |
903 void fcomp_d(Address src); | |
904 void fcomp_s(Address src); | |
905 | |
906 void fcompp(); | |
907 | |
908 void fcos(); | |
909 | |
910 void fdecstp(); | |
911 | |
912 void fdiv(int i); | |
913 void fdiv_d(Address src); | |
914 void fdivr_s(Address src); | |
915 void fdiva(int i); // "alternate" fdiv | |
916 void fdivp(int i = 1); | |
917 | |
918 void fdivr(int i); | |
919 void fdivr_d(Address src); | |
920 void fdiv_s(Address src); | |
921 | |
922 void fdivra(int i); // "alternate" reversed fdiv | |
923 | |
924 void fdivrp(int i = 1); | |
925 | |
926 void ffree(int i = 0); | |
927 | |
928 void fild_d(Address adr); | |
929 void fild_s(Address adr); | |
930 | |
931 void fincstp(); | |
932 | |
933 void finit(); | |
934 | |
935 void fist_s (Address adr); | |
936 void fistp_d(Address adr); | |
937 void fistp_s(Address adr); | |
938 | |
939 void fld1(); | |
940 | |
941 void fld_d(Address adr); | |
942 void fld_s(Address adr); | |
943 void fld_s(int index); | |
944 void fld_x(Address adr); // extended-precision (80-bit) format | |
945 | |
946 void fldcw(Address src); | |
947 | |
948 void fldenv(Address src); | |
949 | |
950 void fldlg2(); | |
951 | |
952 void fldln2(); | |
953 | |
954 void fldz(); | |
955 | |
956 void flog(); | |
957 void flog10(); | |
958 | |
959 void fmul(int i); | |
960 | |
961 void fmul_d(Address src); | |
962 void fmul_s(Address src); | |
963 | |
964 void fmula(int i); // "alternate" fmul | |
965 | |
966 void fmulp(int i = 1); | |
967 | |
968 void fnsave(Address dst); | |
969 | |
970 void fnstcw(Address src); | |
971 | |
972 void fnstsw_ax(); | |
973 | |
974 void fprem(); | |
975 void fprem1(); | |
976 | |
977 void frstor(Address src); | |
978 | |
979 void fsin(); | |
980 | |
981 void fsqrt(); | |
982 | |
983 void fst_d(Address adr); | |
984 void fst_s(Address adr); | |
985 | |
986 void fstp_d(Address adr); | |
987 void fstp_d(int index); | |
988 void fstp_s(Address adr); | |
989 void fstp_x(Address adr); // extended-precision (80-bit) format | |
990 | |
991 void fsub(int i); | |
992 void fsub_d(Address src); | |
993 void fsub_s(Address src); | |
994 | |
995 void fsuba(int i); // "alternate" fsub | |
996 | |
997 void fsubp(int i = 1); | |
998 | |
999 void fsubr(int i); | |
1000 void fsubr_d(Address src); | |
1001 void fsubr_s(Address src); | |
1002 | |
1003 void fsubra(int i); // "alternate" reversed fsub | |
1004 | |
1005 void fsubrp(int i = 1); | |
1006 | |
1007 void ftan(); | |
1008 | |
1009 void ftst(); | |
1010 | |
1011 void fucomi(int i = 1); | |
1012 void fucomip(int i = 1); | |
1013 | |
1014 void fwait(); | |
1015 | |
1016 void fxch(int i = 1); | |
1017 | |
1018 void fxrstor(Address src); | |
1019 | |
1020 void fxsave(Address dst); | |
1021 | |
1022 void fyl2x(); | |
1023 | |
1024 void hlt(); | |
1025 | |
1026 void idivl(Register src); | |
1920 | 1027 void divl(Register src); // Unsigned division |
304 | 1028 |
1029 void idivq(Register src); | |
1030 | |
1031 void imull(Register dst, Register src); | |
1032 void imull(Register dst, Register src, int value); | |
1033 | |
1034 void imulq(Register dst, Register src); | |
1035 void imulq(Register dst, Register src, int value); | |
1036 | |
0 | 1037 |
1038 // jcc is the generic conditional branch generator to run- | |
1039 // time routines, jcc is used for branches to labels. jcc | |
1040 // takes a branch opcode (cc) and a label (L) and generates | |
1041 // either a backward branch or a forward branch and links it | |
1042 // to the label fixup chain. Usage: | |
1043 // | |
1044 // Label L; // unbound label | |
1045 // jcc(cc, L); // forward branch to unbound label | |
1046 // bind(L); // bind label to the current pc | |
1047 // jcc(cc, L); // backward branch to bound label | |
1048 // bind(L); // illegal: a label may be bound only once | |
1049 // | |
1050 // Note: The same Label can be used for forward and backward branches | |
1051 // but it may be bound only once. | |
1052 | |
1053 void jcc(Condition cc, Label& L, | |
1054 relocInfo::relocType rtype = relocInfo::none); | |
1055 | |
1056 // Conditional jump to a 8-bit offset to L. | |
1057 // WARNING: be very careful using this for forward jumps. If the label is | |
1058 // not bound within an 8-bit offset of this instruction, a run-time error | |
1059 // will occur. | |
1060 void jccb(Condition cc, Label& L); | |
1061 | |
304 | 1062 void jmp(Address entry); // pc <- entry |
1063 | |
1064 // Label operations & relative jumps (PPUM Appendix D) | |
1065 void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L | |
1066 | |
1067 void jmp(Register entry); // pc <- entry | |
1068 | |
1069 // Unconditional 8-bit offset jump to L. | |
1070 // WARNING: be very careful using this for forward jumps. If the label is | |
1071 // not bound within an 8-bit offset of this instruction, a run-time error | |
1072 // will occur. | |
1073 void jmpb(Label& L); | |
1074 | |
1075 void ldmxcsr( Address src ); | |
1076 | |
1077 void leal(Register dst, Address src); | |
1078 | |
1079 void leaq(Register dst, Address src); | |
1080 | |
1081 void lfence() { | |
1082 emit_byte(0x0F); | |
1083 emit_byte(0xAE); | |
1084 emit_byte(0xE8); | |
1085 } | |
1086 | |
1087 void lock(); | |
1088 | |
775
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1089 void lzcntl(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1090 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1091 #ifdef _LP64 |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1092 void lzcntq(Register dst, Register src); |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1093 #endif |
93c14e5562c4
6823354: Add intrinsics for {Integer,Long}.{numberOfLeadingZeros,numberOfTrailingZeros}()
twisti
parents:
710
diff
changeset
|
1094 |
304 | 1095 enum Membar_mask_bits { |
1096 StoreStore = 1 << 3, | |
1097 LoadStore = 1 << 2, | |
1098 StoreLoad = 1 << 1, | |
1099 LoadLoad = 1 << 0 | |
1100 }; | |
1101 | |
671
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1102 // Serializes memory and blows flags |
304 | 1103 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
|
1104 if (os::is_MP()) { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1105 // We only have to handle StoreLoad |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1106 if (order_constraint & StoreLoad) { |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1107 // 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
|
1108 // 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
|
1109 // 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
|
1110 // 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
|
1111 // flags. |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1112 // 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
|
1113 // 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
|
1114 // orderAccess code. |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1115 lock(); |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1116 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
|
1117 } |
d0994e5bebce
6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents:
665
diff
changeset
|
1118 } |
304 | 1119 } |
1120 | |
1121 void mfence(); | |
1122 | |
1123 // Moves | |
1124 | |
1125 void mov64(Register dst, int64_t imm64); | |
1126 | |
1127 void movb(Address dst, Register src); | |
1128 void movb(Address dst, int imm8); | |
1129 void movb(Register dst, Address src); | |
1130 | |
1131 void movdl(XMMRegister dst, Register src); | |
1132 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
|
1133 void movdl(XMMRegister dst, Address src); |
304 | 1134 |
1135 // Move Double Quadword | |
1136 void movdq(XMMRegister dst, Register src); | |
1137 void movdq(Register dst, XMMRegister src); | |
1138 | |
1139 // Move Aligned Double Quadword | |
1140 void movdqa(Address dst, XMMRegister src); | |
1141 void movdqa(XMMRegister dst, Address src); | |
1142 void movdqa(XMMRegister dst, XMMRegister src); | |
1143 | |
405 | 1144 // Move Unaligned Double Quadword |
1145 void movdqu(Address dst, XMMRegister src); | |
1146 void movdqu(XMMRegister dst, Address src); | |
1147 void movdqu(XMMRegister dst, XMMRegister src); | |
1148 | |
304 | 1149 void movl(Register dst, int32_t imm32); |
1150 void movl(Address dst, int32_t imm32); | |
1151 void movl(Register dst, Register src); | |
1152 void movl(Register dst, Address src); | |
1153 void movl(Address dst, Register src); | |
1154 | |
1155 // These dummies prevent using movl from converting a zero (like NULL) into Register | |
1156 // by giving the compiler two choices it can't resolve | |
1157 | |
1158 void movl(Address dst, void* junk); | |
1159 void movl(Register dst, void* junk); | |
1160 | |
1161 #ifdef _LP64 | |
1162 void movq(Register dst, Register src); | |
1163 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
|
1164 void movq(Address dst, Register src); |
304 | 1165 #endif |
1166 | |
1167 void movq(Address dst, MMXRegister src ); | |
1168 void movq(MMXRegister dst, Address src ); | |
1169 | |
1170 #ifdef _LP64 | |
1171 // These dummies prevent using movq from converting a zero (like NULL) into Register | |
1172 // by giving the compiler two choices it can't resolve | |
1173 | |
1174 void movq(Address dst, void* dummy); | |
1175 void movq(Register dst, void* dummy); | |
1176 #endif | |
1177 | |
1178 // Move Quadword | |
1179 void movq(Address dst, XMMRegister src); | |
1180 void movq(XMMRegister dst, Address src); | |
1181 | |
1182 void movsbl(Register dst, Address src); | |
1183 void movsbl(Register dst, Register src); | |
1184 | |
1185 #ifdef _LP64 | |
624 | 1186 void movsbq(Register dst, Address src); |
1187 void movsbq(Register dst, Register src); | |
1188 | |
304 | 1189 // 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
|
1190 void movslq(Address dst, int32_t imm64); |
304 | 1191 void movslq(Register dst, int32_t imm64); |
1192 | |
1193 void movslq(Register dst, Address src); | |
1194 void movslq(Register dst, Register src); | |
1195 void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous | |
1196 #endif | |
1197 | |
1198 void movswl(Register dst, Address src); | |
1199 void movswl(Register dst, Register src); | |
1200 | |
624 | 1201 #ifdef _LP64 |
1202 void movswq(Register dst, Address src); | |
1203 void movswq(Register dst, Register src); | |
1204 #endif | |
1205 | |
304 | 1206 void movw(Address dst, int imm16); |
1207 void movw(Register dst, Address src); | |
1208 void movw(Address dst, Register src); | |
1209 | |
1210 void movzbl(Register dst, Address src); | |
1211 void movzbl(Register dst, Register src); | |
1212 | |
624 | 1213 #ifdef _LP64 |
1214 void movzbq(Register dst, Address src); | |
1215 void movzbq(Register dst, Register src); | |
1216 #endif | |
1217 | |
304 | 1218 void movzwl(Register dst, Address src); |
1219 void movzwl(Register dst, Register src); | |
1220 | |
624 | 1221 #ifdef _LP64 |
1222 void movzwq(Register dst, Address src); | |
1223 void movzwq(Register dst, Register src); | |
1224 #endif | |
1225 | |
304 | 1226 void mull(Address src); |
1227 void mull(Register src); | |
1228 | |
1229 // Multiply Scalar Double-Precision Floating-Point Values | |
1230 void mulsd(XMMRegister dst, Address src); | |
1231 void mulsd(XMMRegister dst, XMMRegister src); | |
1232 | |
1233 // Multiply Scalar Single-Precision Floating-Point Values | |
1234 void mulss(XMMRegister dst, Address src); | |
1235 void mulss(XMMRegister dst, XMMRegister src); | |
1236 | |
1237 void negl(Register dst); | |
1238 | |
1239 #ifdef _LP64 | |
1240 void negq(Register dst); | |
1241 #endif | |
1242 | |
1243 void nop(int i = 1); | |
1244 | |
1245 void notl(Register dst); | |
1246 | |
1247 #ifdef _LP64 | |
1248 void notq(Register dst); | |
1249 #endif | |
1250 | |
1251 void orl(Address dst, int32_t imm32); | |
1252 void orl(Register dst, int32_t imm32); | |
1253 void orl(Register dst, Address src); | |
1254 void orl(Register dst, Register src); | |
1255 | |
1256 void orq(Address dst, int32_t imm32); | |
1257 void orq(Register dst, int32_t imm32); | |
1258 void orq(Register dst, Address src); | |
1259 void orq(Register dst, Register src); | |
1260 | |
681 | 1261 // SSE4.2 string instructions |
1262 void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8); | |
1263 void pcmpestri(XMMRegister xmm1, Address src, int imm8); | |
1264 | |
1060 | 1265 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1266 void popl(Address dst); |
1060 | 1267 #endif |
304 | 1268 |
1269 #ifdef _LP64 | |
1270 void popq(Address dst); | |
1271 #endif | |
1272 | |
643
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1273 void popcntl(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1274 void popcntl(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1275 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1276 #ifdef _LP64 |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1277 void popcntq(Register dst, Address src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1278 void popcntq(Register dst, Register src); |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1279 #endif |
c771b7f43bbf
6378821: bitCount() should use POPC on SPARC processors and AMD+10h
twisti
parents:
642
diff
changeset
|
1280 |
304 | 1281 // Prefetches (SSE, SSE2, 3DNOW only) |
1282 | |
1283 void prefetchnta(Address src); | |
1284 void prefetchr(Address src); | |
1285 void prefetcht0(Address src); | |
1286 void prefetcht1(Address src); | |
1287 void prefetcht2(Address src); | |
1288 void prefetchw(Address src); | |
1289 | |
2262 | 1290 // POR - Bitwise logical OR |
1291 void por(XMMRegister dst, XMMRegister src); | |
1292 | |
304 | 1293 // Shuffle Packed Doublewords |
1294 void pshufd(XMMRegister dst, XMMRegister src, int mode); | |
1295 void pshufd(XMMRegister dst, Address src, int mode); | |
1296 | |
1297 // Shuffle Packed Low Words | |
1298 void pshuflw(XMMRegister dst, XMMRegister src, int mode); | |
1299 void pshuflw(XMMRegister dst, Address src, int mode); | |
1300 | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1301 // Shift Right by bits Logical Quadword Immediate |
304 | 1302 void psrlq(XMMRegister dst, int shift); |
1303 | |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1304 // 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
|
1305 void psrldq(XMMRegister dst, int shift); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
1306 |
681 | 1307 // Logical Compare Double Quadword |
1308 void ptest(XMMRegister dst, XMMRegister src); | |
1309 void ptest(XMMRegister dst, Address src); | |
1310 | |
304 | 1311 // Interleave Low Bytes |
1312 void punpcklbw(XMMRegister dst, XMMRegister src); | |
1313 | |
1060 | 1314 #ifndef _LP64 // no 32bit push/pop on amd64 |
304 | 1315 void pushl(Address src); |
1060 | 1316 #endif |
304 | 1317 |
1318 void pushq(Address src); | |
1319 | |
1320 // Xor Packed Byte Integer Values | |
1321 void pxor(XMMRegister dst, Address src); | |
1322 void pxor(XMMRegister dst, XMMRegister src); | |
1323 | |
1324 void rcll(Register dst, int imm8); | |
1325 | |
1326 void rclq(Register dst, int imm8); | |
1327 | |
1328 void ret(int imm16); | |
0 | 1329 |
1330 void sahf(); | |
1331 | |
304 | 1332 void sarl(Register dst, int imm8); |
1333 void sarl(Register dst); | |
1334 | |
1335 void sarq(Register dst, int imm8); | |
1336 void sarq(Register dst); | |
1337 | |
1338 void sbbl(Address dst, int32_t imm32); | |
1339 void sbbl(Register dst, int32_t imm32); | |
1340 void sbbl(Register dst, Address src); | |
1341 void sbbl(Register dst, Register src); | |
1342 | |
1343 void sbbq(Address dst, int32_t imm32); | |
1344 void sbbq(Register dst, int32_t imm32); | |
1345 void sbbq(Register dst, Address src); | |
1346 void sbbq(Register dst, Register src); | |
1347 | |
1348 void setb(Condition cc, Register dst); | |
1349 | |
1350 void shldl(Register dst, Register src); | |
1351 | |
1352 void shll(Register dst, int imm8); | |
1353 void shll(Register dst); | |
1354 | |
1355 void shlq(Register dst, int imm8); | |
1356 void shlq(Register dst); | |
1357 | |
1358 void shrdl(Register dst, Register src); | |
1359 | |
1360 void shrl(Register dst, int imm8); | |
1361 void shrl(Register dst); | |
1362 | |
1363 void shrq(Register dst, int imm8); | |
1364 void shrq(Register dst); | |
1365 | |
1366 void smovl(); // QQQ generic? | |
1367 | |
1368 // Compute Square Root of Scalar Double-Precision Floating-Point Value | |
1369 void sqrtsd(XMMRegister dst, Address src); | |
1370 void sqrtsd(XMMRegister dst, XMMRegister src); | |
1371 | |
2008 | 1372 // Compute Square Root of Scalar Single-Precision Floating-Point Value |
1373 void sqrtss(XMMRegister dst, Address src); | |
1374 void sqrtss(XMMRegister dst, XMMRegister src); | |
1375 | |
304 | 1376 void std() { emit_byte(0xfd); } |
1377 | |
1378 void stmxcsr( Address dst ); | |
1379 | |
1380 void subl(Address dst, int32_t imm32); | |
1381 void subl(Address dst, Register src); | |
1382 void subl(Register dst, int32_t imm32); | |
1383 void subl(Register dst, Address src); | |
1384 void subl(Register dst, Register src); | |
1385 | |
1386 void subq(Address dst, int32_t imm32); | |
1387 void subq(Address dst, Register src); | |
1388 void subq(Register dst, int32_t imm32); | |
1389 void subq(Register dst, Address src); | |
1390 void subq(Register dst, Register src); | |
1391 | |
1392 | |
1393 // Subtract Scalar Double-Precision Floating-Point Values | |
1394 void subsd(XMMRegister dst, Address src); | |
0 | 1395 void subsd(XMMRegister dst, XMMRegister src); |
1396 | |
304 | 1397 // Subtract Scalar Single-Precision Floating-Point Values |
1398 void subss(XMMRegister dst, Address src); | |
1399 void subss(XMMRegister dst, XMMRegister src); | |
1400 | |
1401 void testb(Register dst, int imm8); | |
1402 | |
1403 void testl(Register dst, int32_t imm32); | |
1404 void testl(Register dst, Register src); | |
1405 void testl(Register dst, Address src); | |
1406 | |
1407 void testq(Register dst, int32_t imm32); | |
1408 void testq(Register dst, Register src); | |
1409 | |
1410 | |
1411 // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS | |
1412 void ucomisd(XMMRegister dst, Address src); | |
0 | 1413 void ucomisd(XMMRegister dst, XMMRegister src); |
1414 | |
304 | 1415 // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS |
1416 void ucomiss(XMMRegister dst, Address src); | |
1417 void ucomiss(XMMRegister dst, XMMRegister src); | |
1418 | |
1419 void xaddl(Address dst, Register src); | |
1420 | |
1421 void xaddq(Address dst, Register src); | |
1422 | |
1423 void xchgl(Register reg, Address adr); | |
1424 void xchgl(Register dst, Register src); | |
1425 | |
1426 void xchgq(Register reg, Address adr); | |
1427 void xchgq(Register dst, Register src); | |
1428 | |
1429 void xorl(Register dst, int32_t imm32); | |
1430 void xorl(Register dst, Address src); | |
1431 void xorl(Register dst, Register src); | |
1432 | |
1433 void xorq(Register dst, Address src); | |
1434 void xorq(Register dst, Register src); | |
1435 | |
1436 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
1437 void xorpd(XMMRegister dst, Address src); | |
1438 void xorpd(XMMRegister dst, XMMRegister src); | |
1439 | |
1440 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
1441 void xorps(XMMRegister dst, Address src); | |
0 | 1442 void xorps(XMMRegister dst, XMMRegister src); |
304 | 1443 |
1444 void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0 | |
0 | 1445 }; |
1446 | |
1447 | |
1448 // MacroAssembler extends Assembler by frequently used macros. | |
1449 // | |
1450 // Instructions for which a 'better' code sequence exists depending | |
1451 // on arguments should also go in here. | |
1452 | |
1453 class MacroAssembler: public Assembler { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1454 friend class LIR_Assembler; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1455 friend class Runtime1; // as_Address() |
0 | 1456 protected: |
1457 | |
1458 Address as_Address(AddressLiteral adr); | |
1459 Address as_Address(ArrayAddress adr); | |
1460 | |
1461 // Support for VM calls | |
1462 // | |
1463 // This is the base routine called by the different versions of call_VM_leaf. The interpreter | |
1464 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1465 // additional registers when doing a VM call). | |
1466 #ifdef CC_INTERP | |
1467 // c++ interpreter never wants to use interp_masm version of call_VM | |
1468 #define VIRTUAL | |
1469 #else | |
1470 #define VIRTUAL virtual | |
1471 #endif | |
1472 | |
1473 VIRTUAL void call_VM_leaf_base( | |
1474 address entry_point, // the entry point | |
1475 int number_of_arguments // the number of arguments to pop after the call | |
1476 ); | |
1477 | |
1478 // This is the base routine called by the different versions of call_VM. The interpreter | |
1479 // may customize this version by overriding it for its purposes (e.g., to save/restore | |
1480 // additional registers when doing a VM call). | |
1481 // | |
1482 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base | |
1483 // returns the register which contains the thread upon return. If a thread register has been | |
1484 // specified, the return value will correspond to that register. If no last_java_sp is specified | |
1485 // (noreg) than rsp will be used instead. | |
1486 VIRTUAL void call_VM_base( // returns the register containing the thread upon return | |
1487 Register oop_result, // where an oop-result ends up if any; use noreg otherwise | |
1488 Register java_thread, // the thread if computed before ; use noreg otherwise | |
1489 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise | |
1490 address entry_point, // the entry point | |
1491 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call | |
1492 bool check_exceptions // whether to check for pending exceptions after return | |
1493 ); | |
1494 | |
1495 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code. | |
1496 // The implementation is only non-empty for the InterpreterMacroAssembler, | |
1497 // as only the interpreter handles PopFrame and ForceEarlyReturn requests. | |
1498 virtual void check_and_handle_popframe(Register java_thread); | |
1499 virtual void check_and_handle_earlyret(Register java_thread); | |
1500 | |
1501 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true); | |
1502 | |
1503 // helpers for FPU flag access | |
1504 // tmp is a temporary register, if none is available use noreg | |
1505 void save_rax (Register tmp); | |
1506 void restore_rax(Register tmp); | |
1507 | |
1508 public: | |
1509 MacroAssembler(CodeBuffer* code) : Assembler(code) {} | |
1510 | |
1511 // Support for NULL-checks | |
1512 // | |
1513 // Generates code that causes a NULL OS exception if the content of reg is NULL. | |
1514 // If the accessed location is M[reg + offset] and the offset is known, provide the | |
1515 // offset. No explicit code generation is needed if the offset is within a certain | |
1516 // range (0 <= offset <= page_size). | |
1517 | |
1518 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
|
1519 static bool needs_explicit_null_check(intptr_t offset); |
0 | 1520 |
1521 // Required platform-specific helpers for Label::patch_instructions. | |
1522 // They _shadow_ the declarations in AbstractAssembler, which are undefined. | |
1523 void pd_patch_instruction(address branch, address target); | |
1524 #ifndef PRODUCT | |
1525 static void pd_print_patched_instruction(address branch); | |
1526 #endif | |
1527 | |
1528 // The following 4 methods return the offset of the appropriate move instruction | |
1529 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1530 // Support for fast byte/short loading with zero extension (depending on particular CPU) |
0 | 1531 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
|
1532 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
|
1533 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1534 // Support for fast byte/short loading with sign extension (depending on particular CPU) |
0 | 1535 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
|
1536 int load_signed_short(Register dst, Address src); |
0 | 1537 |
1538 // Support for sign-extension (hi:lo = extend_sign(lo)) | |
1539 void extend_sign(Register hi, Register lo); | |
1540 | |
2258
28bf941f445e
7018378: JSR 292: _bound_int_mh produces wrong result on 64-bit SPARC
twisti
parents:
2100
diff
changeset
|
1541 // 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
|
1542 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
|
1543 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
|
1544 |
0 | 1545 // Support for inc/dec with optimal instruction selection depending on value |
304 | 1546 |
1547 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; } | |
1548 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; } | |
1549 | |
1550 void decrementl(Address dst, int value = 1); | |
1551 void decrementl(Register reg, int value = 1); | |
1552 | |
1553 void decrementq(Register reg, int value = 1); | |
1554 void decrementq(Address dst, int value = 1); | |
1555 | |
1556 void incrementl(Address dst, int value = 1); | |
1557 void incrementl(Register reg, int value = 1); | |
1558 | |
1559 void incrementq(Register reg, int value = 1); | |
1560 void incrementq(Address dst, int value = 1); | |
1561 | |
0 | 1562 |
1563 // Support optimal SSE move instructions. | |
1564 void movflt(XMMRegister dst, XMMRegister src) { | |
1565 if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; } | |
1566 else { movss (dst, src); return; } | |
1567 } | |
1568 void movflt(XMMRegister dst, Address src) { movss(dst, src); } | |
1569 void movflt(XMMRegister dst, AddressLiteral src); | |
1570 void movflt(Address dst, XMMRegister src) { movss(dst, src); } | |
1571 | |
1572 void movdbl(XMMRegister dst, XMMRegister src) { | |
1573 if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; } | |
1574 else { movsd (dst, src); return; } | |
1575 } | |
1576 | |
1577 void movdbl(XMMRegister dst, AddressLiteral src); | |
1578 | |
1579 void movdbl(XMMRegister dst, Address src) { | |
1580 if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; } | |
1581 else { movlpd(dst, src); return; } | |
1582 } | |
1583 void movdbl(Address dst, XMMRegister src) { movsd(dst, src); } | |
1584 | |
304 | 1585 void incrementl(AddressLiteral dst); |
1586 void incrementl(ArrayAddress dst); | |
0 | 1587 |
1588 // Alignment | |
1589 void align(int modulus); | |
1590 | |
1591 // Misc | |
1592 void fat_nop(); // 5 byte nop | |
1593 | |
1594 // Stack frame creation/removal | |
1595 void enter(); | |
1596 void leave(); | |
1597 | |
1598 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information) | |
1599 // The pointer will be loaded into the thread register. | |
1600 void get_thread(Register thread); | |
1601 | |
362 | 1602 |
0 | 1603 // Support for VM calls |
1604 // | |
1605 // It is imperative that all calls into the VM are handled via the call_VM macros. | |
1606 // They make sure that the stack linkage is setup correctly. call_VM's correspond | |
1607 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. | |
1608 | |
304 | 1609 |
1610 void call_VM(Register oop_result, | |
1611 address entry_point, | |
1612 bool check_exceptions = true); | |
1613 void call_VM(Register oop_result, | |
1614 address entry_point, | |
1615 Register arg_1, | |
1616 bool check_exceptions = true); | |
1617 void call_VM(Register oop_result, | |
1618 address entry_point, | |
1619 Register arg_1, Register arg_2, | |
1620 bool check_exceptions = true); | |
1621 void call_VM(Register oop_result, | |
1622 address entry_point, | |
1623 Register arg_1, Register arg_2, Register arg_3, | |
1624 bool check_exceptions = true); | |
1625 | |
1626 // Overloadings with last_Java_sp | |
1627 void call_VM(Register oop_result, | |
1628 Register last_java_sp, | |
1629 address entry_point, | |
1630 int number_of_arguments = 0, | |
1631 bool check_exceptions = true); | |
1632 void call_VM(Register oop_result, | |
1633 Register last_java_sp, | |
1634 address entry_point, | |
1635 Register arg_1, bool | |
1636 check_exceptions = true); | |
1637 void call_VM(Register oop_result, | |
1638 Register last_java_sp, | |
1639 address entry_point, | |
1640 Register arg_1, Register arg_2, | |
1641 bool check_exceptions = true); | |
1642 void call_VM(Register oop_result, | |
1643 Register last_java_sp, | |
1644 address entry_point, | |
1645 Register arg_1, Register arg_2, Register arg_3, | |
1646 bool check_exceptions = true); | |
1647 | |
1648 void call_VM_leaf(address entry_point, | |
1649 int number_of_arguments = 0); | |
1650 void call_VM_leaf(address entry_point, | |
1651 Register arg_1); | |
1652 void call_VM_leaf(address entry_point, | |
1653 Register arg_1, Register arg_2); | |
1654 void call_VM_leaf(address entry_point, | |
1655 Register arg_1, Register arg_2, Register arg_3); | |
0 | 1656 |
1657 // last Java Frame (fills frame anchor) | |
304 | 1658 void set_last_Java_frame(Register thread, |
1659 Register last_java_sp, | |
1660 Register last_java_fp, | |
1661 address last_java_pc); | |
1662 | |
1663 // thread in the default location (r15_thread on 64bit) | |
1664 void set_last_Java_frame(Register last_java_sp, | |
1665 Register last_java_fp, | |
1666 address last_java_pc); | |
1667 | |
0 | 1668 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); |
1669 | |
304 | 1670 // thread in the default location (r15_thread on 64bit) |
1671 void reset_last_Java_frame(bool clear_fp, bool clear_pc); | |
1672 | |
0 | 1673 // Stores |
1674 void store_check(Register obj); // store check for obj - register is destroyed afterwards | |
1675 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed) | |
1676 | |
362 | 1677 void g1_write_barrier_pre(Register obj, |
1678 #ifndef _LP64 | |
1679 Register thread, | |
1680 #endif | |
1681 Register tmp, | |
1682 Register tmp2, | |
1683 bool tosca_live); | |
1684 void g1_write_barrier_post(Register store_addr, | |
1685 Register new_val, | |
1686 #ifndef _LP64 | |
1687 Register thread, | |
1688 #endif | |
1689 Register tmp, | |
1690 Register tmp2); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1691 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
71
diff
changeset
|
1692 |
0 | 1693 // split store_check(Register obj) to enhance instruction interleaving |
1694 void store_check_part_1(Register obj); | |
1695 void store_check_part_2(Register obj); | |
1696 | |
1697 // C 'boolean' to Java boolean: x == 0 ? 0 : 1 | |
1698 void c2bool(Register x); | |
1699 | |
1700 // C++ bool manipulation | |
1701 | |
1702 void movbool(Register dst, Address src); | |
1703 void movbool(Address dst, bool boolconst); | |
1704 void movbool(Address dst, Register src); | |
1705 void testbool(Register dst); | |
1706 | |
304 | 1707 // oop manipulations |
1708 void load_klass(Register dst, Register src); | |
1709 void store_klass(Register dst, Register src); | |
1710 | |
1846 | 1711 void load_heap_oop(Register dst, Address src); |
2464
d86923d96dca
7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents:
2455
diff
changeset
|
1712 void load_heap_oop_not_null(Register dst, Address src); |
1846 | 1713 void store_heap_oop(Address dst, Register src); |
1714 | |
1715 // Used for storing NULL. All other oop constants should be | |
1716 // stored using routines that take a jobject. | |
1717 void store_heap_oop_null(Address dst); | |
1718 | |
304 | 1719 void load_prototype_header(Register dst, Register src); |
1720 | |
1721 #ifdef _LP64 | |
1722 void store_klass_gap(Register dst, Register src); | |
1723 | |
1047
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1724 // 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
|
1725 // 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
|
1726 // the compiler two choices it can't resolve |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1727 |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1728 void store_heap_oop(Address dst, void* dummy); |
beb8f45ee9f0
6889740: G1: OpenDS fails with "unhandled exception in compiled code"
johnc
parents:
986
diff
changeset
|
1729 |
304 | 1730 void encode_heap_oop(Register r); |
1731 void decode_heap_oop(Register r); | |
1732 void encode_heap_oop_not_null(Register r); | |
1733 void decode_heap_oop_not_null(Register r); | |
1734 void encode_heap_oop_not_null(Register dst, Register src); | |
1735 void decode_heap_oop_not_null(Register dst, Register src); | |
1736 | |
1737 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
|
1738 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
|
1739 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
|
1740 void cmp_narrow_oop(Address dst, jobject obj); |
304 | 1741 |
1742 // if heap base register is used - reinit it with the correct value | |
1743 void reinit_heapbase(); | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1744 |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1579
diff
changeset
|
1745 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
|
1746 |
304 | 1747 #endif // _LP64 |
1748 | |
1749 // Int division/remainder for Java | |
0 | 1750 // (as idivl, but checks for special case as described in JVM spec.) |
1751 // returns idivl instruction offset for implicit exception handling | |
1752 int corrected_idivl(Register reg); | |
1753 | |
304 | 1754 // Long division/remainder for Java |
1755 // (as idivq, but checks for special case as described in JVM spec.) | |
1756 // returns idivq instruction offset for implicit exception handling | |
1757 int corrected_idivq(Register reg); | |
1758 | |
0 | 1759 void int3(); |
1760 | |
304 | 1761 // Long operation macros for a 32bit cpu |
0 | 1762 // Long negation for Java |
1763 void lneg(Register hi, Register lo); | |
1764 | |
1765 // Long multiplication for Java | |
304 | 1766 // (destroys contents of eax, ebx, ecx and edx) |
0 | 1767 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y |
1768 | |
1769 // Long shifts for Java | |
1770 // (semantics as described in JVM spec.) | |
1771 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f) | |
1772 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f) | |
1773 | |
1774 // Long compare for Java | |
1775 // (semantics as described in JVM spec.) | |
1776 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y) | |
1777 | |
304 | 1778 |
1779 // misc | |
1780 | |
1781 // Sign extension | |
1782 void sign_extend_short(Register reg); | |
1783 void sign_extend_byte(Register reg); | |
1784 | |
1785 // Division by power of 2, rounding towards 0 | |
1786 void division_with_shift(Register reg, int shift_value); | |
1787 | |
0 | 1788 // Compares the top-most stack entries on the FPU stack and sets the eflags as follows: |
1789 // | |
1790 // CF (corresponds to C0) if x < y | |
1791 // PF (corresponds to C2) if unordered | |
1792 // ZF (corresponds to C3) if x = y | |
1793 // | |
1794 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1795 // tmp is a temporary register, if none is available use noreg (only matters for non-P6 code) | |
1796 void fcmp(Register tmp); | |
1797 // Variant of the above which allows y to be further down the stack | |
1798 // and which only pops x and y if specified. If pop_right is | |
1799 // specified then pop_left must also be specified. | |
1800 void fcmp(Register tmp, int index, bool pop_left, bool pop_right); | |
1801 | |
1802 // Floating-point comparison for Java | |
1803 // Compares the top-most stack entries on the FPU stack and stores the result in dst. | |
1804 // The arguments are in reversed order on the stack (i.e., top of stack is first argument). | |
1805 // (semantics as described in JVM spec.) | |
1806 void fcmp2int(Register dst, bool unordered_is_less); | |
1807 // Variant of the above which allows y to be further down the stack | |
1808 // and which only pops x and y if specified. If pop_right is | |
1809 // specified then pop_left must also be specified. | |
1810 void fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right); | |
1811 | |
1812 // Floating-point remainder for Java (ST0 = ST0 fremr ST1, ST1 is empty afterwards) | |
1813 // tmp is a temporary register, if none is available use noreg | |
1814 void fremr(Register tmp); | |
1815 | |
1816 | |
1817 // same as fcmp2int, but using SSE2 | |
1818 void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1819 void cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less); | |
1820 | |
1821 // Inlined sin/cos generator for Java; must not use CPU instruction | |
1822 // directly on Intel as it does not have high enough precision | |
1823 // outside of the range [-pi/4, pi/4]. Extra argument indicate the | |
1824 // number of FPU stack slots in use; all but the topmost will | |
1825 // require saving if a slow case is necessary. Assumes argument is | |
1826 // on FP TOS; result is on FP TOS. No cpu registers are changed by | |
1827 // this code. | |
1828 void trigfunc(char trig, int num_fpu_regs_in_use = 1); | |
1829 | |
1830 // branch to L if FPU flag C2 is set/not set | |
1831 // tmp is a temporary register, if none is available use noreg | |
1832 void jC2 (Register tmp, Label& L); | |
1833 void jnC2(Register tmp, Label& L); | |
1834 | |
1835 // Pop ST (ffree & fincstp combined) | |
1836 void fpop(); | |
1837 | |
1838 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack | |
1839 void push_fTOS(); | |
1840 | |
1841 // pops double TOS element from CPU stack and pushes on FPU stack | |
1842 void pop_fTOS(); | |
1843 | |
1844 void empty_FPU_stack(); | |
1845 | |
1846 void push_IU_state(); | |
1847 void pop_IU_state(); | |
1848 | |
1849 void push_FPU_state(); | |
1850 void pop_FPU_state(); | |
1851 | |
1852 void push_CPU_state(); | |
1853 void pop_CPU_state(); | |
1854 | |
1855 // Round up to a power of two | |
1856 void round_to(Register reg, int modulus); | |
1857 | |
1858 // Callee saved registers handling | |
1859 void push_callee_saved_registers(); | |
1860 void pop_callee_saved_registers(); | |
1861 | |
1862 // allocation | |
1863 void eden_allocate( | |
1864 Register obj, // result: pointer to object after successful allocation | |
1865 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1866 int con_size_in_bytes, // object size in bytes if known at compile time | |
1867 Register t1, // temp register | |
1868 Label& slow_case // continuation point if fast allocation fails | |
1869 ); | |
1870 void tlab_allocate( | |
1871 Register obj, // result: pointer to object after successful allocation | |
1872 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise | |
1873 int con_size_in_bytes, // object size in bytes if known at compile time | |
1874 Register t1, // temp register | |
1875 Register t2, // temp register | |
1876 Label& slow_case // continuation point if fast allocation fails | |
1877 ); | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
1878 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
|
1879 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
|
1880 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
|
1881 Register t1 = noreg); |
0 | 1882 |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1883 // interface method calling |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1884 void lookup_interface_method(Register recv_klass, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1885 Register intf_klass, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1886 RegisterOrConstant itable_index, |
623
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1887 Register method_result, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1888 Register scan_temp, |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1889 Label& no_such_interface); |
9adddb8c0fc8
6812831: factor duplicated assembly code for megamorphic invokeinterface (for 6655638)
jrose
parents:
622
diff
changeset
|
1890 |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1891 // 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
|
1892 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1893 // 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
|
1894 // 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
|
1895 // 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
|
1896 // No registers are killed, except temp_reg. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1897 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
|
1898 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1899 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1900 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1901 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1902 Label* L_slow_path, |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1903 RegisterOrConstant super_check_offset = RegisterOrConstant(-1)); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1904 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1905 // 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
|
1906 // 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
|
1907 // 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
|
1908 // 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
|
1909 // 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
|
1910 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
|
1911 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1912 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1913 Register temp2_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1914 Label* L_success, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1915 Label* L_failure, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1916 bool set_cond_codes = false); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1917 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1918 // Simplified, combined version, good for typical uses. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1919 // Falls through on failure. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1920 void check_klass_subtype(Register sub_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1921 Register super_klass, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1922 Register temp_reg, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1923 Label& L_success); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
643
diff
changeset
|
1924 |
710 | 1925 // method handles (JSR 292) |
1926 void check_method_handle_type(Register mtype_reg, Register mh_reg, | |
1927 Register temp_reg, | |
1928 Label& wrong_method_type); | |
1929 void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg, | |
1930 Register temp_reg); | |
1931 void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); | |
1932 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); | |
1933 | |
1934 | |
0 | 1935 //---- |
1936 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 | |
1937 | |
1938 // Debugging | |
304 | 1939 |
1940 // only if +VerifyOops | |
1941 void verify_oop(Register reg, const char* s = "broken oop"); | |
0 | 1942 void verify_oop_addr(Address addr, const char * s = "broken oop addr"); |
1943 | |
304 | 1944 // only if +VerifyFPU |
1945 void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); | |
1946 | |
1947 // prints msg, dumps registers and stops execution | |
1948 void stop(const char* msg); | |
1949 | |
1950 // prints msg and continues | |
1951 void warn(const char* msg); | |
1952 | |
1953 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg); | |
1954 static void debug64(char* msg, int64_t pc, int64_t regs[]); | |
1955 | |
0 | 1956 void os_breakpoint(); |
304 | 1957 |
0 | 1958 void untested() { stop("untested"); } |
304 | 1959 |
1846 | 1960 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); } |
304 | 1961 |
0 | 1962 void should_not_reach_here() { stop("should not reach here"); } |
304 | 1963 |
0 | 1964 void print_CPU_state(); |
1965 | |
1966 // Stack overflow checking | |
1967 void bang_stack_with_offset(int offset) { | |
1968 // stack grows down, caller passes positive offset | |
1969 assert(offset > 0, "must bang with negative offset"); | |
1970 movl(Address(rsp, (-offset)), rax); | |
1971 } | |
1972 | |
1973 // Writes to stack successive pages until offset reached to check for | |
1974 // stack overflow + shadow pages. Also, clobbers tmp | |
1975 void bang_stack_size(Register size, Register tmp); | |
1976 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1977 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1978 Register tmp, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
644
diff
changeset
|
1979 int offset); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
420
diff
changeset
|
1980 |
0 | 1981 // Support for serializing memory accesses between threads |
1982 void serialize_memory(Register thread, Register tmp); | |
1983 | |
1984 void verify_tlab(); | |
1985 | |
1986 // Biased locking support | |
1987 // lock_reg and obj_reg must be loaded up with the appropriate values. | |
1988 // swap_reg must be rax, and is killed. | |
1989 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will | |
1990 // be killed; if not supplied, push/pop will be used internally to | |
1991 // allocate a temporary (inefficient, avoid if possible). | |
1992 // Optional slow case is for implementations (interpreter and C1) which branch to | |
1993 // slow case directly. Leaves condition codes set for C2's Fast_Lock node. | |
1994 // Returns offset of first potentially-faulting instruction for null | |
1995 // check info (currently consumed only by C1). If | |
1996 // swap_reg_contains_mark is true then returns -1 as it is assumed | |
1997 // 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
|
1998 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
|
1999 Register swap_reg, Register tmp_reg, |
0 | 2000 bool swap_reg_contains_mark, |
2001 Label& done, Label* slow_case = NULL, | |
2002 BiasedLockingCounters* counters = NULL); | |
2003 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); | |
2004 | |
2005 | |
2006 Condition negate_condition(Condition cond); | |
2007 | |
2008 // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit | |
2009 // operands. In general the names are modified to avoid hiding the instruction in Assembler | |
2010 // so that we don't need to implement all the varieties in the Assembler with trivial wrappers | |
2011 // here in MacroAssembler. The major exception to this rule is call | |
2012 | |
2013 // Arithmetics | |
2014 | |
304 | 2015 |
2016 void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; } | |
2017 void addptr(Address dst, Register src); | |
2018 | |
2019 void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); } | |
2020 void addptr(Register dst, int32_t src); | |
2021 void addptr(Register dst, Register src); | |
2022 | |
2023 void andptr(Register dst, int32_t src); | |
2024 void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; } | |
2025 | |
2026 void cmp8(AddressLiteral src1, int imm); | |
2027 | |
2028 // renamed to drag out the casting of address to int32_t/intptr_t | |
0 | 2029 void cmp32(Register src1, int32_t imm); |
2030 | |
2031 void cmp32(AddressLiteral src1, int32_t imm); | |
2032 // compare reg - mem, or reg - &mem | |
2033 void cmp32(Register src1, AddressLiteral src2); | |
2034 | |
2035 void cmp32(Register src1, Address src2); | |
2036 | |
304 | 2037 #ifndef _LP64 |
2038 void cmpoop(Address dst, jobject obj); | |
2039 void cmpoop(Register dst, jobject obj); | |
2040 #endif // _LP64 | |
2041 | |
0 | 2042 // NOTE src2 must be the lval. This is NOT an mem-mem compare |
2043 void cmpptr(Address src1, AddressLiteral src2); | |
2044 | |
2045 void cmpptr(Register src1, AddressLiteral src2); | |
2046 | |
304 | 2047 void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } |
2048 void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2049 // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2050 | |
2051 void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2052 void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; } | |
2053 | |
2054 // cmp64 to avoild hiding cmpq | |
2055 void cmp64(Register src1, AddressLiteral src); | |
2056 | |
2057 void cmpxchgptr(Register reg, Address adr); | |
2058 | |
2059 void locked_cmpxchgptr(Register reg, AddressLiteral adr); | |
2060 | |
2061 | |
2062 void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); } | |
2063 | |
2064 | |
2065 void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); } | |
2066 | |
2067 void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); } | |
2068 | |
2069 void shlptr(Register dst, int32_t shift); | |
2070 void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); } | |
2071 | |
2072 void shrptr(Register dst, int32_t shift); | |
2073 void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); } | |
2074 | |
2075 void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); } | |
2076 void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); } | |
2077 | |
2078 void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2079 | |
2080 void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); } | |
2081 void subptr(Register dst, int32_t src); | |
2082 void subptr(Register dst, Register src); | |
2083 | |
2084 | |
2085 void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2086 void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); } | |
2087 | |
2088 void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2089 void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; } | |
2090 | |
2091 void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; } | |
2092 | |
2093 | |
0 | 2094 |
2095 // Helper functions for statistics gathering. | |
2096 // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes. | |
2097 void cond_inc32(Condition cond, AddressLiteral counter_addr); | |
2098 // Unconditional atomic increment. | |
2099 void atomic_incl(AddressLiteral counter_addr); | |
2100 | |
2101 void lea(Register dst, AddressLiteral adr); | |
2102 void lea(Address dst, AddressLiteral adr); | |
304 | 2103 void lea(Register dst, Address adr) { Assembler::lea(dst, adr); } |
2104 | |
2105 void leal32(Register dst, Address src) { leal(dst, src); } | |
2106 | |
2404
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
2107 // Import other testl() methods from the parent class or else |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
2108 // they will be hidden by the following overriding declaration. |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
2109 using Assembler::testl; |
b40d4fa697bf
6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents:
2320
diff
changeset
|
2110 void testl(Register dst, AddressLiteral src); |
304 | 2111 |
2112 void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2113 void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2114 void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); } | |
2115 | |
2116 void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); } | |
2117 void testptr(Register src1, Register src2); | |
2118 | |
2119 void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
2120 void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); } | |
0 | 2121 |
2122 // Calls | |
2123 | |
2124 void call(Label& L, relocInfo::relocType rtype); | |
2125 void call(Register entry); | |
2126 | |
2127 // NOTE: this call tranfers to the effective address of entry NOT | |
2128 // the address contained by entry. This is because this is more natural | |
2129 // for jumps/calls. | |
2130 void call(AddressLiteral entry); | |
2131 | |
2132 // Jumps | |
2133 | |
2134 // NOTE: these jumps tranfer to the effective address of dst NOT | |
2135 // the address contained by dst. This is because this is more natural | |
2136 // for jumps/calls. | |
2137 void jump(AddressLiteral dst); | |
2138 void jump_cc(Condition cc, AddressLiteral dst); | |
2139 | |
2140 // 32bit can do a case table jump in one instruction but we no longer allow the base | |
2141 // to be installed in the Address class. This jump will tranfers to the address | |
2142 // contained in the location described by entry (not the address of entry) | |
2143 void jump(ArrayAddress entry); | |
2144 | |
2145 // Floating | |
2146 | |
2147 void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); } | |
2148 void andpd(XMMRegister dst, AddressLiteral src); | |
2149 | |
2150 void comiss(XMMRegister dst, Address src) { Assembler::comiss(dst, src); } | |
2151 void comiss(XMMRegister dst, AddressLiteral src); | |
2152 | |
2153 void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); } | |
2154 void comisd(XMMRegister dst, AddressLiteral src); | |
2155 | |
2008 | 2156 void fadd_s(Address src) { Assembler::fadd_s(src); } |
2157 void fadd_s(AddressLiteral src) { Assembler::fadd_s(as_Address(src)); } | |
2158 | |
0 | 2159 void fldcw(Address src) { Assembler::fldcw(src); } |
2160 void fldcw(AddressLiteral src); | |
2161 | |
2162 void fld_s(int index) { Assembler::fld_s(index); } | |
2163 void fld_s(Address src) { Assembler::fld_s(src); } | |
2164 void fld_s(AddressLiteral src); | |
2165 | |
2166 void fld_d(Address src) { Assembler::fld_d(src); } | |
2167 void fld_d(AddressLiteral src); | |
2168 | |
2169 void fld_x(Address src) { Assembler::fld_x(src); } | |
2170 void fld_x(AddressLiteral src); | |
2171 | |
2008 | 2172 void fmul_s(Address src) { Assembler::fmul_s(src); } |
2173 void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); } | |
2174 | |
0 | 2175 void ldmxcsr(Address src) { Assembler::ldmxcsr(src); } |
2176 void ldmxcsr(AddressLiteral src); | |
2177 | |
304 | 2178 private: |
2179 // these are private because users should be doing movflt/movdbl | |
2180 | |
0 | 2181 void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); } |
2182 void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); } | |
2183 void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); } | |
2184 void movss(XMMRegister dst, AddressLiteral src); | |
2185 | |
304 | 2186 void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); } |
2187 void movlpd(XMMRegister dst, AddressLiteral src); | |
2188 | |
2189 public: | |
2190 | |
2008 | 2191 void addsd(XMMRegister dst, XMMRegister src) { Assembler::addsd(dst, src); } |
2192 void addsd(XMMRegister dst, Address src) { Assembler::addsd(dst, src); } | |
2193 void addsd(XMMRegister dst, AddressLiteral src) { Assembler::addsd(dst, as_Address(src)); } | |
2194 | |
2195 void addss(XMMRegister dst, XMMRegister src) { Assembler::addss(dst, src); } | |
2196 void addss(XMMRegister dst, Address src) { Assembler::addss(dst, src); } | |
2197 void addss(XMMRegister dst, AddressLiteral src) { Assembler::addss(dst, as_Address(src)); } | |
2198 | |
2199 void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); } | |
2200 void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); } | |
2201 void divsd(XMMRegister dst, AddressLiteral src) { Assembler::divsd(dst, as_Address(src)); } | |
2202 | |
2203 void divss(XMMRegister dst, XMMRegister src) { Assembler::divss(dst, src); } | |
2204 void divss(XMMRegister dst, Address src) { Assembler::divss(dst, src); } | |
2205 void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); } | |
2206 | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2008
diff
changeset
|
2207 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
|
2208 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
|
2209 void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } |
2008 | 2210 void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); } |
2211 | |
2212 void mulsd(XMMRegister dst, XMMRegister src) { Assembler::mulsd(dst, src); } | |
2213 void mulsd(XMMRegister dst, Address src) { Assembler::mulsd(dst, src); } | |
2214 void mulsd(XMMRegister dst, AddressLiteral src) { Assembler::mulsd(dst, as_Address(src)); } | |
2215 | |
2216 void mulss(XMMRegister dst, XMMRegister src) { Assembler::mulss(dst, src); } | |
2217 void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); } | |
2218 void mulss(XMMRegister dst, AddressLiteral src) { Assembler::mulss(dst, as_Address(src)); } | |
2219 | |
2220 void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); } | |
2221 void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); } | |
2222 void sqrtsd(XMMRegister dst, AddressLiteral src) { Assembler::sqrtsd(dst, as_Address(src)); } | |
2223 | |
2224 void sqrtss(XMMRegister dst, XMMRegister src) { Assembler::sqrtss(dst, src); } | |
2225 void sqrtss(XMMRegister dst, Address src) { Assembler::sqrtss(dst, src); } | |
2226 void sqrtss(XMMRegister dst, AddressLiteral src) { Assembler::sqrtss(dst, as_Address(src)); } | |
2227 | |
2228 void subsd(XMMRegister dst, XMMRegister src) { Assembler::subsd(dst, src); } | |
2229 void subsd(XMMRegister dst, Address src) { Assembler::subsd(dst, src); } | |
2230 void subsd(XMMRegister dst, AddressLiteral src) { Assembler::subsd(dst, as_Address(src)); } | |
2231 | |
2232 void subss(XMMRegister dst, XMMRegister src) { Assembler::subss(dst, src); } | |
2233 void subss(XMMRegister dst, Address src) { Assembler::subss(dst, src); } | |
2234 void subss(XMMRegister dst, AddressLiteral src) { Assembler::subss(dst, as_Address(src)); } | |
0 | 2235 |
2236 void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); } | |
2237 void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); } | |
2238 void ucomiss(XMMRegister dst, AddressLiteral src); | |
2239 | |
2240 void ucomisd(XMMRegister dst, XMMRegister src) { Assembler::ucomisd(dst, src); } | |
2241 void ucomisd(XMMRegister dst, Address src) { Assembler::ucomisd(dst, src); } | |
2242 void ucomisd(XMMRegister dst, AddressLiteral src); | |
2243 | |
2244 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values | |
2245 void xorpd(XMMRegister dst, XMMRegister src) { Assembler::xorpd(dst, src); } | |
2246 void xorpd(XMMRegister dst, Address src) { Assembler::xorpd(dst, src); } | |
2247 void xorpd(XMMRegister dst, AddressLiteral src); | |
2248 | |
2249 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values | |
2250 void xorps(XMMRegister dst, XMMRegister src) { Assembler::xorps(dst, src); } | |
2251 void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); } | |
2252 void xorps(XMMRegister dst, AddressLiteral src); | |
2253 | |
2254 // Data | |
2255 | |
2415
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2256 void cmov32( Condition cc, Register dst, Address src); |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2257 void cmov32( Condition cc, Register dst, Register src); |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2258 |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2259 void cmov( Condition cc, Register dst, Register src) { cmovptr(cc, dst, src); } |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2260 |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2261 void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); } |
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2404
diff
changeset
|
2262 void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmov32(cc, dst, src)); } |
304 | 2263 |
0 | 2264 void movoop(Register dst, jobject obj); |
2265 void movoop(Address dst, jobject obj); | |
2266 | |
2267 void movptr(ArrayAddress dst, Register src); | |
2268 // can this do an lea? | |
2269 void movptr(Register dst, ArrayAddress src); | |
2270 | |
304 | 2271 void movptr(Register dst, Address src); |
2272 | |
0 | 2273 void movptr(Register dst, AddressLiteral src); |
2274 | |
304 | 2275 void movptr(Register dst, intptr_t src); |
2276 void movptr(Register dst, Register src); | |
2277 void movptr(Address dst, intptr_t src); | |
2278 | |
2279 void movptr(Address dst, Register src); | |
2280 | |
2281 #ifdef _LP64 | |
2282 // Generally the next two are only used for moving NULL | |
2283 // Although there are situations in initializing the mark word where | |
2284 // they could be used. They are dangerous. | |
2285 | |
2286 // They only exist on LP64 so that int32_t and intptr_t are not the same | |
2287 // and we have ambiguous declarations. | |
2288 | |
2289 void movptr(Address dst, int32_t imm32); | |
2290 void movptr(Register dst, int32_t imm32); | |
2291 #endif // _LP64 | |
2292 | |
0 | 2293 // to avoid hiding movl |
2294 void mov32(AddressLiteral dst, Register src); | |
2295 void mov32(Register dst, AddressLiteral src); | |
304 | 2296 |
0 | 2297 // to avoid hiding movb |
2298 void movbyte(ArrayAddress dst, int src); | |
2299 | |
2300 // Can push value or effective address | |
2301 void pushptr(AddressLiteral src); | |
2302 | |
304 | 2303 void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); } |
2304 void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); } | |
2305 | |
2306 void pushoop(jobject obj); | |
2307 | |
2308 // sign extend as need a l to ptr sized element | |
2309 void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); } | |
2310 void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); } | |
2311 | |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2312 // IndexOf strings. |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2313 // 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
|
2314 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
|
2315 Register cnt1, Register cnt2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2316 int int_cnt2, Register result, |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2317 XMMRegister vec, Register tmp); |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2318 |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2319 // 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
|
2320 // 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
|
2321 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
|
2322 Register cnt1, Register cnt2, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2323 int int_cnt2, Register result, |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2324 XMMRegister vec, Register tmp); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2325 |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2326 // 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
|
2327 // check string tail. |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2262
diff
changeset
|
2328 |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2329 // Compare strings. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2330 void string_compare(Register str1, Register str2, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2331 Register cnt1, Register cnt2, Register result, |
2262 | 2332 XMMRegister vec1); |
986
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2333 |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2334 // Compare char[] arrays. |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2335 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
|
2336 Register limit, Register result, Register chr, |
62001a362ce9
6827605: new String intrinsics may prevent EA scalar replacement
kvn
parents:
775
diff
changeset
|
2337 XMMRegister vec1, XMMRegister vec2); |
304 | 2338 |
1763 | 2339 // Fill primitive arrays |
2340 void generate_fill(BasicType t, bool aligned, | |
2341 Register to, Register value, Register count, | |
2342 Register rtmp, XMMRegister xtmp); | |
2343 | |
0 | 2344 #undef VIRTUAL |
2345 | |
2346 }; | |
2347 | |
2348 /** | |
2349 * class SkipIfEqual: | |
2350 * | |
2351 * Instantiating this class will result in assembly code being output that will | |
2352 * jump around any code emitted between the creation of the instance and it's | |
2353 * automatic destruction at the end of a scope block, depending on the value of | |
2354 * the flag passed to the constructor, which will be checked at run-time. | |
2355 */ | |
2356 class SkipIfEqual { | |
2357 private: | |
2358 MacroAssembler* _masm; | |
2359 Label _label; | |
2360 | |
2361 public: | |
2362 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value); | |
2363 ~SkipIfEqual(); | |
2364 }; | |
2365 | |
2366 #ifdef ASSERT | |
2367 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; } | |
2368 #endif | |
1972 | 2369 |
2370 #endif // CPU_X86_VM_ASSEMBLER_X86_HPP |