annotate src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 2007:5ddfcf4b079e

7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation. Reviewed-by: kvn, never
author iveresov
date Thu, 02 Dec 2010 17:21:12 -0800
parents ac637b7220d1
children 7601ab0e1e33
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
diff changeset
2 * Copyright (c) 2000, 2010, 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: 1378
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
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: 1378
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: 1830
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
26 #include "c1/c1_Compilation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
27 #include "c1/c1_LIRAssembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
28 #include "c1/c1_MacroAssembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
29 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
30 #include "c1/c1_ValueStack.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
31 #include "ci/ciArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
32 #include "ci/ciInstance.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
33 #include "gc_interface/collectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
34 #include "memory/barrierSet.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
35 #include "memory/cardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
36 #include "nativeInst_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
37 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1830
diff changeset
38 #include "runtime/sharedRuntime.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
39
a61af66fc99e Initial load
duke
parents:
diff changeset
40 #define __ _masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 //------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 bool LIR_Assembler::is_small_constant(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 if (opr->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 LIR_Const* constant = opr->as_constant_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 switch (constant->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 case T_INT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 jint value = constant->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
52 return Assembler::is_simm13(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
56 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 bool LIR_Assembler::is_single_instruction(LIR_Op* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 switch (op->code()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 case lir_null_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
66 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 case lir_add:
a61af66fc99e Initial load
duke
parents:
diff changeset
70 case lir_ushr:
a61af66fc99e Initial load
duke
parents:
diff changeset
71 case lir_shr:
a61af66fc99e Initial load
duke
parents:
diff changeset
72 case lir_shl:
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // integer shifts and adds are always one instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
74 return op->result_opr()->is_single_cpu();
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 case lir_move: {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 LIR_Op1* op1 = op->as_Op1();
a61af66fc99e Initial load
duke
parents:
diff changeset
79 LIR_Opr src = op1->in_opr();
a61af66fc99e Initial load
duke
parents:
diff changeset
80 LIR_Opr dst = op1->result_opr();
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 if (src == dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 NEEDS_CLEANUP;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // this works around a problem where moves with the same src and dst
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // end up in the delay slot and then the assembler swallows the mov
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // since it has no effect and then it complains because the delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // is empty. returning false stops the optimizer from putting this in
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // the delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // don't put moves involving oops into the delay slot since the VerifyOops code
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // will make it much larger than a single instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (VerifyOops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none ||
a61af66fc99e Initial load
duke
parents:
diff changeset
99 ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
103 if (UseCompressedOops) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
104 if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
105 if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
106 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
107
0
a61af66fc99e Initial load
duke
parents:
diff changeset
108 if (dst->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 return !PatchALot;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 } else if (src->is_single_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 if (src->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if (dst->is_address() && Assembler::is_simm13(dst->as_address_ptr()->disp())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return !PatchALot;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 } else if (dst->is_single_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (dst->is_register() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
125 ((src->is_register() && src->is_single_word() && src->is_same_type(dst)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
126 (src->is_constant() && LIR_Assembler::is_small_constant(op->as_Op1()->in_opr())))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
134 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 LIR_Opr LIR_Assembler::receiverOpr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return FrameMap::O0_oop_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 LIR_Opr LIR_Assembler::incomingReceiverOpr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 return FrameMap::I0_oop_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 LIR_Opr LIR_Assembler::osrBufferPointer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return FrameMap::I0_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 int LIR_Assembler::initial_frame_size_in_bytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return in_bytes(frame_map()->framesize_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // inline cache check: the inline cached class is in G5_inline_cache_reg(G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // we fetch the class of the receiver (O0) and compare it with the cached class.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // If they do not match we jump to slow case.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 int LIR_Assembler::check_icache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 int offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 __ inline_cache_check(O0, G5_inline_cache_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 void LIR_Assembler::osr_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp):
a61af66fc99e Initial load
duke
parents:
diff changeset
172 //
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // 1. Create a new compiled activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // 2. Initialize local variables in the compiled activation. The expression stack must be empty
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // at the osr_bci; it is not initialized.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // 3. Jump to the continuation address in compiled code to resume execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // OSR entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
179 offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
180 BlockBegin* osr_entry = compilation()->hir()->osr_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 ValueStack* entry_state = osr_entry->end()->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
182 int number_of_locks = entry_state->locks_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Create a frame for the compiled activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
185 __ build_frame(initial_frame_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // OSR buffer is
a61af66fc99e Initial load
duke
parents:
diff changeset
188 //
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // locals[nlocals-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // monitors[number_of_locks-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
191 //
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // locals is a direct copy of the interpreter frame so in the osr buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // so first slot in the local array is the last local from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // and last slot is local[0] (receiver) from the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
195 //
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // Similarly with locks. The first lock slot in the osr buffer is the nth lock
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // in the interpreter frame (the method lock if a sync method)
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Initialize monitors in the compiled activation.
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // I0: pointer to osr buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
202 //
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // All other registers are dead at this point and the locals will be
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // copied into place by code emitted in the IR.
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 Register OSR_buf = osrBufferPointer()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
a61af66fc99e Initial load
duke
parents:
diff changeset
208 int monitor_offset = BytesPerWord * method()->max_locals() +
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
209 (2 * BytesPerWord) * (number_of_locks - 1);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
210 // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
211 // the OSR buffer using 2 word entries: first the lock and then
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
212 // the oop.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213 for (int i = 0; i < number_of_locks; i++) {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
214 int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // verify the interpreter's monitor has a non-null object
a61af66fc99e Initial load
duke
parents:
diff changeset
217 {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 Label L;
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
219 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 __ cmp(G0, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 __ br(Assembler::notEqual, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
223 __ stop("locked object is NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
224 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // Copy the lock field into the compiled activation.
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
228 __ ld_ptr(OSR_buf, slot_offset + 0, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 __ st_ptr(O7, frame_map()->address_for_monitor_lock(i));
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
230 __ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
231 __ st_ptr(O7, frame_map()->address_for_monitor_object(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Optimized Library calls
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // This is the fast version of java.lang.String.compare; it has not
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // OSR-entry and therefore, we generate a slow version for OSR's
a61af66fc99e Initial load
duke
parents:
diff changeset
240 void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 Register str0 = left->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
242 Register str1 = right->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 Label Ldone;
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 Register result = dst->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
247 {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Get a pointer to the first character of string0 in tmp0 and get string0.count in str0
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Get a pointer to the first character of string1 in tmp1 and get string1.count in str1
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Also, get string0.count-string1.count in o7 and get the condition code set
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Note: some instructions have been hoisted for better instruction scheduling
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 Register tmp0 = L0;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 Register tmp1 = L1;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 Register tmp2 = L2;
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 int value_offset = java_lang_String:: value_offset_in_bytes(); // char array
a61af66fc99e Initial load
duke
parents:
diff changeset
258 int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
a61af66fc99e Initial load
duke
parents:
diff changeset
259 int count_offset = java_lang_String:: count_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
260
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
261 __ load_heap_oop(str0, value_offset, tmp0);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
262 __ ld(str0, offset_offset, tmp2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
263 __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
264 __ ld(str0, count_offset, str0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // str1 may be null
a61af66fc99e Initial load
duke
parents:
diff changeset
268 add_debug_info_for_null_check_here(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
269
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
270 __ load_heap_oop(str1, value_offset, tmp1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
271 __ add(tmp0, tmp2, tmp0);
a61af66fc99e Initial load
duke
parents:
diff changeset
272
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
273 __ ld(str1, offset_offset, tmp2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
274 __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
275 __ ld(str1, count_offset, str1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
276 __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 __ subcc(str0, str1, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 __ add(tmp1, tmp2, tmp1);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Compute the minimum of the string lengths, scale it and store it in limit
a61af66fc99e Initial load
duke
parents:
diff changeset
283 Register count0 = I0;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 Register count1 = I1;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 Register limit = L3;
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 Label Lskip;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 __ sll(count0, exact_log2(sizeof(jchar)), limit); // string0 is shorter
a61af66fc99e Initial load
duke
parents:
diff changeset
289 __ br(Assembler::greater, true, Assembler::pt, Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
290 __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit); // string1 is shorter
a61af66fc99e Initial load
duke
parents:
diff changeset
291 __ bind(Lskip);
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // If either string is empty (or both of them) the result is the difference in lengths
a61af66fc99e Initial load
duke
parents:
diff changeset
294 __ cmp(limit, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 __ br(Assembler::equal, true, Assembler::pn, Ldone);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 __ delayed()->mov(O7, result); // result is difference in lengths
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // Neither string is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
301 Label Lloop;
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 Register base0 = L0;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 Register base1 = L1;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 Register chr0 = I0;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 Register chr1 = I1;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 Register limit = L3;
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Shift base0 and base1 to the end of the arrays, negate limit
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ add(base0, limit, base0);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 __ add(base1, limit, base1);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 __ neg(limit); // limit = -min{string0.count, strin1.count}
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 __ lduh(base0, limit, chr0);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 __ bind(Lloop);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 __ lduh(base1, limit, chr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 __ subcc(chr0, chr1, chr0);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 __ br(Assembler::notZero, false, Assembler::pn, Ldone);
a61af66fc99e Initial load
duke
parents:
diff changeset
319 assert(chr0 == result, "result must be pre-placed");
a61af66fc99e Initial load
duke
parents:
diff changeset
320 __ delayed()->inccc(limit, sizeof(jchar));
a61af66fc99e Initial load
duke
parents:
diff changeset
321 __ br(Assembler::notZero, true, Assembler::pt, Lloop);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 __ delayed()->lduh(base0, limit, chr0);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // If strings are equal up to min length, return the length difference.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 __ mov(O7, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Otherwise, return the difference between the first mismatched chars.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 __ bind(Ldone);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // --------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 if (!GenerateSynchronizationCode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 Register obj_reg = obj_opr->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 Register lock_reg = lock_opr->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 Register reg = mon_addr.base();
a61af66fc99e Initial load
duke
parents:
diff changeset
343 int offset = mon_addr.disp();
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // compute pointer to BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
345 if (mon_addr.is_simm13()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 __ add(reg, offset, lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 __ set(offset, lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 __ add(reg, lock_reg, lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // unlock object
a61af66fc99e Initial load
duke
parents:
diff changeset
353 MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, UseFastLocking, monitor_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // _slow_case_stubs->append(slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // temporary fix: must be created after exceptionhandler, therefore as call stub
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _slow_case_stubs->append(slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (UseFastLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // try inlined fast unlocking first, revert to slow locking if it fails
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // note: lock_reg points to the displaced header since the displaced header offset is 0!
a61af66fc99e Initial load
duke
parents:
diff changeset
360 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
a61af66fc99e Initial load
duke
parents:
diff changeset
361 __ unlock_object(hdr, obj_reg, lock_reg, *slow_case->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // always do slow unlocking
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // note: the slow unlocking code could be inlined here, however if we use
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // slow unlocking, speed doesn't matter anyway and this solution is
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // simpler and requires less duplicated code - additionally, the
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // slow unlocking code is the same in either case which simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
369 __ br(Assembler::always, false, Assembler::pt, *slow_case->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
370 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // done
a61af66fc99e Initial load
duke
parents:
diff changeset
373 __ bind(*slow_case->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
377 int LIR_Assembler::emit_exception_handler() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // if the last instruction is a call (typically to do a throw which
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // is coming at the end after block reordering) the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // must still point into the code area in order to avoid assertion
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // failures when searching for the corresponding bci => add a nop
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // (was bug 5/14/1999 - gri)
a61af66fc99e Initial load
duke
parents:
diff changeset
383 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // generate code for exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
386 ciMethod* method = compilation()->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 address handler_base = __ start_a_stub(exception_handler_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if (handler_base == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // not enough space left for the handler
a61af66fc99e Initial load
duke
parents:
diff changeset
392 bailout("exception handler overflow");
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
393 return -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
395
0
a61af66fc99e Initial load
duke
parents:
diff changeset
396 int offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
397
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
398 __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
399 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 debug_only(__ stop("should have gone to the caller");)
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(code_offset() - offset <= exception_handler_size, "overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
402 __ end_a_stub();
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
403
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
404 return offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
407
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
408 // Emit the code to remove the frame from the stack in the exception
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
409 // unwind path.
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
410 int LIR_Assembler::emit_unwind_handler() {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
411 #ifndef PRODUCT
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
412 if (CommentedAssembly) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
413 _masm->block_comment("Unwind handler");
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
414 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
415 #endif
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
416
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
417 int offset = code_offset();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
418
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
419 // Fetch the exception from TLS and clear out exception related thread state
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
420 __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), O0);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
421 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
422 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
423
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
424 __ bind(_unwind_handler_entry);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
425 __ verify_not_null_oop(O0);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
426 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
427 __ mov(O0, I0); // Preserve the exception
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
428 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
429
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
430 // Preform needed unlocking
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
431 MonitorExitStub* stub = NULL;
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
432 if (method()->is_synchronized()) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
433 monitor_address(0, FrameMap::I1_opr);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
434 stub = new MonitorExitStub(FrameMap::I1_opr, true, 0);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
435 __ unlock_object(I3, I2, I1, *stub->entry());
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
436 __ bind(*stub->continuation());
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
437 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
438
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
439 if (compilation()->env()->dtrace_method_probes()) {
1830
a3f7f95b0165 6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents: 1791
diff changeset
440 __ mov(G2_thread, O0);
a3f7f95b0165 6988018: dtrace/hotspot/MethodInvocation/MethodInvocation002 crashes with client compiler
never
parents: 1791
diff changeset
441 jobject2reg(method()->constant_encoding(), O1);
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
442 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), relocInfo::runtime_call_type);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
443 __ delayed()->nop();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
444 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
445
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
446 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
447 __ mov(I0, O0); // Restore the exception
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
448 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
449
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
450 // dispatch to the unwind logic
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
451 __ call(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
452 __ delayed()->nop();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
453
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
454 // Emit the slow path assembly
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
455 if (stub != NULL) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
456 stub->emit_code(this);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
457 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
458
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
459 return offset;
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
460 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
461
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
462
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
463 int LIR_Assembler::emit_deopt_handler() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // if the last instruction is a call (typically to do a throw which
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // is coming at the end after block reordering) the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // must still point into the code area in order to avoid assertion
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // failures when searching for the corresponding bci => add a nop
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // (was bug 5/14/1999 - gri)
a61af66fc99e Initial load
duke
parents:
diff changeset
469 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // generate code for deopt handler
a61af66fc99e Initial load
duke
parents:
diff changeset
472 ciMethod* method = compilation()->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
473 address handler_base = __ start_a_stub(deopt_handler_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 if (handler_base == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // not enough space left for the handler
a61af66fc99e Initial load
duke
parents:
diff changeset
476 bailout("deopt handler overflow");
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
477 return -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
479
0
a61af66fc99e Initial load
duke
parents:
diff changeset
480 int offset = code_offset();
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
481 AddressLiteral deopt_blob(SharedRuntime::deopt_blob()->unpack());
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
482 __ JUMP(deopt_blob, G3_scratch, 0); // sethi;jmp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
483 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
484 assert(code_offset() - offset <= deopt_handler_size, "overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
485 debug_only(__ stop("should have gone to the caller");)
a61af66fc99e Initial load
duke
parents:
diff changeset
486 __ end_a_stub();
1204
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
487
18a389214829 6921352: JSR 292 needs its own deopt handler
twisti
parents: 1201
diff changeset
488 return offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 void LIR_Assembler::jobject2reg(jobject o, Register reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if (o == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 __ set(NULL_WORD, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 int oop_index = __ oop_recorder()->find_index(o);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 RelocationHolder rspec = oop_Relocation::spec(oop_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
498 __ set(NULL_WORD, reg, rspec); // Will be set when the nmethod is created
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Allocate a new index in oop table to hold the oop once it's been patched
a61af66fc99e Initial load
duke
parents:
diff changeset
505 int oop_index = __ oop_recorder()->allocate_index((jobject)NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, oop_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
507
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
508 AddressLiteral addrlit(NULL, oop_Relocation::spec(oop_index));
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
509 assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // It may not seem necessary to use a sethi/add pair to load a NULL into dest, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // NULL will be dynamically patched later and the patched value may be large. We must
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // therefore generate the sethi/add as a placeholders
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
513 __ patchable_set(addrlit, reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 patching_epilog(patch, lir_patch_normal, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 void LIR_Assembler::emit_op3(LIR_Op3* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 Register Rdividend = op->in_opr1()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
521 Register Rdivisor = noreg;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 Register Rscratch = op->in_opr3()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
523 Register Rresult = op->result_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
524 int divisor = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (op->in_opr2()->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 Rdivisor = op->in_opr2()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
528 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 divisor = op->in_opr2()->as_constant_ptr()->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 assert(Assembler::is_simm13(divisor), "can only handle simm13");
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 assert(Rdividend != Rscratch, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
534 assert(Rdivisor != Rscratch, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
535 assert(op->code() == lir_idiv || op->code() == lir_irem, "Must be irem or idiv");
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (Rdivisor == noreg && is_power_of_2(divisor)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // convert division by a power of two into some shifts and logical operations
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (op->code() == lir_idiv) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if (divisor == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 __ srl(Rdividend, 31, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 __ sra(Rdividend, 31, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 __ and3(Rscratch, divisor - 1, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 __ add(Rdividend, Rscratch, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 __ sra(Rscratch, log2_intptr(divisor), Rresult);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 if (divisor == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
551 __ srl(Rdividend, 31, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
552 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 __ sra(Rdividend, 31, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 __ and3(Rscratch, divisor - 1,Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 __ add(Rdividend, Rscratch, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
557 __ andn(Rscratch, divisor - 1,Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 __ sub(Rdividend, Rscratch, Rresult);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 __ sra(Rdividend, 31, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 __ wry(Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (!VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // v9 doesn't require these nops
a61af66fc99e Initial load
duke
parents:
diff changeset
567 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
568 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
569 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
570 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 add_debug_info_for_div0_here(op->info());
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (Rdivisor != noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 __ sdivcc(Rdividend, Rdivisor, (op->code() == lir_idiv ? Rresult : Rscratch));
a61af66fc99e Initial load
duke
parents:
diff changeset
577 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 assert(Assembler::is_simm13(divisor), "can only handle simm13");
a61af66fc99e Initial load
duke
parents:
diff changeset
579 __ sdivcc(Rdividend, divisor, (op->code() == lir_idiv ? Rresult : Rscratch));
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
583 __ br(Assembler::overflowSet, true, Assembler::pn, skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 __ delayed()->Assembler::sethi(0x80000000, (op->code() == lir_idiv ? Rresult : Rscratch));
a61af66fc99e Initial load
duke
parents:
diff changeset
585 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 if (op->code() == lir_irem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if (Rdivisor != noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 __ smul(Rscratch, Rdivisor, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 __ smul(Rscratch, divisor, Rscratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593 __ sub(Rdividend, Rscratch, Rresult);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598 void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
599 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
600 assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (op->block() != NULL) _branch_target_blocks.append(op->block());
a61af66fc99e Initial load
duke
parents:
diff changeset
602 if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());
a61af66fc99e Initial load
duke
parents:
diff changeset
603 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
604 assert(op->info() == NULL, "shouldn't have CodeEmitInfo");
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 if (op->cond() == lir_cond_always) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 __ br(Assembler::always, false, Assembler::pt, *(op->label()));
a61af66fc99e Initial load
duke
parents:
diff changeset
608 } else if (op->code() == lir_cond_float_branch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
609 assert(op->ublock() != NULL, "must have unordered successor");
a61af66fc99e Initial load
duke
parents:
diff changeset
610 bool is_unordered = (op->ublock() == op->block());
a61af66fc99e Initial load
duke
parents:
diff changeset
611 Assembler::Condition acond;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 switch (op->cond()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 case lir_cond_equal: acond = Assembler::f_equal; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 case lir_cond_notEqual: acond = Assembler::f_notEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
615 case lir_cond_less: acond = (is_unordered ? Assembler::f_unorderedOrLess : Assembler::f_less); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 case lir_cond_greater: acond = (is_unordered ? Assembler::f_unorderedOrGreater : Assembler::f_greater); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
617 case lir_cond_lessEqual: acond = (is_unordered ? Assembler::f_unorderedOrLessOrEqual : Assembler::f_lessOrEqual); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 case lir_cond_greaterEqual: acond = (is_unordered ? Assembler::f_unorderedOrGreaterOrEqual: Assembler::f_greaterOrEqual); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
620 };
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (!VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625 __ fb( acond, false, Assembler::pn, *(op->label()));
a61af66fc99e Initial load
duke
parents:
diff changeset
626 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 assert (op->code() == lir_branch, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 Assembler::Condition acond;
a61af66fc99e Initial load
duke
parents:
diff changeset
630 switch (op->cond()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 case lir_cond_equal: acond = Assembler::equal; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 case lir_cond_notEqual: acond = Assembler::notEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 case lir_cond_less: acond = Assembler::less; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
634 case lir_cond_lessEqual: acond = Assembler::lessEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
635 case lir_cond_greaterEqual: acond = Assembler::greaterEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 case lir_cond_greater: acond = Assembler::greater; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
637 case lir_cond_aboveEqual: acond = Assembler::greaterEqualUnsigned; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 case lir_cond_belowEqual: acond = Assembler::lessEqualUnsigned; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
640 };
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // sparc has different condition codes for testing 32-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // vs. 64-bit values. We could always test xcc is we could
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // guarantee that 32-bit loads always sign extended but that isn't
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // true and since sign extension isn't free, it would impose a
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // slight cost.
a61af66fc99e Initial load
duke
parents:
diff changeset
647 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
648 if (op->type() == T_INT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 __ br(acond, false, Assembler::pn, *(op->label()));
a61af66fc99e Initial load
duke
parents:
diff changeset
650 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
651 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
652 __ brx(acond, false, Assembler::pn, *(op->label()));
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // The peephole pass fills the delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 Bytecodes::Code code = op->bytecode();
a61af66fc99e Initial load
duke
parents:
diff changeset
660 LIR_Opr dst = op->result_opr();
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 case Bytecodes::_i2l: {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 Register rlo = dst->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
665 Register rhi = dst->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
666 Register rval = op->in_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
667 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
668 __ sra(rval, 0, rlo);
a61af66fc99e Initial load
duke
parents:
diff changeset
669 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
670 __ mov(rval, rlo);
a61af66fc99e Initial load
duke
parents:
diff changeset
671 __ sra(rval, BitsPerInt-1, rhi);
a61af66fc99e Initial load
duke
parents:
diff changeset
672 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
673 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675 case Bytecodes::_i2d:
a61af66fc99e Initial load
duke
parents:
diff changeset
676 case Bytecodes::_i2f: {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 bool is_double = (code == Bytecodes::_i2d);
a61af66fc99e Initial load
duke
parents:
diff changeset
678 FloatRegister rdst = is_double ? dst->as_double_reg() : dst->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
679 FloatRegisterImpl::Width w = is_double ? FloatRegisterImpl::D : FloatRegisterImpl::S;
a61af66fc99e Initial load
duke
parents:
diff changeset
680 FloatRegister rsrc = op->in_opr()->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (rsrc != rdst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 __ fmov(FloatRegisterImpl::S, rsrc, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684 __ fitof(w, rdst, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687 case Bytecodes::_f2i:{
a61af66fc99e Initial load
duke
parents:
diff changeset
688 FloatRegister rsrc = op->in_opr()->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
689 Address addr = frame_map()->address_for_slot(dst->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
690 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // result must be 0 if value is NaN; test by comparing value to itself
a61af66fc99e Initial load
duke
parents:
diff changeset
692 __ fcmp(FloatRegisterImpl::S, Assembler::fcc0, rsrc, rsrc);
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (!VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 __ nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 __ fb(Assembler::f_unordered, true, Assembler::pn, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 __ delayed()->st(G0, addr); // annuled if contents of rsrc is not NaN
a61af66fc99e Initial load
duke
parents:
diff changeset
698 __ ftoi(FloatRegisterImpl::S, rsrc, rsrc);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // move integer result from float register to int register
a61af66fc99e Initial load
duke
parents:
diff changeset
700 __ stf(FloatRegisterImpl::S, rsrc, addr.base(), addr.disp());
a61af66fc99e Initial load
duke
parents:
diff changeset
701 __ bind (L);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
704 case Bytecodes::_l2i: {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 Register rlo = op->in_opr()->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
706 Register rhi = op->in_opr()->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
707 Register rdst = dst->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
708 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
709 __ sra(rlo, 0, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
711 __ mov(rlo, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
713 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715 case Bytecodes::_d2f:
a61af66fc99e Initial load
duke
parents:
diff changeset
716 case Bytecodes::_f2d: {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 bool is_double = (code == Bytecodes::_f2d);
a61af66fc99e Initial load
duke
parents:
diff changeset
718 assert((!is_double && dst->is_single_fpu()) || (is_double && dst->is_double_fpu()), "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
719 LIR_Opr val = op->in_opr();
a61af66fc99e Initial load
duke
parents:
diff changeset
720 FloatRegister rval = (code == Bytecodes::_d2f) ? val->as_double_reg() : val->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
721 FloatRegister rdst = is_double ? dst->as_double_reg() : dst->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
722 FloatRegisterImpl::Width vw = is_double ? FloatRegisterImpl::S : FloatRegisterImpl::D;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 FloatRegisterImpl::Width dw = is_double ? FloatRegisterImpl::D : FloatRegisterImpl::S;
a61af66fc99e Initial load
duke
parents:
diff changeset
724 __ ftof(vw, dw, rval, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 case Bytecodes::_i2s:
a61af66fc99e Initial load
duke
parents:
diff changeset
728 case Bytecodes::_i2b: {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 Register rval = op->in_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
730 Register rdst = dst->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
731 int shift = (code == Bytecodes::_i2b) ? (BitsPerInt - T_BYTE_aelem_bytes * BitsPerByte) : (BitsPerInt - BitsPerShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
732 __ sll (rval, shift, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 __ sra (rdst, shift, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 case Bytecodes::_i2c: {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 Register rval = op->in_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
738 Register rdst = dst->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
739 int shift = BitsPerInt - T_CHAR_aelem_bytes * BitsPerByte;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 __ sll (rval, shift, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 __ srl (rdst, shift, rdst);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 void LIR_Assembler::align_call(LIR_Code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // do nothing since all instructions are word aligned on sparc
a61af66fc99e Initial load
duke
parents:
diff changeset
752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
753
a61af66fc99e Initial load
duke
parents:
diff changeset
754
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
755 void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
756 __ call(op->addr(), rtype);
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
757 // The peephole pass fills the delay slot, add_call_info is done in
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
758 // LIR_Assembler::emit_delay.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
762 void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
763 RelocationHolder rspec = virtual_call_Relocation::spec(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
764 __ set_oop((jobject)Universe::non_oop_word(), G5_inline_cache_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 __ relocate(rspec);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
766 __ call(op->addr(), relocInfo::none);
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
767 // The peephole pass fills the delay slot, add_call_info is done in
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
768 // LIR_Assembler::emit_delay.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
772 void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
773 add_debug_info_for_null_check_here(op->info());
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
774 __ load_klass(O0, G3_scratch);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
775 if (__ is_simm13(op->vtable_offset())) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
776 __ ld_ptr(G3_scratch, op->vtable_offset(), G5_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
777 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // This will generate 2 instructions
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1257
diff changeset
779 __ set(op->vtable_offset(), G5_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // ld_ptr, set_hi, set
a61af66fc99e Initial load
duke
parents:
diff changeset
781 __ ld_ptr(G3_scratch, G5_method, G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
783 __ ld_ptr(G5_method, methodOopDesc::from_compiled_offset(), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
784 __ callr(G3_scratch, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // the peephole pass fills the delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
788 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
789 int store_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 assert(!unaligned, "can't handle this");
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // for offsets larger than a simm13 we setup the offset in O7
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
793 __ set(offset, O7);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
794 store_offset = store(from_reg, base, O7, type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
795 } else {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
796 if (type == T_ARRAY || type == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
797 __ verify_oop(from_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
798 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
799 store_offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
800 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
801 case T_BOOLEAN: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
802 case T_BYTE : __ stb(from_reg->as_register(), base, offset); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 case T_CHAR : __ sth(from_reg->as_register(), base, offset); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
804 case T_SHORT : __ sth(from_reg->as_register(), base, offset); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
805 case T_INT : __ stw(from_reg->as_register(), base, offset); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
806 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
807 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (unaligned || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 __ srax(from_reg->as_register_lo(), 32, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
811 __ stw(O7, base, offset + hi_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 __ stx(from_reg->as_register_lo(), base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
815 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
816 assert(Assembler::is_simm13(offset + 4), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
817 __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
818 __ stw(from_reg->as_register_hi(), base, offset + hi_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
819 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
820 break;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
821 case T_ADDRESS:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
822 __ st_ptr(from_reg->as_register(), base, offset);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
823 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
824 case T_ARRAY : // fall through
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
825 case T_OBJECT:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
826 {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
827 if (UseCompressedOops && !wide) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
828 __ encode_heap_oop(from_reg->as_register(), G3_scratch);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
829 store_offset = code_offset();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
830 __ stw(G3_scratch, base, offset);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
831 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
832 __ st_ptr(from_reg->as_register(), base, offset);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
833 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
834 break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
835 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
836
0
a61af66fc99e Initial load
duke
parents:
diff changeset
837 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, offset); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
839 {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 FloatRegister reg = from_reg->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // split unaligned stores
a61af66fc99e Initial load
duke
parents:
diff changeset
842 if (unaligned || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 assert(Assembler::is_simm13(offset + 4), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
844 __ stf(FloatRegisterImpl::S, reg->successor(), base, offset + 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
845 __ stf(FloatRegisterImpl::S, reg, base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
846 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 __ stf(FloatRegisterImpl::D, reg, base, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854 return store_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
858 int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
859 if (type == T_ARRAY || type == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
860 __ verify_oop(from_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
861 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
862 int store_offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
863 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
864 case T_BOOLEAN: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
865 case T_BYTE : __ stb(from_reg->as_register(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
866 case T_CHAR : __ sth(from_reg->as_register(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 case T_SHORT : __ sth(from_reg->as_register(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 case T_INT : __ stw(from_reg->as_register(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
869 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
870 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
871 __ stx(from_reg->as_register_lo(), base, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
873 assert(from_reg->as_register_hi()->successor() == from_reg->as_register_lo(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
874 __ std(from_reg->as_register_hi(), base, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
876 break;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
877 case T_ADDRESS:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
878 __ st_ptr(from_reg->as_register(), base, disp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
879 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
880 case T_ARRAY : // fall through
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
881 case T_OBJECT:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
882 {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
883 if (UseCompressedOops && !wide) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
884 __ encode_heap_oop(from_reg->as_register(), G3_scratch);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
885 store_offset = code_offset();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
886 __ stw(G3_scratch, base, disp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
887 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
888 __ st_ptr(from_reg->as_register(), base, disp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
889 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
890 break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
891 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
892 case T_FLOAT : __ stf(FloatRegisterImpl::S, from_reg->as_float_reg(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
893 case T_DOUBLE: __ stf(FloatRegisterImpl::D, from_reg->as_double_reg(), base, disp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
894 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
896 return store_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898
a61af66fc99e Initial load
duke
parents:
diff changeset
899
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
900 int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
901 int load_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 assert(base != O7, "destroying register");
a61af66fc99e Initial load
duke
parents:
diff changeset
904 assert(!unaligned, "can't handle this");
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // for offsets larger than a simm13 we setup the offset in O7
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
906 __ set(offset, O7);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
907 load_offset = load(base, O7, to_reg, type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
908 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 load_offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
910 switch(type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 case T_BOOLEAN: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
912 case T_BYTE : __ ldsb(base, offset, to_reg->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 case T_CHAR : __ lduh(base, offset, to_reg->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
914 case T_SHORT : __ ldsh(base, offset, to_reg->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 case T_INT : __ ld(base, offset, to_reg->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
917 if (!unaligned) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
919 __ ldx(base, offset, to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
920 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
921 assert(to_reg->as_register_hi()->successor() == to_reg->as_register_lo(),
a61af66fc99e Initial load
duke
parents:
diff changeset
922 "must be sequential");
a61af66fc99e Initial load
duke
parents:
diff changeset
923 __ ldd(base, offset, to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
924 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
925 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
927 assert(base != to_reg->as_register_lo(), "can't handle this");
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
928 assert(O7 != to_reg->as_register_lo(), "can't handle this");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
929 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
930 __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
0
a61af66fc99e Initial load
duke
parents:
diff changeset
931 __ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
932 __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
933 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
934 if (base == to_reg->as_register_lo()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
936 __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
937 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
939 __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943 break;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
944 case T_ADDRESS: __ ld_ptr(base, offset, to_reg->as_register()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 case T_ARRAY : // fall through
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
946 case T_OBJECT:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
947 {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
948 if (UseCompressedOops && !wide) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
949 __ lduw(base, offset, to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
950 __ decode_heap_oop(to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
951 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
952 __ ld_ptr(base, offset, to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
953 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
954 break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
955 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
956 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
957 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
958 {
a61af66fc99e Initial load
duke
parents:
diff changeset
959 FloatRegister reg = to_reg->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // split unaligned loads
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if (unaligned || PatchALot) {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
962 __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
963 __ ldf(FloatRegisterImpl::S, base, offset, reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
964 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 __ ldf(FloatRegisterImpl::D, base, offset, to_reg->as_double_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
971 if (type == T_ARRAY || type == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
972 __ verify_oop(to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
973 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975 return load_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
979 int LIR_Assembler::load(Register base, Register disp, LIR_Opr to_reg, BasicType type, bool wide) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
980 int load_offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
981 switch(type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 case T_BOOLEAN: // fall through
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
983 case T_BYTE : __ ldsb(base, disp, to_reg->as_register()); break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
984 case T_CHAR : __ lduh(base, disp, to_reg->as_register()); break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
985 case T_SHORT : __ ldsh(base, disp, to_reg->as_register()); break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
986 case T_INT : __ ld(base, disp, to_reg->as_register()); break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
987 case T_ADDRESS: __ ld_ptr(base, disp, to_reg->as_register()); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
988 case T_ARRAY : // fall through
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
989 case T_OBJECT:
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
990 {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
991 if (UseCompressedOops && !wide) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
992 __ lduw(base, disp, to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
993 __ decode_heap_oop(to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
994 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
995 __ ld_ptr(base, disp, to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
996 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
997 break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
998 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
999 case T_FLOAT: __ ldf(FloatRegisterImpl::S, base, disp, to_reg->as_float_reg()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 case T_DOUBLE: __ ldf(FloatRegisterImpl::D, base, disp, to_reg->as_double_reg()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 __ ldx(base, disp, to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 assert(to_reg->as_register_hi()->successor() == to_reg->as_register_lo(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 "must be sequential");
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 __ ldd(base, disp, to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1012 if (type == T_ARRAY || type == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1013 __ verify_oop(to_reg->as_register());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1014 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 return load_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 LIR_Const* c = src->as_constant_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 switch (c->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 case T_INT:
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1022 case T_FLOAT: {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1023 Register src_reg = O7;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1024 int value = c->as_jint_bits();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1025 if (value == 0) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1026 src_reg = G0;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1027 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1028 __ set(value, O7);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1029 }
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1030 Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1031 __ stw(src_reg, addr.base(), addr.disp());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1032 break;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1033 }
1297
c466efa608d5 6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents: 1295
diff changeset
1034 case T_ADDRESS: {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 Register src_reg = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 int value = c->as_jint_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 if (value == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 src_reg = G0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 __ set(value, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1043 __ st_ptr(src_reg, addr.base(), addr.disp());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 case T_OBJECT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 Register src_reg = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 jobject2reg(c->as_jobject(), src_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 Address addr = frame_map()->address_for_slot(dest->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 __ st_ptr(src_reg, addr.base(), addr.disp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 case T_DOUBLE: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 Address addr = frame_map()->address_for_double_slot(dest->double_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 Register tmp = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 int value_lo = c->as_jint_lo_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 if (value_lo == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 tmp = G0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 __ set(value_lo, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 __ stw(tmp, addr.base(), addr.disp() + lo_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 int value_hi = c->as_jint_hi_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 if (value_hi == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 tmp = G0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 __ set(value_hi, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 __ stw(tmp, addr.base(), addr.disp() + hi_word_offset_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1078
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1080 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 LIR_Const* c = src->as_constant_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 LIR_Address* addr = dest->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 Register base = addr->base()->as_pointer_register();
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1084 int offset = -1;
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1085
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 switch (c->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 case T_INT:
1297
c466efa608d5 6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents: 1295
diff changeset
1088 case T_FLOAT:
c466efa608d5 6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents: 1295
diff changeset
1089 case T_ADDRESS: {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 LIR_Opr tmp = FrameMap::O7_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 int value = c->as_jint_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 if (value == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 tmp = FrameMap::G0_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 } else if (Assembler::is_simm13(value)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 __ set(value, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (addr->index()->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 assert(addr->disp() == 0, "must be zero");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1099 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1102 offset = store(tmp, base, addr->disp(), type, wide, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 case T_DOUBLE: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 assert(!addr->index()->is_valid(), "can't handle reg reg address here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 assert(Assembler::is_simm13(addr->disp()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 Assembler::is_simm13(addr->disp() + 4), "can't handle larger addresses");
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1112 LIR_Opr tmp = FrameMap::O7_opr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 int value_lo = c->as_jint_lo_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if (value_lo == 0) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1115 tmp = FrameMap::G0_opr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 __ set(value_lo, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1119 offset = store(tmp, base, addr->disp() + lo_word_offset_in_bytes, T_INT, wide, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 int value_hi = c->as_jint_hi_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 if (value_hi == 0) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1122 tmp = FrameMap::G0_opr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 __ set(value_hi, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1126 offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 case T_OBJECT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 jobject obj = c->as_jobject();
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 LIR_Opr tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 if (obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 tmp = FrameMap::G0_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 tmp = FrameMap::O7_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 jobject2reg(c->as_jobject(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // handle either reg+reg or reg+disp address
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 if (addr->index()->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 assert(addr->disp() == 0, "must be zero");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1141 offset = store(tmp, base, addr->index()->as_pointer_register(), type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 assert(Assembler::is_simm13(addr->disp()), "can't handle larger addresses");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1144 offset = store(tmp, base, addr->disp(), type, wide, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1152 if (info != NULL) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1153 assert(offset != -1, "offset should've been set");
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1154 add_debug_info_for_null_check(offset, info);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1155 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 LIR_Const* c = src->as_constant_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 LIR_Opr to_reg = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 switch (c->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 case T_INT:
1297
c466efa608d5 6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents: 1295
diff changeset
1165 case T_ADDRESS:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 jint con = c->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 if (to_reg->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 assert(patch_code == lir_patch_none, "no patching handled here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 __ set(con, to_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 assert(to_reg->is_single_fpu(), "wrong register kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 __ set(con, O7);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1176 Address temp_slot(SP, (frame::register_save_words * wordSize) + STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 __ st(O7, temp_slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 __ ldf(FloatRegisterImpl::S, temp_slot, to_reg->as_float_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 jlong con = c->as_jlong();
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 if (to_reg->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 __ set(con, to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 __ set(low(con), to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 __ set(high(con), to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 } else if (to_reg->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ set(con, to_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 assert(to_reg->is_double_fpu(), "wrong register kind");
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1201 Address temp_slot_lo(SP, ((frame::register_save_words ) * wordSize) + STACK_BIAS);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1202 Address temp_slot_hi(SP, ((frame::register_save_words) * wordSize) + (longSize/2) + STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 __ set(low(con), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 __ st(O7, temp_slot_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 __ set(high(con), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 __ st(O7, temp_slot_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 __ ldf(FloatRegisterImpl::D, temp_slot_lo, to_reg->as_double_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if (patch_code == lir_patch_none) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 jobject2reg(c->as_jobject(), to_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 jobject2reg_with_patching(to_reg->as_register(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 address const_addr = __ float_constant(c->as_jfloat());
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (const_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 bailout("const section overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 RelocationHolder rspec = internal_word_Relocation::spec(const_addr);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1230 AddressLiteral const_addrlit(const_addr, rspec);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (to_reg->is_single_fpu()) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1232 __ patchable_sethi(const_addrlit, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 __ relocate(rspec);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1234 __ ldf(FloatRegisterImpl::S, O7, const_addrlit.low10(), to_reg->as_float_reg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 assert(to_reg->is_single_cpu(), "Must be a cpu register.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1239 __ set(const_addrlit, O7);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1240 __ ld(O7, 0, to_reg->as_register());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 address const_addr = __ double_constant(c->as_jdouble());
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 if (const_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 bailout("const section overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 RelocationHolder rspec = internal_word_Relocation::spec(const_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 if (to_reg->is_double_fpu()) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1255 AddressLiteral const_addrlit(const_addr, rspec);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1256 __ patchable_sethi(const_addrlit, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 __ relocate(rspec);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1258 __ ldf (FloatRegisterImpl::D, O7, const_addrlit.low10(), to_reg->as_double_reg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 assert(to_reg->is_double_cpu(), "Must be a long register.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 __ set(jlong_cast(c->as_jdouble()), to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 __ set(low(jlong_cast(c->as_jdouble())), to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 __ set(high(jlong_cast(c->as_jdouble())), to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 Address LIR_Assembler::as_Address(LIR_Address* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 Register reg = addr->base()->as_register();
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1279 return Address(reg, addr->disp());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1281
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 case T_FLOAT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 Register tmp = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 Address from = frame_map()->address_for_slot(src->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 Address to = frame_map()->address_for_slot(dest->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 __ lduw(from.base(), from.disp(), tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 __ stw(tmp, to.base(), to.disp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 case T_OBJECT: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 Register tmp = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 Address from = frame_map()->address_for_slot(src->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 Address to = frame_map()->address_for_slot(dest->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 __ ld_ptr(from.base(), from.disp(), tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 __ st_ptr(tmp, to.base(), to.disp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 case T_DOUBLE: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 Register tmp = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 Address from = frame_map()->address_for_double_slot(src->double_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 Address to = frame_map()->address_for_double_slot(dest->double_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 __ lduw(from.base(), from.disp(), tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 __ stw(tmp, to.base(), to.disp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 __ lduw(from.base(), from.disp() + 4, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 __ stw(tmp, to.base(), to.disp() + 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 Address LIR_Assembler::as_Address_hi(LIR_Address* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 Address base = as_Address(addr);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1322 return Address(base.base(), base.disp() + hi_word_offset_in_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
a61af66fc99e Initial load
duke
parents:
diff changeset
1325
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 Address LIR_Assembler::as_Address_lo(LIR_Address* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 Address base = as_Address(addr);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1328 return Address(base.base(), base.disp() + lo_word_offset_in_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type,
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1333 LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool unaligned) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 LIR_Address* addr = src_opr->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 LIR_Opr to_reg = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 Register src = addr->base()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 Register disp_reg = noreg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 int disp_value = addr->disp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 bool needs_patching = (patch_code != lir_patch_none);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 if (addr->base()->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 __ verify_oop(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 PatchingStub* patch = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 patch = new PatchingStub(_masm, PatchingStub::access_field_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 assert(!to_reg->is_double_cpu() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 patch_code == lir_patch_none ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 patch_code == lir_patch_normal, "patching doesn't match register");
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 if (addr->index()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 if (!Assembler::is_simm13(disp_value) && (!unaligned || Assembler::is_simm13(disp_value + 4))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 if (needs_patching) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1358 __ patchable_set(0, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 __ set(disp_value, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 disp_reg = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 } else if (unaligned || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 __ add(src, addr->index()->as_register(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 src = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 disp_reg = addr->index()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 assert(disp_value == 0, "can't handle 3 operand addresses");
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // remember the offset of the load. The patching_epilog must be done
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // before the call to add_debug_info, otherwise the PcDescs don't get
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // entered in increasing order.
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 int offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 if (disp_reg == noreg) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1379 offset = load(src, disp_value, to_reg, type, wide, unaligned);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 assert(!unaligned, "can't handle this");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1382 offset = load(src, disp_reg, to_reg, type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 if (patch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 patching_epilog(patch, patch_code, src, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 if (info != NULL) add_debug_info_for_null_check(offset, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 void LIR_Assembler::prefetchr(LIR_Opr src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 LIR_Address* addr = src->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 Address from_addr = as_Address(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1395
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 if (VM_Version::has_v9()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 __ prefetch(from_addr, Assembler::severalReads);
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 void LIR_Assembler::prefetchw(LIR_Opr src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 LIR_Address* addr = src->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 Address from_addr = as_Address(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (VM_Version::has_v9()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 __ prefetch(from_addr, Assembler::severalWritesAndPossiblyReads);
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 Address addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 if (src->is_single_word()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 addr = frame_map()->address_for_slot(src->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 } else if (src->is_double_word()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 addr = frame_map()->address_for_double_slot(src->double_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1419
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1421 load(addr.base(), addr.disp(), dest, dest->type(), true /*wide*/, unaligned);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
a61af66fc99e Initial load
duke
parents:
diff changeset
1424
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 void LIR_Assembler::reg2stack(LIR_Opr from_reg, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 Address addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 if (dest->is_single_word()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 addr = frame_map()->address_for_slot(dest->single_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 } else if (dest->is_double_word()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 addr = frame_map()->address_for_slot(dest->double_stack_ix());
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 bool unaligned = (addr.disp() - STACK_BIAS) % 8 != 0;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1433 store(from_reg, addr.base(), addr.disp(), from_reg->type(), true /*wide*/, unaligned);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1435
a61af66fc99e Initial load
duke
parents:
diff changeset
1436
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 if (from_reg->is_float_kind() && to_reg->is_float_kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 if (from_reg->is_double_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 // double to double moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 assert(to_reg->is_double_fpu(), "should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 __ fmov(FloatRegisterImpl::D, from_reg->as_double_reg(), to_reg->as_double_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // float to float moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 assert(to_reg->is_single_fpu(), "should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 __ fmov(FloatRegisterImpl::S, from_reg->as_float_reg(), to_reg->as_float_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 } else if (!from_reg->is_float_kind() && !to_reg->is_float_kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (from_reg->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 __ mov(from_reg->as_pointer_register(), to_reg->as_pointer_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 assert(to_reg->is_double_cpu() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 from_reg->as_register_hi() != to_reg->as_register_lo() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 from_reg->as_register_lo() != to_reg->as_register_hi(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 "should both be long and not overlap");
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // long to long moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 __ mov(from_reg->as_register_hi(), to_reg->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 __ mov(from_reg->as_register_lo(), to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 } else if (to_reg->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 // int to int moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 __ mov(from_reg->as_register(), to_reg->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // int to int moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 __ mov(from_reg->as_register(), to_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 if (to_reg->type() == T_OBJECT || to_reg->type() == T_ARRAY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 __ verify_oop(to_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1477
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 void LIR_Assembler::reg2mem(LIR_Opr from_reg, LIR_Opr dest, BasicType type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack,
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1481 bool wide, bool unaligned) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 LIR_Address* addr = dest->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 Register src = addr->base()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 Register disp_reg = noreg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 int disp_value = addr->disp();
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 bool needs_patching = (patch_code != lir_patch_none);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 if (addr->base()->is_oop_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 __ verify_oop(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 PatchingStub* patch = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 patch = new PatchingStub(_masm, PatchingStub::access_field_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 assert(!from_reg->is_double_cpu() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 patch_code == lir_patch_none ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 patch_code == lir_patch_normal, "patching doesn't match register");
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1500
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 if (addr->index()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 if (!Assembler::is_simm13(disp_value) && (!unaligned || Assembler::is_simm13(disp_value + 4))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 if (needs_patching) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1504 __ patchable_set(0, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 __ set(disp_value, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 disp_reg = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 } else if (unaligned || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 __ add(src, addr->index()->as_register(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 src = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 disp_reg = addr->index()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 assert(disp_value == 0, "can't handle 3 operand addresses");
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1517
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // remember the offset of the store. The patching_epilog must be done
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 // before the call to add_debug_info_for_null_check, otherwise the PcDescs don't get
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // entered in increasing order.
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 assert(disp_reg != noreg || Assembler::is_simm13(disp_value), "should have set this up");
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 if (disp_reg == noreg) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1525 offset = store(from_reg, src, disp_value, type, wide, unaligned);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 assert(!unaligned, "can't handle this");
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1528 offset = store(from_reg, src, disp_reg, type, wide);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 if (patch != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 patching_epilog(patch, patch_code, src, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 if (info != NULL) add_debug_info_for_null_check(offset, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 void LIR_Assembler::return_op(LIR_Opr result) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 // the poll may need a register so just pick one that isn't the return register
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1541 #if defined(TIERED) && !defined(_LP64)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 if (result->type_field() == LIR_OprDesc::long_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // Must move the result to G1
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 // Must leave proper result in O0,O1 and G1 (TIERED only)
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 __ sllx(I0, 32, G1); // Shift bits into high G1
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 __ srl (I1, 0, I1); // Zero extend O1 (harmless?)
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 __ or3 (I1, G1, G1); // OR 64 bits into G1
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1548 #ifdef ASSERT
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1549 // mangle it so any problems will show up
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1550 __ set(0xdeadbeef, I0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1551 __ set(0xdeadbeef, I1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1552 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 #endif // TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 __ set((intptr_t)os::get_polling_page(), L0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 __ relocate(relocInfo::poll_return_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 __ ld_ptr(L0, 0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 __ ret();
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 __ delayed()->restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1561
a61af66fc99e Initial load
duke
parents:
diff changeset
1562
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 __ set((intptr_t)os::get_polling_page(), tmp->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 if (info != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 add_debug_info_for_branch(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 __ relocate(relocInfo::poll_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1570
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 int offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 __ ld_ptr(tmp->as_register(), 0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1576
a61af66fc99e Initial load
duke
parents:
diff changeset
1577
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 void LIR_Assembler::emit_static_call_stub() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 address call_pc = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 address stub = __ start_a_stub(call_stub_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 if (stub == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 bailout("static call stub overflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1585
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 int start = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 __ relocate(static_stub_Relocation::spec(call_pc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 __ set_oop(NULL, G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // must be set to -1 at code generation time
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1591 AddressLiteral addrlit(-1);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
1592 __ jump_to(addrlit, G3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 assert(__ offset() - start <= call_stub_size, "stub too big");
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 __ end_a_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 if (opr1->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 __ fcmp(FloatRegisterImpl::S, Assembler::fcc0, opr1->as_float_reg(), opr2->as_float_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 } else if (opr1->is_double_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 __ fcmp(FloatRegisterImpl::D, Assembler::fcc0, opr1->as_double_reg(), opr2->as_double_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 } else if (opr1->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 if (opr2->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 switch (opr2->as_constant_ptr()->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 { jint con = opr2->as_constant_ptr()->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 if (Assembler::is_simm13(con)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 __ cmp(opr1->as_register(), con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 __ set(con, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 __ cmp(opr1->as_register(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1618
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // there are only equal/notequal comparisions on objects
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 { jobject con = opr2->as_constant_ptr()->as_jobject();
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 if (con == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 __ cmp(opr1->as_register(), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 jobject2reg(con, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 __ cmp(opr1->as_register(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 if (opr2->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 LIR_Address * addr = opr2->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 BasicType type = addr->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 if ( type == T_OBJECT ) __ ld_ptr(as_Address(addr), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 else __ ld(as_Address(addr), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 __ cmp(opr1->as_register(), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 __ cmp(opr1->as_register(), opr2->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 } else if (opr1->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 Register xlo = opr1->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 Register xhi = opr1->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 if (opr2->is_constant() && opr2->as_jlong() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles these cases");
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 __ orcc(xhi, G0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 __ orcc(xhi, xlo, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 } else if (opr2->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 Register ylo = opr2->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 Register yhi = opr2->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 __ cmp(xlo, ylo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 __ subcc(xlo, ylo, xlo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 __ subccc(xhi, yhi, xhi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 if (condition == lir_cond_equal || condition == lir_cond_notEqual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 __ orcc(xhi, xlo, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 } else if (opr1->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 LIR_Address * addr = opr1->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 BasicType type = addr->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 assert (opr2->is_constant(), "Checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 if ( type == T_OBJECT ) __ ld_ptr(as_Address(addr), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 else __ ld(as_Address(addr), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 __ cmp(O7, opr2->as_constant_ptr()->as_jint());
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op){
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 bool is_unordered_less = (code == lir_ucmp_fd2i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 if (left->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 __ float_cmp(true, is_unordered_less ? -1 : 1, left->as_float_reg(), right->as_float_reg(), dst->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 } else if (left->is_double_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 __ float_cmp(false, is_unordered_less ? -1 : 1, left->as_double_reg(), right->as_double_reg(), dst->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 } else if (code == lir_cmp_l2i) {
1369
0a43776437b6 6942223: c1 64 bit fixes
iveresov
parents: 1365
diff changeset
1695 #ifdef _LP64
0a43776437b6 6942223: c1 64 bit fixes
iveresov
parents: 1365
diff changeset
1696 __ lcmp(left->as_register_lo(), right->as_register_lo(), dst->as_register());
0a43776437b6 6942223: c1 64 bit fixes
iveresov
parents: 1365
diff changeset
1697 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 __ lcmp(left->as_register_hi(), left->as_register_lo(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 right->as_register_hi(), right->as_register_lo(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 dst->as_register());
1369
0a43776437b6 6942223: c1 64 bit fixes
iveresov
parents: 1365
diff changeset
1701 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1706
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 Assembler::Condition acond;
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 switch (condition) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 case lir_cond_equal: acond = Assembler::equal; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 case lir_cond_notEqual: acond = Assembler::notEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 case lir_cond_less: acond = Assembler::less; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 case lir_cond_lessEqual: acond = Assembler::lessEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 case lir_cond_greaterEqual: acond = Assembler::greaterEqual; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 case lir_cond_greater: acond = Assembler::greater; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 case lir_cond_aboveEqual: acond = Assembler::greaterEqualUnsigned; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 case lir_cond_belowEqual: acond = Assembler::lessEqualUnsigned; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 if (opr1->is_constant() && opr1->type() == T_INT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 Register dest = result->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // load up first part of constant before branch
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // and do the rest in the delay slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 if (!Assembler::is_simm13(opr1->as_jint())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 __ sethi(opr1->as_jint(), dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 } else if (opr1->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 const2reg(opr1, result, lir_patch_none, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 } else if (opr1->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 reg2reg(opr1, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 } else if (opr1->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 stack2reg(opr1, result, result->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 __ br(acond, false, Assembler::pt, skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 if (opr1->is_constant() && opr1->type() == T_INT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 Register dest = result->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 if (Assembler::is_simm13(opr1->as_jint())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 __ delayed()->or3(G0, opr1->as_jint(), dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // the sethi has been done above, so just put in the low 10 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 __ delayed()->or3(dest, opr1->as_jint() & 0x3ff, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // can't do anything useful in the delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 if (opr2->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 const2reg(opr2, result, lir_patch_none, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 } else if (opr2->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 reg2reg(opr2, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 } else if (opr2->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 stack2reg(opr2, result, result->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 __ bind(skip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 assert(info == NULL, "unused on this code path");
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 assert(left->is_register(), "wrong items state");
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 assert(dest->is_register(), "wrong items state");
a61af66fc99e Initial load
duke
parents:
diff changeset
1770
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 if (right->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 if (dest->is_float_kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1773
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 FloatRegister lreg, rreg, res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 FloatRegisterImpl::Width w;
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 if (right->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 w = FloatRegisterImpl::S;
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 lreg = left->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 rreg = right->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 res = dest->as_float_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 w = FloatRegisterImpl::D;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 lreg = left->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 rreg = right->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 res = dest->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 case lir_add: __ fadd(w, lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 case lir_sub: __ fsub(w, lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 case lir_mul: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 case lir_mul_strictfp: __ fmul(w, lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 case lir_div: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 case lir_div_strictfp: __ fdiv(w, lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 } else if (dest->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 Register dst_lo = dest->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 Register op1_lo = left->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 Register op2_lo = right->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 case lir_add:
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 __ add(op1_lo, op2_lo, dst_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 case lir_sub:
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 __ sub(op1_lo, op2_lo, dst_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1812
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 Register op1_lo = left->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 Register op1_hi = left->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 Register op2_lo = right->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 Register op2_hi = right->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 Register dst_lo = dest->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 Register dst_hi = dest->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1822
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 case lir_add:
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 __ addcc(op1_lo, op2_lo, dst_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 __ addc (op1_hi, op2_hi, dst_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 case lir_sub:
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 __ subcc(op1_lo, op2_lo, dst_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 __ subc (op1_hi, op2_hi, dst_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1833
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 assert (right->is_single_cpu(), "Just Checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1839
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 Register lreg = left->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 Register res = dest->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 Register rreg = right->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 case lir_add: __ add (lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 case lir_sub: __ sub (lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 case lir_mul: __ mult (lreg, rreg, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 assert (right->is_constant(), "must be constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
1852
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 if (dest->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 Register lreg = left->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 Register res = dest->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 int simm13 = right->as_constant_ptr()->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1857
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 case lir_add: __ add (lreg, simm13, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 case lir_sub: __ sub (lreg, simm13, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 case lir_mul: __ mult (lreg, simm13, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 Register lreg = left->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 Register res = dest->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 long con = right->as_constant_ptr()->as_jlong();
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 assert(Assembler::is_simm13(con), "must be simm13");
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 case lir_add: __ add (lreg, (int)con, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 case lir_sub: __ sub (lreg, (int)con, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 case lir_mul: __ mult (lreg, (int)con, res); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 void LIR_Assembler::fpop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // do nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1884
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr thread, LIR_Opr dest, LIR_Op* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 case lir_sin:
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 case lir_tan:
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 case lir_cos: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 assert(thread->is_valid(), "preserve the thread object for performance reasons");
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 assert(dest->as_double_reg() == F0, "the result will be in f0/f1");
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 case lir_sqrt: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 assert(!thread->is_valid(), "there is no need for a thread_reg for dsqrt");
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 FloatRegister src_reg = value->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 FloatRegister dst_reg = dest->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 __ fsqrt(FloatRegisterImpl::D, src_reg, dst_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 case lir_abs: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 assert(!thread->is_valid(), "there is no need for a thread_reg for fabs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 FloatRegister src_reg = value->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 FloatRegister dst_reg = dest->as_double_reg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 __ fabs(FloatRegisterImpl::D, src_reg, dst_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 default: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1915
a61af66fc99e Initial load
duke
parents:
diff changeset
1916
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 if (right->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 if (dest->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 int simm13 = right->as_constant_ptr()->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 case lir_logic_and: __ and3 (left->as_register(), simm13, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 case lir_logic_or: __ or3 (left->as_register(), simm13, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 case lir_logic_xor: __ xor3 (left->as_register(), simm13, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 long c = right->as_constant_ptr()->as_jlong();
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 assert(c == (int)c && Assembler::is_simm13(c), "out of range");
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 int simm13 = (int)c;
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 case lir_logic_and:
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 __ and3 (left->as_register_hi(), 0, dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 __ and3 (left->as_register_lo(), simm13, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 case lir_logic_or:
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 __ or3 (left->as_register_hi(), 0, dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 __ or3 (left->as_register_lo(), simm13, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 case lir_logic_xor:
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 __ xor3 (left->as_register_hi(), 0, dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 __ xor3 (left->as_register_lo(), simm13, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1952
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 assert(right->is_register(), "right should be in register");
a61af66fc99e Initial load
duke
parents:
diff changeset
1958
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 if (dest->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 case lir_logic_and: __ and3 (left->as_register(), right->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 case lir_logic_or: __ or3 (left->as_register(), right->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 case lir_logic_xor: __ xor3 (left->as_register(), right->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 Register l = (left->is_single_cpu() && left->is_oop_register()) ? left->as_register() :
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 left->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 Register r = (right->is_single_cpu() && right->is_oop_register()) ? right->as_register() :
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 right->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
1972
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 case lir_logic_and: __ and3 (l, r, dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 case lir_logic_or: __ or3 (l, r, dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 case lir_logic_xor: __ xor3 (l, r, dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 case lir_logic_and:
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 __ and3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 __ and3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1985
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 case lir_logic_or:
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 __ or3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 __ or3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1990
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 case lir_logic_xor:
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 __ xor3 (left->as_register_hi(), right->as_register_hi(), dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 __ xor3 (left->as_register_lo(), right->as_register_lo(), dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1995
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2002
a61af66fc99e Initial load
duke
parents:
diff changeset
2003
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 int LIR_Assembler::shift_amount(BasicType t) {
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
2005 int elem_size = type2aelembytes(t);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 switch (elem_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 case 1 : return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 case 2 : return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 case 4 : return 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 case 8 : return 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2017 void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 assert(exceptionOop->as_register() == Oexception, "should match");
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2019 assert(exceptionPC->as_register() == Oissuing_pc, "should match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 info->add_register_oop(exceptionOop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2023 // reuse the debug info from the safepoint poll for the throw op itself
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2024 address pc_for_athrow = __ pc();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2025 int pc_for_athrow_offset = __ offset();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2026 RelocationHolder rspec = internal_word_Relocation::spec(pc_for_athrow);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2027 __ set(pc_for_athrow, Oissuing_pc, rspec);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2028 add_call_info(pc_for_athrow_offset, info); // for exception handler
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2029
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2030 __ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2031 __ delayed()->nop();
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2032 }
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2033
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2034
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2035 void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2036 assert(exceptionOop->as_register() == Oexception, "should match");
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2037
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2038 __ br(Assembler::always, false, Assembler::pt, _unwind_handler_entry);
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2039 __ delayed()->nop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
a61af66fc99e Initial load
duke
parents:
diff changeset
2042
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 Register src = op->src()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 Register dst = op->dst()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 Register src_pos = op->src_pos()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 Register dst_pos = op->dst_pos()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 Register length = op->length()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 Register tmp = op->tmp()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 Register tmp2 = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 int flags = op->flags();
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 ciArrayKlass* default_type = op->expected_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 if (basic_type == T_ARRAY) basic_type = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2056
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 // set up the arraycopy stub information
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 ArrayCopyStub* stub = op->stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
2059
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 // always do stub if no type information is available. it's ok if
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 // the known type isn't loaded since the code sanity checks
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // in debug mode and the type isn't required when we know the exact type
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // also check that the type is an array type.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 29
diff changeset
2064 // We also, for now, always call the stub if the barrier set requires a
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 29
diff changeset
2065 // write_ref_pre barrier (which the stub does, but none of the optimized
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 29
diff changeset
2066 // cases currently does).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 29
diff changeset
2067 if (op->expected_type() == NULL ||
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 29
diff changeset
2068 Universe::heap()->barrier_set()->has_write_ref_pre_barrier()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 __ mov(src, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 __ mov(src_pos, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 __ mov(dst, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 __ mov(dst_pos, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 __ mov(length, O4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 __ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 __ bind(*stub->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 assert(default_type != NULL && default_type->is_array_klass(), "must be true at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
2083
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 // make sure src and dst are non-null and load array length
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 if (flags & LIR_OpArrayCopy::src_null_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 __ tst(src);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2087 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2090
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 if (flags & LIR_OpArrayCopy::dst_null_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 __ tst(dst);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2093 __ brx(Assembler::equal, false, Assembler::pn, *stub->entry());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // test src_pos register
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 __ tst(src_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 __ br(Assembler::less, false, Assembler::pn, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2103
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 // test dst_pos register
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 __ tst(dst_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 __ br(Assembler::less, false, Assembler::pn, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2110
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 if (flags & LIR_OpArrayCopy::length_positive_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // make sure length isn't negative
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 __ tst(length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 __ br(Assembler::less, false, Assembler::pn, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 if (flags & LIR_OpArrayCopy::src_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 __ ld(src, arrayOopDesc::length_offset_in_bytes(), tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 __ add(length, src_pos, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 __ cmp(tmp2, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 if (flags & LIR_OpArrayCopy::dst_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 __ ld(dst, arrayOopDesc::length_offset_in_bytes(), tmp2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 __ add(length, dst_pos, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 __ cmp(tmp2, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 __ br(Assembler::carrySet, false, Assembler::pn, *stub->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2133
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 if (flags & LIR_OpArrayCopy::type_check) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2135 if (UseCompressedOops) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2136 // We don't need decode because we just need to compare
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2137 __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2138 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2139 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2140 __ br(Assembler::notEqual, false, Assembler::pt, *stub->entry());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2141 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2142 __ ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2143 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2144 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2145 __ brx(Assembler::notEqual, false, Assembler::pt, *stub->entry());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2146 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 // Sanity check the known type with the incoming class. For the
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // primitive case the types must match exactly with src.klass and
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // dst.klass each exactly matching the default type. For the
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // object array case, if no type check is needed then either the
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 // dst type is exactly the expected type and the src type is a
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 // subtype which we can't check or src is the same array as dst
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 // but not necessarily exactly of type default_type.
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 Label known_ok, halt;
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 780
diff changeset
2160 jobject2reg(op->expected_type()->constant_encoding(), tmp);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2161 if (UseCompressedOops) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2162 // tmp holds the default type. It currently comes uncompressed after the
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2163 // load of a constant, so encode it.
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2164 __ encode_heap_oop(tmp);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2165 // load the raw value of the dst klass, since we will be comparing
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2166 // uncompressed values directly.
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2167 __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2168 if (basic_type != T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2169 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2170 __ br(Assembler::notEqual, false, Assembler::pn, halt);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2171 // load the raw value of the src klass.
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2172 __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2173 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2174 __ br(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2175 __ delayed()->nop();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2176 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2177 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2178 __ br(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2179 __ delayed()->cmp(src, dst);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2180 __ brx(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2181 __ delayed()->nop();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2182 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 } else {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2184 __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2185 if (basic_type != T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2186 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2187 __ brx(Assembler::notEqual, false, Assembler::pn, halt);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2188 __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2189 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2190 __ brx(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2191 __ delayed()->nop();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2192 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2193 __ cmp(tmp, tmp2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2194 __ brx(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2195 __ delayed()->cmp(src, dst);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2196 __ brx(Assembler::equal, false, Assembler::pn, known_ok);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2197 __ delayed()->nop();
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2198 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 __ bind(halt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 __ stop("incorrect type information in arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 __ bind(known_ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2205
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 int shift = shift_amount(basic_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2207
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 Register src_ptr = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 Register dst_ptr = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 Register len = O2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2211
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 __ add(src, arrayOopDesc::base_offset_in_bytes(basic_type), src_ptr);
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2213 LP64_ONLY(__ sra(src_pos, 0, src_pos);) //higher 32bits must be null
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 if (shift == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 __ add(src_ptr, src_pos, src_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 __ sll(src_pos, shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 __ add(src_ptr, tmp, src_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2220
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 __ add(dst, arrayOopDesc::base_offset_in_bytes(basic_type), dst_ptr);
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2222 LP64_ONLY(__ sra(dst_pos, 0, dst_pos);) //higher 32bits must be null
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 if (shift == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 __ add(dst_ptr, dst_pos, dst_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 __ sll(dst_pos, shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 __ add(dst_ptr, tmp, dst_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 if (basic_type != T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 if (shift == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 __ mov(length, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 __ sll(length, shift, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::primitive_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 // oop_arraycopy takes a length in number of elements, so don't scale it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 __ mov(length, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::oop_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 __ bind(*stub->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2245
a61af66fc99e Initial load
duke
parents:
diff changeset
2246
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 if (dest->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 if (left->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 case lir_shl: __ sllx (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 case lir_shr: __ srax (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 case lir_ushr: __ srl (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 case lir_shl: __ sll (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 case lir_shr: __ sra (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 case lir_ushr: __ srl (left->as_register(), count->as_register(), dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 case lir_shl: __ sllx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 case lir_shr: __ srax (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 case lir_ushr: __ srlx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 case lir_shl: __ lshl (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 case lir_shr: __ lshr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 case lir_ushr: __ lushr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 if (left->type() == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 count = count & 63; // shouldn't shift by more than sizeof(intptr_t)
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 Register l = left->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 Register d = dest->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 case lir_shl: __ sllx (l, count, d); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 case lir_shr: __ srax (l, count, d); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 case lir_ushr: __ srlx (l, count, d); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2300
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 if (dest->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 count = count & 0x1F; // Java spec
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 case lir_shl: __ sll (left->as_register(), count, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 case lir_shr: __ sra (left->as_register(), count, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 case lir_ushr: __ srl (left->as_register(), count, dest->as_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 } else if (dest->is_double_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 count = count & 63; // Java spec
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 case lir_shl: __ sllx (left->as_pointer_register(), count, dest->as_pointer_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 case lir_shr: __ srax (left->as_pointer_register(), count, dest->as_pointer_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 case lir_ushr: __ srlx (left->as_pointer_register(), count, dest->as_pointer_register()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2321
a61af66fc99e Initial load
duke
parents:
diff changeset
2322
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 assert(op->tmp1()->as_register() == G1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 op->tmp2()->as_register() == G3 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 op->tmp3()->as_register() == G4 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 op->obj()->as_register() == O0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 op->klass()->as_register() == G5, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 if (op->init_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 __ ld(op->klass()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc),
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 op->tmp1()->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 add_debug_info_for_null_check_here(op->stub()->info());
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 __ cmp(op->tmp1()->as_register(), instanceKlass::fully_initialized);
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 __ br(Assembler::notEqual, false, Assembler::pn, *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 __ allocate_object(op->obj()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 op->tmp1()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 op->tmp2()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 op->tmp3()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 op->header_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 op->object_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 op->klass()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 __ bind(*op->stub()->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 __ verify_oop(op->obj()->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2349
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 assert(op->tmp1()->as_register() == G1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 op->tmp2()->as_register() == G3 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 op->tmp3()->as_register() == G4 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 op->tmp4()->as_register() == O1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 op->klass()->as_register() == G5, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 if (UseSlowPath ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 (!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1369
diff changeset
2360 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 __ allocate_array(op->obj()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 op->len()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 op->tmp1()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 op->tmp2()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 op->tmp3()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 arrayOopDesc::header_size(op->type()),
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 0
diff changeset
2369 type2aelembytes(op->type()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 op->klass()->as_register(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 __ bind(*op->stub()->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2375
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2377 void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2378 ciMethodData *md, ciProfileData *data,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2379 Register recv, Register tmp1, Label* update_done) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2380 uint i;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2381 for (i = 0; i < VirtualCallData::row_limit(); i++) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2382 Label next_test;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2383 // See if the receiver is receiver[n].
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2384 Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2385 mdo_offset_bias);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2386 __ ld_ptr(receiver_addr, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2387 __ verify_oop(tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2388 __ cmp(recv, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2389 __ brx(Assembler::notEqual, false, Assembler::pt, next_test);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2390 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2391 Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2392 mdo_offset_bias);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2393 __ ld_ptr(data_addr, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2394 __ add(tmp1, DataLayout::counter_increment, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2395 __ st_ptr(tmp1, data_addr);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2396 __ ba(false, *update_done);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2397 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2398 __ bind(next_test);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2399 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2400
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2401 // Didn't find receiver; find next empty slot and fill it in
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2402 for (i = 0; i < VirtualCallData::row_limit(); i++) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2403 Label next_test;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2404 Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2405 mdo_offset_bias);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2406 __ ld_ptr(recv_addr, tmp1);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2407 __ br_notnull(tmp1, false, Assembler::pt, next_test);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2408 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2409 __ st_ptr(recv, recv_addr);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2410 __ set(DataLayout::counter_increment, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2411 __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2412 mdo_offset_bias);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2413 __ ba(false, *update_done);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2414 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2415 __ bind(next_test);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2416 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2417 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2418
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2419
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2420 void LIR_Assembler::setup_md_access(ciMethod* method, int bci,
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2421 ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2422 md = method->method_data_or_null();
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2423 assert(md != NULL, "Sanity");
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2424 data = md->bci_to_data(bci);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2425 assert(data != NULL, "need data for checkcast");
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2426 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2427 if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2428 // The offset is large so bias the mdo by the base of the slot so
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2429 // that the ld can use simm13s to reference the slots of the data
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2430 mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2431 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2432 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2433
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2434 void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2435 // we always need a stub for the failure case.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2436 CodeStub* stub = op->stub();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2437 Register obj = op->object()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2438 Register k_RInfo = op->tmp1()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2439 Register klass_RInfo = op->tmp2()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2440 Register dst = op->result_opr()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2441 Register Rtmp1 = op->tmp3()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2442 ciKlass* k = op->klass();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2443
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2444
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2445 if (obj == k_RInfo) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2446 k_RInfo = klass_RInfo;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2447 klass_RInfo = obj;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2448 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2449
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2450 ciMethodData* md;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2451 ciProfileData* data;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2452 int mdo_offset_bias = 0;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2453 if (op->should_profile()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2454 ciMethod* method = op->profiled_method();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2455 assert(method != NULL, "Should have method");
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2456 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2457
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2458 Label not_null;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2459 __ br_notnull(obj, false, Assembler::pn, not_null);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2460 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2461 Register mdo = k_RInfo;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2462 Register data_val = Rtmp1;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2463 jobject2reg(md->constant_encoding(), mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2464 if (mdo_offset_bias > 0) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2465 __ set(mdo_offset_bias, data_val);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2466 __ add(mdo, data_val, mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2467 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2468 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2469 __ ldub(flags_addr, data_val);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2470 __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2471 __ stb(data_val, flags_addr);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2472 __ ba(false, *obj_is_null);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2473 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2474 __ bind(not_null);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2475 } else {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2476 __ br_null(obj, false, Assembler::pn, *obj_is_null);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2477 __ delayed()->nop();
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2478 }
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2479
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2480 Label profile_cast_failure, profile_cast_success;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2481 Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2482 Label *success_target = op->should_profile() ? &profile_cast_success : success;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2483
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2484 // patching may screw with our temporaries on sparc,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2485 // so let's do it before loading the class
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2486 if (k->is_loaded()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2487 jobject2reg(k->constant_encoding(), k_RInfo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2488 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2489 jobject2reg_with_patching(k_RInfo, op->info_for_patch());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2490 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2491 assert(obj != k_RInfo, "must be different");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2492
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2493 // get object class
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2494 // not a safepoint as obj null check happens earlier
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2495 __ load_klass(obj, klass_RInfo);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2496 if (op->fast_check()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2497 assert_different_registers(klass_RInfo, k_RInfo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2498 __ cmp(k_RInfo, klass_RInfo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2499 __ brx(Assembler::notEqual, false, Assembler::pt, *failure_target);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2500 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2501 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2502 bool need_slow_path = true;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2503 if (k->is_loaded()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2504 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2505 need_slow_path = false;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2506 // perform the fast part of the checking logic
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2507 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg,
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2508 (need_slow_path ? success_target : NULL),
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2509 failure_target, NULL,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2510 RegisterOrConstant(k->super_check_offset()));
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2511 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2512 // perform the fast part of the checking logic
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2513 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target,
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2514 failure_target, NULL);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2515 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2516 if (need_slow_path) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2517 // call out-of-line instance of __ check_klass_subtype_slow_path(...):
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2518 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2519 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2520 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2521 __ cmp(G3, 0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2522 __ br(Assembler::equal, false, Assembler::pn, *failure_target);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2523 __ delayed()->nop();
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2524 // Fall through to success case
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2525 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2526 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2527
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2528 if (op->should_profile()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2529 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2530 assert_different_registers(obj, mdo, recv, tmp1);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2531 __ bind(profile_cast_success);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2532 jobject2reg(md->constant_encoding(), mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2533 if (mdo_offset_bias > 0) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2534 __ set(mdo_offset_bias, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2535 __ add(mdo, tmp1, mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2536 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2537 __ load_klass(obj, recv);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2538 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2539 // Jump over the failure case
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2540 __ ba(false, *success);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2541 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2542 // Cast failure case
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2543 __ bind(profile_cast_failure);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2544 jobject2reg(md->constant_encoding(), mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2545 if (mdo_offset_bias > 0) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2546 __ set(mdo_offset_bias, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2547 __ add(mdo, tmp1, mdo);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2548 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2549 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2550 __ ld_ptr(data_addr, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2551 __ sub(tmp1, DataLayout::counter_increment, tmp1);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2552 __ st_ptr(tmp1, data_addr);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2553 __ ba(false, *failure);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2554 __ delayed()->nop();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2555 }
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2556 __ ba(false, *success);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2557 __ delayed()->nop();
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2558 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 LIR_Code code = op->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 if (code == lir_store_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 Register value = op->object()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 Register array = op->array()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 Register k_RInfo = op->tmp1()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 Register klass_RInfo = op->tmp2()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 Register Rtmp1 = op->tmp3()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2568
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 __ verify_oop(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 CodeStub* stub = op->stub();
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2571 // check if it needs to be profiled
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2572 ciMethodData* md;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2573 ciProfileData* data;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2574 int mdo_offset_bias = 0;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2575 if (op->should_profile()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2576 ciMethod* method = op->profiled_method();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2577 assert(method != NULL, "Should have method");
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2578 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2579 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2580 Label profile_cast_success, profile_cast_failure, done;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2581 Label *success_target = op->should_profile() ? &profile_cast_success : &done;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2582 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2583
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2584 if (op->should_profile()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2585 Label not_null;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2586 __ br_notnull(value, false, Assembler::pn, not_null);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2587 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2588 Register mdo = k_RInfo;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2589 Register data_val = Rtmp1;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2590 jobject2reg(md->constant_encoding(), mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2591 if (mdo_offset_bias > 0) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2592 __ set(mdo_offset_bias, data_val);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2593 __ add(mdo, data_val, mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2594 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2595 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2596 __ ldub(flags_addr, data_val);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2597 __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2598 __ stb(data_val, flags_addr);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2599 __ ba(false, done);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2600 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2601 __ bind(not_null);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2602 } else {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2603 __ br_null(value, false, Assembler::pn, done);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2604 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2605 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2606 add_debug_info_for_null_check_here(op->info_for_exception());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2607 __ load_klass(array, k_RInfo);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2608 __ load_klass(value, klass_RInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2609
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 // get instance klass
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2611 __ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 356
diff changeset
2612 // perform the fast part of the checking logic
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2613 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 356
diff changeset
2614
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 356
diff changeset
2615 // call out-of-line instance of __ check_klass_subtype_slow_path(...):
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 356
diff changeset
2616 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 __ cmp(G3, 0);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2620 __ br(Assembler::equal, false, Assembler::pn, *failure_target);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 __ delayed()->nop();
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2622 // fall through to the success case
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2623
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2624 if (op->should_profile()) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2625 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2626 assert_different_registers(value, mdo, recv, tmp1);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2627 __ bind(profile_cast_success);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2628 jobject2reg(md->constant_encoding(), mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2629 if (mdo_offset_bias > 0) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2630 __ set(mdo_offset_bias, tmp1);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2631 __ add(mdo, tmp1, mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2632 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2633 __ load_klass(value, recv);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2634 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2635 __ ba(false, done);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2636 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2637 // Cast failure case
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2638 __ bind(profile_cast_failure);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2639 jobject2reg(md->constant_encoding(), mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2640 if (mdo_offset_bias > 0) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2641 __ set(mdo_offset_bias, tmp1);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2642 __ add(mdo, tmp1, mdo);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2643 }
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2644 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2645 __ ld_ptr(data_addr, tmp1);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2646 __ sub(tmp1, DataLayout::counter_increment, tmp1);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2647 __ st_ptr(tmp1, data_addr);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2648 __ ba(false, *stub->entry());
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2649 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2650 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 __ bind(done);
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2652 } else if (code == lir_checkcast) {
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2653 Register obj = op->object()->as_register();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2654 Register dst = op->result_opr()->as_register();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2655 Label success;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2656 emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2657 __ bind(success);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2658 __ mov(obj, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 } else if (code == lir_instanceof) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 Register obj = op->object()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 Register dst = op->result_opr()->as_register();
1791
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2662 Label success, failure, done;
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2663 emit_typecheck_helper(op, &success, &failure, &failure);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2664 __ bind(failure);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2665 __ set(0, dst);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2666 __ ba(false, done);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2667 __ delayed()->nop();
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2668 __ bind(success);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2669 __ set(1, dst);
3a294e483abc 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 1783
diff changeset
2670 __ bind(done);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2674
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2676
a61af66fc99e Initial load
duke
parents:
diff changeset
2677
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 if (op->code() == lir_cas_long) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 assert(VM_Version::supports_cx8(), "wrong machine");
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 Register addr = op->addr()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 Register cmp_value_lo = op->cmp_value()->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 Register cmp_value_hi = op->cmp_value()->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 Register new_value_lo = op->new_value()->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 Register new_value_hi = op->new_value()->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 Register t1 = op->tmp1()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 Register t2 = op->tmp2()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 __ mov(cmp_value_lo, t1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 __ mov(new_value_lo, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 // move high and low halves of long values into single registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 __ sllx(cmp_value_hi, 32, t1); // shift high half into temp reg
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 __ srl(cmp_value_lo, 0, cmp_value_lo); // clear upper 32 bits of low half
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 __ or3(t1, cmp_value_lo, t1); // t1 holds 64-bit compare value
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 __ sllx(new_value_hi, 32, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 __ srl(new_value_lo, 0, new_value_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 __ or3(t2, new_value_lo, t2); // t2 holds 64-bit value to swap
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 // perform the compare and swap operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 __ casx(addr, t1, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // generate condition code - if the swap succeeded, t2 ("new value" reg) was
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 // overwritten with the original value in "addr" and will be equal to t1.
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 __ cmp(t1, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2705
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 Register addr = op->addr()->as_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 Register cmp_value = op->cmp_value()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 Register new_value = op->new_value()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 Register t1 = op->tmp1()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 Register t2 = op->tmp2()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 __ mov(cmp_value, t1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 __ mov(new_value, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 if (op->code() == lir_cas_obj) {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2715 if (UseCompressedOops) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2716 __ encode_heap_oop(t1);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2717 __ encode_heap_oop(t2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 __ cas(addr, t1, t2);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2719 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2720 __ casx(addr, t1, t2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 }
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2722 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2723 __ cas(addr, t1, t2);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2724 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 __ cmp(t1, t2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 void LIR_Assembler::set_24bit_FPU() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2734
a61af66fc99e Initial load
duke
parents:
diff changeset
2735
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 void LIR_Assembler::reset_FPU() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2739
a61af66fc99e Initial load
duke
parents:
diff changeset
2740
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 void LIR_Assembler::breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 __ breakpoint_trap();
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2744
a61af66fc99e Initial load
duke
parents:
diff changeset
2745
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 void LIR_Assembler::push(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2749
a61af66fc99e Initial load
duke
parents:
diff changeset
2750
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 void LIR_Assembler::pop(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2754
a61af66fc99e Initial load
duke
parents:
diff changeset
2755
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst_opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 Register dst = dst_opr->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 Register reg = mon_addr.base();
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 int offset = mon_addr.disp();
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 // compute pointer to BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 if (mon_addr.is_simm13()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 __ add(reg, offset, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 __ set(offset, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 __ add(dst, reg, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2769
a61af66fc99e Initial load
duke
parents:
diff changeset
2770
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 void LIR_Assembler::emit_lock(LIR_OpLock* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 Register obj = op->obj_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 Register hdr = op->hdr_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 Register lock = op->lock_opr()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2775
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // obj may not be an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 if (op->code() == lir_lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 MonitorEnterStub* stub = (MonitorEnterStub*)op->stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 if (UseFastLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // add debug info for NullPointerException only if one is possible
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 if (op->info() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 add_debug_info_for_null_check_here(op->info());
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 __ lock_object(hdr, obj, lock, op->scratch_opr()->as_register(), *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // always do slow locking
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 // note: the slow locking code could be inlined here, however if we use
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 // slow locking, speed doesn't matter anyway and this solution is
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 // simpler and requires less duplicated code - additionally, the
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 // slow locking code is the same in either case which simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 assert (op->code() == lir_unlock, "Invalid code, expected lir_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 if (UseFastLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 __ unlock_object(hdr, obj, lock, *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 // always do slow unlocking
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // note: the slow unlocking code could be inlined here, however if we use
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 // slow unlocking, speed doesn't matter anyway and this solution is
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 // simpler and requires less duplicated code - additionally, the
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 // slow unlocking code is the same in either case which simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 // debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 __ br(Assembler::always, false, Assembler::pt, *op->stub()->entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 __ bind(*op->stub()->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2814
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 ciMethod* method = op->profiled_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 int bci = op->profiled_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
2819
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // Update counter for all call types
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2821 ciMethodData* md = method->method_data_or_null();
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2822 assert(md != NULL, "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 ciProfileData* data = md->bci_to_data(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 assert(data->is_CounterData(), "need CounterData for calls");
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 assert(op->mdo()->is_single_cpu(), "mdo must be allocated");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2826 Register mdo = op->mdo()->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2827 #ifdef _LP64
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2828 assert(op->tmp1()->is_double_cpu(), "tmp1 must be allocated");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2829 Register tmp1 = op->tmp1()->as_register_lo();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2830 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 assert(op->tmp1()->is_single_cpu(), "tmp1 must be allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 Register tmp1 = op->tmp1()->as_register();
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2833 #endif
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 780
diff changeset
2834 jobject2reg(md->constant_encoding(), mdo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 int mdo_offset_bias = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 if (!Assembler::is_simm13(md->byte_offset_of_slot(data, CounterData::count_offset()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 data->size_in_bytes())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // The offset is large so bias the mdo by the base of the slot so
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // that the ld can use simm13s to reference the slots of the data
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 mdo_offset_bias = md->byte_offset_of_slot(data, CounterData::count_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 __ set(mdo_offset_bias, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 __ add(mdo, O7, mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2844
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
2845 Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 Bytecodes::Code bc = method->java_code_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 // Perform additional virtual call profiling for invokevirtual and
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 // invokeinterface bytecodes
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2850 C1ProfileVirtualCalls) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 assert(op->recv()->is_single_cpu(), "recv must be allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 Register recv = op->recv()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 assert_different_registers(mdo, tmp1, recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 ciKlass* known_klass = op->known_holder();
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2856 if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 // We know the type that will be seen at this call site; we can
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // statically update the methodDataOop rather than needing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 // dynamic tests on the receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
2860
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 // NOTE: we should probably put a lock around this search to
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // avoid collisions by concurrent compilations
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 for (i = 0; i < VirtualCallData::row_limit(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 ciKlass* receiver = vc_data->receiver(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 if (known_klass->equals(receiver)) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
2868 Address data_addr(mdo, md->byte_offset_of_slot(data,
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
2869 VirtualCallData::receiver_count_offset(i)) -
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 mdo_offset_bias);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2871 __ ld_ptr(data_addr, tmp1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 __ add(tmp1, DataLayout::counter_increment, tmp1);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2873 __ st_ptr(tmp1, data_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2877
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 // Receiver type not found in profile data; select an empty slot
a61af66fc99e Initial load
duke
parents:
diff changeset
2879
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 // Note that this is less efficient than it should be because it
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 // always does a write to the receiver part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 // VirtualCallData rather than just the first time
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 for (i = 0; i < VirtualCallData::row_limit(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 ciKlass* receiver = vc_data->receiver(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 if (receiver == NULL) {
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
2886 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) -
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 mdo_offset_bias);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 780
diff changeset
2888 jobject2reg(known_klass->constant_encoding(), tmp1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 __ st_ptr(tmp1, recv_addr);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 665
diff changeset
2890 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 mdo_offset_bias);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2892 __ ld_ptr(data_addr, tmp1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 __ add(tmp1, DataLayout::counter_increment, tmp1);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2894 __ st_ptr(tmp1, data_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 } else {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2899 __ load_klass(recv, recv);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 Label update_done;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2901 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done);
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2902 // Receiver did not match any saved receiver and there is no empty row for it.
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2903 // Increment total counter to indicate polymorphic case.
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2904 __ ld_ptr(counter_addr, tmp1);
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2905 __ add(tmp1, DataLayout::counter_increment, tmp1);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2906 __ st_ptr(tmp1, counter_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2907
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 __ bind(update_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 }
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2910 } else {
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2911 // Static call
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2912 __ ld_ptr(counter_addr, tmp1);
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1204
diff changeset
2913 __ add(tmp1, DataLayout::counter_increment, tmp1);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
2914 __ st_ptr(tmp1, counter_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2917
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 void LIR_Assembler::align_backward_branch_target() {
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1301
diff changeset
2919 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2921
a61af66fc99e Initial load
duke
parents:
diff changeset
2922
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 void LIR_Assembler::emit_delay(LIR_OpDelay* op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 // make sure we are expecting a delay
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 // this has the side effect of clearing the delay state
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // so we can use _masm instead of _masm->delayed() to do the
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // code generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 __ delayed();
a61af66fc99e Initial load
duke
parents:
diff changeset
2929
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // make sure we only emit one instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 int offset = code_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 op->delay_op()->emit_code(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 if (code_offset() - offset != NativeInstruction::nop_instruction_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 op->delay_op()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 assert(code_offset() - offset == NativeInstruction::nop_instruction_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 "only one instruction can go in a delay slot");
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2940
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 // we may also be emitting the call info for the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 // which we are the delay slot of.
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2943 CodeEmitInfo* call_info = op->call_info();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 if (call_info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 add_call_info(code_offset(), call_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2947
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 if (VerifyStackAtCalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 _masm->sub(FP, SP, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 _masm->cmp(O7, initial_frame_size_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 _masm->trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2954
a61af66fc99e Initial load
duke
parents:
diff changeset
2955
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 assert(left->is_register(), "can only handle registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
2958
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 if (left->is_single_cpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 __ neg(left->as_register(), dest->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 } else if (left->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 __ fneg(FloatRegisterImpl::S, left->as_float_reg(), dest->as_float_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 } else if (left->is_double_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 __ fneg(FloatRegisterImpl::D, left->as_double_reg(), dest->as_double_reg());
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 assert (left->is_double_cpu(), "Must be a long");
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 Register Rlow = left->as_register_lo();
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 Register Rhi = left->as_register_hi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 __ sub(G0, Rlow, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 __ subcc(G0, Rlow, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 __ subc (G0, Rhi, dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2977
a61af66fc99e Initial load
duke
parents:
diff changeset
2978
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 void LIR_Assembler::fxch(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2982
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 void LIR_Assembler::fld(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 void LIR_Assembler::ffree(int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2990
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 void LIR_Assembler::rt_call(LIR_Opr result, address dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2993
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 // if tmp is invalid, then the function being called doesn't destroy the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 if (tmp->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 __ save_thread(tmp->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 __ call(dest, relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 if (info != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 add_call_info_here(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 if (tmp->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 __ restore_thread(tmp->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 __ verify_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3011
a61af66fc99e Initial load
duke
parents:
diff changeset
3012
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 NEEDS_CLEANUP;
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 if (type == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 LIR_Address* mem_addr = dest->is_address() ? dest->as_address_ptr() : src->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3021
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // (extended to allow indexed as well as constant displaced for JSR-166)
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 Register idx = noreg; // contains either constant offset or index
a61af66fc99e Initial load
duke
parents:
diff changeset
3024
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 int disp = mem_addr->disp();
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 if (mem_addr->index() == LIR_OprFact::illegalOpr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 if (!Assembler::is_simm13(disp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 idx = O7;
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 __ set(disp, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 assert(disp == 0, "not both indexed and disp");
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 idx = mem_addr->index()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3035
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 int null_check_offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3037
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 Register base = mem_addr->base()->as_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 if (src->is_register() && dest->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 // G4 is high half, G5 is low half
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 if (VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 // clear the top bits of G5, and scale up G4
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 __ srl (src->as_register_lo(), 0, G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 __ sllx(src->as_register_hi(), 32, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 // combine the two halves into the 64 bits of G4
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 __ or3(G4, G5, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 null_check_offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 if (idx == noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 __ stx(G4, base, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 __ stx(G4, base, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 __ mov (src->as_register_hi(), G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 __ mov (src->as_register_lo(), G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 null_check_offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 if (idx == noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 __ std(G4, base, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 __ std(G4, base, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 } else if (src->is_address() && dest->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 null_check_offset = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 if (VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 if (idx == noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 __ ldx(base, disp, G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 __ ldx(base, idx, G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 __ srax(G5, 32, dest->as_register_hi()); // fetch the high half into hi
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 __ mov (G5, dest->as_register_lo()); // copy low half into lo
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 if (idx == noreg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 __ ldd(base, disp, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 __ ldd(base, idx, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 // G4 is high half, G5 is low half
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 __ mov (G4, dest->as_register_hi());
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 __ mov (G5, dest->as_register_lo());
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 if (info != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 add_debug_info_for_null_check(null_check_offset, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3089
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // use normal move for all other volatiles since they don't need
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 // special handling to remain atomic.
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
3093 move_op(src, dest, type, lir_patch_none, info, false, false, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3096
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 void LIR_Assembler::membar() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 // only StoreLoad membars are ever explicitly needed on sparcs in TSO mode
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3101
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 void LIR_Assembler::membar_acquire() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 // no-op on TSO
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3105
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 void LIR_Assembler::membar_release() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 // no-op on TSO
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3109
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3110 // Pack two sequential registers containing 32 bit values
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 // into a single 64 bit register.
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3112 // src and src->successor() are packed into dst
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3113 // src and dst may be the same register.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3114 // Note: src is destroyed
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3115 void LIR_Assembler::pack64(LIR_Opr src, LIR_Opr dst) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3116 Register rs = src->as_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3117 Register rd = dst->as_register_lo();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 __ sllx(rs, 32, rs);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 __ srl(rs->successor(), 0, rs->successor());
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 __ or3(rs, rs->successor(), rd);
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3122
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3123 // Unpack a 64 bit value in a register into
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 // two sequential registers.
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3125 // src is unpacked into dst and dst->successor()
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3126 void LIR_Assembler::unpack64(LIR_Opr src, LIR_Opr dst) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3127 Register rs = src->as_register_lo();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3128 Register rd = dst->as_register_hi();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3129 assert_different_registers(rs, rd, rd->successor());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3130 __ srlx(rs, 32, rd);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3131 __ srl (rs, 0, rd->successor());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3133
a61af66fc99e Initial load
duke
parents:
diff changeset
3134
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 LIR_Address* addr = addr_opr->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 assert(addr->index()->is_illegal() && addr->scale() == LIR_Address::times_1 && Assembler::is_simm13(addr->disp()), "can't handle complex addresses yet");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3138
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3139 __ add(addr->base()->as_pointer_register(), addr->disp(), dest->as_pointer_register());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3141
a61af66fc99e Initial load
duke
parents:
diff changeset
3142
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 void LIR_Assembler::get_thread(LIR_Opr result_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 assert(result_reg->is_register(), "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 __ mov(G2_thread, result_reg->as_register());
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3147
a61af66fc99e Initial load
duke
parents:
diff changeset
3148
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 void LIR_Assembler::peephole(LIR_List* lir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 LIR_OpList* inst = lir->instructions_list();
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 for (int i = 0; i < inst->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 LIR_Op* op = inst->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 switch (op->code()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 case lir_cond_float_branch:
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 case lir_branch: {
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 LIR_OpBranch* branch = op->as_OpBranch();
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 assert(branch->info() == NULL, "shouldn't be state on branches anymore");
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 LIR_Op* delay_op = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 // we'd like to be able to pull following instructions into
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // this slot but we don't know enough to do it safely yet so
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 // only optimize block to block control flow.
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 if (LIRFillDelaySlots && branch->block()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 LIR_Op* prev = inst->at(i - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 if (prev && LIR_Assembler::is_single_instruction(prev) && prev->info() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 // swap previous instruction into delay slot
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 inst->at_put(i - 1, op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 inst->at_put(i, new LIR_OpDelay(prev, op->info()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 if (LIRTracePeephole) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 tty->print_cr("delayed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 inst->at(i - 1)->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 inst->at(i)->print();
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
3173 tty->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3179
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 if (!delay_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 delay_op = new LIR_OpDelay(new LIR_Op0(lir_nop), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 inst->insert_before(i + 1, delay_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 case lir_static_call:
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 case lir_virtual_call:
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 case lir_icvirtual_call:
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
3189 case lir_optvirtual_call:
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
3190 case lir_dynamic_call: {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 LIR_Op* prev = inst->at(i - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 if (LIRFillDelaySlots && prev && prev->code() == lir_move && prev->info() == NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 (op->code() != lir_virtual_call ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 !prev->result_opr()->is_single_cpu() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 prev->result_opr()->as_register() != O0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 LIR_Assembler::is_single_instruction(prev)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 // Only moves without info can be put into the delay slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 // Also don't allow the setup of the receiver in the delay
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // slot for vtable calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 inst->at_put(i - 1, op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 inst->at_put(i, new LIR_OpDelay(prev, op->info()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 if (LIRTracePeephole) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 tty->print_cr("delayed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 inst->at(i - 1)->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 inst->at(i)->print();
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
3207 tty->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 #endif
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3210 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3211 LIR_Op* delay_op = new LIR_OpDelay(new LIR_Op0(lir_nop), op->as_OpJavaCall()->info());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3212 inst->insert_before(i + 1, delay_op);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3213 i++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3215
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3216 #if defined(TIERED) && !defined(_LP64)
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3217 // fixup the return value from G1 to O0/O1 for long returns.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3218 // It's done here instead of in LIRGenerator because there's
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3219 // such a mismatch between the single reg and double reg
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3220 // calling convention.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3221 LIR_OpJavaCall* callop = op->as_OpJavaCall();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3222 if (callop->result_opr() == FrameMap::out_long_opr) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3223 LIR_OpJavaCall* call;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3224 LIR_OprList* arguments = new LIR_OprList(callop->arguments()->length());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3225 for (int a = 0; a < arguments->length(); a++) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3226 arguments[a] = callop->arguments()[a];
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3227 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3228 if (op->code() == lir_virtual_call) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3229 call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3230 callop->vtable_offset(), arguments, callop->info());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3231 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3232 call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3233 callop->addr(), arguments, callop->info());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3234 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3235 inst->at_put(i - 1, call);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3236 inst->insert_before(i + 1, new LIR_Op1(lir_unpack64, FrameMap::g1_long_single_opr, callop->result_opr(),
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3237 T_LONG, lir_patch_none, NULL));
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3238 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3239 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3245
a61af66fc99e Initial load
duke
parents:
diff changeset
3246
a61af66fc99e Initial load
duke
parents:
diff changeset
3247
a61af66fc99e Initial load
duke
parents:
diff changeset
3248
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 #undef __