annotate src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 20504:6948da6d7c13

8052172: Evacuation failure handling in G1 does not evacuate all objects if -XX:-G1DeferredRSUpdate is set Summary: Remove -XX:-G1DeferredRSUpdate functionality as it is racy. During evacuation failure handling, threads where evacuation failure handling occurred may try to add remembered sets to regions which remembered sets are currently being scanned. The iterator to handle the remembered set scan does not support addition of entries during scan and so may skip valid references. Reviewed-by: iveresov, brutisso, mgerdin
author tschatzl
date Tue, 30 Sep 2014 09:44:36 +0200
parents 04d32e7fad07
children d8041d695d19
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1506
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1506
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: 1506
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
25 #include "precompiled.hpp"
7199
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6894
diff changeset
26 #include "asm/macroAssembler.hpp"
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6894
diff changeset
27 #include "asm/macroAssembler.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
28 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
29 #include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
30 #include "oops/instanceOop.hpp"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
31 #include "oops/method.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
32 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
33 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
34 #include "prims/methodHandles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
35 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
36 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
37 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
38 #include "runtime/stubCodeGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
39 #include "runtime/stubRoutines.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 6894
diff changeset
40 #include "runtime/thread.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
41 #include "utilities/top.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
42 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
43 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
44 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // Declaration and definition of StubGenerator (no .hpp file).
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // For a more detailed description of the stub routine structure
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // see the comment in stubRoutines.hpp
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 #define __ _masm->
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
51 #define a__ ((Assembler*)_masm)->
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
54 #define BLOCK_COMMENT(str) /* nothing */
a61af66fc99e Initial load
duke
parents:
diff changeset
55 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
56 #define BLOCK_COMMENT(str) __ block_comment(str)
a61af66fc99e Initial load
duke
parents:
diff changeset
57 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 const int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
62 const int FPU_CNTRL_WRD_MASK = 0xFFFF;
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // -------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Stub Code definitions
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 static address handle_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
69 address pc = thread->saved_exception_pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // pc is the instruction which we must emulate
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // doing a no-op is fine: return garbage from the load
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // therefore, compute npc
a61af66fc99e Initial load
duke
parents:
diff changeset
73 address npc = Assembler::locate_next_instruction(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // request an async exception
a61af66fc99e Initial load
duke
parents:
diff changeset
76 thread->set_pending_unsafe_access_error();
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // return address of next instruction to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return npc;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 class StubGenerator: public StubCodeGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #ifdef PRODUCT
10973
ef57c43512d6 8014431: cleanup warnings indicated by the -Wunused-value compiler option on linux
ccheung
parents: 10324
diff changeset
86 #define inc_counter_np(counter) ((void)0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
87 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
88 void inc_counter_np_(int& counter) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
89 __ incrementl(ExternalAddress((address)&counter));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #define inc_counter_np(counter) \
a61af66fc99e Initial load
duke
parents:
diff changeset
92 BLOCK_COMMENT("inc_counter " #counter); \
a61af66fc99e Initial load
duke
parents:
diff changeset
93 inc_counter_np_(counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 void inc_copy_counter_np(BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
98 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 case T_BYTE: inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 case T_SHORT: inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 case T_INT: inc_counter_np(SharedRuntime::_jint_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 case T_LONG: inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 case T_OBJECT: inc_counter_np(SharedRuntime::_oop_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
106 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Call stubs are used to call Java from C
a61af66fc99e Initial load
duke
parents:
diff changeset
111 //
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // -N [ argument word 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // -7 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // -6 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // -5 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // -4 [ mxcsr save ] <--- rsp_after_call
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // -3 [ saved rbx, ]
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // -2 [ saved rsi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // -1 [ saved rdi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // 0 [ saved rbp, ] <--- rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // 2 [ ptr. to call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // 3 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // 4 [ result_type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // 5 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // 6 [ entry_point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // 7 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // 8 [ parameter_size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // 9 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 address generate_call_stub(address& return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 StubCodeMark mark(this, "StubRoutines", "call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
137 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // stub code parameters / addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert(frame::entry_frame_call_wrapper_offset == 2, "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 bool sse_save = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
143 const int locals_count_in_bytes (4*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 const Address mxcsr_save (rbp, -4 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 const Address saved_rbx (rbp, -3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 const Address saved_rsi (rbp, -2 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 const Address saved_rdi (rbp, -1 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 const Address result (rbp, 3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 const Address result_type (rbp, 4 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
150 const Address method (rbp, 5 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 const Address entry_point (rbp, 6 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 const Address parameters (rbp, 7 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 const Address parameter_size(rbp, 8 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 const Address thread (rbp, 9 * wordSize); // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
155 sse_save = UseSSE > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // stub code
a61af66fc99e Initial load
duke
parents:
diff changeset
158 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
159 __ movptr(rcx, parameter_size); // parameter counter
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1368
diff changeset
160 __ shlptr(rcx, Interpreter::logStackElementSize); // convert parameter count to bytes
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
161 __ addptr(rcx, locals_count_in_bytes); // reserve space for register saves
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
162 __ subptr(rsp, rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
163 __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // save rdi, rsi, & rbx, according to C calling conventions
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
166 __ movptr(saved_rdi, rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
167 __ movptr(saved_rsi, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
168 __ movptr(saved_rbx, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // save and initialize %mxcsr
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (sse_save) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 Label skip_ldmx;
a61af66fc99e Initial load
duke
parents:
diff changeset
172 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
a61af66fc99e Initial load
duke
parents:
diff changeset
175 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
176 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 __ jcc(Assembler::equal, skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 __ bind(skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // make sure the control word is correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // make sure we have no pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
187 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
188 __ movptr(rcx, thread);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
189 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 __ stop("StubRoutines::call_stub: entered with pending exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // pass parameters if any
a61af66fc99e Initial load
duke
parents:
diff changeset
197 BLOCK_COMMENT("pass parameters if any");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 Label parameters_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 __ movl(rcx, parameter_size); // parameter counter
a61af66fc99e Initial load
duke
parents:
diff changeset
200 __ testl(rcx, rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 __ jcc(Assembler::zero, parameters_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // parameter passing loop
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 Label loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // Copy Java parameters in reverse order (receiver last)
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Note that the argument order is inverted in the process
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // source is rdx[rcx: N-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // dest is rsp[rbx: 0..N-1]
a61af66fc99e Initial load
duke
parents:
diff changeset
210
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
211 __ movptr(rdx, parameters); // parameter pointer
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
212 __ xorptr(rbx, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 __ BIND(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // get parameter
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
217 __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
218 __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
219 Interpreter::expr_offset_in_bytes(0)), rax); // store parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
220 __ increment(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 __ decrement(rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 __ jcc(Assembler::notZero, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // call Java function
a61af66fc99e Initial load
duke
parents:
diff changeset
225 __ BIND(parameters_done);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
226 __ movptr(rbx, method); // get Method*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
227 __ movptr(rax, entry_point); // get entry_point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
228 __ mov(rsi, rsp); // set sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 BLOCK_COMMENT("call Java function");
a61af66fc99e Initial load
duke
parents:
diff changeset
230 __ call(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 BLOCK_COMMENT("call_stub_return_address:");
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return_address = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
234
2245
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
235 #ifdef COMPILER2
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
236 {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
237 Label L_skip;
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
238 if (UseSSE >= 2) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
239 __ verify_FPU(0, "call_stub_return");
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
240 } else {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
241 for (int i = 1; i < 8; i++) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
242 __ ffree(i);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
243 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244
2245
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
245 // UseSSE <= 1 so double result should be left on TOS
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
246 __ movl(rsi, result_type);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
247 __ cmpl(rsi, T_DOUBLE);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
248 __ jcc(Assembler::equal, L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
249 if (UseSSE == 0) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
250 // UseSSE == 0 so float result should be left on TOS
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
251 __ cmpl(rsi, T_FLOAT);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
252 __ jcc(Assembler::equal, L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
253 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
254 __ ffree(0);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
255 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
256 __ BIND(L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
257 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
258 #endif // COMPILER2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // store result depending on type
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // (everything that is not T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
262 __ movptr(rdi, result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
263 Label is_long, is_float, is_double, exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 __ movl(rsi, result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 __ cmpl(rsi, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 __ cmpl(rsi, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
268 __ jcc(Assembler::equal, is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 __ cmpl(rsi, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 __ jcc(Assembler::equal, is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // handle T_INT case
a61af66fc99e Initial load
duke
parents:
diff changeset
273 __ movl(Address(rdi, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 __ BIND(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // check that FPU stack is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
277 __ verify_FPU(0, "generate_call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // pop parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
280 __ lea(rsp, rsp_after_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // restore %mxcsr
a61af66fc99e Initial load
duke
parents:
diff changeset
283 if (sse_save) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 __ ldmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // restore rdi, rsi and rbx,
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
288 __ movptr(rbx, saved_rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
289 __ movptr(rsi, saved_rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
290 __ movptr(rdi, saved_rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
291 __ addptr(rsp, 4*wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
294 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
295 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // handle return types different from T_INT
a61af66fc99e Initial load
duke
parents:
diff changeset
298 __ BIND(is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 __ movl(Address(rdi, 0 * wordSize), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 __ movl(Address(rdi, 1 * wordSize), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
301 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 __ BIND(is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // interpreter uses xmm0 for return values
a61af66fc99e Initial load
duke
parents:
diff changeset
305 if (UseSSE >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 __ movflt(Address(rdi, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 __ fstp_s(Address(rdi, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 __ BIND(is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // interpreter uses xmm0 for return values
a61af66fc99e Initial load
duke
parents:
diff changeset
314 if (UseSSE >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 __ movdbl(Address(rdi, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 __ fstp_d(Address(rdi, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // Return point for a Java call if there's an exception thrown in Java code.
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // The exception is caught and transformed into a pending exception stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // JavaThread that can be tested from within the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 //
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Note: Usually the parameters are removed by the callee. In case of an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // crossing an activation frame boundary, that is not the case if the callee
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // is compiled code => need to setup the rsp.
a61af66fc99e Initial load
duke
parents:
diff changeset
333 //
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // rax,: exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 address generate_catch_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 StubCodeMark mark(this, "StubRoutines", "catch_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_call_stub()!
a61af66fc99e Initial load
duke
parents:
diff changeset
339 const Address thread (rbp, 9 * wordSize); // same as in generate_call_stub()!
a61af66fc99e Initial load
duke
parents:
diff changeset
340 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // get thread directly
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
343 __ movptr(rcx, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
346 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
348 __ cmpptr(rbx, rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
349 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 __ stop("StubRoutines::catch_exception: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
351 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // set pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
355 __ verify_oop(rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
356 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357 __ lea(Address(rcx, Thread::exception_file_offset ()),
a61af66fc99e Initial load
duke
parents:
diff changeset
358 ExternalAddress((address)__FILE__));
a61af66fc99e Initial load
duke
parents:
diff changeset
359 __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ );
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // complete return to VM
a61af66fc99e Initial load
duke
parents:
diff changeset
361 assert(StubRoutines::_call_stub_return_address != NULL, "_call_stub_return_address must have been generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
362 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address));
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // Continuation point for runtime calls returning with a pending exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // The pending exception check happened in the runtime or native call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // The pending exception in Thread is converted into a Java-level exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 //
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // Contract with Java-level exception handlers:
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
374 // rax: exception
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
376 //
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // NOTE: At entry of this stub, exception-pc must be on stack !!
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 address generate_forward_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 StubCodeMark mark(this, "StubRoutines", "forward exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
381 address start = __ pc();
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
382 const Register thread = rcx;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
383
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
384 // other registers used in this stub
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
385 const Register exception_oop = rax;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
386 const Register handler_addr = rbx;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
387 const Register exception_pc = rdx;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // Upon entry, the sp points to the return address returning into Java
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // (interpreted or compiled) code; i.e., the return address becomes the
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // throwing pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 //
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Arguments pushed before the runtime call are still on the stack but
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // the exception handler will reset the stack pointer -> ignore them.
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // A potential result in registers can be ignored as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // make sure this code is only executed if there is a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
399 { Label L;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
400 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
401 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
402 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 __ stop("StubRoutines::forward exception: no pending exception (1)");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // compute exception handler into rbx,
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
409 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
410 __ movptr(exception_pc, Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
411 BLOCK_COMMENT("call exception_handler_for_return_address");
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
412 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
413 __ mov(handler_addr, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
415 // setup rax & rdx, remove return address & clear pending exception
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
416 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
417 __ pop(exception_pc);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
418 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
419 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // make sure exception is set
a61af66fc99e Initial load
duke
parents:
diff changeset
423 { Label L;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
424 __ testptr(exception_oop, exception_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
425 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 __ stop("StubRoutines::forward exception: no pending exception (2)");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
430
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
431 // Verify that there is really a valid exception in RAX.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
432 __ verify_oop(exception_oop);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
433
0
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // continue at exception handler (return address removed)
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
435 // rax: exception
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
436 // rbx: exception handler
0
a61af66fc99e Initial load
duke
parents:
diff changeset
437 // rdx: throwing pc
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
438 __ jmp(handler_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
446 //
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // xchg exists as far back as 8086, lock needed for MP only
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Stack layout immediately after call:
a61af66fc99e Initial load
duke
parents:
diff changeset
449 //
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // 0 [ret addr ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // 1 [ ex ]
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // 2 [ dest ]
a61af66fc99e Initial load
duke
parents:
diff changeset
453 //
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // Result: *dest <- ex, return (old *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
455 //
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Note: win32 does not currently use this code
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 address generate_atomic_xchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 StubCodeMark mark(this, "StubRoutines", "atomic_xchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
460 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
461
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
462 __ push(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
463 Address exchange(rsp, 2 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 Address dest_addr(rsp, 3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
465 __ movl(rax, exchange);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
466 __ movptr(rdx, dest_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
467 __ xchgl(rax, Address(rdx, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
468 __ pop(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
469 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Support for void verify_mxcsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
476 //
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // MXCSR register to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 address generate_verify_mxcsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 StubCodeMark mark(this, "StubRoutines", "verify_mxcsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
484 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 const Address mxcsr_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 if (CheckJNICalls && UseSSE > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 Label ok_ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
491 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
492 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
493 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 __ andl(rax, MXCSR_MASK);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 __ warn("MXCSR changed by native JNI code.");
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
504 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
505 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Support for void verify_fpu_cntrl_wrd()
a61af66fc99e Initial load
duke
parents:
diff changeset
516 //
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // FP control word to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 address generate_verify_fpu_cntrl_wrd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 StubCodeMark mark(this, "StubRoutines", "verify_spcw");
a61af66fc99e Initial load
duke
parents:
diff changeset
523 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 const Address fpu_cntrl_wrd_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 Label ok_ret;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
529 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
530 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
531 __ fnstcw(fpu_cntrl_wrd_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 __ movl(rax, fpu_cntrl_wrd_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 __ andl(rax, FPU_CNTRL_WRD_MASK);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 ExternalAddress fpu_std(StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
535 __ cmp32(rax, fpu_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
536 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 __ warn("Floating point control word changed by native JNI code.");
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 __ fldcw(fpu_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
543 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
544 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Wrapper for slow-case handling of double-to-integer conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // d2i or f2i fast case failed either because it is nan or because
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // of under/overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Input: FPU TOS: float value
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // Output: rax, (rdx): integer (long) result
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 address generate_d2i_wrapper(BasicType t, address fcn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 StubCodeMark mark(this, "StubRoutines", "d2i_wrapper");
a61af66fc99e Initial load
duke
parents:
diff changeset
561 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // Capture info about frame layout
a61af66fc99e Initial load
duke
parents:
diff changeset
564 enum layout { FPUState_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
565 rbp_off = FPUStateSizeInWords,
a61af66fc99e Initial load
duke
parents:
diff changeset
566 rdi_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
567 rsi_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
568 rcx_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
569 rbx_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
570 saved_argument_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
571 saved_argument_off2, // 2nd half of double
a61af66fc99e Initial load
duke
parents:
diff changeset
572 framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
573 };
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 assert(FPUStateSizeInWords == 27, "update stack layout");
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Save outgoing argument to stack across push_FPU_state()
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
578 __ subptr(rsp, wordSize * 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
579 __ fstp_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Save CPU & FPU state
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
582 __ push(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
583 __ push(rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
584 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
585 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
586 __ push(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
587 __ push_FPU_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // push_FPU_state() resets the FP top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // Load original double into FP top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
591 __ fld_d(Address(rsp, saved_argument_off * wordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Store double into stack as outgoing argument
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
593 __ subptr(rsp, wordSize*2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
594 __ fst_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Prepare FPU for doing math in C-land
a61af66fc99e Initial load
duke
parents:
diff changeset
597 __ empty_FPU_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // Call the C code to massage the double. Result in EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (t == T_INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
600 { BLOCK_COMMENT("SharedRuntime::d2i"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 else if (t == T_LONG)
a61af66fc99e Initial load
duke
parents:
diff changeset
602 { BLOCK_COMMENT("SharedRuntime::d2l"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
603 __ call_VM_leaf( fcn, 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Restore CPU & FPU state
a61af66fc99e Initial load
duke
parents:
diff changeset
606 __ pop_FPU_state();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
607 __ pop(rbp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
608 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
609 __ pop(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
610 __ pop(rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
611 __ pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
612 __ addptr(rsp, wordSize * 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // The following routine generates a subroutine to throw an asynchronous
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // UnknownError when an unsafe access gets a fault that could not be
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
a61af66fc99e Initial load
duke
parents:
diff changeset
624 address generate_handler_for_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
626 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
627
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
628 __ push(0); // hole for return address-to-be
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
629 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
630 Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 BLOCK_COMMENT("call handle_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
632 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
633 __ movptr(next_pc, rax); // stuff next address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
634 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
635 __ ret(0); // jump to next address
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Non-destructive plausibility checks for oops
a61af66fc99e Initial load
duke
parents:
diff changeset
643
a61af66fc99e Initial load
duke
parents:
diff changeset
644 address generate_verify_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
645 StubCodeMark mark(this, "StubRoutines", "verify_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
646 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // Incoming arguments on stack after saving rax,:
a61af66fc99e Initial load
duke
parents:
diff changeset
649 //
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // [tos ]: saved rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // [tos + 1]: saved EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // [tos + 2]: return address
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // [tos + 3]: char* error message
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // [tos + 4]: oop object to verify
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // [tos + 5]: saved rax, - saved by caller and bashed
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 Label exit, error;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
658 __ pushf();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
659 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
660 __ push(rdx); // save rdx
0
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // make sure object is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
662 __ movptr(rax, Address(rsp, 4 * wordSize)); // get object
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
663 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
664 __ jcc(Assembler::zero, exit); // if obj is NULL it is ok
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // Check if the oop is in the right area of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
667 const int oop_mask = Universe::verify_oop_mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
668 const int oop_bits = Universe::verify_oop_bits();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
669 __ mov(rdx, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
670 __ andptr(rdx, oop_mask);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
671 __ cmpptr(rdx, oop_bits);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
672 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
673
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
674 // make sure klass is 'reasonable', which is not zero.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
675 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
676 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
677 __ jcc(Assembler::zero, error); // if klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
678
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // return if everything seems ok
a61af66fc99e Initial load
duke
parents:
diff changeset
680 __ bind(exit);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
681 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
682 __ pop(rdx); // restore rdx
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
683 __ popf(); // restore EFLAGS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
684 __ ret(3 * wordSize); // pop arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // handle errors
a61af66fc99e Initial load
duke
parents:
diff changeset
687 __ bind(error);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
688 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
689 __ pop(rdx); // get saved rdx back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
690 __ popf(); // get saved EFLAGS off stack -- will be ignored
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
691 __ pusha(); // push registers (eip = return address & msg are already pushed)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
692 BLOCK_COMMENT("call MacroAssembler::debug");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
693 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
694 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
695 __ ret(3 * wordSize); // pop arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
696 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 //
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // Generate pre-barrier for array stores
a61af66fc99e Initial load
duke
parents:
diff changeset
701 //
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // start - starting address
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 710
diff changeset
704 // count - element count
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
705 void gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
706 assert_different_registers(start, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
708 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
710 case BarrierSet::G1SATBCTLogging:
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
711 // With G1, don't generate the call if we statically know that the target in uninitialized
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
712 if (!uninitialized_target) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
713 __ pusha(); // push registers
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
714 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
715 start, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
716 __ popa();
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
717 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
718 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
719 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
720 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
721 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
722 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
724 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 //
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Generate a post-barrier for an array store
a61af66fc99e Initial load
duke
parents:
diff changeset
732 //
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // start - starting address
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // count - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
735 //
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // The two input registers are overwritten.
a61af66fc99e Initial load
duke
parents:
diff changeset
737 //
a61af66fc99e Initial load
duke
parents:
diff changeset
738 void gen_write_ref_array_post_barrier(Register start, Register count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
740 assert_different_registers(start, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
743 case BarrierSet::G1SATBCTLogging:
a61af66fc99e Initial load
duke
parents:
diff changeset
744 {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
745 __ pusha(); // push registers
1192
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
746 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post),
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
747 start, count);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
748 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
753 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
754 {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 Label L_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 const Register end = count; // elements count; end == start+count-1
a61af66fc99e Initial load
duke
parents:
diff changeset
760 assert_different_registers(start, end);
a61af66fc99e Initial load
duke
parents:
diff changeset
761
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
762 __ lea(end, Address(start, count, Address::times_ptr, -wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
763 __ shrptr(start, CardTableModRefBS::card_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
764 __ shrptr(end, CardTableModRefBS::card_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
765 __ subptr(end, start); // end --> count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
766 __ BIND(L_loop);
249
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
767 intptr_t disp = (intptr_t) ct->byte_map_base;
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
768 Address cardtable(start, count, Address::times_1, disp);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
769 __ movb(cardtable, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
770 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 __ jcc(Assembler::greaterEqual, L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
773 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
775 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
776 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
777 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
782
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
783 // Copy 64 bytes chunks
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
784 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
785 // Inputs:
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
786 // from - source array address
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
787 // to_from - destination array address - from
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
788 // qword_count - 8-bytes element count, negative
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
789 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
790 void xmm_copy_forward(Register from, Register to_from, Register qword_count) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
791 assert( UseSSE >= 2, "supported cpu only" );
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
792 Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
793 // Copy 64-byte chunks
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
794 __ jmpb(L_copy_64_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
795 __ align(OptoLoopAlignment);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
796 __ BIND(L_copy_64_bytes_loop);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
797
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
798 if (UseUnalignedLoadStores) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
799 if (UseAVX >= 2) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
800 __ vmovdqu(xmm0, Address(from, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
801 __ vmovdqu(Address(from, to_from, Address::times_1, 0), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
802 __ vmovdqu(xmm1, Address(from, 32));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
803 __ vmovdqu(Address(from, to_from, Address::times_1, 32), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
804 } else {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
805 __ movdqu(xmm0, Address(from, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
806 __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
807 __ movdqu(xmm1, Address(from, 16));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
808 __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
809 __ movdqu(xmm2, Address(from, 32));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
810 __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
811 __ movdqu(xmm3, Address(from, 48));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
812 __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
813 }
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
814 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
815 __ movq(xmm0, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
816 __ movq(Address(from, to_from, Address::times_1, 0), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
817 __ movq(xmm1, Address(from, 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
818 __ movq(Address(from, to_from, Address::times_1, 8), xmm1);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
819 __ movq(xmm2, Address(from, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
820 __ movq(Address(from, to_from, Address::times_1, 16), xmm2);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
821 __ movq(xmm3, Address(from, 24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
822 __ movq(Address(from, to_from, Address::times_1, 24), xmm3);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
823 __ movq(xmm4, Address(from, 32));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
824 __ movq(Address(from, to_from, Address::times_1, 32), xmm4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
825 __ movq(xmm5, Address(from, 40));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
826 __ movq(Address(from, to_from, Address::times_1, 40), xmm5);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
827 __ movq(xmm6, Address(from, 48));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
828 __ movq(Address(from, to_from, Address::times_1, 48), xmm6);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
829 __ movq(xmm7, Address(from, 56));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
830 __ movq(Address(from, to_from, Address::times_1, 56), xmm7);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
831 }
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
832
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
833 __ addl(from, 64);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
834 __ BIND(L_copy_64_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
835 __ subl(qword_count, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
836 __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
8873
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
837
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
838 if (UseUnalignedLoadStores && (UseAVX >= 2)) {
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
839 // clean upper bits of YMM registers
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
840 __ vzeroupper();
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
841 }
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
842 __ addl(qword_count, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
843 __ jccb(Assembler::zero, L_exit);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
844 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
845 // length is too short, just copy qwords
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
846 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
847 __ BIND(L_copy_8_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
848 __ movq(xmm0, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
849 __ movq(Address(from, to_from, Address::times_1), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
850 __ addl(from, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
851 __ decrement(qword_count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
852 __ jcc(Assembler::greater, L_copy_8_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
853 __ BIND(L_exit);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
854 }
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
855
0
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // Copy 64 bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
857 //
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
859 // from - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // to_from - destination array address - from
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // qword_count - 8-bytes element count, negative
a61af66fc99e Initial load
duke
parents:
diff changeset
862 //
a61af66fc99e Initial load
duke
parents:
diff changeset
863 void mmx_copy_forward(Register from, Register to_from, Register qword_count) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
864 assert( VM_Version::supports_mmx(), "supported cpu only" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
865 Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // Copy 64-byte chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
867 __ jmpb(L_copy_64_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
868 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
869 __ BIND(L_copy_64_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
870 __ movq(mmx0, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
871 __ movq(mmx1, Address(from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
872 __ movq(mmx2, Address(from, 16));
a61af66fc99e Initial load
duke
parents:
diff changeset
873 __ movq(Address(from, to_from, Address::times_1, 0), mmx0);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 __ movq(mmx3, Address(from, 24));
a61af66fc99e Initial load
duke
parents:
diff changeset
875 __ movq(Address(from, to_from, Address::times_1, 8), mmx1);
a61af66fc99e Initial load
duke
parents:
diff changeset
876 __ movq(mmx4, Address(from, 32));
a61af66fc99e Initial load
duke
parents:
diff changeset
877 __ movq(Address(from, to_from, Address::times_1, 16), mmx2);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 __ movq(mmx5, Address(from, 40));
a61af66fc99e Initial load
duke
parents:
diff changeset
879 __ movq(Address(from, to_from, Address::times_1, 24), mmx3);
a61af66fc99e Initial load
duke
parents:
diff changeset
880 __ movq(mmx6, Address(from, 48));
a61af66fc99e Initial load
duke
parents:
diff changeset
881 __ movq(Address(from, to_from, Address::times_1, 32), mmx4);
a61af66fc99e Initial load
duke
parents:
diff changeset
882 __ movq(mmx7, Address(from, 56));
a61af66fc99e Initial load
duke
parents:
diff changeset
883 __ movq(Address(from, to_from, Address::times_1, 40), mmx5);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 __ movq(Address(from, to_from, Address::times_1, 48), mmx6);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 __ movq(Address(from, to_from, Address::times_1, 56), mmx7);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
886 __ addptr(from, 64);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
887 __ BIND(L_copy_64_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 __ subl(qword_count, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
889 __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
890 __ addl(qword_count, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 //
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // length is too short, just copy qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
894 //
a61af66fc99e Initial load
duke
parents:
diff changeset
895 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 __ movq(mmx0, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
897 __ movq(Address(from, to_from, Address::times_1), mmx0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
898 __ addptr(from, 8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
899 __ decrement(qword_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 __ jcc(Assembler::greater, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 __ emms();
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 address generate_disjoint_copy(BasicType t, bool aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
906 Address::ScaleFactor sf,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
907 address* entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
908 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
909 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
a61af66fc99e Initial load
duke
parents:
diff changeset
914 Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
915
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
916 int shift = Address::times_ptr - sf;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 const Register from = rsi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
919 const Register to = rdi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
920 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
921 const Register to_from = to; // (to - from)
a61af66fc99e Initial load
duke
parents:
diff changeset
922 const Register saved_to = rdx; // saved destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
925 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
926 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
927 __ movptr(from , Address(rsp, 12+ 4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
928 __ movptr(to , Address(rsp, 12+ 8));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
929 __ movl(count, Address(rsp, 12+ 12));
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
930
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
931 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
932 *entry = __ pc(); // Entry point from conjoint arraycopy stub.
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
933 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
934 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
935
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (t == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 __ testl(count, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
938 __ jcc(Assembler::zero, L_0_count);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
939 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
940 __ mov(saved_to, to); // save 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
943 __ subptr(to, from); // to --> to_from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
944 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
945 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
946 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // align source address at 4 bytes address boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
948 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // One byte misalignment happens only for byte arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
950 __ testl(from, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
951 __ jccb(Assembler::zero, L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
952 __ movb(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
953 __ movb(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 __ increment(from);
a61af66fc99e Initial load
duke
parents:
diff changeset
955 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 __ BIND(L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // Two bytes misalignment happens only for byte and short (char) arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
959 __ testl(from, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
960 __ jccb(Assembler::zero, L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 __ movw(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
962 __ movw(Address(from, to_from, Address::times_1, 0), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
963 __ addptr(from, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
964 __ subl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
965 __ BIND(L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967 if (!VM_Version::supports_mmx()) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
968 __ mov(rax, count); // save 'count'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
969 __ shrl(count, shift); // bytes count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
970 __ addptr(to_from, from);// restore 'to'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
971 __ rep_mov();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
972 __ subptr(to_from, from);// restore 'to_from'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
973 __ mov(count, rax); // restore 'count'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
974 __ jmpb(L_copy_2_bytes); // all dwords were copied
a61af66fc99e Initial load
duke
parents:
diff changeset
975 } else {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
976 if (!UseUnalignedLoadStores) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
977 // align to 8 bytes, we know we are 4 byte aligned to start
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
978 __ testptr(from, 4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
979 __ jccb(Assembler::zero, L_copy_64_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
980 __ movl(rax, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
981 __ movl(Address(from, to_from, Address::times_1, 0), rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
982 __ addptr(from, 4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
983 __ subl(count, 1<<shift);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
984 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
985 __ BIND(L_copy_64_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
986 __ mov(rax, count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
987 __ shrl(rax, shift+1); // 8 bytes chunk count
a61af66fc99e Initial load
duke
parents:
diff changeset
988 //
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // Copy 8-byte chunks through MMX registers, 8 per iteration of the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
990 //
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
991 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
992 xmm_copy_forward(from, to_from, rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
993 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
994 mmx_copy_forward(from, to_from, rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
995 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // copy tailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
998 __ BIND(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
999 __ testl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 __ movl(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 __ movl(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 if (t == T_BYTE || t == T_SHORT) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1004 __ addptr(from, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // copy tailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 __ testl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 __ movw(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 __ movw(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 if (t == T_BYTE) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1012 __ addptr(from, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // copy tailing byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 __ testl(count, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 __ movb(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 __ movb(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if (t == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 __ movl(count, Address(rsp, 12+12)); // reread 'count'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1029 __ mov(to, saved_to); // restore 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 __ BIND(L_0_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 inc_copy_counter_np(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1034 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1035 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1037 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1043 address generate_fill(BasicType t, bool aligned, const char *name) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1044 __ align(CodeEntryAlignment);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1045 StubCodeMark mark(this, "StubRoutines", name);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1046 address start = __ pc();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1047
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1048 BLOCK_COMMENT("Entry:");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1049
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1050 const Register to = rdi; // source array address
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1051 const Register value = rdx; // value
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1052 const Register count = rsi; // elements count
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1053
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1054 __ enter(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1055 __ push(rsi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1056 __ push(rdi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1057 __ movptr(to , Address(rsp, 12+ 4));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1058 __ movl(value, Address(rsp, 12+ 8));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1059 __ movl(count, Address(rsp, 12+ 12));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1060
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1061 __ generate_fill(t, aligned, to, value, count, rax, xmm0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1062
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1063 __ pop(rdi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1064 __ pop(rsi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1065 __ leave(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1066 __ ret(0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1067 return start;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1068 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1069
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 address generate_conjoint_copy(BasicType t, bool aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 Address::ScaleFactor sf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 address nooverlap_target,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1073 address* entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1074 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1078
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 Label L_copy_2_bytes, L_copy_4_bytes, L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1082 int shift = Address::times_ptr - sf;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 const Register src = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 const Register dst = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 const Register from = rsi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 const Register to = rdi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 const Register end = rax; // array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1092 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1093 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1094 __ movptr(src , Address(rsp, 12+ 4)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1095 __ movptr(dst , Address(rsp, 12+ 8)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1096 __ movl2ptr(count, Address(rsp, 12+12)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 *entry = __ pc(); // Entry point from generic arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1103 // nooverlap_target expects arguments in rsi and rdi.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1104 __ mov(from, src);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1105 __ mov(to , dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1107 // arrays overlap test: dispatch to disjoint stub if necessary.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 RuntimeAddress nooverlap(nooverlap_target);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1109 __ cmpptr(dst, src);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1110 __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 __ jump_cc(Assembler::belowEqual, nooverlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1112 __ cmpptr(dst, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 __ jump_cc(Assembler::aboveEqual, nooverlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1115 if (t == T_OBJECT) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1116 __ testl(count, count);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1117 __ jcc(Assembler::zero, L_0_count);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1118 gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1119 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1120
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // copy from high to low
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 if (t == T_BYTE || t == T_SHORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // Align the end of destination array at 4 bytes address boundary
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1126 __ lea(end, Address(dst, count, sf, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // One byte misalignment happens only for byte arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 __ testl(end, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 __ jccb(Assembler::zero, L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 __ movb(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 __ movb(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 __ BIND(L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Two bytes misalignment happens only for byte and short (char) arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 __ testl(end, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 __ jccb(Assembler::zero, L_skip_align2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1139 __ subptr(count, 1<<(shift-1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 __ movw(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 __ movw(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 __ BIND(L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 __ jcc(Assembler::below, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 if (!VM_Version::supports_mmx()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 __ std();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1149 __ mov(rax, count); // Save 'count'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1150 __ mov(rdx, to); // Save 'to'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1151 __ lea(rsi, Address(from, count, sf, -4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1152 __ lea(rdi, Address(to , count, sf, -4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1153 __ shrptr(count, shift); // bytes count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1154 __ rep_mov();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 __ cld();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1156 __ mov(count, rax); // restore 'count'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 __ andl(count, (1<<shift)-1); // mask the number of rest elements
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1158 __ movptr(from, Address(rsp, 12+4)); // reread 'from'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1159 __ mov(to, rdx); // restore 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 __ jmpb(L_copy_2_bytes); // all dword were copied
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // Align to 8 bytes the end of array. It is aligned to 4 bytes already.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1163 __ testptr(end, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 __ jccb(Assembler::zero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 __ subl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 __ movl(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 __ movl(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 __ jmpb(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1169
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1170 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // Move 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 __ BIND(L_copy_8_bytes_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1173 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1174 __ movq(xmm0, Address(from, count, sf, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1175 __ movq(Address(to, count, sf, 0), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1176 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1177 __ movq(mmx0, Address(from, count, sf, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1178 __ movq(Address(to, count, sf, 0), mmx0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1179 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 __ subl(count, 2<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 __ addl(count, 2<<shift);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1184 if (!UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1185 __ emms();
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1186 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 __ BIND(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // copy prefix qword
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 __ testl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 __ movl(rdx, Address(from, count, sf, -4));
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 __ movl(Address(to, count, sf, -4), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 if (t == T_BYTE || t == T_SHORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ subl(count, (1<<shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // copy prefix dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 __ testl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 __ movw(rdx, Address(from, count, sf, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 __ movw(Address(to, count, sf, -2), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 __ subl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // copy prefix byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 __ testl(count, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 __ movb(rdx, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 __ movb(Address(to, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 if (t == T_OBJECT) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1219 __ movl2ptr(count, Address(rsp, 12+12)); // reread count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 __ BIND(L_0_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 inc_copy_counter_np(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1224 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1225 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1227 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 address generate_disjoint_long_copy(address* entry, const char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 Label L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 const Register to_from = rdx; // (to - from)
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1245 __ movptr(from , Address(rsp, 8+0)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1246 __ movptr(to , Address(rsp, 8+4)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1247 __ movl2ptr(count, Address(rsp, 8+8)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 *entry = __ pc(); // Entry point from conjoint arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1252 __ subptr(to, from); // to --> to_from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 if (VM_Version::supports_mmx()) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1254 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1255 xmm_copy_forward(from, to_from, count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1256 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1257 mmx_copy_forward(from, to_from, count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1258 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 __ jmpb(L_copy_8_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1261 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 __ BIND(L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 __ fild_d(Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 __ fistp_d(Address(from, to_from, Address::times_1));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1265 __ addptr(from, 8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 inc_copy_counter_np(T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1272 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 address generate_conjoint_long_copy(address nooverlap_target,
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 address* entry, const char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 Label L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 const Register end_from = rax; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1288
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1290 __ movptr(from , Address(rsp, 8+0)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1291 __ movptr(to , Address(rsp, 8+4)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1292 __ movl2ptr(count, Address(rsp, 8+8)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1293
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 *entry = __ pc(); // Entry point from generic arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // arrays overlap test
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1298 __ cmpptr(to, from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 RuntimeAddress nooverlap(nooverlap_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 __ jump_cc(Assembler::belowEqual, nooverlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1301 __ lea(end_from, Address(from, count, Address::times_8, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1302 __ cmpptr(to, end_from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1303 __ movptr(from, Address(rsp, 8)); // from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 __ jump_cc(Assembler::aboveEqual, nooverlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 __ jmpb(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1308 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 __ BIND(L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 if (VM_Version::supports_mmx()) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1311 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1312 __ movq(xmm0, Address(from, count, Address::times_8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1313 __ movq(Address(to, count, Address::times_8), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1314 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1315 __ movq(mmx0, Address(from, count, Address::times_8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1316 __ movq(Address(to, count, Address::times_8), mmx0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1317 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 __ fild_d(Address(from, count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 __ fistp_d(Address(to, count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1326 if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 __ emms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 inc_copy_counter_np(T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1331 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 // Helper for generating a dynamic type check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // The sub_klass must be one of {rbx, rdx, rsi}.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // The temp is killed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 void generate_type_check(Register sub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 Address& super_check_offset_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 Address& super_klass_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 Register temp,
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1344 Label* L_success, Label* L_failure) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 BLOCK_COMMENT("type_check:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 Label L_fallthrough;
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1348 #define LOCAL_JCC(assembler_con, label_ptr) \
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1349 if (label_ptr != NULL) __ jcc(assembler_con, *(label_ptr)); \
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1350 else __ jcc(assembler_con, L_fallthrough) /*omit semi*/
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1352 // The following is a strange variation of the fast path which requires
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1353 // one less register, because needed values are on the argument stack.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1354 // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1355 // L_success, L_failure, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 assert_different_registers(sub_klass, temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3960
diff changeset
1358 int sc_offset = in_bytes(Klass::secondary_super_cache_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // if the pointers are equal, we are done (e.g., String[] elements)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1361 __ cmpptr(sub_klass, super_klass_addr);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1362 LOCAL_JCC(Assembler::equal, L_success);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // check the supertype display:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1365 __ movl2ptr(temp, super_check_offset_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 Address super_check_addr(sub_klass, temp, Address::times_1, 0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1367 __ movptr(temp, super_check_addr); // load displayed supertype
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1368 __ cmpptr(temp, super_klass_addr); // test the super type
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1369 LOCAL_JCC(Assembler::equal, L_success);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1370
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // if it was a primary super, we can just fail immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 __ cmpl(super_check_offset_addr, sc_offset);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1373 LOCAL_JCC(Assembler::notEqual, L_failure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1374
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1375 // The repne_scan instruction uses fixed registers, which will get spilled.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1376 // We happen to know this works best when super_klass is in rax.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1377 Register super_klass = temp;
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1378 __ movptr(super_klass, super_klass_addr);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1379 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1380 L_success, L_failure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1382 __ bind(L_fallthrough);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1384 if (L_success == NULL) { BLOCK_COMMENT("L_success:"); }
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1385 if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1386
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1387 #undef LOCAL_JCC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // Generate checkcasting array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // 4(rsp) - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // 8(rsp) - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // 12(rsp) - element count, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // 16(rsp) - size_t ckoff (super_check_offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 // 20(rsp) - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // rax, == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1404 address generate_checkcast_copy(const char *name, address* entry, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 Label L_load_element, L_store_element, L_do_card_marks, L_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // register use:
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // rax, rdx, rcx -- loop control (end_from, end_to, count)
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // rdi, rsi -- element access (oop, klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // rbx, -- temp
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 const Register length = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 const Register elem = rdi; // each oop copied
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 const Register elem_klass = rsi; // each elem._klass (sub_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 const Register temp = rbx; // lone remaining temp
a61af66fc99e Initial load
duke
parents:
diff changeset
1421
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1424 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1425 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1426 __ push(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 Address from_arg(rsp, 16+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 Address to_arg(rsp, 16+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 Address length_arg(rsp, 16+12); // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 Address ckoff_arg(rsp, 16+16); // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 Address ckval_arg(rsp, 16+20); // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1433
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // Load up:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1435 __ movptr(from, from_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1436 __ movptr(to, to_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1437 __ movl2ptr(length, length_arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1438
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1439 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1440 *entry = __ pc(); // Entry point from generic arraycopy stub.
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1441 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1442 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 //---------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // if the two arrays are subtypes of Object[] but the
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // destination array type is not equal to or a supertype
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // of the source type. Each element must be separately
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Loop-invariant addresses. They are exclusive end pointers.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1452 Address end_from_addr(from, length, Address::times_ptr, 0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1453 Address end_to_addr(to, length, Address::times_ptr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1454
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 Register end_from = from; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 Register end_to = to; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 Register count = length; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Loop-variant addresses. They assume post-incremented count < 0.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1460 Address from_element_addr(end_from, count, Address::times_ptr, 0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1461 Address to_element_addr(end_to, count, Address::times_ptr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // Copy from low to high addresses, indexed from the end of each array.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1465 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1466 __ lea(end_from, end_from_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1467 __ lea(end_to, end_to_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 assert(length == count, ""); // else fix next line:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1469 __ negptr(count); // negate and test the length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 __ jccb(Assembler::notZero, L_load_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
1471
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // Empty array: Nothing to do.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1473 __ xorptr(rax, rax); // return 0 on (trivial) success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 __ jmp(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // ======== begin loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // (Loop is rotated; its entry is L_load_element.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // Loop control:
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // for (count = -count; count != 0; count++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // Base pointers src, dst are biased by 8*count,to last element.
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1481 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 __ BIND(L_store_element);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1484 __ movptr(to_element_addr, elem); // store the oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 __ increment(count); // increment the count toward zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 __ jccb(Assembler::zero, L_do_card_marks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // ======== loop entry is here ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 __ BIND(L_load_element);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1490 __ movptr(elem, from_element_addr); // load the oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1491 __ testptr(elem, elem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 __ jccb(Assembler::zero, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
1493
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // (Could do a trick here: Remember last successful non-null
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 // element stored and make a quick oop equality check on it.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1496
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1497 __ movptr(elem_klass, elem_klass_addr); // query the object klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 &L_store_element, NULL);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1500 // (On fall-through, we have failed the element type check.)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // ======== end loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // It was a real error; we must depend on the caller to finish the job.
19
a73cc31728fe 6614036: REGRESSION: Java server x86 VM intermittently crash with SIGSEGV (0xb)
rasbold
parents: 16
diff changeset
1504 // Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops.
a73cc31728fe 6614036: REGRESSION: Java server x86 VM intermittently crash with SIGSEGV (0xb)
rasbold
parents: 16
diff changeset
1505 // Emit GC store barriers for the oops we have copied (length_arg + count),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // and report their number to the caller.
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1507 assert_different_registers(to, count, rax);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1508 Label L_post_barrier;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 __ addl(count, length_arg); // transfers = (length - remaining)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1510 __ movl2ptr(rax, count); // save the value
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1511 __ notptr(rax); // report (-1^K) to caller (does not affect flags)
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1512 __ jccb(Assembler::notZero, L_post_barrier);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1513 __ jmp(L_done); // K == 0, nothing was copied, skip post barrier
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1514
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // Come here on success only.
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 __ BIND(L_do_card_marks);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1517 __ xorptr(rax, rax); // return 0 on success
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1518 __ movl2ptr(count, length_arg);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1519
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1520 __ BIND(L_post_barrier);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1521 __ movptr(to, to_arg); // reload
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // Common exit point (success or failure).
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 __ BIND(L_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1526 __ pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1527 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1528 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1535
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Generate 'unsafe' array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // Though just as safe as the other stubs, it takes an unscaled
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // size_t argument instead of an element count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // 4(rsp) - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // 8(rsp) - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // 12(rsp) - byte count, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // rax, == -1 - need to call System.arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // Examines the alignment of the operands and dispatches
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // to a long, int, short, or byte copy loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 address generate_unsafe_copy(const char *name,
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 address byte_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 address short_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 address int_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 address long_copy_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1558
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 Label L_long_aligned, L_int_aligned, L_short_aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1564
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1568
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1570 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1571 __ push(rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 Address from_arg(rsp, 12+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 Address to_arg(rsp, 12+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 Address count_arg(rsp, 12+12); // byte count
a61af66fc99e Initial load
duke
parents:
diff changeset
1575
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // Load up:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1577 __ movptr(from , from_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1578 __ movptr(to , to_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1579 __ movl2ptr(count, count_arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1580
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 const Register bits = rsi;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1585 __ mov(bits, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1586 __ orptr(bits, to);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1587 __ orptr(bits, count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 __ testl(bits, BytesPerLong-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 __ jccb(Assembler::zero, L_long_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
1591
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 __ testl(bits, BytesPerInt-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 __ jccb(Assembler::zero, L_int_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 __ testl(bits, BytesPerShort-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1597
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 __ BIND(L_short_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1599 __ shrptr(count, LogBytesPerShort); // size => short_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 __ movl(count_arg, count); // update 'count'
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1602
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 __ BIND(L_int_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1604 __ shrptr(count, LogBytesPerInt); // size => int_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 __ movl(count_arg, count); // update 'count'
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1607
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 __ BIND(L_long_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1609 __ shrptr(count, LogBytesPerLong); // size => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 __ movl(count_arg, count); // update 'count'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1611 __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1612 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1614
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 // Perform range checks on the proposed arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // Smashes src_pos and dst_pos. (Uses them up for temps.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 void arraycopy_range_checks(Register src,
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 Register src_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 Register dst,
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 Register dst_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 Address& length,
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 Label& L_failed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 BLOCK_COMMENT("arraycopy_range_checks:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 const Register src_end = src_pos; // source array end position
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 const Register dst_end = dst_pos; // destination array end position
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 __ addl(src_end, length); // src_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 __ addl(dst_end, length); // dst_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // if (src_pos + length > arrayOop(src)->length() ) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 __ cmpl(src_end, Address(src, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1636
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // if (dst_pos + length > arrayOop(dst)->length() ) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 __ cmpl(dst_end, Address(dst, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1640
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 BLOCK_COMMENT("arraycopy_range_checks done");
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // Generate generic array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // 4(rsp) - src oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // 8(rsp) - src_pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // 12(rsp) - dst oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // 16(rsp) - dst_pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // 20(rsp) - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // rax, == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 address generate_generic_copy(const char *name,
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 address entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 address entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 address entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 address entry_oop_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 address entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 address entry_checkcast_arraycopy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 Label L_failed, L_failed_0, L_objArray;
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 { int modulus = CodeEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 int target = modulus - 5; // 5 = sizeof jmp(L_failed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 int advance = target - (__ offset() % modulus);
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 if (advance < 0) advance += modulus;
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 if (advance > 0) __ nop(advance);
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // Short-hop target to L_failed. Makes for denser prologue code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 __ BIND(L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 __ jmp(L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 assert(__ offset() % CodeEntryAlignment == 0, "no further alignment needed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1680
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1683
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1685 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1686 __ push(rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 inc_counter_np(SharedRuntime::_generic_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // Input values
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 Address SRC (rsp, 12+ 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 Address SRC_POS (rsp, 12+ 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 Address DST (rsp, 12+12);
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 Address DST_POS (rsp, 12+16);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 Address LENGTH (rsp, 12+20);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 //-----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // if the following conditions are met:
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // (1) src and dst must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // (2) src_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // (3) dst_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // (4) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // (5) src klass and dst klass should be the same and not NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // (6) src and dst should be arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // (7) src_pos + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // (8) dst_pos + length must not exceed length of dst.
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1711
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 const Register src = rax; // source array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 const Register src_pos = rsi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 const Register dst = rdx; // destination array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 const Register dst_pos = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 const Register length = rcx; // transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1717
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // if (src == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1719 __ movptr(src, SRC); // src oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1720 __ testptr(src, src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // if (src_pos < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1724 __ movl2ptr(src_pos, SRC_POS); // src_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 __ testl(src_pos, src_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1727
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // if (dst == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1729 __ movptr(dst, DST); // dst oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1730 __ testptr(dst, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1732
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // if (dst_pos < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1734 __ movl2ptr(dst_pos, DST_POS); // dst_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 __ testl(dst_pos, dst_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // if (length < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1739 __ movl2ptr(length, LENGTH); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 __ testl(length, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1742
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // if (src->klass() == NULL) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 Address src_klass_addr(src, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 Address dst_klass_addr(dst, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 const Register rcx_src_klass = rcx; // array klass
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1747 __ movptr(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1748
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // assert(src->klass() != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 BLOCK_COMMENT("assert klasses not null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 { Label L1, L2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1753 __ testptr(rcx_src_klass, rcx_src_klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 __ jccb(Assembler::notZero, L2); // it is broken if klass is NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 __ bind(L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 __ stop("broken null klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 __ bind(L2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1758 __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 __ jccb(Assembler::equal, L1); // this would be broken also
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 BLOCK_COMMENT("assert done");
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // Load layout helper (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 // |array_tag| | header_size | element_type | |log2_element_size|
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // 32 30 24 16 8 2 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1771
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3960
diff changeset
1772 int lh_offset = in_bytes(Klass::layout_helper_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 Address src_klass_lh_addr(rcx_src_klass, lh_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1774
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // Handle objArrays completely differently...
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 __ cmpl(src_klass_lh_addr, objArray_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 __ jcc(Assembler::equal, L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
1779
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 // if (src->klass() != dst->klass()) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1781 __ cmpptr(rcx_src_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 __ jccb(Assembler::notEqual, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1783
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 const Register rcx_lh = rcx; // layout helper
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 assert(rcx_lh == rcx_src_klass, "known alias");
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 __ movl(rcx_lh, src_klass_lh_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // if (!src->is_Array()) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 __ cmpl(rcx_lh, Klass::_lh_neutral_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 __ jcc(Assembler::greaterEqual, L_failed_0); // signed cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1791
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 // At this point, it is known to be a typeArray (array_tag 0x3).
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 __ cmpl(rcx_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 __ jcc(Assembler::greaterEqual, L); // signed cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 __ stop("must be a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 assert_different_registers(src, src_pos, dst, dst_pos, rcx_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1804
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
1805 // TypeArrayKlass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 const Register rsi_offset = rsi; // array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 const Register src_array = src; // src array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 const Register dst_array = dst; // dst array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 const Register rdi_elsize = rdi; // log2 element size
a61af66fc99e Initial load
duke
parents:
diff changeset
1814
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1815 __ mov(rsi_offset, rcx_lh);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1816 __ shrptr(rsi_offset, Klass::_lh_header_size_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1817 __ andptr(rsi_offset, Klass::_lh_header_size_mask); // array_offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1818 __ addptr(src_array, rsi_offset); // src array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1819 __ addptr(dst_array, rsi_offset); // dst array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1820 __ andptr(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1821
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // next registers should be set before the jump to corresponding stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 const Register from = src; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 const Register to = dst; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // some of them should be duplicated on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 #define FROM Address(rsp, 12+ 4)
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 #define TO Address(rsp, 12+ 8) // Not used now
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 #define COUNT Address(rsp, 12+12) // Only for oop arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 BLOCK_COMMENT("scale indexes to element size");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1832 __ movl2ptr(rsi, SRC_POS); // src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1833 __ shlptr(rsi); // src_pos << rcx (log2 elsize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 assert(src_array == from, "");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1835 __ addptr(from, rsi); // from = src_array + SRC_POS << log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1836 __ movl2ptr(rdi, DST_POS); // dst_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1837 __ shlptr(rdi); // dst_pos << rcx (log2 elsize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 assert(dst_array == to, "");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1839 __ addptr(to, rdi); // to = dst_array + DST_POS << log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1840 __ movptr(FROM, from); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1841 __ mov(rdi_elsize, rcx_lh); // log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1842 __ movl2ptr(count, LENGTH); // elements count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 BLOCK_COMMENT("choose copy loop based on element size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 __ cmpl(rdi_elsize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jbyte_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 __ cmpl(rdi_elsize, LogBytesPerShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jshort_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 __ cmpl(rdi_elsize, LogBytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jint_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 __ cmpl(rdi_elsize, LogBytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 __ jccb(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1856 __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1857 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 __ jump(RuntimeAddress(entry_jlong_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 __ BIND(L_failed);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1861 __ xorptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1862 __ notptr(rax); // return -1
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1863 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1864 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1867
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
1868 // ObjArrayKlass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 __ BIND(L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // live at this point: rcx_src_klass, src[_pos], dst[_pos]
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 Label L_plain_copy, L_checkcast_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // test array classes for subtyping
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1874 __ cmpptr(rcx_src_klass, dst_klass_addr); // usual case is exact equality
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 __ jccb(Assembler::notEqual, L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1876
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 // Identically typed arrays can be copied without element-wise checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 assert_different_registers(src, src_pos, dst, dst_pos, rcx_src_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1880
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 __ BIND(L_plain_copy);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1882 __ movl2ptr(count, LENGTH); // elements count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1883 __ movl2ptr(src_pos, SRC_POS); // reload src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1884 __ lea(from, Address(src, src_pos, Address::times_ptr,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1885 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1886 __ movl2ptr(dst_pos, DST_POS); // reload dst_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1887 __ lea(to, Address(dst, dst_pos, Address::times_ptr,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1888 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1889 __ movptr(FROM, from); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1890 __ movptr(TO, to); // dst_addr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 __ movl(COUNT, count); // count
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 __ jump(RuntimeAddress(entry_oop_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1893
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 __ BIND(L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // live at this point: rcx_src_klass, dst[_pos], src[_pos]
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // Handy offsets:
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
1898 int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3960
diff changeset
1899 int sco_offset = in_bytes(Klass::super_check_offset_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1900
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 Register rsi_dst_klass = rsi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 Register rdi_temp = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 assert(rsi_dst_klass == src_pos, "expected alias w/ src_pos");
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 assert(rdi_temp == dst_pos, "expected alias w/ dst_pos");
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 Address dst_klass_lh_addr(rsi_dst_klass, lh_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1906
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 // Before looking at dst.length, make sure dst is also an objArray.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1908 __ movptr(rsi_dst_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 __ cmpl(dst_klass_lh_addr, objArray_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 __ jccb(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 // It is safe to examine both src.length and dst.length.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1913 __ movl2ptr(src_pos, SRC_POS); // reload rsi
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // (Now src_pos and dst_pos are killed, but not src and dst.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1916
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 // We'll need this temp (don't forget to pop it after the type check).
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1918 __ push(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 Register rbx_src_klass = rbx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1920
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1921 __ mov(rbx_src_klass, rcx_src_klass); // spill away from rcx
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1922 __ movptr(rsi_dst_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 Address super_check_offset_addr(rsi_dst_klass, sco_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 Label L_fail_array_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 generate_type_check(rbx_src_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 super_check_offset_addr, dst_klass_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 rdi_temp, NULL, &L_fail_array_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 // (On fall-through, we have passed the array type check.)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1929 __ pop(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 __ jmp(L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ BIND(L_fail_array_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // Reshuffle arguments so we can call checkcast_arraycopy:
a61af66fc99e Initial load
duke
parents:
diff changeset
1934
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // match initial saves for checkcast_arraycopy
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1936 // push(rsi); // already done; see above
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1937 // push(rdi); // already done; see above
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1938 // push(rbx); // already done; see above
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1939
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // Marshal outgoing arguments now, freeing registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 Address from_arg(rsp, 16+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 Address to_arg(rsp, 16+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 Address length_arg(rsp, 16+12); // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 Address ckoff_arg(rsp, 16+16); // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 Address ckval_arg(rsp, 16+20); // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1946
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 Address SRC_POS_arg(rsp, 16+ 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 Address DST_POS_arg(rsp, 16+16);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 Address LENGTH_arg(rsp, 16+20);
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // push rbx, changed the incoming offsets (why not just use rbp,??)
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // assert(SRC_POS_arg.disp() == SRC_POS.disp() + 4, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1952
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1953 __ movptr(rbx, Address(rsi_dst_klass, ek_offset));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1954 __ movl2ptr(length, LENGTH_arg); // reload elements count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1955 __ movl2ptr(src_pos, SRC_POS_arg); // reload src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1956 __ movl2ptr(dst_pos, DST_POS_arg); // reload dst_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1958 __ movptr(ckval_arg, rbx); // destination element type
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 __ movl(rbx, Address(rbx, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 __ movl(ckoff_arg, rbx); // corresponding class check offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 __ movl(length_arg, length); // outgoing length argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1963
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1964 __ lea(from, Address(src, src_pos, Address::times_ptr,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1966 __ movptr(from_arg, from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1968 __ lea(to, Address(dst, dst_pos, Address::times_ptr,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1970 __ movptr(to_arg, to);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 __ jump(RuntimeAddress(entry_checkcast_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1973
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1976
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 void generate_arraycopy_stubs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 address entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 address entry_jbyte_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 address entry_jshort_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 address entry_jint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 address entry_oop_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 address entry_jlong_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 address entry_checkcast_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1985
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 generate_disjoint_copy(T_BYTE, true, Address::times_1, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 "arrayof_jbyte_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 StubRoutines::_arrayof_jbyte_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 generate_conjoint_copy(T_BYTE, true, Address::times_1, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 NULL, "arrayof_jbyte_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 StubRoutines::_jbyte_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 generate_disjoint_copy(T_BYTE, false, Address::times_1, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 "jbyte_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 StubRoutines::_jbyte_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 generate_conjoint_copy(T_BYTE, false, Address::times_1, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 &entry_jbyte_arraycopy, "jbyte_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
1998
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 StubRoutines::_arrayof_jshort_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 generate_disjoint_copy(T_SHORT, true, Address::times_2, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 "arrayof_jshort_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 StubRoutines::_arrayof_jshort_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 generate_conjoint_copy(T_SHORT, true, Address::times_2, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 NULL, "arrayof_jshort_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 StubRoutines::_jshort_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 generate_disjoint_copy(T_SHORT, false, Address::times_2, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 "jshort_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 StubRoutines::_jshort_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 generate_conjoint_copy(T_SHORT, false, Address::times_2, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 &entry_jshort_arraycopy, "jshort_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 // Next arrays are always aligned on 4 bytes at least.
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 StubRoutines::_jint_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 generate_disjoint_copy(T_INT, true, Address::times_4, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 "jint_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 StubRoutines::_jint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 generate_conjoint_copy(T_INT, true, Address::times_4, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 &entry_jint_arraycopy, "jint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2019
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 StubRoutines::_oop_disjoint_arraycopy =
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2021 generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 "oop_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 StubRoutines::_oop_arraycopy =
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2024 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 &entry_oop_arraycopy, "oop_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2027 StubRoutines::_oop_disjoint_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2028 generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2029 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2030 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2031 StubRoutines::_oop_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2032 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2033 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2034 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2035
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 StubRoutines::_jlong_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 StubRoutines::_jlong_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 "jlong_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2042 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2043 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2044 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2045 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2046 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2047 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2048
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2049 StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2050 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2051 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2052 StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2054 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2055 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2056 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2057 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 StubRoutines::_checkcast_arraycopy =
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2060 generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2061 StubRoutines::_checkcast_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2062 generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, /*dest_uninitialized*/true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 StubRoutines::_unsafe_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 generate_unsafe_copy("unsafe_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 entry_jlong_arraycopy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 StubRoutines::_generic_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 generate_generic_copy("generic_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 entry_oop_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 entry_checkcast_arraycopy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2081 void generate_math_stubs() {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2082 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2083 StubCodeMark mark(this, "StubRoutines", "log");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2084 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2085
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2086 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2087 __ flog();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2088 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2089 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2090 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2091 StubCodeMark mark(this, "StubRoutines", "log10");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2092 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2093
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2094 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2095 __ flog10();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2096 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2097 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2098 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2099 StubCodeMark mark(this, "StubRoutines", "sin");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2100 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2101
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2102 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2103 __ trigfunc('s');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2104 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2105 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2106 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2107 StubCodeMark mark(this, "StubRoutines", "cos");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2108 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2109
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2110 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2111 __ trigfunc('c');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2112 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2113 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2114 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2115 StubCodeMark mark(this, "StubRoutines", "tan");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2116 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2117
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2118 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2119 __ trigfunc('t');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2120 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2121 }
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2122 {
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2123 StubCodeMark mark(this, "StubRoutines", "exp");
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2124 StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2125
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2126 __ fld_d(Address(rsp, 4));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2127 __ exp_with_fallback(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2128 __ ret(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2129 }
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2130 {
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2131 StubCodeMark mark(this, "StubRoutines", "pow");
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2132 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2133
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2134 __ fld_d(Address(rsp, 12));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2135 __ fld_d(Address(rsp, 4));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2136 __ pow_with_fallback(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2137 __ ret(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 4771
diff changeset
2138 }
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2139 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2140
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2141 // AES intrinsic stubs
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2142 enum {AESBlockSize = 16};
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2143
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2144 address generate_key_shuffle_mask() {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2145 __ align(16);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2146 StubCodeMark mark(this, "StubRoutines", "key_shuffle_mask");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2147 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2148 __ emit_data(0x00010203, relocInfo::none, 0 );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2149 __ emit_data(0x04050607, relocInfo::none, 0 );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2150 __ emit_data(0x08090a0b, relocInfo::none, 0 );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2151 __ emit_data(0x0c0d0e0f, relocInfo::none, 0 );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2152 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2153 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2154
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2155 // Utility routine for loading a 128-bit key word in little endian format
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2156 // can optionally specify that the shuffle mask is already in an xmmregister
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2157 void load_key(XMMRegister xmmdst, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2158 __ movdqu(xmmdst, Address(key, offset));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2159 if (xmm_shuf_mask != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2160 __ pshufb(xmmdst, xmm_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2161 } else {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2162 __ pshufb(xmmdst, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2163 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2164 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2165
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2166 // aesenc using specified key+offset
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2167 // can optionally specify that the shuffle mask is already in an xmmregister
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2168 void aes_enc_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2169 load_key(xmmtmp, key, offset, xmm_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2170 __ aesenc(xmmdst, xmmtmp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2171 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2172
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2173 // aesdec using specified key+offset
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2174 // can optionally specify that the shuffle mask is already in an xmmregister
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2175 void aes_dec_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2176 load_key(xmmtmp, key, offset, xmm_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2177 __ aesdec(xmmdst, xmmtmp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2178 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2179
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2180
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2181 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2182 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2183 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2184 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2185 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2186 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2187 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2188 address generate_aescrypt_encryptBlock() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2189 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2190 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2191 StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2192 Label L_doLast;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2193 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2194
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2195 const Register from = rdx; // source array address
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2196 const Register to = rdx; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2197 const Register key = rcx; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2198 const Register keylen = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2199 const Address from_param(rbp, 8+0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2200 const Address to_param (rbp, 8+4);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2201 const Address key_param (rbp, 8+8);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2202
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2203 const XMMRegister xmm_result = xmm0;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2204 const XMMRegister xmm_key_shuf_mask = xmm1;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2205 const XMMRegister xmm_temp1 = xmm2;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2206 const XMMRegister xmm_temp2 = xmm3;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2207 const XMMRegister xmm_temp3 = xmm4;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2208 const XMMRegister xmm_temp4 = xmm5;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2209
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2210 __ enter(); // required for proper stackwalking of RuntimeStub frame
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2211 __ movptr(from, from_param);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2212 __ movptr(key, key_param);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2213
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2214 // keylen could be only {11, 13, 15} * 4 = {44, 52, 60}
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2215 __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2216
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2217 __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2218 __ movdqu(xmm_result, Address(from, 0)); // get 16 bytes of input
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2219 __ movptr(to, to_param);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2220
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2221 // For encryption, the java expanded key ordering is just what we need
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2222
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2223 load_key(xmm_temp1, key, 0x00, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2224 __ pxor(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2225
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2226 load_key(xmm_temp1, key, 0x10, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2227 load_key(xmm_temp2, key, 0x20, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2228 load_key(xmm_temp3, key, 0x30, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2229 load_key(xmm_temp4, key, 0x40, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2230
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2231 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2232 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2233 __ aesenc(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2234 __ aesenc(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2235
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2236 load_key(xmm_temp1, key, 0x50, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2237 load_key(xmm_temp2, key, 0x60, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2238 load_key(xmm_temp3, key, 0x70, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2239 load_key(xmm_temp4, key, 0x80, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2240
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2241 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2242 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2243 __ aesenc(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2244 __ aesenc(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2245
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2246 load_key(xmm_temp1, key, 0x90, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2247 load_key(xmm_temp2, key, 0xa0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2248
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2249 __ cmpl(keylen, 44);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2250 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2251
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2252 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2253 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2254
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2255 load_key(xmm_temp1, key, 0xb0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2256 load_key(xmm_temp2, key, 0xc0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2257
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2258 __ cmpl(keylen, 52);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2259 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2260
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2261 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2262 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2263
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2264 load_key(xmm_temp1, key, 0xd0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2265 load_key(xmm_temp2, key, 0xe0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2266
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2267 __ BIND(L_doLast);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2268 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2269 __ aesenclast(xmm_result, xmm_temp2);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2270 __ movdqu(Address(to, 0), xmm_result); // store the result
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2271 __ xorptr(rax, rax); // return 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2272 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2273 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2274
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2275 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2276 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2277
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2278
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2279 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2280 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2281 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2282 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2283 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2284 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2285 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2286 address generate_aescrypt_decryptBlock() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2287 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2288 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2289 StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2290 Label L_doLast;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2291 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2292
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2293 const Register from = rdx; // source array address
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2294 const Register to = rdx; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2295 const Register key = rcx; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2296 const Register keylen = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2297 const Address from_param(rbp, 8+0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2298 const Address to_param (rbp, 8+4);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2299 const Address key_param (rbp, 8+8);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2300
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2301 const XMMRegister xmm_result = xmm0;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2302 const XMMRegister xmm_key_shuf_mask = xmm1;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2303 const XMMRegister xmm_temp1 = xmm2;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2304 const XMMRegister xmm_temp2 = xmm3;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2305 const XMMRegister xmm_temp3 = xmm4;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2306 const XMMRegister xmm_temp4 = xmm5;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2307
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2308 __ enter(); // required for proper stackwalking of RuntimeStub frame
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2309 __ movptr(from, from_param);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2310 __ movptr(key, key_param);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2311
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2312 // keylen could be only {11, 13, 15} * 4 = {44, 52, 60}
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2313 __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2314
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2315 __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2316 __ movdqu(xmm_result, Address(from, 0));
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2317 __ movptr(to, to_param);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2318
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2319 // for decryption java expanded key ordering is rotated one position from what we want
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2320 // so we start from 0x10 here and hit 0x00 last
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2321 // we don't know if the key is aligned, hence not using load-execute form
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2322 load_key(xmm_temp1, key, 0x10, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2323 load_key(xmm_temp2, key, 0x20, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2324 load_key(xmm_temp3, key, 0x30, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2325 load_key(xmm_temp4, key, 0x40, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2326
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2327 __ pxor (xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2328 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2329 __ aesdec(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2330 __ aesdec(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2331
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2332 load_key(xmm_temp1, key, 0x50, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2333 load_key(xmm_temp2, key, 0x60, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2334 load_key(xmm_temp3, key, 0x70, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2335 load_key(xmm_temp4, key, 0x80, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2336
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2337 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2338 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2339 __ aesdec(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2340 __ aesdec(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2341
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2342 load_key(xmm_temp1, key, 0x90, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2343 load_key(xmm_temp2, key, 0xa0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2344 load_key(xmm_temp3, key, 0x00, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2345
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2346 __ cmpl(keylen, 44);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2347 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2348
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2349 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2350 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2351
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2352 load_key(xmm_temp1, key, 0xb0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2353 load_key(xmm_temp2, key, 0xc0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2354
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2355 __ cmpl(keylen, 52);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2356 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2357
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2358 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2359 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2360
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2361 load_key(xmm_temp1, key, 0xd0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2362 load_key(xmm_temp2, key, 0xe0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2363
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2364 __ BIND(L_doLast);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2365 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2366 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2367
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2368 // for decryption the aesdeclast operation is always on key+0x00
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2369 __ aesdeclast(xmm_result, xmm_temp3);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2370 __ movdqu(Address(to, 0), xmm_result); // store the result
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2371 __ xorptr(rax, rax); // return 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2372 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2373 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2374
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2375 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2376 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2377
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2378 void handleSOERegisters(bool saving) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2379 const int saveFrameSizeInBytes = 4 * wordSize;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2380 const Address saved_rbx (rbp, -3 * wordSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2381 const Address saved_rsi (rbp, -2 * wordSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2382 const Address saved_rdi (rbp, -1 * wordSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2383
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2384 if (saving) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2385 __ subptr(rsp, saveFrameSizeInBytes);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2386 __ movptr(saved_rsi, rsi);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2387 __ movptr(saved_rdi, rdi);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2388 __ movptr(saved_rbx, rbx);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2389 } else {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2390 // restoring
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2391 __ movptr(rsi, saved_rsi);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2392 __ movptr(rdi, saved_rdi);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2393 __ movptr(rbx, saved_rbx);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2394 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2395 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2396
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2397 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2398 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2399 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2400 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2401 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2402 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2403 // c_rarg3 - r vector byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2404 // c_rarg4 - input length
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2405 //
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2406 // Output:
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2407 // rax - input length
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2408 //
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2409 address generate_cipherBlockChaining_encryptAESCrypt() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2410 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2411 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2412 StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2413 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2414
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2415 Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2416 const Register from = rsi; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2417 const Register to = rdx; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2418 const Register key = rcx; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2419 const Register rvec = rdi; // r byte array initialized from initvector array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2420 // and left with the results of the last encryption block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2421 const Register len_reg = rbx; // src len (must be multiple of blocksize 16)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2422 const Register pos = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2423
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2424 // xmm register assignments for the loops below
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2425 const XMMRegister xmm_result = xmm0;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2426 const XMMRegister xmm_temp = xmm1;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2427 // first 6 keys preloaded into xmm2-xmm7
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2428 const int XMM_REG_NUM_KEY_FIRST = 2;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2429 const int XMM_REG_NUM_KEY_LAST = 7;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2430 const XMMRegister xmm_key0 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2431
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2432 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2433 handleSOERegisters(true /*saving*/);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2434
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2435 // load registers from incoming parameters
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2436 const Address from_param(rbp, 8+0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2437 const Address to_param (rbp, 8+4);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2438 const Address key_param (rbp, 8+8);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2439 const Address rvec_param (rbp, 8+12);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2440 const Address len_param (rbp, 8+16);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2441 __ movptr(from , from_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2442 __ movptr(to , to_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2443 __ movptr(key , key_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2444 __ movptr(rvec , rvec_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2445 __ movptr(len_reg , len_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2446
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2447 const XMMRegister xmm_key_shuf_mask = xmm_temp; // used temporarily to swap key bytes up front
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2448 __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2449 // load up xmm regs 2 thru 7 with keys 0-5
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2450 for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x00; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2451 load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2452 offset += 0x10;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2453 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2454
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2455 __ movdqu(xmm_result, Address(rvec, 0x00)); // initialize xmm_result with r vec
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2456
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2457 // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2458 __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2459 __ cmpl(rax, 44);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2460 __ jcc(Assembler::notEqual, L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2461
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2462 // 128 bit code follows here
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2463 __ movl(pos, 0);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2464 __ align(OptoLoopAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2465 __ BIND(L_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2466 __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2467 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2468
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2469 __ pxor (xmm_result, xmm_key0); // do the aes rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2470 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2471 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2472 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2473 for (int key_offset = 0x60; key_offset <= 0x90; key_offset += 0x10) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2474 aes_enc_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2475 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2476 load_key(xmm_temp, key, 0xa0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2477 __ aesenclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2478
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2479 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2480 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2481 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2482 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2483 __ jcc(Assembler::notEqual, L_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2484
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2485 __ BIND(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2486 __ movdqu(Address(rvec, 0), xmm_result); // final value of r stored in rvec of CipherBlockChaining object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2487
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2488 handleSOERegisters(false /*restoring*/);
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2489 __ movptr(rax, len_param); // return length
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2490 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2491 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2492
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2493 __ BIND(L_key_192_256);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2494 // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2495 __ cmpl(rax, 52);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2496 __ jcc(Assembler::notEqual, L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2497
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2498 // 192-bit code follows here (could be changed to use more xmm registers)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2499 __ movl(pos, 0);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2500 __ align(OptoLoopAlignment);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2501 __ BIND(L_loopTop_192);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2502 __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2503 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2504
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2505 __ pxor (xmm_result, xmm_key0); // do the aes rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2506 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2507 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2508 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2509 for (int key_offset = 0x60; key_offset <= 0xb0; key_offset += 0x10) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2510 aes_enc_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2511 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2512 load_key(xmm_temp, key, 0xc0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2513 __ aesenclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2514
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2515 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2516 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2517 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2518 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2519 __ jcc(Assembler::notEqual, L_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2520 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2521
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2522 __ BIND(L_key_256);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2523 // 256-bit code follows here (could be changed to use more xmm registers)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2524 __ movl(pos, 0);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2525 __ align(OptoLoopAlignment);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2526 __ BIND(L_loopTop_256);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2527 __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2528 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2529
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2530 __ pxor (xmm_result, xmm_key0); // do the aes rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2531 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2532 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2533 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2534 for (int key_offset = 0x60; key_offset <= 0xd0; key_offset += 0x10) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2535 aes_enc_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2536 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2537 load_key(xmm_temp, key, 0xe0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2538 __ aesenclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2539
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2540 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2541 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2542 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2543 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2544 __ jcc(Assembler::notEqual, L_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2545 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2546
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2547 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2548 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2549
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2550
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2551 // CBC AES Decryption.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2552 // In 32-bit stub, because of lack of registers we do not try to parallelize 4 blocks at a time.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2553 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2554 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2555 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2556 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2557 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2558 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2559 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2560 // c_rarg3 - r vector byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2561 // c_rarg4 - input length
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2562 //
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2563 // Output:
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2564 // rax - input length
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2565 //
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2566
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2567 address generate_cipherBlockChaining_decryptAESCrypt() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2568 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2569 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2570 StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2571 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2572
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2573 Label L_exit, L_key_192_256, L_key_256;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2574 Label L_singleBlock_loopTop_128;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2575 Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2576 const Register from = rsi; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2577 const Register to = rdx; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2578 const Register key = rcx; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2579 const Register rvec = rdi; // r byte array initialized from initvector array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2580 // and left with the results of the last encryption block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2581 const Register len_reg = rbx; // src len (must be multiple of blocksize 16)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2582 const Register pos = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2583
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2584 // xmm register assignments for the loops below
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2585 const XMMRegister xmm_result = xmm0;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2586 const XMMRegister xmm_temp = xmm1;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2587 // first 6 keys preloaded into xmm2-xmm7
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2588 const int XMM_REG_NUM_KEY_FIRST = 2;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2589 const int XMM_REG_NUM_KEY_LAST = 7;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2590 const int FIRST_NON_REG_KEY_offset = 0x70;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2591 const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2592
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2593 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2594 handleSOERegisters(true /*saving*/);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2595
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2596 // load registers from incoming parameters
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2597 const Address from_param(rbp, 8+0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2598 const Address to_param (rbp, 8+4);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2599 const Address key_param (rbp, 8+8);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2600 const Address rvec_param (rbp, 8+12);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2601 const Address len_param (rbp, 8+16);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2602 __ movptr(from , from_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2603 __ movptr(to , to_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2604 __ movptr(key , key_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2605 __ movptr(rvec , rvec_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2606 __ movptr(len_reg , len_param);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2607
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2608 // the java expanded key ordering is rotated one position from what we want
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2609 // so we start from 0x10 here and hit 0x00 last
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2610 const XMMRegister xmm_key_shuf_mask = xmm1; // used temporarily to swap key bytes up front
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2611 __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2612 // load up xmm regs 2 thru 6 with first 5 keys
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2613 for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2614 load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2615 offset += 0x10;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2616 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2617
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2618 // inside here, use the rvec register to point to previous block cipher
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2619 // with which we xor at the end of each newly decrypted block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2620 const Register prev_block_cipher_ptr = rvec;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2621
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2622 // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2623 __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2624 __ cmpl(rax, 44);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2625 __ jcc(Assembler::notEqual, L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2626
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2627
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2628 // 128-bit code follows here, parallelized
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2629 __ movl(pos, 0);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2630 __ align(OptoLoopAlignment);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2631 __ BIND(L_singleBlock_loopTop_128);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2632 __ cmpptr(len_reg, 0); // any blocks left??
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2633 __ jcc(Assembler::equal, L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2634 __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2635 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2636 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2637 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2638 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2639 for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xa0; key_offset += 0x10) { // 128-bit runs up to key offset a0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2640 aes_dec_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2641 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2642 load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2643 __ aesdeclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2644 __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2645 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2646 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2647 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2648 __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2649 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2650 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2651 __ jmp(L_singleBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2652
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2653
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2654 __ BIND(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2655 __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2656 __ movptr(rvec , rvec_param); // restore this since used in loop
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2657 __ movdqu(Address(rvec, 0), xmm_temp); // final value of r stored in rvec of CipherBlockChaining object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2658 handleSOERegisters(false /*restoring*/);
17670
04d32e7fad07 8002074: Support for AES on SPARC
kvn
parents: 12056
diff changeset
2659 __ movptr(rax, len_param); // return length
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2660 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2661 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2662
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2663
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2664 __ BIND(L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2665 // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2666 __ cmpl(rax, 52);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2667 __ jcc(Assembler::notEqual, L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2668
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2669 // 192-bit code follows here (could be optimized to use parallelism)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2670 __ movl(pos, 0);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2671 __ align(OptoLoopAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2672 __ BIND(L_singleBlock_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2673 __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2674 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2675 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2676 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2677 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2678 for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xc0; key_offset += 0x10) { // 192-bit runs up to key offset c0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2679 aes_dec_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2680 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2681 load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2682 __ aesdeclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2683 __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2684 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2685 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2686 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2687 __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2688 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2689 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2690 __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2691 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2692
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2693 __ BIND(L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2694 // 256-bit code follows here (could be optimized to use parallelism)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
2695 __ movl(pos, 0);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2696 __ align(OptoLoopAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2697 __ BIND(L_singleBlock_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2698 __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2699 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2700 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2701 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2702 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2703 for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xe0; key_offset += 0x10) { // 256-bit runs up to key offset e0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2704 aes_dec_key(xmm_result, xmm_temp, key, key_offset);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2705 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2706 load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2707 __ aesdeclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2708 __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2709 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2710 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2711 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2712 __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2713 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2714 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2715 __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2716 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2717
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2718 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2719 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2720
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2721 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2722 * Arguments:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2723 *
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2724 * Inputs:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2725 * rsp(4) - int crc
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2726 * rsp(8) - byte* buf
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2727 * rsp(12) - int length
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2728 *
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2729 * Ouput:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2730 * rax - int crc result
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2731 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2732 address generate_updateBytesCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2733 assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2734
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2735 __ align(CodeEntryAlignment);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2736 StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2737
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2738 address start = __ pc();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2739
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2740 const Register crc = rdx; // crc
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2741 const Register buf = rsi; // source java byte array address
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2742 const Register len = rcx; // length
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2743 const Register table = rdi; // crc_table address (reuse register)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2744 const Register tmp = rbx;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2745 assert_different_registers(crc, buf, len, table, tmp, rax);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2746
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2747 BLOCK_COMMENT("Entry:");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2748 __ enter(); // required for proper stackwalking of RuntimeStub frame
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2749 __ push(rsi);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2750 __ push(rdi);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2751 __ push(rbx);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2752
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2753 Address crc_arg(rbp, 8 + 0);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2754 Address buf_arg(rbp, 8 + 4);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2755 Address len_arg(rbp, 8 + 8);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2756
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2757 // Load up:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2758 __ movl(crc, crc_arg);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2759 __ movptr(buf, buf_arg);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2760 __ movl(len, len_arg);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2761
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2762 __ kernel_crc32(crc, buf, len, table, tmp);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2763
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2764 __ movl(rax, crc);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2765 __ pop(rbx);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2766 __ pop(rdi);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2767 __ pop(rsi);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2768 __ leave(); // required for proper stackwalking of RuntimeStub frame
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2769 __ ret(0);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2770
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2771 return start;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2772 }
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2773
11127
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2774 // Safefetch stubs.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2775 void generate_safefetch(const char* name, int size, address* entry,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2776 address* fault_pc, address* continuation_pc) {
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2777 // safefetch signatures:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2778 // int SafeFetch32(int* adr, int errValue);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2779 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2780
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2781 StubCodeMark mark(this, "StubRoutines", name);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2782
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2783 // Entry point, pc or function descriptor.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2784 *entry = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2785
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2786 __ movl(rax, Address(rsp, 0x8));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2787 __ movl(rcx, Address(rsp, 0x4));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2788 // Load *adr into eax, may fault.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2789 *fault_pc = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2790 switch (size) {
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2791 case 4:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2792 // int32_t
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2793 __ movl(rax, Address(rcx, 0));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2794 break;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2795 case 8:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2796 // int64_t
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2797 Unimplemented();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2798 break;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2799 default:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2800 ShouldNotReachHere();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2801 }
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2802
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2803 // Return errValue or *adr.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2804 *continuation_pc = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2805 __ ret(0);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
2806 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2807
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // Information about frame layout at time of blocking runtime call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // Note that we only have to preserve callee-saved registers since
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // the compilers are responsible for supplying a continuation point
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 // if they expect all registers to be preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 enum layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 thread_off, // last_java_sp
3781
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2815 arg1_off,
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2816 arg2_off,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 rbp_off, // callee saved register
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 ret_pc,
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2821
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2823
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 #undef __
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 #define __ masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
2826
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // Continuation point for throwing of implicit exceptions that are not handled in
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 // the current activation. Fabricates an exception oop and initiates normal
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 // exception dispatching in this frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 // Previously the compiler (c2) allowed for callee save registers on Java calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 // This is no longer true after adapter frames were removed but could possibly
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // be brought back in the future if the interpreter code was reworked and it
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // was deemed worthwhile. The comment below was left to describe what must
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 // happen here if callee saves were resurrected. As it stands now this stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 // could actually be a vanilla BufferBlob and have now oopMap at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // Since it doesn't make much difference we've chosen to leave it the
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // way it was in the callee save days and keep the comment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2840
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 // If we need to preserve callee-saved values we need a callee-saved oop map and
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 // therefore have to make these stubs into RuntimeStubs rather than BufferBlobs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 // If the compiler needs all registers to be preserved between the fault
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 // point and the exception handler then it must assume responsibility for that in
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 // AbstractCompiler::continuation_for_implicit_null_exception or
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 // continuation_for_implicit_division_by_zero_exception. All other implicit
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 // exceptions (e.g., NullPointerException or AbstractMethodError on entry) are
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 // either at call sites or otherwise assume that stack unwinding will be initiated,
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 // so caller saved registers were assumed volatile in the compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 address generate_throw_exception(const char* name, address runtime_entry,
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3781
diff changeset
2851 Register arg1 = noreg, Register arg2 = noreg) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2852
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 int insts_size = 256;
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 int locs_size = 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
2855
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 CodeBuffer code(name, insts_size, locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 OopMapSet* oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 MacroAssembler* masm = new MacroAssembler(&code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2859
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2861
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // This is an inlined and slightly modified version of call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 // which has the ability to fetch the return PC out of
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 // thread-local storage and also sets up last_Java_sp slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // differently than the real call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 Register java_thread = rbx;
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 __ get_thread(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2868
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2870
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 // pc and rbp, already pushed
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2872 __ subptr(rsp, (framesize-2) * wordSize); // prolog
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2873
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 // Frame is now completed as far as size and linkage.
a61af66fc99e Initial load
duke
parents:
diff changeset
2875
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 int frame_complete = __ pc() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2877
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 // push java thread (becomes first argument of C function)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2879 __ movptr(Address(rsp, thread_off * wordSize), java_thread);
3781
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2880 if (arg1 != noreg) {
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2881 __ movptr(Address(rsp, arg1_off * wordSize), arg1);
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2882 }
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2883 if (arg2 != noreg) {
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2884 assert(arg1 != noreg, "missing reg arg");
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2885 __ movptr(Address(rsp, arg2_off * wordSize), arg2);
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2886 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2887
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 // Set up last_Java_sp and last_Java_fp
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 __ set_last_Java_frame(java_thread, rsp, rbp, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2890
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 // Call runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 BLOCK_COMMENT("call runtime_entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 __ call(RuntimeAddress(runtime_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 // Generate oop map
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 OopMap* map = new OopMap(framesize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 oop_maps->add_gc_map(__ pc() - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2897
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // restore the thread (cannot use the pushed argument since arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 // may be overwritten by C code generated by an optimizing compiler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 // however can use the register value directly if it is callee saved.
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 __ get_thread(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2902
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 __ reset_last_Java_frame(java_thread, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2904
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2906
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 // check for pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2910 __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
a61af66fc99e Initial load
duke
parents:
diff changeset
2917
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &code, frame_complete, framesize, oop_maps, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 return stub->entry_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2921
a61af66fc99e Initial load
duke
parents:
diff changeset
2922
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 void create_control_words() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 // Round to nearest, 53-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 StubRoutines::_fpu_cntrl_wrd_std = 0x027F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // Round to zero, 53-bit mode, exception mased
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // Round to nearest, 24-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // Round to nearest, 64-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // Round to nearest, 64-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 StubRoutines::_mxcsr_std = 0x1F80;
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 // Note: the following two constants are 80-bit values
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 // layout is critical for correct loading by FPU.
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 // Bias for strict fp multiply/divide
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // Un-Bias for strict fp multiply/divide
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2945
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 // Initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
2948
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 void generate_initial() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
2951
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 // entry points that exist in all platforms
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 // Note: This is code that could be shared among different platforms - however the benefit seems to be smaller than
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 // the disadvantage of having a much more complicated generator structure. See also comment in stubRoutines.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 StubRoutines::_forward_exception_entry = generate_forward_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
2957
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 StubRoutines::_call_stub_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 generate_call_stub(StubRoutines::_call_stub_return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 // is referenced by megamorphic call
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 StubRoutines::_catch_exception_entry = generate_catch_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
2962
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 // These are currently used by Solaris/Intel
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
2965
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 StubRoutines::_handler_for_unsafe_access_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 generate_handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
2968
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 // platform dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 create_control_words();
a61af66fc99e Initial load
duke
parents:
diff changeset
2971
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2972 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2973 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT,
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 CAST_FROM_FN_PTR(address, SharedRuntime::d2i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG,
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 CAST_FROM_FN_PTR(address, SharedRuntime::d2l));
3781
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2978
d83ac25d0304 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2324
diff changeset
2979 // Build this early so it's available for the interpreter
4743
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 3960
diff changeset
2980 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2981
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2982 if (UseCRC32Intrinsics) {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2983 // set table address before stub generation which use it
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2984 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2985 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
2986 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2988
a61af66fc99e Initial load
duke
parents:
diff changeset
2989
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 void generate_all() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
2992
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 // These entry points require SharedInfo::stack0 to be set up in non-core builds
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 // and need to be relocatable, so they each fabricate a RuntimeStub internally.
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3781
diff changeset
2995 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3781
diff changeset
2996 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3781
diff changeset
2997 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2998
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 // entry points that are platform specific
a61af66fc99e Initial load
duke
parents:
diff changeset
3001
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 // support for verify_oop (must happen after universe_init)
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3004
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // arraycopy stubs used by compilers
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 generate_arraycopy_stubs();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
3007
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
3008 generate_math_stubs();
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3009
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3010 // don't bother generating these AES intrinsic stubs unless global flag is set
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3011 if (UseAESIntrinsics) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3012 StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask(); // might be needed by the others
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3013
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3014 StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3015 StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3016 StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3017 StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3018 }
11127
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3019
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3020 // Safefetch stubs.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3021 generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3022 &StubRoutines::_safefetch32_fault_pc,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3023 &StubRoutines::_safefetch32_continuation_pc);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3024 StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3025 StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3026 StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3028
a61af66fc99e Initial load
duke
parents:
diff changeset
3029
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 if (all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 generate_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 generate_initial();
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 }; // end class declaration
a61af66fc99e Initial load
duke
parents:
diff changeset
3039
a61af66fc99e Initial load
duke
parents:
diff changeset
3040
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 void StubGenerator_generate(CodeBuffer* code, bool all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 StubGenerator g(code, all);
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }