annotate src/cpu/x86/vm/stubGenerator_x86_64.cpp @ 15388:769fc3629f59

Add phase FlowSensitiveReductionPhase. It is possible to remove GuardingPiNodes, CheckCastNodes, and FixedGuards during HighTier under certain conditions (control-flow sensitive conditions). The phase added in this commit (FlowSensitiveReductionPhase) does that, and in addition replaces usages with "downcasting" PiNodes when possible thus resulting in more precise object stamps (e.g., non-null). Finally, usages of floating, side-effects free, expressions are also simplified (as per control-flow sensitive conditions). The newly added phase runs only during HighTier and can be deactivated using Graal option FlowSensitiveReduction (it is active by default).
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Fri, 25 Apr 2014 16:50:52 +0200
parents 4062efea018b
children 52b4284cb496
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) 2003, 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->
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
51 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
52 #define a__ ((Assembler*)_masm)->
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
55 #define BLOCK_COMMENT(str) /* nothing */
a61af66fc99e Initial load
duke
parents:
diff changeset
56 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
57 #define BLOCK_COMMENT(str) __ block_comment(str)
a61af66fc99e Initial load
duke
parents:
diff changeset
58 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
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
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Stub Code definitions
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static address handle_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 address pc = thread->saved_exception_pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // pc is the instruction which we must emulate
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // doing a no-op is fine: return garbage from the load
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // therefore, compute npc
a61af66fc99e Initial load
duke
parents:
diff changeset
71 address npc = Assembler::locate_next_instruction(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // request an async exception
a61af66fc99e Initial load
duke
parents:
diff changeset
74 thread->set_pending_unsafe_access_error();
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // return address of next instruction to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return npc;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 class StubGenerator: public StubCodeGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
81 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 #ifdef PRODUCT
10973
ef57c43512d6 8014431: cleanup warnings indicated by the -Wunused-value compiler option on linux
ccheung
parents: 10324
diff changeset
84 #define inc_counter_np(counter) ((void)0)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
86 void inc_counter_np_(int& counter) {
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
87 // This can destroy rscratch1 if counter is far from the code cache
0
a61af66fc99e Initial load
duke
parents:
diff changeset
88 __ incrementl(ExternalAddress((address)&counter));
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 #define inc_counter_np(counter) \
a61af66fc99e Initial load
duke
parents:
diff changeset
91 BLOCK_COMMENT("inc_counter " #counter); \
a61af66fc99e Initial load
duke
parents:
diff changeset
92 inc_counter_np_(counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Call stubs are used to call Java from C
a61af66fc99e Initial load
duke
parents:
diff changeset
96 //
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // Linux Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // c_rarg0: call wrapper address address
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // c_rarg1: result address
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // c_rarg2: result type BasicType
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
101 // c_rarg3: method Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // c_rarg4: (interpreter) entry point address
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // c_rarg5: parameters intptr_t*
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // 16(rbp): parameter size (in words) int
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // 24(rbp): thread Thread*
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // -12 [ argument word 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // -11 [ saved r15 ] <--- rsp_after_call
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // -10 [ saved r14 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // -9 [ saved r13 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // -8 [ saved r12 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // -7 [ saved rbx ]
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // -6 [ call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // -5 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // -4 [ result type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // -3 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // -2 [ entry point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // -1 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // 0 [ saved rbp ] <--- rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // 2 [ parameter size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // 3 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
126 //
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Windows Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // c_rarg0: call wrapper address address
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // c_rarg1: result address
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // c_rarg2: result type BasicType
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
131 // c_rarg3: method Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // 48(rbp): (interpreter) entry point address
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // 56(rbp): parameters intptr_t*
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // 64(rbp): parameter size (in words) int
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // 72(rbp): thread Thread*
a61af66fc99e Initial load
duke
parents:
diff changeset
136 //
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // ...
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
140 // -28 [ argument word 1 ]
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
141 // -27 [ saved xmm15 ] <--- rsp_after_call
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
142 // [ saved xmm7-xmm14 ]
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
143 // -9 [ saved xmm6 ] (each xmm register takes 2 slots)
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
144 // -7 [ saved r15 ]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // -6 [ saved r14 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // -5 [ saved r13 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // -4 [ saved r12 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // -3 [ saved rdi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // -2 [ saved rsi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // -1 [ saved rbx ]
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // 0 [ saved rbp ] <--- rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // 2 [ call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // 3 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // 4 [ result type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // 5 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // 6 [ entry point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // 7 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // 8 [ parameter size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // 9 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
161 //
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // Windows reserves the callers stack space for arguments 1-4.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // We spill c_rarg0-c_rarg3 to this space.
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Call stub stack layout word offsets from rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
166 enum call_stub_layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 #ifdef _WIN64
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
168 xmm_save_first = 6, // save from xmm6
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
169 xmm_save_last = 15, // to xmm15
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
170 xmm_save_base = -9,
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
171 rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
172 r15_off = -7,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
173 r14_off = -6,
a61af66fc99e Initial load
duke
parents:
diff changeset
174 r13_off = -5,
a61af66fc99e Initial load
duke
parents:
diff changeset
175 r12_off = -4,
a61af66fc99e Initial load
duke
parents:
diff changeset
176 rdi_off = -3,
a61af66fc99e Initial load
duke
parents:
diff changeset
177 rsi_off = -2,
a61af66fc99e Initial load
duke
parents:
diff changeset
178 rbx_off = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
179 rbp_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
180 retaddr_off = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
181 call_wrapper_off = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
182 result_off = 3,
a61af66fc99e Initial load
duke
parents:
diff changeset
183 result_type_off = 4,
a61af66fc99e Initial load
duke
parents:
diff changeset
184 method_off = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
185 entry_point_off = 6,
a61af66fc99e Initial load
duke
parents:
diff changeset
186 parameters_off = 7,
a61af66fc99e Initial load
duke
parents:
diff changeset
187 parameter_size_off = 8,
a61af66fc99e Initial load
duke
parents:
diff changeset
188 thread_off = 9
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
190 rsp_after_call_off = -12,
a61af66fc99e Initial load
duke
parents:
diff changeset
191 mxcsr_off = rsp_after_call_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
192 r15_off = -11,
a61af66fc99e Initial load
duke
parents:
diff changeset
193 r14_off = -10,
a61af66fc99e Initial load
duke
parents:
diff changeset
194 r13_off = -9,
a61af66fc99e Initial load
duke
parents:
diff changeset
195 r12_off = -8,
a61af66fc99e Initial load
duke
parents:
diff changeset
196 rbx_off = -7,
a61af66fc99e Initial load
duke
parents:
diff changeset
197 call_wrapper_off = -6,
a61af66fc99e Initial load
duke
parents:
diff changeset
198 result_off = -5,
a61af66fc99e Initial load
duke
parents:
diff changeset
199 result_type_off = -4,
a61af66fc99e Initial load
duke
parents:
diff changeset
200 method_off = -3,
a61af66fc99e Initial load
duke
parents:
diff changeset
201 entry_point_off = -2,
a61af66fc99e Initial load
duke
parents:
diff changeset
202 parameters_off = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
203 rbp_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
204 retaddr_off = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
205 parameter_size_off = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
206 thread_off = 3
a61af66fc99e Initial load
duke
parents:
diff changeset
207 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
208 };
a61af66fc99e Initial load
duke
parents:
diff changeset
209
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
210 #ifdef _WIN64
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
211 Address xmm_save(int reg) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
212 assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range");
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
213 return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize);
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
214 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
215 #endif
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
216
0
a61af66fc99e Initial load
duke
parents:
diff changeset
217 address generate_call_stub(address& return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
219 (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
220 "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 StubCodeMark mark(this, "StubRoutines", "call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
222 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
225 const Address rsp_after_call(rbp, rsp_after_call_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 const Address call_wrapper (rbp, call_wrapper_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 const Address result (rbp, result_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 const Address result_type (rbp, result_type_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 const Address method (rbp, method_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 const Address entry_point (rbp, entry_point_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
232 const Address parameters (rbp, parameters_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
233 const Address parameter_size(rbp, parameter_size_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
236 const Address thread (rbp, thread_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 const Address r15_save(rbp, r15_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 const Address r14_save(rbp, r14_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 const Address r13_save(rbp, r13_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 const Address r12_save(rbp, r12_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
242 const Address rbx_save(rbp, rbx_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // stub code
a61af66fc99e Initial load
duke
parents:
diff changeset
245 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
246 __ subptr(rsp, -rsp_after_call_off * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // save register parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
249 #ifndef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
250 __ movptr(parameters, c_rarg5); // parameters
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
251 __ movptr(entry_point, c_rarg4); // entry_point
0
a61af66fc99e Initial load
duke
parents:
diff changeset
252 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
253
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
254 __ movptr(method, c_rarg3); // method
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
255 __ movl(result_type, c_rarg2); // result type
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
256 __ movptr(result, c_rarg1); // result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
257 __ movptr(call_wrapper, c_rarg0); // call wrapper
0
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // save regs belonging to calling function
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
260 __ movptr(rbx_save, rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
261 __ movptr(r12_save, r12);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
262 __ movptr(r13_save, r13);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
263 __ movptr(r14_save, r14);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
264 __ movptr(r15_save, r15);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265 #ifdef _WIN64
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
266 for (int i = 6; i <= 15; i++) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
267 __ movdqu(xmm_save(i), as_XMMRegister(i));
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
268 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
269
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 const Address rdi_save(rbp, rdi_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 const Address rsi_save(rbp, rsi_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
272
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
273 __ movptr(rsi_save, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
274 __ movptr(rdi_save, rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
275 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
276 const Address mxcsr_save(rbp, mxcsr_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 Label skip_ldmx;
a61af66fc99e Initial load
duke
parents:
diff changeset
279 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
282 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
283 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 __ jcc(Assembler::equal, skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 __ bind(skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Load up thread register
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
291 __ movptr(r15_thread, thread);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
292 __ reinit_heapbase();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // make sure we have no pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
296 {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
298 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
299 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 __ stop("StubRoutines::call_stub: entered with pending exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
301 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // pass parameters if any
a61af66fc99e Initial load
duke
parents:
diff changeset
306 BLOCK_COMMENT("pass parameters if any");
a61af66fc99e Initial load
duke
parents:
diff changeset
307 Label parameters_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 __ movl(c_rarg3, parameter_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 __ testl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ jcc(Assembler::zero, parameters_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 Label loop;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
313 __ movptr(c_rarg2, parameters); // parameter pointer
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
314 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
315 __ BIND(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
316 __ movptr(rax, Address(c_rarg2, 0));// get parameter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
317 __ addptr(c_rarg2, wordSize); // advance to next parameter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
318 __ decrementl(c_rarg1); // decrement counter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
319 __ push(rax); // pass parameter
0
a61af66fc99e Initial load
duke
parents:
diff changeset
320 __ jcc(Assembler::notZero, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // call Java function
a61af66fc99e Initial load
duke
parents:
diff changeset
323 __ BIND(parameters_done);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
324 __ movptr(rbx, method); // get Method*
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
325 __ movptr(c_rarg1, entry_point); // get entry_point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
326 __ mov(r13, rsp); // set sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
327 BLOCK_COMMENT("call Java function");
a61af66fc99e Initial load
duke
parents:
diff changeset
328 __ call(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 BLOCK_COMMENT("call_stub_return_address:");
a61af66fc99e Initial load
duke
parents:
diff changeset
331 return_address = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // store result depending on type (everything that is not
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // T_OBJECT, 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
335 __ movptr(c_rarg0, result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336 Label is_long, is_float, is_double, exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 __ movl(c_rarg1, result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 __ cmpl(c_rarg1, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 __ cmpl(c_rarg1, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 __ cmpl(c_rarg1, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 __ jcc(Assembler::equal, is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 __ cmpl(c_rarg1, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 __ jcc(Assembler::equal, is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // handle T_INT case
a61af66fc99e Initial load
duke
parents:
diff changeset
348 __ movl(Address(c_rarg0, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 __ BIND(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // pop parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
353 __ lea(rsp, rsp_after_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
357 {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 Label L, S;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
359 __ cmpptr(r15_thread, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 __ jcc(Assembler::notEqual, S);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
362 __ cmpptr(r15_thread, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
363 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 __ bind(S);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 __ stop("StubRoutines::call_stub: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
367 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // restore regs belonging to calling function
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
372 #ifdef _WIN64
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
373 for (int i = 15; i >= 6; i--) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
374 __ movdqu(as_XMMRegister(i), xmm_save(i));
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
375 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
376 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
377 __ movptr(r15, r15_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
378 __ movptr(r14, r14_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
379 __ movptr(r13, r13_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
380 __ movptr(r12, r12_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
381 __ movptr(rbx, rbx_save);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 #ifdef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
384 __ movptr(rdi, rdi_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
385 __ movptr(rsi, rsi_save);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
386 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
387 __ ldmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // restore rsp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
391 __ addptr(rsp, -rsp_after_call_off * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
394 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // handle return types different from T_INT
a61af66fc99e Initial load
duke
parents:
diff changeset
398 __ BIND(is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
399 __ movq(Address(c_rarg0, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 __ BIND(is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 __ movflt(Address(c_rarg0, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 __ BIND(is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 __ movdbl(Address(c_rarg0, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Return point for a Java call if there's an exception thrown in
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Java code. The exception is caught and transformed into a
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // pending exception stored in JavaThread that can be tested from
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // within the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 //
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Note: Usually the parameters are removed by the callee. In case
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // of an exception crossing an activation frame boundary, that is
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // not the case if the callee is compiled code => need to setup the
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // rsp.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 //
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // rax: exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 address generate_catch_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 StubCodeMark mark(this, "StubRoutines", "catch_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
427 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // same as in generate_call_stub():
a61af66fc99e Initial load
duke
parents:
diff changeset
430 const Address rsp_after_call(rbp, rsp_after_call_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
431 const Address thread (rbp, thread_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
435 {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 Label L, S;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
437 __ cmpptr(r15_thread, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
438 __ jcc(Assembler::notEqual, S);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
440 __ cmpptr(r15_thread, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
441 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 __ bind(S);
a61af66fc99e Initial load
duke
parents:
diff changeset
443 __ stop("StubRoutines::catch_exception: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
444 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // set pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
449 __ verify_oop(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
450
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
451 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
452 __ lea(rscratch1, ExternalAddress((address)__FILE__));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
453 __ movptr(Address(r15_thread, Thread::exception_file_offset()), rscratch1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
454 __ movl(Address(r15_thread, Thread::exception_line_offset()), (int) __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // complete return to VM
a61af66fc99e Initial load
duke
parents:
diff changeset
457 assert(StubRoutines::_call_stub_return_address != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
458 "_call_stub_return_address must have been generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address));
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Continuation point for runtime calls returning with a pending
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // exception. The pending exception check happened in the runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // or native call stub. The pending exception in Thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // converted into a Java-level exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 //
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // Contract with Java-level exception handlers:
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
472 //
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // NOTE: At entry of this stub, exception-pc must be on stack !!
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 address generate_forward_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 StubCodeMark mark(this, "StubRoutines", "forward exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
477 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // Upon entry, the sp points to the return address returning into
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Java (interpreted or compiled) code; i.e., the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // becomes the throwing pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
482 //
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Arguments pushed before the runtime call are still on the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // but the exception handler will reset the stack pointer ->
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // ignore them. A potential result in registers can be ignored as
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // well.
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // make sure this code is only executed if there is a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
490 {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
492 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
493 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 __ stop("StubRoutines::forward exception: no pending exception (1)");
a61af66fc99e Initial load
duke
parents:
diff changeset
495 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // compute exception handler into rbx
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
500 __ movptr(c_rarg0, Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 BLOCK_COMMENT("call exception_handler_for_return_address");
a61af66fc99e Initial load
duke
parents:
diff changeset
502 __ call_VM_leaf(CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
503 SharedRuntime::exception_handler_for_return_address),
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
504 r15_thread, c_rarg0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
505 __ mov(rbx, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // setup rax & rdx, remove return address & clear pending exception
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
508 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
509 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
510 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // make sure exception is set
a61af66fc99e Initial load
duke
parents:
diff changeset
514 {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
516 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 __ stop("StubRoutines::forward exception: no pending exception (2)");
a61af66fc99e Initial load
duke
parents:
diff changeset
519 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // continue at exception handler (return address removed)
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // rbx: exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
527 __ verify_oop(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
528 __ jmp(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // Support for jint atomic::xchg(jint exchange_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
534 //
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // c_rarg0: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
538 //
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // *dest <- ex, return (orig *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
541 address generate_atomic_xchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 StubCodeMark mark(this, "StubRoutines", "atomic_xchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
543 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 __ movl(rax, c_rarg0); // Copy to eax we need a return value anyhow
a61af66fc99e Initial load
duke
parents:
diff changeset
546 __ xchgl(rax, Address(c_rarg1, 0)); // automatic LOCK
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 // Support for intptr_t atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
553 //
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
557 //
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // *dest <- ex, return (orig *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
560 address generate_atomic_xchg_ptr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 StubCodeMark mark(this, "StubRoutines", "atomic_xchg_ptr");
a61af66fc99e Initial load
duke
parents:
diff changeset
562 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
563
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
564 __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
565 __ xchgptr(rax, Address(c_rarg1, 0)); // automatic LOCK
0
a61af66fc99e Initial load
duke
parents:
diff changeset
566 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Support for jint atomic::atomic_cmpxchg(jint exchange_value, volatile jint* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // jint compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
573 //
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // c_rarg2: compare_value
a61af66fc99e Initial load
duke
parents:
diff changeset
578 //
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // if ( compare_value == *dest ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // *dest = exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // return compare_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
585 address generate_atomic_cmpxchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
587 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 __ movl(rax, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
591 __ cmpxchgl(c_rarg0, Address(c_rarg1, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
592 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Support for jint atomic::atomic_cmpxchg_long(jlong exchange_value,
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // volatile jlong* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // jlong compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // c_rarg2: compare_value
a61af66fc99e Initial load
duke
parents:
diff changeset
604 //
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // if ( compare_value == *dest ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // *dest = exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // return compare_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
611 address generate_atomic_cmpxchg_long() {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long");
a61af66fc99e Initial load
duke
parents:
diff changeset
613 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615 __ movq(rax, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
617 __ cmpxchgq(c_rarg0, Address(c_rarg1, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
618 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Support for jint atomic::add(jint add_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
624 //
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // c_rarg0: add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
628 //
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // *dest += add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 address generate_atomic_add() {
a61af66fc99e Initial load
duke
parents:
diff changeset
633 StubCodeMark mark(this, "StubRoutines", "atomic_add");
a61af66fc99e Initial load
duke
parents:
diff changeset
634 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 __ movl(rax, c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
638 __ xaddl(Address(c_rarg1, 0), c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 __ addl(rax, c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // Support for intptr_t atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
646 //
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // c_rarg0: add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
650 //
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // *dest += add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 address generate_atomic_add_ptr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 StubCodeMark mark(this, "StubRoutines", "atomic_add_ptr");
a61af66fc99e Initial load
duke
parents:
diff changeset
656 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
657
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
658 __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
659 if ( os::is_MP() ) __ lock();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
660 __ xaddptr(Address(c_rarg1, 0), c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
661 __ addptr(rax, c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
662 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Support for intptr_t OrderAccess::fence()
a61af66fc99e Initial load
duke
parents:
diff changeset
668 //
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
670 //
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
672 address generate_orderaccess_fence() {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 StubCodeMark mark(this, "StubRoutines", "orderaccess_fence");
a61af66fc99e Initial load
duke
parents:
diff changeset
674 address start = __ pc();
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
675 __ membar(Assembler::StoreLoad);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
676 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Support for intptr_t get_previous_fp()
a61af66fc99e Initial load
duke
parents:
diff changeset
682 //
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // This routine is used to find the previous frame pointer for the
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // caller (current_frame_guess). This is used as part of debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // ps() is seemingly lost trying to find frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // This code assumes that caller current_frame_guess) has a frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
687 address generate_get_previous_fp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 StubCodeMark mark(this, "StubRoutines", "get_previous_fp");
a61af66fc99e Initial load
duke
parents:
diff changeset
689 const Address old_fp(rbp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 const Address older_fp(rax, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
691 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
694 __ movptr(rax, old_fp); // callers fp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
695 __ movptr(rax, older_fp); // the frame for ps()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
696 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701
5903
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
702 // Support for intptr_t get_previous_sp()
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
703 //
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
704 // This routine is used to find the previous stack pointer for the
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
705 // caller.
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
706 address generate_get_previous_sp() {
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
707 StubCodeMark mark(this, "StubRoutines", "get_previous_sp");
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
708 address start = __ pc();
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
709
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
710 __ movptr(rax, rsp);
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
711 __ addptr(rax, 8); // return address is at the top of the stack.
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
712 __ ret(0);
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
713
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
714 return start;
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
715 }
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
716
0
a61af66fc99e Initial load
duke
parents:
diff changeset
717 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // Support for void verify_mxcsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
719 //
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // MXCSR register to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 address generate_verify_mxcsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 StubCodeMark mark(this, "StubRoutines", "verify_mxcsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
726 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 const Address mxcsr_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 Label ok_ret;
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
732 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
733 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
734 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
735 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
738 __ cmp32(rax, mxcsr_std);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
a61af66fc99e Initial load
duke
parents:
diff changeset
742
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
743 __ ldmxcsr(mxcsr_std);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
746 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
747 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 address generate_f2i_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 StubCodeMark mark(this, "StubRoutines", "f2i_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
757 Address inout(rsp, 5 * wordSize); // return address + 4 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
762
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
763 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
764 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
765 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
766 __ push(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 __ movl(rax, 0x7f800000);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 __ xorl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 __ movl(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 __ movl(c_rarg1, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
773 __ cmpl(rax, c_rarg1); // NaN? -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
774 __ jcc(Assembler::negative, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
775 __ testl(c_rarg2, c_rarg2); // signed ? min_jint : max_jint
a61af66fc99e Initial load
duke
parents:
diff changeset
776 __ movl(c_rarg3, 0x80000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 __ movl(rax, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 __ cmovl(Assembler::positive, c_rarg3, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
781 __ movptr(inout, c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
782
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
783 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
784 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
785 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
786 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 address generate_f2l_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 StubCodeMark mark(this, "StubRoutines", "f2l_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
795 Address inout(rsp, 5 * wordSize); // return address + 4 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
796 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
799
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
800 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
801 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
802 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
803 __ push(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 __ movl(rax, 0x7f800000);
a61af66fc99e Initial load
duke
parents:
diff changeset
806 __ xorl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
807 __ movl(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 __ movl(c_rarg1, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 __ cmpl(rax, c_rarg1); // NaN? -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
811 __ jcc(Assembler::negative, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 __ testl(c_rarg2, c_rarg2); // signed ? min_jlong : max_jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
813 __ mov64(c_rarg3, 0x8000000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 __ mov64(rax, 0x7fffffffffffffff);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
815 __ cmov(Assembler::positive, c_rarg3, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
818 __ movptr(inout, c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
819
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
820 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
821 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
822 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
823 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829
a61af66fc99e Initial load
duke
parents:
diff changeset
830 address generate_d2i_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 StubCodeMark mark(this, "StubRoutines", "d2i_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
832 Address inout(rsp, 6 * wordSize); // return address + 5 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
837
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
838 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
839 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
840 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
841 __ push(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
842 __ push(c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 __ movl(rax, 0x7ff00000);
a61af66fc99e Initial load
duke
parents:
diff changeset
845 __ movq(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
846 __ movl(c_rarg3, c_rarg2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
847 __ mov(c_rarg1, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
848 __ mov(c_rarg0, c_rarg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 __ negl(c_rarg3);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
850 __ shrptr(c_rarg1, 0x20);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
851 __ orl(c_rarg3, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 __ xorl(c_rarg2, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 __ shrl(c_rarg3, 0x1f);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 __ orl(c_rarg1, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
856 __ cmpl(rax, c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 __ jcc(Assembler::negative, L); // NaN -> 0
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
858 __ testptr(c_rarg0, c_rarg0); // signed ? min_jint : max_jint
0
a61af66fc99e Initial load
duke
parents:
diff changeset
859 __ movl(c_rarg2, 0x80000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 __ movl(rax, 0x7fffffff);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
861 __ cmov(Assembler::positive, c_rarg2, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
864 __ movptr(inout, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
865
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
866 __ pop(c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
867 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
868 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
869 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
870 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
873
a61af66fc99e Initial load
duke
parents:
diff changeset
874 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 address generate_d2l_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
878 StubCodeMark mark(this, "StubRoutines", "d2l_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
879 Address inout(rsp, 6 * wordSize); // return address + 5 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
884
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
885 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
886 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
887 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
888 __ push(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
889 __ push(c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 __ movl(rax, 0x7ff00000);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 __ movq(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
893 __ movl(c_rarg3, c_rarg2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
894 __ mov(c_rarg1, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
895 __ mov(c_rarg0, c_rarg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 __ negl(c_rarg3);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
897 __ shrptr(c_rarg1, 0x20);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
898 __ orl(c_rarg3, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 __ xorl(c_rarg2, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ shrl(c_rarg3, 0x1f);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 __ orl(c_rarg1, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
903 __ cmpl(rax, c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 __ jcc(Assembler::negative, L); // NaN -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 __ testq(c_rarg0, c_rarg0); // signed ? min_jlong : max_jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
906 __ mov64(c_rarg2, 0x8000000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
907 __ mov64(rax, 0x7fffffffffffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 __ cmovq(Assembler::positive, c_rarg2, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 __ movq(inout, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
912
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
913 __ pop(c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
914 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
915 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
916 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
917 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924 address generate_fp_mask(const char *stub_name, int64_t mask) {
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
925 __ align(CodeEntryAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
926 StubCodeMark mark(this, "StubRoutines", stub_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
927 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 __ emit_data64( mask, relocInfo::none );
a61af66fc99e Initial load
duke
parents:
diff changeset
930 __ emit_data64( mask, relocInfo::none );
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // The following routine generates a subroutine to throw an
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // asynchronous UnknownError when an unsafe access gets a fault that
a61af66fc99e Initial load
duke
parents:
diff changeset
937 // could not be reasonably prevented by the programmer. (Example:
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // SIGBUS/OBJERR.)
a61af66fc99e Initial load
duke
parents:
diff changeset
939 address generate_handler_for_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
941 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
942
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
943 __ push(0); // hole for return address-to-be
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
944 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
946
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3451
diff changeset
947 // FIXME: this probably needs alignment logic
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3451
diff changeset
948
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
949 __ subptr(rsp, frame::arg_reg_save_area_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
950 BLOCK_COMMENT("call handle_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
951 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
952 __ addptr(rsp, frame::arg_reg_save_area_bytes);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
953
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
954 __ movptr(next_pc, rax); // stuff next address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
955 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
956 __ ret(0); // jump to next address
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Non-destructive plausibility checks for oops
a61af66fc99e Initial load
duke
parents:
diff changeset
962 //
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
964 // all args on stack!
a61af66fc99e Initial load
duke
parents:
diff changeset
965 //
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // Stack after saving c_rarg3:
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // [tos + 0]: saved c_rarg3
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // [tos + 1]: saved c_rarg2
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
969 // [tos + 2]: saved r12 (several TemplateTable methods use it)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
970 // [tos + 3]: saved flags
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
971 // [tos + 4]: return address
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
972 // * [tos + 5]: error message (char*)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
973 // * [tos + 6]: object to verify (oop)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
974 // * [tos + 7]: saved rax - saved by caller and bashed
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
975 // * [tos + 8]: saved r10 (rscratch1) - saved by caller
0
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // * = popped on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
977 address generate_verify_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 StubCodeMark mark(this, "StubRoutines", "verify_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
979 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 Label exit, error;
a61af66fc99e Initial load
duke
parents:
diff changeset
982
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
983 __ pushf();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
984 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
985
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
986 __ push(r12);
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
987
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // save c_rarg2 and c_rarg3
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
989 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
990 __ push(c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
991
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
992 enum {
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
993 // After previous pushes.
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
994 oop_to_verify = 6 * wordSize,
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
995 saved_rax = 7 * wordSize,
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
996 saved_r10 = 8 * wordSize,
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
997
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
998 // Before the call to MacroAssembler::debug(), see below.
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
999 return_addr = 16 * wordSize,
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1000 error_msg = 17 * wordSize
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1001 };
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1002
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // get object
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1004 __ movptr(rax, Address(rsp, oop_to_verify));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // make sure object is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1007 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 __ jcc(Assembler::zero, exit); // if obj is NULL it is OK
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // Check if the oop is in the right area of memory
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1010 __ movptr(c_rarg2, rax);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1011 __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1012 __ andptr(c_rarg2, c_rarg3);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1013 __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1014 __ cmpptr(c_rarg2, c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1017 // set r12 to heapbase for load_klass()
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1018 __ reinit_heapbase();
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1019
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1020 // make sure klass is 'reasonable', which is not zero.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1021 __ load_klass(rax, rax); // get klass
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1022 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 __ jcc(Assembler::zero, error); // if klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // return if everything seems ok
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 __ bind(exit);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1027 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1028 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1029 __ pop(c_rarg3); // restore c_rarg3
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1030 __ pop(c_rarg2); // restore c_rarg2
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1031 __ pop(r12); // restore r12
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1032 __ popf(); // restore flags
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1033 __ ret(4 * wordSize); // pop caller saved stuff
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // handle errors
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 __ bind(error);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1037 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1038 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1039 __ pop(c_rarg3); // get saved c_rarg3 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1040 __ pop(c_rarg2); // get saved c_rarg2 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1041 __ pop(r12); // get saved r12 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1042 __ popf(); // get saved flags off stack --
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // will be ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1045 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // (rip is already
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // already pushed)
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1048 // debug(char* msg, int64_t pc, int64_t regs[])
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // We've popped the registers we'd saved (c_rarg3, c_rarg2 and flags), and
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // pushed all the registers, so now the stack looks like:
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // [tos + 0] 16 saved registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // [tos + 16] return address
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1053 // * [tos + 17] error message (char*)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1054 // * [tos + 18] object to verify (oop)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1055 // * [tos + 19] saved rax - saved by caller and bashed
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1056 // * [tos + 20] saved r10 (rscratch1) - saved by caller
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1057 // * = popped on exit
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1058
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1059 __ movptr(c_rarg0, Address(rsp, error_msg)); // pass address of error message
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1060 __ movptr(c_rarg1, Address(rsp, return_addr)); // pass return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1061 __ movq(c_rarg2, rsp); // pass address of regs on stack
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1062 __ mov(r12, rsp); // remember rsp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1063 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1064 __ andptr(rsp, -16); // align stack as required by ABI
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 BLOCK_COMMENT("call MacroAssembler::debug");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1066 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1067 __ mov(rsp, r12); // restore rsp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1068 __ popa(); // pop registers (includes r12)
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1069 __ ret(4 * wordSize); // pop caller saved stuff
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // Verify that a register contains clean 32-bits positive value
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // (high 32-bits are 0) so it could be used in 64-bits shifts.
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // Rint - 32-bits value
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // Rtmp - scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 void assert_clean_int(Register Rint, Register Rtmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 assert_different_registers(Rtmp, Rint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 __ movslq(Rtmp, Rint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 __ cmpq(Rtmp, Rint);
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1088 __ jcc(Assembler::equal, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 __ stop("high 32-bits of int value are not 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // Generate overlap test for array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 // c_rarg0 - from
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // c_rarg1 - to
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 // c_rarg2 - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // rax - &from[element count - 1]
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 void array_overlap_test(address no_overlap_target, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 assert(no_overlap_target != NULL, "must be generated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 array_overlap_test(no_overlap_target, NULL, sf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 void array_overlap_test(Label& L_no_overlap, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 array_overlap_test(NULL, &L_no_overlap, sf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 void array_overlap_test(address no_overlap_target, Label* NOLp, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 const Register from = c_rarg0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 const Register to = c_rarg1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 const Register count = c_rarg2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 const Register end_from = rax;
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1117 __ cmpptr(to, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1118 __ lea(end_from, Address(from, count, sf, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 if (NOLp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 ExternalAddress no_overlap(no_overlap_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 __ jump_cc(Assembler::belowEqual, no_overlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1122 __ cmpptr(to, end_from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 __ jump_cc(Assembler::aboveEqual, no_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 __ jcc(Assembler::belowEqual, (*NOLp));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1126 __ cmpptr(to, end_from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 __ jcc(Assembler::aboveEqual, (*NOLp));
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Shuffle first three arg regs on Windows into Linux/Solaris locations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // Outputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // rdi - rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // rsi - rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // rdx - r8
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // rcx - r9
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Registers r9 and r10 are used to save rdi and rsi on Windows, which latter
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // are non-volatile. r9 and r10 should not be used by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 void setup_arg_regs(int nargs = 3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 const Register saved_rdi = r9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 const Register saved_rsi = r10;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 assert(nargs == 3 || nargs == 4, "else fix");
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 assert(c_rarg0 == rcx && c_rarg1 == rdx && c_rarg2 == r8 && c_rarg3 == r9,
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 "unexpected argument registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 if (nargs >= 4)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1150 __ mov(rax, r9); // r9 is also saved_rdi
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1151 __ movptr(saved_rdi, rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1152 __ movptr(saved_rsi, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1153 __ mov(rdi, rcx); // c_rarg0
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1154 __ mov(rsi, rdx); // c_rarg1
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1155 __ mov(rdx, r8); // c_rarg2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 if (nargs >= 4)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1157 __ mov(rcx, rax); // c_rarg3 (via rax)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 assert(c_rarg0 == rdi && c_rarg1 == rsi && c_rarg2 == rdx && c_rarg3 == rcx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 "unexpected argument registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1163
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 void restore_arg_regs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 const Register saved_rdi = r9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 const Register saved_rsi = r10;
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 #ifdef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1168 __ movptr(rdi, saved_rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1169 __ movptr(rsi, saved_rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Generate code for an array write pre barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // addr - starting address
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1176 // count - element count
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1177 // tmp - scratch register
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // Destroy no registers!
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1181 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 case BarrierSet::G1SATBCTLogging:
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1186 // 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: 2313
diff changeset
1187 if (!dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1188 __ pusha(); // push registers
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1189 if (count == c_rarg0) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1190 if (addr == c_rarg1) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1191 // exactly backwards!!
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1192 __ xchgptr(c_rarg1, c_rarg0);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1193 } else {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1194 __ movptr(c_rarg1, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1195 __ movptr(c_rarg0, addr);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1196 }
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1197 } else {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1198 __ movptr(c_rarg0, addr);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1199 __ movptr(c_rarg1, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1200 }
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1201 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1202 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1204 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 break;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1209 default:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // Generate code for an array write post barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // start - register containing starting address of destination array
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1220 // count - elements count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // scratch - scratch register
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // The input registers are overwritten.
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1224 //
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1225 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1226 assert_different_registers(start, count, scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 case BarrierSet::G1SATBCTLogging:
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 {
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1232 __ pusha(); // push registers (overkill)
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1233 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1234 assert_different_registers(c_rarg1, start);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1235 __ mov(c_rarg1, count);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1236 __ mov(c_rarg0, start);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1237 } else {
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1238 assert_different_registers(c_rarg0, count);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1239 __ mov(c_rarg0, start);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1240 __ mov(c_rarg1, count);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1241 }
1192
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
1242 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1243 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1251
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 Label L_loop;
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1253 const Register end = count;
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1254
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1255 __ leaq(end, Address(start, count, TIMES_OOP, 0)); // end == start+count*oop_size
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1256 __ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1257 __ shrptr(start, CardTableModRefBS::card_shift);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1258 __ shrptr(end, CardTableModRefBS::card_shift);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1259 __ subptr(end, start); // end --> cards count
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1260
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1261 int64_t disp = (int64_t) ct->byte_map_base;
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1262 __ mov64(scratch, disp);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1263 __ addptr(start, scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 __ BIND(L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 __ movb(Address(start, count, Address::times_1), 0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1266 __ decrement(count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 __ jcc(Assembler::greaterEqual, L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1269 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1270 default:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1271 ShouldNotReachHere();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1272
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1273 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1274 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1276
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // Copy big chunks forward
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // end_from - source arrays end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // end_to - destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // qword_count - 64-bits element count, negative
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // to - scratch
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1284 // L_copy_bytes - entry label
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // L_copy_8_bytes - exit label
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 //
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1287 void copy_bytes_forward(Register end_from, Register end_to,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 Register qword_count, Register to,
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1289 Label& L_copy_bytes, Label& L_copy_8_bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 DEBUG_ONLY(__ stop("enter at entry label, not here"));
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 Label L_loop;
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1292 __ align(OptoLoopAlignment);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1293 if (UseUnalignedLoadStores) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1294 Label L_end;
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1295 // Copy 64-bytes per iteration
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1296 __ BIND(L_loop);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1297 if (UseAVX >= 2) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1298 __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1299 __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1300 __ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1301 __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1302 } else {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1303 __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1304 __ movdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1305 __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, -40));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1306 __ movdqu(Address(end_to, qword_count, Address::times_8, -40), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1307 __ movdqu(xmm2, Address(end_from, qword_count, Address::times_8, -24));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1308 __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm2);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1309 __ movdqu(xmm3, Address(end_from, qword_count, Address::times_8, - 8));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1310 __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm3);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1311 }
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1312 __ BIND(L_copy_bytes);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1313 __ addptr(qword_count, 8);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1314 __ jcc(Assembler::lessEqual, L_loop);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1315 __ subptr(qword_count, 4); // sub(8) and add(4)
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1316 __ jccb(Assembler::greater, L_end);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1317 // Copy trailing 32 bytes
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1318 if (UseAVX >= 2) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1319 __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1320 __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1321 } else {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1322 __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1323 __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1324 __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1325 __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1326 }
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1327 __ addptr(qword_count, 4);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1328 __ BIND(L_end);
8873
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1329 if (UseAVX >= 2) {
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1330 // clean upper bits of YMM registers
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1331 __ vzeroupper();
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1332 }
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1333 } else {
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1334 // Copy 32-bytes per iteration
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1335 __ BIND(L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1336 __ movq(to, Address(end_from, qword_count, Address::times_8, -24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1337 __ movq(Address(end_to, qword_count, Address::times_8, -24), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1338 __ movq(to, Address(end_from, qword_count, Address::times_8, -16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1339 __ movq(Address(end_to, qword_count, Address::times_8, -16), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1340 __ movq(to, Address(end_from, qword_count, Address::times_8, - 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1341 __ movq(Address(end_to, qword_count, Address::times_8, - 8), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1342 __ movq(to, Address(end_from, qword_count, Address::times_8, - 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1343 __ movq(Address(end_to, qword_count, Address::times_8, - 0), to);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1344
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1345 __ BIND(L_copy_bytes);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1346 __ addptr(qword_count, 4);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1347 __ jcc(Assembler::lessEqual, L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1348 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1349 __ subptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // Copy big chunks backward
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // from - source arrays address
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // dest - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // qword_count - 64-bits element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // to - scratch
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1360 // L_copy_bytes - entry label
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // L_copy_8_bytes - exit label
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 //
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1363 void copy_bytes_backward(Register from, Register dest,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 Register qword_count, Register to,
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1365 Label& L_copy_bytes, Label& L_copy_8_bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 DEBUG_ONLY(__ stop("enter at entry label, not here"));
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 Label L_loop;
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1368 __ align(OptoLoopAlignment);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1369 if (UseUnalignedLoadStores) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1370 Label L_end;
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1371 // Copy 64-bytes per iteration
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1372 __ BIND(L_loop);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1373 if (UseAVX >= 2) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1374 __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1375 __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1376 __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1377 __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1378 } else {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1379 __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 48));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1380 __ movdqu(Address(dest, qword_count, Address::times_8, 48), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1381 __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 32));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1382 __ movdqu(Address(dest, qword_count, Address::times_8, 32), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1383 __ movdqu(xmm2, Address(from, qword_count, Address::times_8, 16));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1384 __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm2);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1385 __ movdqu(xmm3, Address(from, qword_count, Address::times_8, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1386 __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm3);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1387 }
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1388 __ BIND(L_copy_bytes);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1389 __ subptr(qword_count, 8);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1390 __ jcc(Assembler::greaterEqual, L_loop);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1391
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1392 __ addptr(qword_count, 4); // add(8) and sub(4)
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1393 __ jccb(Assembler::less, L_end);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1394 // Copy trailing 32 bytes
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1395 if (UseAVX >= 2) {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1396 __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1397 __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1398 } else {
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1399 __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1400 __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1401 __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1402 __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1403 }
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1404 __ subptr(qword_count, 4);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1405 __ BIND(L_end);
8873
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1406 if (UseAVX >= 2) {
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1407 // clean upper bits of YMM registers
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1408 __ vzeroupper();
e961c11b85fe 8011102: Clear AVX registers after return from JNI call
kvn
parents: 7475
diff changeset
1409 }
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1410 } else {
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1411 // Copy 32-bytes per iteration
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1412 __ BIND(L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1413 __ movq(to, Address(from, qword_count, Address::times_8, 24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1414 __ movq(Address(dest, qword_count, Address::times_8, 24), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1415 __ movq(to, Address(from, qword_count, Address::times_8, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1416 __ movq(Address(dest, qword_count, Address::times_8, 16), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1417 __ movq(to, Address(from, qword_count, Address::times_8, 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1418 __ movq(Address(dest, qword_count, Address::times_8, 8), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1419 __ movq(to, Address(from, qword_count, Address::times_8, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1420 __ movq(Address(dest, qword_count, Address::times_8, 0), to);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1421
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1422 __ BIND(L_copy_bytes);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1423 __ subptr(qword_count, 4);
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1424 __ jcc(Assembler::greaterEqual, L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1425 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1426 __ addptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1429
a61af66fc99e Initial load
duke
parents:
diff changeset
1430
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 // we let the hardware handle it. The one to eight bytes within words,
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 // dwords or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // disjoint_byte_copy_entry is set to the no-overlap entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // used by generate_conjoint_byte_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1450 address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1454
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1455 Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 Label L_copy_byte, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 const Register byte_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 const Register end_to = to; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1469
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1470 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1471 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1472 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1473 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1474 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1480 __ movptr(byte_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1481 __ shrptr(count, 3); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1484 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1485 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1486 __ negptr(qword_count); // make the count negative
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1487 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1488
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1493 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1498 __ testl(byte_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1503 __ addptr(end_from, 4);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1504 __ addptr(end_to, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1505
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1508 __ testl(byte_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 __ movw(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 __ movw(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1512
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1513 __ addptr(end_from, 2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1514 __ addptr(end_to, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1515
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // Check for and copy trailing byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 __ BIND(L_copy_byte);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1518 __ testl(byte_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 __ movb(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 __ movb(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1525 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1526 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1530 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1531 copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1533
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1536
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // we let the hardware handle it. The one to eight bytes within words,
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // dwords or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1552 address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1553 address* entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1558 Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 const Register byte_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1564
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1567
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1568 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1569 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1570 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1571 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1572 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1573
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1574 array_overlap_test(nooverlap_target, Address::times_1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1577
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1579 __ movptr(byte_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1580 __ shrptr(count, 3); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1581
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // Copy from high to low addresses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // Check for and copy trailing byte
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1585 __ testl(byte_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 __ jcc(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 __ movb(rax, Address(from, byte_count, Address::times_1, -1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 __ movb(Address(to, byte_count, Address::times_1, -1), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1589 __ decrement(byte_count); // Adjust for possible trailing word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1593 __ testl(byte_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 __ jcc(Assembler::zero, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 __ movw(rax, Address(from, byte_count, Address::times_1, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 __ movw(Address(to, byte_count, Address::times_1, -2), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1597
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1600 __ testl(byte_count, 4);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1601 __ jcc(Assembler::zero, L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 __ movl(rax, Address(from, qword_count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 __ movl(Address(to, qword_count, Address::times_8), rax);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1604 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1610 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1612
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1614 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1615 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1618
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1619 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1620 copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1623 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1624 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // let the hardware handle it. The two or four words within dwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // disjoint_short_copy_entry is set to the no-overlap entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // used by generate_conjoint_short_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1650 address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1654
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1655 Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 const Register word_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 const Register end_to = to; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1669 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1670 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1671 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1672 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1673 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1674
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1677
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1679 __ movptr(word_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1680 __ shrptr(count, 2); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1681
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1683 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1684 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1685 __ negptr(qword_count);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1686 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1687
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1692 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // Original 'dest' is trashed, so we can't use it as a
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // base register for a possible trailing word copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1697
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1700 __ testl(word_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1704
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1705 __ addptr(end_from, 4);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1706 __ addptr(end_to, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1710 __ testl(word_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 __ movw(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 __ movw(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1717 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1718 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1721
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1722 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1723 copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1725
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1729 address generate_fill(BasicType t, bool aligned, const char *name) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1730 __ align(CodeEntryAlignment);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1731 StubCodeMark mark(this, "StubRoutines", name);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1732 address start = __ pc();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1733
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1734 BLOCK_COMMENT("Entry:");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1735
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1736 const Register to = c_rarg0; // source array address
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1737 const Register value = c_rarg1; // value
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1738 const Register count = c_rarg2; // elements count
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1739
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1740 __ enter(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1741
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1742 __ generate_fill(t, aligned, to, value, count, rax, xmm0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1743
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1744 __ leave(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1745 __ ret(0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1746 return start;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1747 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1748
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // let the hardware handle it. The two or four words within dwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1764 address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1765 address *entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1769
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1770 Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 const Register word_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1776
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1779
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1780 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1781 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1782 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1783 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1784 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1785
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1786 array_overlap_test(nooverlap_target, Address::times_2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1789
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1791 __ movptr(word_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1792 __ shrptr(count, 2); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1793
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // Copy from high to low addresses. Use 'to' as scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // Check for and copy trailing word
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1797 __ testl(word_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 __ jccb(Assembler::zero, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 __ movw(rax, Address(from, word_count, Address::times_2, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 __ movw(Address(to, word_count, Address::times_2, -2), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1804 __ testl(word_count, 2);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1805 __ jcc(Assembler::zero, L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 __ movl(rax, Address(from, qword_count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 __ movl(Address(to, qword_count, Address::times_8), rax);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1808 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1814 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1816
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1818 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1819 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1823 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1824 copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1825
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1827 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1828 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // ignored
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1838 // is_oop - true => oop array, so generate store check code
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 // the hardware handle it. The two dwords within qwords that span
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 // cache line boundaries will still be loaded and stored atomicly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // disjoint_int_copy_entry is set to the no-overlap entry point
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1852 // used by generate_conjoint_int_oop_copy().
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1854 address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1855 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1860 Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 const Register dword_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 const Register end_to = to; // destination array end address
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1868 const Register saved_to = r11; // saved destination array address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1874
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1875 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1876 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1877 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1878 BLOCK_COMMENT("Entry:");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1879 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1880
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // r9 and r10 may be used to save non-volatile registers
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1883 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1884 __ movq(saved_to, to);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1885 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1886 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1887
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1889 __ movptr(dword_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1890 __ shrptr(count, 1); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1891
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1893 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1894 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1895 __ negptr(qword_count);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1896 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1897
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1902 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1904
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1907 __ testl(dword_count, 1); // Only byte test since the value is 0 or 1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 __ BIND(L_exit);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1913 if (is_oop) {
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
1914 gen_write_ref_array_post_barrier(saved_to, dword_count, rax);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1915 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
1917 inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1918 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1921
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1922 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1923 copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 // ignored
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1932 // is_oop - true => oop array, so generate store check code
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 // the hardware handle it. The two dwords within qwords that span
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // cache line boundaries will still be loaded and stored atomicly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1944 address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1945 address *entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1946 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1951 Label L_copy_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 const Register dword_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1961 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1962 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1963 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1964 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1965 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1966
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1967 array_overlap_test(nooverlap_target, Address::times_4);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1968 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1969 // r9 and r10 may be used to save non-volatile registers
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1970
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1971 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1972 // no registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1973 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1974 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1975
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1976 assert_clean_int(count, rax); // Make sure 'count' is clean int.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1978 __ movptr(dword_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1979 __ shrptr(count, 1); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1980
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 // Copy from high to low addresses. Use 'to' as scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // Check for and copy trailing dword
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1984 __ testl(dword_count, 1);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1985 __ jcc(Assembler::zero, L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 __ movl(rax, Address(from, dword_count, Address::times_4, -4));
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 __ movl(Address(to, dword_count, Address::times_4, -4), rax);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
1988 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1989
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1994 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1996
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1997 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1998 __ jmp(L_exit);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1999 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2001 inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2002 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2006 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2007 copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2009 __ BIND(L_exit);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2010 if (is_oop) {
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2011 gen_write_ref_array_post_barrier(to, dword_count, rax);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2012 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2014 inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2015 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2018
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 // is_oop - true => oop array, so generate store check code
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 //
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2033 // Side Effects:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // no-overlap entry point used by generate_conjoint_long_oop_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2037 address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2038 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2042
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2043 Label L_copy_bytes, L_copy_8_bytes, L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 const Register qword_count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 const Register end_to = rcx; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 const Register saved_to = to;
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2050 const Register saved_count = r11;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // Save no-overlap entry point for generate_conjoint_long_oop_copy()
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
2057
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2058 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2059 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2060 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2061 BLOCK_COMMENT("Entry:");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // 'from', 'to' and 'qword_count' are now valid
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2067 if (is_oop) {
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2068 // Save to and count for store barrier
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2069 __ movptr(saved_count, qword_count);
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2070 // no registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2071 gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2072 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2073
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2075 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2076 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2077 __ negptr(qword_count);
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2078 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2079
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2084 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 __ jmp(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2091 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2092 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2097 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2098 copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2099
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 __ BIND(L_exit);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2102 gen_write_ref_array_post_barrier(saved_to, saved_count, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2105 if (is_oop) {
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2106 inc_counter_np(SharedRuntime::_oop_array_copy_ctr); // Update counter after rscratch1 is free
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2107 } else {
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2108 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); // Update counter after rscratch1 is free
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2109 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2110 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2113
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2116
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // is_oop - true => oop array, so generate store check code
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2128 address generate_conjoint_long_oop_copy(bool aligned, bool is_oop,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2129 address nooverlap_target, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2130 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2134
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2135 Label L_copy_bytes, L_copy_8_bytes, L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 const Register qword_count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 const Register saved_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
2140
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
2143
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2144 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2145 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2146 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2147 BLOCK_COMMENT("Entry:");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 }
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2149
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2150 array_overlap_test(nooverlap_target, Address::times_8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // 'from', 'to' and 'qword_count' are now valid
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // Save to and count for store barrier
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2156 __ movptr(saved_count, qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // No registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2158 gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2160
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2161 __ jmp(L_copy_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2162
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2167 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 __ jmp(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2174 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); // Update counter after rscratch1 is free
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2175 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2179
7475
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2180 // Copy in multi-bytes chunks
e2e6bf86682c 8005544: Use 256bit YMM registers in arraycopy stubs on x86
kvn
parents: 7427
diff changeset
2181 copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2182
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 __ BIND(L_exit);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2185 gen_write_ref_array_post_barrier(to, saved_count, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2188 if (is_oop) {
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2189 inc_counter_np(SharedRuntime::_oop_array_copy_ctr); // Update counter after rscratch1 is free
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2190 } else {
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2191 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); // Update counter after rscratch1 is free
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2192 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2193 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2196
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199
a61af66fc99e Initial load
duke
parents:
diff changeset
2200
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // Helper for generating a dynamic type check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // Smashes no registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 void generate_type_check(Register sub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 Register super_check_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 Register super_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 Label& L_success) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 assert_different_registers(sub_klass, super_check_offset, super_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2208
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 BLOCK_COMMENT("type_check:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2210
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 Label L_miss;
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2213 __ check_klass_subtype_fast_path(sub_klass, super_klass, noreg, &L_success, &L_miss, NULL,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2214 super_check_offset);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2215 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, &L_success, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 // Fall through on failure!
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 __ BIND(L_miss);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2220
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // Generate checkcasting array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 // c_rarg3 - size_t ckoff (super_check_offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 // not Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 // c_rarg4 - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // rsp+40 - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // rax == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // rax == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2238 address generate_checkcast_copy(const char *name, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2239 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 Label L_load_element, L_store_element, L_do_card_marks, L_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // Input registers (after setup_arg_regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 const Register length = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 const Register ckoff = rcx; // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 const Register ckval = r8; // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2249
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // Registers used as temps (r13, r14 are save-on-entry)
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 const Register end_to = r13; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 const Register count = rdx; // -(count_remaining)
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 const Register r14_length = r14; // saved copy of length
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // End pointers are inclusive, and if length is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
2257
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 const Register rax_oop = rax; // actual oop copied
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 const Register r11_klass = r11; // oop._klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2260
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 //---------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // if the two arrays are subtypes of Object[] but the
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // destination array type is not equal to or a supertype
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 // of the source type. Each element must be separately
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
2267
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2271
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2273
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 // caller guarantees that the arrays really are different
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 // otherwise, we would have to make conjoint checks
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 { Label L;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2278 array_overlap_test(L, TIMES_OOP);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 __ stop("checkcast_copy within a single array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 setup_arg_regs(4); // from => rdi, to => rsi, length => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // ckoff => rcx, ckval => r8
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // last argument (#4) is on stack on Win64
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2289 __ movptr(ckval, Address(rsp, 6 * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2291
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2292 // Caller of this entry point must set up the argument registers.
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2293 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2294 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2295 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2296 }
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2297
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2298 // allocate spill slots for r13, r14
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2299 enum {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2300 saved_r13_offset,
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2301 saved_r14_offset,
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2302 saved_rbp_offset
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2303 };
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2304 __ subptr(rsp, saved_rbp_offset * wordSize);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2305 __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2306 __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2307
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // check that int operands are properly extended to size_t
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 assert_clean_int(length, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 assert_clean_int(ckoff, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 BLOCK_COMMENT("assert consistent ckoff/ckval");
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // The ckoff and ckval must be mutually consistent,
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // even though caller generates both.
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 { Label L;
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 4118
diff changeset
2317 int sco_offset = in_bytes(Klass::super_check_offset_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 __ cmpl(ckoff, Address(ckval, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 __ stop("super_check_offset inconsistent");
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 // Loop-invariant addresses. They are exclusive end pointers.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2326 Address end_from_addr(from, length, TIMES_OOP, 0);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2327 Address end_to_addr(to, length, TIMES_OOP, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // Loop-variant addresses. They assume post-incremented count < 0.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2329 Address from_element_addr(end_from, count, TIMES_OOP, 0);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2330 Address to_element_addr(end_to, count, TIMES_OOP, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2331
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2332 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // Copy from low to high addresses, indexed from the end of each array.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2335 __ lea(end_from, end_from_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2336 __ lea(end_to, end_to_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2337 __ movptr(r14_length, length); // save a copy of the length
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2338 assert(length == count, ""); // else fix next line:
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2339 __ negptr(count); // negate and test the length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 __ jcc(Assembler::notZero, L_load_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2341
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // Empty array: Nothing to do.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2343 __ xorptr(rax, rax); // return 0 on (trivial) success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 __ jmp(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2345
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 // ======== begin loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 // (Loop is rotated; its entry is L_load_element.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // Loop control:
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 // for (count = -count; count != 0; count++)
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 // Base pointers src, dst are biased by 8*(count-1),to last element.
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
2351 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2352
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 __ BIND(L_store_element);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2354 __ store_heap_oop(to_element_addr, rax_oop); // store the oop
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2355 __ increment(count); // increment the count toward zero
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 __ jcc(Assembler::zero, L_do_card_marks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2357
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 // ======== loop entry is here ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 __ BIND(L_load_element);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2360 __ load_heap_oop(rax_oop, from_element_addr); // load the oop
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2361 __ testptr(rax_oop, rax_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 __ jcc(Assembler::zero, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2364 __ load_klass(r11_klass, rax_oop);// query the object klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 generate_type_check(r11_klass, ckoff, ckval, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 // ======== end loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2367
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 // It was a real error; we must depend on the caller to finish the job.
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // Emit GC store barriers for the oops we have copied (r14 + rdx),
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // 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
2372 assert_different_registers(rax, r14_length, count, to, end_to, rcx, rscratch1);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2373 Label L_post_barrier;
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2374 __ addptr(r14_length, count); // K = (original - remaining) oops
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2375 __ movptr(rax, r14_length); // save the value
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2376 __ 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
2377 __ jccb(Assembler::notZero, L_post_barrier);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2378 __ jmp(L_done); // K == 0, nothing was copied, skip post barrier
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2379
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 // Come here on success only.
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 __ BIND(L_do_card_marks);
10324
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2382 __ xorptr(rax, rax); // return 0 on success
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2383
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2384 __ BIND(L_post_barrier);
3f281b313240 8010927: Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy
kvn
parents: 8873
diff changeset
2385 gen_write_ref_array_post_barrier(to, r14_length, rscratch1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2386
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // Common exit point (success or failure).
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 __ BIND(L_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2389 __ movptr(r13, Address(rsp, saved_r13_offset * wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2390 __ movptr(r14, Address(rsp, saved_r14_offset * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 restore_arg_regs();
4118
59bc0d4d9ea3 7110489: C1: 64-bit tiered with ForceUnreachable: assert(reachable(src)) failed: Address should be reachable
never
parents: 4114
diff changeset
2392 inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); // Update counter after rscratch1 is free
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2398
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 // Generate 'unsafe' array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // Though just as safe as the other stubs, it takes an unscaled
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // size_t argument instead of an element count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 // c_rarg2 - byte count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 // Examines the alignment of the operands and dispatches
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 // to a long, int, short, or byte copy loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2412 address generate_unsafe_copy(const char *name,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2413 address byte_copy_entry, address short_copy_entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2414 address int_copy_entry, address long_copy_entry) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2415
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 Label L_long_aligned, L_int_aligned, L_short_aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
2417
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 // Input registers (before setup_arg_regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 const Register from = c_rarg0; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 const Register to = c_rarg1; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 const Register size = c_rarg2; // byte count (size_t)
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // Register used as a temp
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 const Register bits = rax; // test copy of low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
2425
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2429
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2431
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2434
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2435 __ mov(bits, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2436 __ orptr(bits, to);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2437 __ orptr(bits, size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2438
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 __ testb(bits, BytesPerLong-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 __ jccb(Assembler::zero, L_long_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
2441
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 __ testb(bits, BytesPerInt-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 __ jccb(Assembler::zero, L_int_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
2444
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 __ testb(bits, BytesPerShort-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2447
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 __ BIND(L_short_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2449 __ shrptr(size, LogBytesPerShort); // size => short_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2451
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 __ BIND(L_int_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2453 __ shrptr(size, LogBytesPerInt); // size => int_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2455
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 __ BIND(L_long_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2457 __ shrptr(size, LogBytesPerLong); // size => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2459
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 // Perform range checks on the proposed arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 // Kills temp, but nothing else.
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 // Also, clean the sign bits of src_pos and dst_pos.
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 void arraycopy_range_checks(Register src, // source array oop (c_rarg0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 Register src_pos, // source position (c_rarg1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 Register dst, // destination array oo (c_rarg2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 Register dst_pos, // destination position (c_rarg3)
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 Register length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 Register temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 Label& L_failed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 BLOCK_COMMENT("arraycopy_range_checks:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2474
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // if (src_pos + length > arrayOop(src)->length()) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 __ movl(temp, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 __ addl(temp, src_pos); // src_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 __ cmpl(temp, Address(src, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 // if (dst_pos + length > arrayOop(dst)->length()) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 __ movl(temp, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 __ addl(temp, dst_pos); // dst_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 __ cmpl(temp, Address(dst, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 // Have to clean up high 32-bits of 'src_pos' and 'dst_pos'.
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 // Move with sign extension can be used since they are positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 __ movslq(src_pos, src_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 __ movslq(dst_pos, dst_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2491
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 BLOCK_COMMENT("arraycopy_range_checks done");
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2494
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 // Generate generic array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 // c_rarg0 - src oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // c_rarg1 - src_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 // c_rarg2 - dst oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 // c_rarg3 - dst_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 // not Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 // c_rarg4 - element count (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 // Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 // rsp+40 - element count (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 // rax == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 // rax == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2512 address generate_generic_copy(const char *name,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2513 address byte_copy_entry, address short_copy_entry,
2409
348c0df561a9 7026307: DEBUG MESSAGE: broken null klass on amd64
iveresov
parents: 2407
diff changeset
2514 address int_copy_entry, address oop_copy_entry,
348c0df561a9 7026307: DEBUG MESSAGE: broken null klass on amd64
iveresov
parents: 2407
diff changeset
2515 address long_copy_entry, address checkcast_copy_entry) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 Label L_failed, L_failed_0, L_objArray;
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2519
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 // Input registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 const Register src = c_rarg0; // source array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 const Register src_pos = c_rarg1; // source position
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 const Register dst = c_rarg2; // destination array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 const Register dst_pos = c_rarg3; // destination position
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2525 #ifndef _WIN64
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2526 const Register length = c_rarg4;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 #else
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2528 const Address length(rsp, 6 * wordSize); // elements count is on stack on Win64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 { int modulus = CodeEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 int target = modulus - 5; // 5 = sizeof jmp(L_failed)
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 int advance = target - (__ offset() % modulus);
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 if (advance < 0) advance += modulus;
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 if (advance > 0) __ nop(advance);
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2538
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 // Short-hop target to L_failed. Makes for denser prologue code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 __ BIND(L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 __ jmp(L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 assert(__ offset() % CodeEntryAlignment == 0, "no further alignment needed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2543
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2546
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2548
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 inc_counter_np(SharedRuntime::_generic_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2551
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 //-----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 // if the following conditions are met:
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // (1) src and dst must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // (2) src_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 // (3) dst_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 // (4) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 // (5) src klass and dst klass should be the same and not NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // (6) src and dst should be arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // (7) src_pos + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // (8) dst_pos + length must not exceed length of dst.
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2565
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 // if (src == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2567 __ testptr(src, src); // src oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 size_t j1off = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2570
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 // if (src_pos < 0) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 __ testl(src_pos, src_pos); // src_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2574
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 // if (dst == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2576 __ testptr(dst, dst); // dst oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2578
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 // if (dst_pos < 0) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 __ testl(dst_pos, dst_pos); // dst_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 size_t j4off = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2583
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 // The first four tests are very dense code,
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // but not quite dense enough to put four
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // jumps in a 16-byte instruction fetch buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 // That's good, because some branch predicters
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 // do not like jumps so close together.
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 // Make sure of this.
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 guarantee(((j1off ^ j4off) & ~15) != 0, "I$ line of 1st & 4th jumps");
a61af66fc99e Initial load
duke
parents:
diff changeset
2591
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 // registers used as temp
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 const Register r11_length = r11; // elements count to copy
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 const Register r10_src_klass = r10; // array klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2595
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 // if (length < 0) return -1;
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2597 __ movl(r11_length, length); // length (elements count, 32-bits value)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 __ testl(r11_length, r11_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2600
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2601 __ load_klass(r10_src_klass, src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 // assert(src->klass() != NULL);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2604 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2605 BLOCK_COMMENT("assert klasses not null {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2606 Label L1, L2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2607 __ testptr(r10_src_klass, r10_src_klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 __ bind(L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 __ stop("broken null klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 __ bind(L2);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2612 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2613 __ cmpq(rax, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 __ jcc(Assembler::equal, L1); // this would be broken also
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2615 BLOCK_COMMENT("} assert klasses not null done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2618
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 // Load layout helper (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 // |array_tag| | header_size | element_type | |log2_element_size|
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 // 32 30 24 16 8 2 0
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2626
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 4118
diff changeset
2627 const int lh_offset = in_bytes(Klass::layout_helper_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2628
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 // Handle objArrays completely differently...
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2630 const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2631 __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 __ jcc(Assembler::equal, L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
2633
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 // if (src->klass() != dst->klass()) return -1;
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2635 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2636 __ cmpq(r10_src_klass, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 __ jcc(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2638
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2639 const Register rax_lh = rax; // layout helper
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2640 __ movl(rax_lh, Address(r10_src_klass, lh_offset));
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2641
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 // if (!src->is_Array()) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 __ cmpl(rax_lh, Klass::_lh_neutral_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 __ jcc(Assembler::greaterEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2645
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 // At this point, it is known to be a typeArray (array_tag 0x3).
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 #ifdef ASSERT
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2648 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2649 BLOCK_COMMENT("assert primitive array {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2650 Label L;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 __ jcc(Assembler::greaterEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 __ stop("must be a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 __ bind(L);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2655 BLOCK_COMMENT("} assert primitive array done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2658
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 r10, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2661
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
2662 // TypeArrayKlass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2667
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 const Register r10_offset = r10; // array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 const Register rax_elsize = rax_lh; // element size
a61af66fc99e Initial load
duke
parents:
diff changeset
2670
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 __ movl(r10_offset, rax_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 __ shrl(r10_offset, Klass::_lh_header_size_shift);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2673 __ andptr(r10_offset, Klass::_lh_header_size_mask); // array_offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2674 __ addptr(src, r10_offset); // src array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2675 __ addptr(dst, r10_offset); // dst array offset
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 BLOCK_COMMENT("choose copy loop based on element size");
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 __ andl(rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize
a61af66fc99e Initial load
duke
parents:
diff changeset
2678
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 // next registers should be set before the jump to corresponding stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 const Register from = c_rarg0; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 const Register to = c_rarg1; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 const Register count = c_rarg2; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2683
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 // 'from', 'to', 'count' registers should be set in such order
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // since they are the same as 'src', 'src_pos', 'dst'.
a61af66fc99e Initial load
duke
parents:
diff changeset
2686
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 __ BIND(L_copy_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 __ cmpl(rax_elsize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 __ jccb(Assembler::notEqual, L_copy_shorts);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2690 __ lea(from, Address(src, src_pos, Address::times_1, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2691 __ lea(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2692 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 __ jump(RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2694
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 __ BIND(L_copy_shorts);
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 __ cmpl(rax_elsize, LogBytesPerShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 __ jccb(Assembler::notEqual, L_copy_ints);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2698 __ lea(from, Address(src, src_pos, Address::times_2, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2699 __ lea(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2700 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2702
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 __ BIND(L_copy_ints);
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 __ cmpl(rax_elsize, LogBytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 __ jccb(Assembler::notEqual, L_copy_longs);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2706 __ lea(from, Address(src, src_pos, Address::times_4, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2707 __ lea(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2708 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2710
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 __ BIND(L_copy_longs);
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 #ifdef ASSERT
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2713 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2714 BLOCK_COMMENT("assert long copy {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2715 Label L;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 __ cmpl(rax_elsize, LogBytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 __ stop("must be long copy, but elsize is wrong");
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 __ bind(L);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2720 BLOCK_COMMENT("} assert long copy done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2723 __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2724 __ lea(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2725 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2727
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
2728 // ObjArrayKlass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 __ BIND(L_objArray);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2730 // live at this point: r10_src_klass, r11_length, src[_pos], dst[_pos]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2731
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 Label L_plain_copy, L_checkcast_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 // test array classes for subtyping
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2734 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2735 __ cmpq(r10_src_klass, rax); // usual case is exact equality
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 __ jcc(Assembler::notEqual, L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2737
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 // Identically typed arrays can be copied without element-wise checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 r10, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2741
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2742 __ lea(from, Address(src, src_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2744 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2745 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2746 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 __ BIND(L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 __ jump(RuntimeAddress(oop_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2749
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 __ BIND(L_checkcast_copy);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2751 // live at this point: r10_src_klass, r11_length, rax (dst_klass)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 // Before looking at dst.length, make sure dst is also an objArray.
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2754 __ cmpl(Address(rax, lh_offset), objArray_lh);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 __ jcc(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2756
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 // It is safe to examine both src.length and dst.length.
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 rax, L_failed);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2760
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2761 const Register r11_dst_klass = r11;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2762 __ load_klass(r11_dst_klass, dst); // reload
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2763
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 // Marshal the base address arguments now, freeing registers.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2765 __ lea(from, Address(src, src_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2767 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2769 __ movl(count, length); // length (reloaded)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 Register sco_temp = c_rarg3; // this register is free now
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 assert_different_registers(from, to, count, sco_temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 r11_dst_klass, r10_src_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 assert_clean_int(count, sco_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2774
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 // Generate the type check.
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 4118
diff changeset
2776 const int sco_offset = in_bytes(Klass::super_check_offset_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 __ movl(sco_temp, Address(r11_dst_klass, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 assert_clean_int(sco_temp, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2780
6831
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
2781 // Fetch destination element klass from the ObjArrayKlass header.
d8ce2825b193 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 6725
diff changeset
2782 int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2783 __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset));
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2784 __ movl( sco_temp, Address(r11_dst_klass, sco_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 assert_clean_int(sco_temp, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2786
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // the checkcast_copy loop needs two extra arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 assert(c_rarg3 == sco_temp, "#3 already in place");
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2789 // Set up arguments for checkcast_copy_entry.
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2790 setup_arg_regs(4);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2791 __ movptr(r8, r11_dst_klass); // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 __ jump(RuntimeAddress(checkcast_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2794
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 __ BIND(L_failed);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2796 __ xorptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2797 __ notptr(rax); // return -1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2800
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2803
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 void generate_arraycopy_stubs() {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2805 address entry;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2806 address entry_jbyte_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2807 address entry_jshort_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2808 address entry_jint_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2809 address entry_oop_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2810 address entry_jlong_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2811 address entry_checkcast_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2812
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2813 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2814 "jbyte_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2815 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2816 "jbyte_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2817
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2818 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2819 "jshort_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2820 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2821 "jshort_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2822
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2823 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2824 "jint_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2825 StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2826 &entry_jint_arraycopy, "jint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2827
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2828 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2829 "jlong_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2830 StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2831 &entry_jlong_arraycopy, "jlong_arraycopy");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2832
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2833
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2834 if (UseCompressedOops) {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2835 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2836 "oop_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2837 StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2838 &entry_oop_arraycopy, "oop_arraycopy");
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2839 StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(false, true, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2840 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2841 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2842 StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(false, true, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2843 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2844 /*dest_uninitialized*/true);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2845 } else {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2846 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2847 "oop_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2848 StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2849 &entry_oop_arraycopy, "oop_arraycopy");
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2850 StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(false, true, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2851 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2852 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2853 StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(false, true, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2854 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2855 /*dest_uninitialized*/true);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2856 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2857
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2858 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2859 StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2860 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2861
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2862 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2863 entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2864 entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2865 entry_jint_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2866 entry_jlong_arraycopy);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2867 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2868 entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2869 entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2870 entry_jint_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2871 entry_oop_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2872 entry_jlong_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2873 entry_checkcast_arraycopy);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2874
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2875 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2876 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2877 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2878 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2879 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2880 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2881
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // We don't generate specialized code for HeapWord-aligned source
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 // arrays, so just use the code we've already generated
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = StubRoutines::_jbyte_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 StubRoutines::_arrayof_jbyte_arraycopy = StubRoutines::_jbyte_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2886
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 StubRoutines::_arrayof_jshort_disjoint_arraycopy = StubRoutines::_jshort_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 StubRoutines::_arrayof_jshort_arraycopy = StubRoutines::_jshort_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2889
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2892
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2895
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2898
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2899 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2900 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2902
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2903 void generate_math_stubs() {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2904 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2905 StubCodeMark mark(this, "StubRoutines", "log");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2906 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2907
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2908 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2909 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2910 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2911 __ flog();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2912 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2913 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2914 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2915 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2916 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2917 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2918 StubCodeMark mark(this, "StubRoutines", "log10");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2919 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2920
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2921 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2922 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2923 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2924 __ flog10();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2925 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2926 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2927 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2928 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2929 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2930 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2931 StubCodeMark mark(this, "StubRoutines", "sin");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2932 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2933
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2934 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2935 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2936 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2937 __ trigfunc('s');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2938 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2939 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2940 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2941 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2942 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2943 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2944 StubCodeMark mark(this, "StubRoutines", "cos");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2945 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2946
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2947 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2948 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2949 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2950 __ trigfunc('c');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2951 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2952 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2953 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2954 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2955 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2956 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2957 StubCodeMark mark(this, "StubRoutines", "tan");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2958 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2959
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2960 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2961 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2962 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2963 __ trigfunc('t');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2964 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2965 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2966 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2967 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2968 }
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2969 {
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2970 StubCodeMark mark(this, "StubRoutines", "exp");
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2971 StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2972
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2973 __ subq(rsp, 8);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2974 __ movdbl(Address(rsp, 0), xmm0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2975 __ fld_d(Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2976 __ exp_with_fallback(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2977 __ fstp_d(Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2978 __ movdbl(xmm0, Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2979 __ addq(rsp, 8);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2980 __ ret(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2981 }
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2982 {
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2983 StubCodeMark mark(this, "StubRoutines", "pow");
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2984 StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2985
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2986 __ subq(rsp, 8);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2987 __ movdbl(Address(rsp, 0), xmm1);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2988 __ fld_d(Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2989 __ movdbl(Address(rsp, 0), xmm0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2990 __ fld_d(Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2991 __ pow_with_fallback(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2992 __ fstp_d(Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2993 __ movdbl(xmm0, Address(rsp, 0));
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2994 __ addq(rsp, 8);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2995 __ ret(0);
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 5903
diff changeset
2996 }
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2997 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2998
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
2999 // AES intrinsic stubs
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3000 enum {AESBlockSize = 16};
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3001
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3002 address generate_key_shuffle_mask() {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3003 __ align(16);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3004 StubCodeMark mark(this, "StubRoutines", "key_shuffle_mask");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3005 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3006 __ emit_data64( 0x0405060700010203, relocInfo::none );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3007 __ emit_data64( 0x0c0d0e0f08090a0b, relocInfo::none );
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3008 return start;
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
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3011 // 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
3012 // 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
3013 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
3014 __ movdqu(xmmdst, Address(key, offset));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3015 if (xmm_shuf_mask != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3016 __ pshufb(xmmdst, xmm_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3017 } else {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3018 __ pshufb(xmmdst, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3019 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3020 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3021
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3022 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3023 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3024 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3025 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3026 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3027 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3028 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3029 address generate_aescrypt_encryptBlock() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3030 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3031 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3032 StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3033 Label L_doLast;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3034 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3035
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3036 const Register from = c_rarg0; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3037 const Register to = c_rarg1; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3038 const Register key = c_rarg2; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3039 const Register keylen = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3040
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3041 const XMMRegister xmm_result = xmm0;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3042 const XMMRegister xmm_key_shuf_mask = xmm1;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3043 // On win64 xmm6-xmm15 must be preserved so don't use them.
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3044 const XMMRegister xmm_temp1 = xmm2;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3045 const XMMRegister xmm_temp2 = xmm3;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3046 const XMMRegister xmm_temp3 = xmm4;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3047 const XMMRegister xmm_temp4 = xmm5;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3048
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3049 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3050
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3051 // 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
3052 __ 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
3053
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3054 __ 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
3055 __ movdqu(xmm_result, Address(from, 0)); // get 16 bytes of input
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3056
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3057 // 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
3058 // we don't know if the key is aligned, hence not using load-execute form
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3059
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3060 load_key(xmm_temp1, key, 0x00, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3061 __ pxor(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3062
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3063 load_key(xmm_temp1, key, 0x10, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3064 load_key(xmm_temp2, key, 0x20, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3065 load_key(xmm_temp3, key, 0x30, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3066 load_key(xmm_temp4, key, 0x40, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3067
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3068 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3069 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3070 __ aesenc(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3071 __ aesenc(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3072
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3073 load_key(xmm_temp1, key, 0x50, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3074 load_key(xmm_temp2, key, 0x60, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3075 load_key(xmm_temp3, key, 0x70, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3076 load_key(xmm_temp4, key, 0x80, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3077
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3078 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3079 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3080 __ aesenc(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3081 __ aesenc(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3082
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3083 load_key(xmm_temp1, key, 0x90, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3084 load_key(xmm_temp2, key, 0xa0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3085
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3086 __ cmpl(keylen, 44);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3087 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3088
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3089 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3090 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3091
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3092 load_key(xmm_temp1, key, 0xb0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3093 load_key(xmm_temp2, key, 0xc0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3094
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3095 __ cmpl(keylen, 52);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3096 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3097
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3098 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3099 __ aesenc(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3100
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3101 load_key(xmm_temp1, key, 0xd0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3102 load_key(xmm_temp2, key, 0xe0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3103
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3104 __ BIND(L_doLast);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3105 __ aesenc(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3106 __ aesenclast(xmm_result, xmm_temp2);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3107 __ movdqu(Address(to, 0), xmm_result); // store the result
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3108 __ xorptr(rax, rax); // return 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3109 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3110 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3111
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3112 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3113 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3114
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3115
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3116 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3117 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3118 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3119 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3120 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3121 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3122 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3123 address generate_aescrypt_decryptBlock() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3124 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3125 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3126 StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3127 Label L_doLast;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3128 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3129
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3130 const Register from = c_rarg0; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3131 const Register to = c_rarg1; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3132 const Register key = c_rarg2; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3133 const Register keylen = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3134
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3135 const XMMRegister xmm_result = xmm0;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3136 const XMMRegister xmm_key_shuf_mask = xmm1;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3137 // On win64 xmm6-xmm15 must be preserved so don't use them.
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3138 const XMMRegister xmm_temp1 = xmm2;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3139 const XMMRegister xmm_temp2 = xmm3;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3140 const XMMRegister xmm_temp3 = xmm4;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3141 const XMMRegister xmm_temp4 = xmm5;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3142
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3143 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3144
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3145 // 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
3146 __ 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
3147
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3148 __ 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
3149 __ movdqu(xmm_result, Address(from, 0));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3150
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3151 // 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
3152 // so we start from 0x10 here and hit 0x00 last
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3153 // 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
3154 load_key(xmm_temp1, key, 0x10, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3155 load_key(xmm_temp2, key, 0x20, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3156 load_key(xmm_temp3, key, 0x30, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3157 load_key(xmm_temp4, key, 0x40, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3158
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3159 __ pxor (xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3160 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3161 __ aesdec(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3162 __ aesdec(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3163
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3164 load_key(xmm_temp1, key, 0x50, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3165 load_key(xmm_temp2, key, 0x60, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3166 load_key(xmm_temp3, key, 0x70, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3167 load_key(xmm_temp4, key, 0x80, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3168
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3169 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3170 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3171 __ aesdec(xmm_result, xmm_temp3);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3172 __ aesdec(xmm_result, xmm_temp4);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3173
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3174 load_key(xmm_temp1, key, 0x90, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3175 load_key(xmm_temp2, key, 0xa0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3176 load_key(xmm_temp3, key, 0x00, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3177
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3178 __ cmpl(keylen, 44);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3179 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3180
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3181 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3182 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3183
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3184 load_key(xmm_temp1, key, 0xb0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3185 load_key(xmm_temp2, key, 0xc0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3186
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3187 __ cmpl(keylen, 52);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3188 __ jccb(Assembler::equal, L_doLast);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3189
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3190 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3191 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3192
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3193 load_key(xmm_temp1, key, 0xd0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3194 load_key(xmm_temp2, key, 0xe0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3195
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3196 __ BIND(L_doLast);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3197 __ aesdec(xmm_result, xmm_temp1);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3198 __ aesdec(xmm_result, xmm_temp2);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3199
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3200 // for decryption the aesdeclast operation is always on key+0x00
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3201 __ aesdeclast(xmm_result, xmm_temp3);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3202 __ movdqu(Address(to, 0), xmm_result); // store the result
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3203 __ xorptr(rax, rax); // return 0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3204 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3205 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3206
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3207 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3208 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3209
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3210
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3211 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3212 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3213 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3214 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3215 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3216 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3217 // c_rarg3 - r vector byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3218 // c_rarg4 - input length
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3219 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3220 address generate_cipherBlockChaining_encryptAESCrypt() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3221 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3222 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3223 StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3224 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3225
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3226 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
3227 const Register from = c_rarg0; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3228 const Register to = c_rarg1; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3229 const Register key = c_rarg2; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3230 const Register rvec = c_rarg3; // r byte array initialized from initvector array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3231 // and left with the results of the last encryption block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3232 #ifndef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3233 const Register len_reg = c_rarg4; // src len (must be multiple of blocksize 16)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3234 #else
14909
4ca6dc0799b6 Backout jdk9 merge
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14518
diff changeset
3235 const Address len_mem(rsp, 6 * wordSize); // length is on stack on Win64
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3236 const Register len_reg = r10; // pick the first volatile windows register
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3237 #endif
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3238 const Register pos = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3239
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3240 // xmm register assignments for the loops below
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3241 const XMMRegister xmm_result = xmm0;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3242 const XMMRegister xmm_temp = xmm1;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3243 // keys 0-10 preloaded into xmm2-xmm12
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3244 const int XMM_REG_NUM_KEY_FIRST = 2;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3245 const int XMM_REG_NUM_KEY_LAST = 15;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3246 const XMMRegister xmm_key0 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3247 const XMMRegister xmm_key10 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST+10);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3248 const XMMRegister xmm_key11 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST+11);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3249 const XMMRegister xmm_key12 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST+12);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3250 const XMMRegister xmm_key13 = as_XMMRegister(XMM_REG_NUM_KEY_FIRST+13);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3251
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3252 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3253
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3254 #ifdef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3255 // on win64, fill len_reg from stack position
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3256 __ movl(len_reg, len_mem);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3257 // save the xmm registers which must be preserved 6-15
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3258 __ subptr(rsp, -rsp_after_call_off * wordSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3259 for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3260 __ movdqu(xmm_save(i), as_XMMRegister(i));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3261 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3262 #endif
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3263
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3264 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
3265 __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3266 // load up xmm regs xmm2 thru xmm12 with key 0x00 - 0xa0
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3267 for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x00; rnum <= XMM_REG_NUM_KEY_FIRST+10; rnum++) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3268 load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3269 offset += 0x10;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3270 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3271 __ 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
3272
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3273 // 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
3274 __ 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
3275 __ cmpl(rax, 44);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3276 __ jcc(Assembler::notEqual, L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3277
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3278 // 128 bit code follows here
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3279 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3280 __ align(OptoLoopAlignment);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3281
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3282 __ BIND(L_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3283 __ 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
3284 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3285 __ pxor (xmm_result, xmm_key0); // do the aes rounds
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3286 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_FIRST + 9; rnum++) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3287 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3288 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3289 __ aesenclast(xmm_result, xmm_key10);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3290 __ 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
3291 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3292 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3293 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3294 __ jcc(Assembler::notEqual, L_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3295
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3296 __ BIND(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3297 __ 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
3298
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3299 #ifdef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3300 // restore xmm regs belonging to calling function
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3301 for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3302 __ movdqu(as_XMMRegister(i), xmm_save(i));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3303 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3304 #endif
14909
4ca6dc0799b6 Backout jdk9 merge
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14518
diff changeset
3305 __ movl(rax, 0); // return 0 (why?)
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3306 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3307 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3308
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3309 __ BIND(L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3310 // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3311 load_key(xmm_key11, key, 0xb0, xmm_key_shuf_mask);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3312 load_key(xmm_key12, key, 0xc0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3313 __ cmpl(rax, 52);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3314 __ jcc(Assembler::notEqual, L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3315
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3316 // 192-bit code follows here (could be changed to use more xmm registers)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3317 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3318 __ align(OptoLoopAlignment);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3319
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3320 __ BIND(L_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3321 __ 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
3322 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3323 __ pxor (xmm_result, xmm_key0); // do the aes rounds
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3324 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_FIRST + 11; rnum++) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3325 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3326 }
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3327 __ aesenclast(xmm_result, xmm_key12);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3328 __ 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
3329 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3330 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3331 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3332 __ jcc(Assembler::notEqual, L_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3333 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3334
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3335 __ BIND(L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3336 // 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
3337 load_key(xmm_key13, key, 0xd0, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3338 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3339 __ align(OptoLoopAlignment);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3340
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3341 __ BIND(L_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3342 __ 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
3343 __ pxor (xmm_result, xmm_temp); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3344 __ pxor (xmm_result, xmm_key0); // do the aes rounds
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3345 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_FIRST + 13; rnum++) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3346 __ aesenc(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3347 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3348 load_key(xmm_temp, key, 0xe0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3349 __ aesenclast(xmm_result, xmm_temp);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3350 __ 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
3351 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3352 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3353 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3354 __ jcc(Assembler::notEqual, L_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3355 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3356
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3357 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3358 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3359
11127
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3360 // Safefetch stubs.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3361 void generate_safefetch(const char* name, int size, address* entry,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3362 address* fault_pc, address* continuation_pc) {
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3363 // safefetch signatures:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3364 // int SafeFetch32(int* adr, int errValue);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3365 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3366 //
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3367 // arguments:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3368 // c_rarg0 = adr
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3369 // c_rarg1 = errValue
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3370 //
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3371 // result:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3372 // PPC_RET = *adr or errValue
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3373
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3374 StubCodeMark mark(this, "StubRoutines", name);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3375
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3376 // Entry point, pc or function descriptor.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3377 *entry = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3378
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3379 // Load *adr into c_rarg1, may fault.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3380 *fault_pc = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3381 switch (size) {
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3382 case 4:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3383 // int32_t
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3384 __ movl(c_rarg1, Address(c_rarg0, 0));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3385 break;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3386 case 8:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3387 // int64_t
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3388 __ movq(c_rarg1, Address(c_rarg0, 0));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3389 break;
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3390 default:
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3391 ShouldNotReachHere();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3392 }
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3393
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3394 // return errValue or *adr
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3395 *continuation_pc = __ pc();
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3396 __ movq(rax, c_rarg1);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3397 __ ret(0);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3398 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3399
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3400 // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3401 // to hide instruction latency
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3402 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3403 // Arguments:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3404 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3405 // Inputs:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3406 // c_rarg0 - source byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3407 // c_rarg1 - destination byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3408 // c_rarg2 - K (key) in little endian int array
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3409 // c_rarg3 - r vector byte array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3410 // c_rarg4 - input length
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3411 //
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3412
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3413 address generate_cipherBlockChaining_decryptAESCrypt_Parallel() {
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3414 assert(UseAES, "need AES instructions and misaligned SSE support");
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3415 __ align(CodeEntryAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3416 StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3417 address start = __ pc();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3418
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3419 Label L_exit, L_key_192_256, L_key_256;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3420 Label L_singleBlock_loopTop_128, L_multiBlock_loopTop_128;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3421 Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3422 const Register from = c_rarg0; // source array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3423 const Register to = c_rarg1; // destination array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3424 const Register key = c_rarg2; // key array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3425 const Register rvec = c_rarg3; // r byte array initialized from initvector array address
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3426 // and left with the results of the last encryption block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3427 #ifndef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3428 const Register len_reg = c_rarg4; // src len (must be multiple of blocksize 16)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3429 #else
14909
4ca6dc0799b6 Backout jdk9 merge
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14518
diff changeset
3430 const Address len_mem(rsp, 6 * wordSize); // length is on stack on Win64
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3431 const Register len_reg = r10; // pick the first volatile windows register
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3432 #endif
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3433 const Register pos = rax;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3434
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3435 // keys 0-10 preloaded into xmm2-xmm12
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3436 const int XMM_REG_NUM_KEY_FIRST = 5;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3437 const int XMM_REG_NUM_KEY_LAST = 15;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3438 const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3439 const XMMRegister xmm_key_last = as_XMMRegister(XMM_REG_NUM_KEY_LAST);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3440
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3441 __ enter(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3442
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3443 #ifdef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3444 // on win64, fill len_reg from stack position
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3445 __ movl(len_reg, len_mem);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3446 // save the xmm registers which must be preserved 6-15
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3447 __ subptr(rsp, -rsp_after_call_off * wordSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3448 for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3449 __ movdqu(xmm_save(i), as_XMMRegister(i));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3450 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3451 #endif
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3452 // 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
3453 // so we start from 0x10 here and hit 0x00 last
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3454 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
3455 __ 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
3456 // load up xmm regs 5 thru 15 with key 0x10 - 0xa0 - 0x00
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3457 for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum < XMM_REG_NUM_KEY_LAST; rnum++) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3458 load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3459 offset += 0x10;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3460 }
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3461 load_key(xmm_key_last, key, 0x00, xmm_key_shuf_mask);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3462
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3463 const XMMRegister xmm_prev_block_cipher = xmm1; // holds cipher of previous block
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3464
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3465 // registers holding the four results in the parallelized loop
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3466 const XMMRegister xmm_result0 = xmm0;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3467 const XMMRegister xmm_result1 = xmm2;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3468 const XMMRegister xmm_result2 = xmm3;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3469 const XMMRegister xmm_result3 = xmm4;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3470
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3471 __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // initialize with initial rvec
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3472
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3473 // 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
3474 __ 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
3475 __ cmpl(rax, 44);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3476 __ jcc(Assembler::notEqual, L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3477
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3478
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3479 // 128-bit code follows here, parallelized
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3480 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3481 __ align(OptoLoopAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3482 __ BIND(L_multiBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3483 __ cmpptr(len_reg, 4*AESBlockSize); // see if at least 4 blocks left
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3484 __ jcc(Assembler::less, L_singleBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3485
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3486 __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0*AESBlockSize)); // get next 4 blocks into xmmresult registers
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3487 __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3488 __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3489 __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3490
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3491 #define DoFour(opc, src_reg) \
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3492 __ opc(xmm_result0, src_reg); \
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3493 __ opc(xmm_result1, src_reg); \
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3494 __ opc(xmm_result2, src_reg); \
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3495 __ opc(xmm_result3, src_reg);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3496
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3497 DoFour(pxor, xmm_key_first);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3498 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3499 DoFour(aesdec, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3500 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3501 DoFour(aesdeclast, xmm_key_last);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3502 // for each result, xor with the r vector of previous cipher block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3503 __ pxor(xmm_result0, xmm_prev_block_cipher);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3504 __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3505 __ pxor(xmm_result1, xmm_prev_block_cipher);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3506 __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3507 __ pxor(xmm_result2, xmm_prev_block_cipher);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3508 __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2*AESBlockSize));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3509 __ pxor(xmm_result3, xmm_prev_block_cipher);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3510 __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3*AESBlockSize)); // this will carry over to next set of blocks
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3511
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3512 __ movdqu(Address(to, pos, Address::times_1, 0*AESBlockSize), xmm_result0); // store 4 results into the next 64 bytes of output
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3513 __ movdqu(Address(to, pos, Address::times_1, 1*AESBlockSize), xmm_result1);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3514 __ movdqu(Address(to, pos, Address::times_1, 2*AESBlockSize), xmm_result2);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3515 __ movdqu(Address(to, pos, Address::times_1, 3*AESBlockSize), xmm_result3);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3516
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3517 __ addptr(pos, 4*AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3518 __ subptr(len_reg, 4*AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3519 __ jmp(L_multiBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3520
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3521 // registers used in the non-parallelized loops
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3522 // xmm register assignments for the loops below
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3523 const XMMRegister xmm_result = xmm0;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3524 const XMMRegister xmm_prev_block_cipher_save = xmm2;
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3525 const XMMRegister xmm_key11 = xmm3;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3526 const XMMRegister xmm_key12 = xmm4;
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3527 const XMMRegister xmm_temp = xmm4;
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3528
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3529 __ align(OptoLoopAlignment);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3530 __ BIND(L_singleBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3531 __ cmpptr(len_reg, 0); // any blocks left??
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3532 __ jcc(Assembler::equal, L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3533 __ 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
3534 __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3535 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3536 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3537 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3538 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3539 __ aesdeclast(xmm_result, xmm_key_last);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3540 __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3541 __ 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
3542 // no need to store r to memory until we exit
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3543 __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3544
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3545 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3546 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3547 __ jmp(L_singleBlock_loopTop_128);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3548
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3549
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3550 __ BIND(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3551 __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3552 #ifdef _WIN64
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3553 // restore regs belonging to calling function
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3554 for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3555 __ movdqu(as_XMMRegister(i), xmm_save(i));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3556 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3557 #endif
14909
4ca6dc0799b6 Backout jdk9 merge
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14518
diff changeset
3558 __ movl(rax, 0); // return 0 (why?)
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3559 __ leave(); // required for proper stackwalking of RuntimeStub frame
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3560 __ ret(0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3561
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3562
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3563 __ BIND(L_key_192_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3564 // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3565 load_key(xmm_key11, key, 0xb0);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3566 __ cmpl(rax, 52);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3567 __ jcc(Assembler::notEqual, L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3568
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3569 // 192-bit code follows here (could be optimized to use parallelism)
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3570 load_key(xmm_key12, key, 0xc0); // 192-bit key goes up to c0
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3571 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3572 __ align(OptoLoopAlignment);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3573
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3574 __ BIND(L_singleBlock_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3575 __ 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
3576 __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3577 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3578 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3579 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3580 }
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3581 __ aesdec(xmm_result, xmm_key11);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3582 __ aesdec(xmm_result, xmm_key12);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3583 __ aesdeclast(xmm_result, xmm_key_last); // xmm15 always came from key+0
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3584 __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3585 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3586 // no need to store r to memory until we exit
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3587 __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3588 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3589 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3590 __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3591 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3592
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3593 __ BIND(L_key_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3594 // 256-bit code follows here (could be optimized to use parallelism)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3595 __ movptr(pos, 0);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3596 __ align(OptoLoopAlignment);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3597
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3598 __ BIND(L_singleBlock_loopTop_256);
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3599 __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3600 __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3601 __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3602 for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3603 __ aesdec(xmm_result, as_XMMRegister(rnum));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3604 }
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3605 __ aesdec(xmm_result, xmm_key11);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3606 load_key(xmm_temp, key, 0xc0);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3607 __ aesdec(xmm_result, xmm_temp);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3608 load_key(xmm_temp, key, 0xd0);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3609 __ aesdec(xmm_result, xmm_temp);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3610 load_key(xmm_temp, key, 0xe0); // 256-bit key goes up to e0
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3611 __ aesdec(xmm_result, xmm_temp);
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3612 __ aesdeclast(xmm_result, xmm_key_last); // xmm15 came from key+0
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3613 __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3614 __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3615 // no need to store r to memory until we exit
7427
2c7f594145dc 8004835: Improve AES intrinsics on x86
kvn
parents: 7206
diff changeset
3616 __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3617 __ addptr(pos, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3618 __ subptr(len_reg, AESBlockSize);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3619 __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3620 __ jmp(L_exit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3621
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3622 return start;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3623 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3624
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3625 /**
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3626 * Arguments:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3627 *
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3628 * Inputs:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3629 * c_rarg0 - int crc
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3630 * c_rarg1 - byte* buf
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3631 * c_rarg2 - int length
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3632 *
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3633 * Ouput:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3634 * rax - int crc result
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3635 */
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3636 address generate_updateBytesCRC32() {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3637 assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3638
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3639 __ align(CodeEntryAlignment);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3640 StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3641
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3642 address start = __ pc();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3643 // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3644 // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3645 // rscratch1: r10
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3646 const Register crc = c_rarg0; // crc
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3647 const Register buf = c_rarg1; // source java byte array address
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3648 const Register len = c_rarg2; // length
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3649 const Register table = c_rarg3; // crc_table address (reuse register)
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3650 const Register tmp = r11;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3651 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
3652
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3653 BLOCK_COMMENT("Entry:");
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3654 __ 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
3655
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3656 __ kernel_crc32(crc, buf, len, table, tmp);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3657
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3658 __ movl(rax, crc);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3659 __ 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
3660 __ ret(0);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3661
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3662 return start;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3663 }
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3664
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 #undef __
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 #define __ masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
3667
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // Continuation point for throwing of implicit exceptions that are
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // not handled in the current activation. Fabricates an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // oop and initiates normal exception dispatching in this
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 // frame. Since we need to preserve callee-saved values (currently
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // only for C2, but done for C1 as well) we need a callee-saved oop
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 // map and therefore have to make these stubs into RuntimeStubs
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // rather than BufferBlobs. If the compiler needs all registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // be preserved between the fault point and the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // then it must assume responsibility for that in
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // AbstractCompiler::continuation_for_implicit_null_exception or
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // continuation_for_implicit_division_by_zero_exception. All other
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // implicit exceptions (e.g., NullPointerException or
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // AbstractMethodError on entry) are either at call sites or
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 // otherwise assume that stack unwinding will be initiated, so
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // caller saved registers were assumed volatile in the compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 address generate_throw_exception(const char* name,
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 address runtime_entry,
3451
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3685 Register arg1 = noreg,
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3686 Register arg2 = noreg) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 // Information about frame layout at time of blocking runtime call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // Note that we only have to preserve callee-saved registers since
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 // the compilers are responsible for supplying a continuation point
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 // if they expect all registers to be preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 enum layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 rbp_off = frame::arg_reg_save_area_bytes/BytesPerInt,
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 rbp_off2,
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 return_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 return_off2,
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 framesize // inclusive of return address
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3698
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 int insts_size = 512;
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 int locs_size = 64;
a61af66fc99e Initial load
duke
parents:
diff changeset
3701
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 CodeBuffer code(name, insts_size, locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 OopMapSet* oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 MacroAssembler* masm = new MacroAssembler(&code);
a61af66fc99e Initial load
duke
parents:
diff changeset
3705
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
3707
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // This is an inlined and slightly modified version of call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 // which has the ability to fetch the return PC out of
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 // thread-local storage and also sets up last_Java_sp slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 // differently than the real call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
3712
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3714
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 assert(is_even(framesize/2), "sp not 16-byte aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
3716
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 // return address and rbp are already in place
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3718 __ subptr(rsp, (framesize-4) << LogBytesPerInt); // prolog
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3719
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 int frame_complete = __ pc() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3721
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 // Set up last_Java_sp and last_Java_fp
4895
c742b0b47fe5 7119286: JSR292: SIGSEGV in JNIHandleBlock::release_block(JNIHandleBlock*, Thread*)+0x3c
roland
parents: 4771
diff changeset
3723 address the_pc = __ pc();
c742b0b47fe5 7119286: JSR292: SIGSEGV in JNIHandleBlock::release_block(JNIHandleBlock*, Thread*)+0x3c
roland
parents: 4771
diff changeset
3724 __ set_last_Java_frame(rsp, rbp, the_pc);
c742b0b47fe5 7119286: JSR292: SIGSEGV in JNIHandleBlock::release_block(JNIHandleBlock*, Thread*)+0x3c
roland
parents: 4771
diff changeset
3725 __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3726
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 // Call runtime
3451
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3728 if (arg1 != noreg) {
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3729 assert(arg2 != c_rarg1, "clobbered");
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3730 __ movptr(c_rarg1, arg1);
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3731 }
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3732 if (arg2 != noreg) {
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3733 __ movptr(c_rarg2, arg2);
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3734 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3735 __ movptr(c_rarg0, r15_thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 BLOCK_COMMENT("call runtime_entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 __ call(RuntimeAddress(runtime_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
3738
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 // Generate oop map
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 OopMap* map = new OopMap(framesize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3741
4941
b522995d91f0 7144405: JumbleGC002 assert(m->offset() == pc_offset) failed: oopmap not found
roland
parents: 4895
diff changeset
3742 oop_maps->add_gc_map(the_pc - start, map);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
4895
c742b0b47fe5 7119286: JSR292: SIGSEGV in JNIHandleBlock::release_block(JNIHandleBlock*, Thread*)+0x3c
roland
parents: 4771
diff changeset
3744 __ reset_last_Java_frame(true, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3745
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3747
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 // check for pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3751 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()),
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3752 (int32_t) NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3758
a61af66fc99e Initial load
duke
parents:
diff changeset
3759
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 // codeBlob framesize is in words (not VMRegImpl::slot_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 RuntimeStub* stub =
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 RuntimeStub::new_runtime_stub(name,
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 &code,
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 frame_complete,
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 (framesize >> (LogBytesPerWord - LogBytesPerInt)),
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 oop_maps, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 return stub->entry_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3769
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3770 void create_control_words() {
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3771 // Round to nearest, 53-bit mode, exceptions masked
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3772 StubRoutines::_fpu_cntrl_wrd_std = 0x027F;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3773 // Round to zero, 53-bit mode, exception mased
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3774 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3775 // Round to nearest, 24-bit mode, exceptions masked
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3776 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3777 // Round to nearest, 64-bit mode, exceptions masked
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3778 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3779 // Round to nearest, 64-bit mode, exceptions masked
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3780 StubRoutines::_mxcsr_std = 0x1F80;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3781 // Note: the following two constants are 80-bit values
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3782 // layout is critical for correct loading by FPU.
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3783 // Bias for strict fp multiply/divide
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3784 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3785 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3786 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3787 // Un-Bias for strict fp multiply/divide
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3788 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3789 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3790 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3791 }
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3792
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 // Initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 void generate_initial() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
3796
11166
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3797 // This platform-specific settings are needed by generate_call_stub()
0f57ccdb9084 8020433: Crash when using -XX:+RestoreMXCSROnJNICalls
kvn
parents: 11080
diff changeset
3798 create_control_words();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3799
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 // entry points that exist in all platforms Note: This is code
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 // that could be shared among different platforms - however the
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 // benefit seems to be smaller than the disadvantage of having a
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 // much more complicated generator structure. See also comment in
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 // stubRoutines.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
3805
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 StubRoutines::_forward_exception_entry = generate_forward_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
3807
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 StubRoutines::_call_stub_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 generate_call_stub(StubRoutines::_call_stub_return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
3810
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 // is referenced by megamorphic call
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 StubRoutines::_catch_exception_entry = generate_catch_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
3813
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 // atomic calls
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 StubRoutines::_atomic_xchg_ptr_entry = generate_atomic_xchg_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 StubRoutines::_atomic_add_entry = generate_atomic_add();
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 StubRoutines::_atomic_add_ptr_entry = generate_atomic_add_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 StubRoutines::_fence_entry = generate_orderaccess_fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
3822
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 StubRoutines::_handler_for_unsafe_access_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 generate_handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
3825
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 // platform dependent
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3827 StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
5903
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 4941
diff changeset
3828 StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3829
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3830 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
3451
38fa55e5e792 7055355: JSR 292: crash while throwing WrongMethodTypeException
never
parents: 2409
diff changeset
3831
4743
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3832 // Build this early so it's available for the interpreter.
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3833 StubRoutines::_throw_StackOverflowError_entry =
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3834 generate_throw_exception("StackOverflowError throw_exception",
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3835 CAST_FROM_FN_PTR(address,
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3836 SharedRuntime::
dca455dea3a7 7116216: StackOverflow GC crash
bdelsart
parents: 4118
diff changeset
3837 throw_StackOverflowError));
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3838 if (UseCRC32Intrinsics) {
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3839 // 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
3840 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
3841 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10973
diff changeset
3842 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3844
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 void generate_all() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
3847
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 // These entry points require SharedInfo::stack0 to be set up in
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 // non-core builds and need to be relocatable, so they each
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 // fabricate a RuntimeStub internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 StubRoutines::_throw_AbstractMethodError_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 generate_throw_exception("AbstractMethodError throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 SharedRuntime::
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3451
diff changeset
3855 throw_AbstractMethodError));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3856
16
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3857 StubRoutines::_throw_IncompatibleClassChangeError_entry =
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3858 generate_throw_exception("IncompatibleClassChangeError throw_exception",
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3859 CAST_FROM_FN_PTR(address,
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3860 SharedRuntime::
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3451
diff changeset
3861 throw_IncompatibleClassChangeError));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3862
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 StubRoutines::_throw_NullPointerException_at_call_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 generate_throw_exception("NullPointerException at call throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 SharedRuntime::
3937
c565834fb592 7088020: SEGV in JNIHandleBlock::release_block
never
parents: 3451
diff changeset
3867 throw_NullPointerException_at_call));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3868
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 // entry points that are platform specific
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3870 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3871 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3872 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3873 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3874
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3875 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3876 StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3877 StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3878 StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3879
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 // support for verify_oop (must happen after universe_init)
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3882
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 // arraycopy stubs used by compilers
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 generate_arraycopy_stubs();
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 845
diff changeset
3885
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
3886 generate_math_stubs();
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3887
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3888 // 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
3889 if (UseAESIntrinsics) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3890 StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask(); // needed by the others
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3891
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3892 StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3893 StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3894 StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3895 StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6831
diff changeset
3896 }
11127
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3897
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3898 // Safefetch stubs.
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3899 generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3900 &StubRoutines::_safefetch32_fault_pc,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3901 &StubRoutines::_safefetch32_continuation_pc);
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3902 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3903 &StubRoutines::_safefetchN_fault_pc,
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 11080
diff changeset
3904 &StubRoutines::_safefetchN_continuation_pc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3906
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 if (all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 generate_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 generate_initial();
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 }; // end class declaration
a61af66fc99e Initial load
duke
parents:
diff changeset
3916
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 void StubGenerator_generate(CodeBuffer* code, bool all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 StubGenerator g(code, all);
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 }