annotate src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 6812:988bf00cc564

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