duke@1
|
1 /*
|
iveresov@6453
|
2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
duke@1
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
duke@1
|
4 *
|
duke@1
|
5 * This code is free software; you can redistribute it and/or modify it
|
duke@1
|
6 * under the terms of the GNU General Public License version 2 only, as
|
duke@1
|
7 * published by the Free Software Foundation.
|
duke@1
|
8 *
|
duke@1
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
duke@1
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
duke@1
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
duke@1
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
duke@1
|
13 * accompanied this code).
|
duke@1
|
14 *
|
duke@1
|
15 * You should have received a copy of the GNU General Public License version
|
duke@1
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
duke@1
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
duke@1
|
18 *
|
trims@5547
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
trims@5547
|
20 * or visit www.oracle.com if you need additional information or have any
|
trims@5547
|
21 * questions.
|
duke@1
|
22 *
|
duke@1
|
23 */
|
duke@1
|
24
|
duke@1
|
25 # include "incls/_precompiled.incl"
|
duke@1
|
26 # include "incls/_c1_LIRGenerator_sparc.cpp.incl"
|
duke@1
|
27
|
duke@1
|
28 #ifdef ASSERT
|
duke@1
|
29 #define __ gen()->lir(__FILE__, __LINE__)->
|
duke@1
|
30 #else
|
duke@1
|
31 #define __ gen()->lir()->
|
duke@1
|
32 #endif
|
duke@1
|
33
|
duke@1
|
34 void LIRItem::load_byte_item() {
|
duke@1
|
35 // byte loads use same registers as other loads
|
duke@1
|
36 load_item();
|
duke@1
|
37 }
|
duke@1
|
38
|
duke@1
|
39
|
duke@1
|
40 void LIRItem::load_nonconstant() {
|
duke@1
|
41 LIR_Opr r = value()->operand();
|
duke@1
|
42 if (_gen->can_inline_as_constant(value())) {
|
duke@1
|
43 if (!r->is_constant()) {
|
duke@1
|
44 r = LIR_OprFact::value_type(value()->type());
|
duke@1
|
45 }
|
duke@1
|
46 _result = r;
|
duke@1
|
47 } else {
|
duke@1
|
48 load_item();
|
duke@1
|
49 }
|
duke@1
|
50 }
|
duke@1
|
51
|
duke@1
|
52
|
duke@1
|
53 //--------------------------------------------------------------
|
duke@1
|
54 // LIRGenerator
|
duke@1
|
55 //--------------------------------------------------------------
|
duke@1
|
56
|
duke@1
|
57 LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::Oexception_opr; }
|
duke@1
|
58 LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::Oissuing_pc_opr; }
|
duke@1
|
59 LIR_Opr LIRGenerator::syncTempOpr() { return new_register(T_OBJECT); }
|
duke@1
|
60 LIR_Opr LIRGenerator::getThreadTemp() { return rlock_callee_saved(T_INT); }
|
duke@1
|
61
|
duke@1
|
62 LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {
|
duke@1
|
63 LIR_Opr opr;
|
duke@1
|
64 switch (type->tag()) {
|
duke@1
|
65 case intTag: opr = callee ? FrameMap::I0_opr : FrameMap::O0_opr; break;
|
duke@1
|
66 case objectTag: opr = callee ? FrameMap::I0_oop_opr : FrameMap::O0_oop_opr; break;
|
duke@1
|
67 case longTag: opr = callee ? FrameMap::in_long_opr : FrameMap::out_long_opr; break;
|
duke@1
|
68 case floatTag: opr = FrameMap::F0_opr; break;
|
duke@1
|
69 case doubleTag: opr = FrameMap::F0_double_opr; break;
|
duke@1
|
70
|
duke@1
|
71 case addressTag:
|
duke@1
|
72 default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
|
duke@1
|
73 }
|
duke@1
|
74
|
duke@1
|
75 assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
|
duke@1
|
76 return opr;
|
duke@1
|
77 }
|
duke@1
|
78
|
duke@1
|
79 LIR_Opr LIRGenerator::rlock_callee_saved(BasicType type) {
|
duke@1
|
80 LIR_Opr reg = new_register(type);
|
duke@1
|
81 set_vreg_flag(reg, callee_saved);
|
duke@1
|
82 return reg;
|
duke@1
|
83 }
|
duke@1
|
84
|
duke@1
|
85
|
duke@1
|
86 LIR_Opr LIRGenerator::rlock_byte(BasicType type) {
|
duke@1
|
87 return new_register(T_INT);
|
duke@1
|
88 }
|
duke@1
|
89
|
duke@1
|
90
|
duke@1
|
91
|
duke@1
|
92
|
duke@1
|
93
|
duke@1
|
94 //--------- loading items into registers --------------------------------
|
duke@1
|
95
|
duke@1
|
96 // SPARC cannot inline all constants
|
duke@1
|
97 bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {
|
duke@1
|
98 if (v->type()->as_IntConstant() != NULL) {
|
duke@1
|
99 return v->type()->as_IntConstant()->value() == 0;
|
duke@1
|
100 } else if (v->type()->as_LongConstant() != NULL) {
|
duke@1
|
101 return v->type()->as_LongConstant()->value() == 0L;
|
duke@1
|
102 } else if (v->type()->as_ObjectConstant() != NULL) {
|
duke@1
|
103 return v->type()->as_ObjectConstant()->value()->is_null_object();
|
duke@1
|
104 } else {
|
duke@1
|
105 return false;
|
duke@1
|
106 }
|
duke@1
|
107 }
|
duke@1
|
108
|
duke@1
|
109
|
duke@1
|
110 // only simm13 constants can be inlined
|
duke@1
|
111 bool LIRGenerator:: can_inline_as_constant(Value i) const {
|
duke@1
|
112 if (i->type()->as_IntConstant() != NULL) {
|
duke@1
|
113 return Assembler::is_simm13(i->type()->as_IntConstant()->value());
|
duke@1
|
114 } else {
|
duke@1
|
115 return can_store_as_constant(i, as_BasicType(i->type()));
|
duke@1
|
116 }
|
duke@1
|
117 }
|
duke@1
|
118
|
duke@1
|
119
|
duke@1
|
120 bool LIRGenerator:: can_inline_as_constant(LIR_Const* c) const {
|
duke@1
|
121 if (c->type() == T_INT) {
|
duke@1
|
122 return Assembler::is_simm13(c->as_jint());
|
duke@1
|
123 }
|
duke@1
|
124 return false;
|
duke@1
|
125 }
|
duke@1
|
126
|
duke@1
|
127
|
duke@1
|
128 LIR_Opr LIRGenerator::safepoint_poll_register() {
|
duke@1
|
129 return new_register(T_INT);
|
duke@1
|
130 }
|
duke@1
|
131
|
duke@1
|
132
|
duke@1
|
133
|
duke@1
|
134 LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
|
duke@1
|
135 int shift, int disp, BasicType type) {
|
duke@1
|
136 assert(base->is_register(), "must be");
|
duke@1
|
137
|
duke@1
|
138 // accumulate fixed displacements
|
duke@1
|
139 if (index->is_constant()) {
|
duke@1
|
140 disp += index->as_constant_ptr()->as_jint() << shift;
|
duke@1
|
141 index = LIR_OprFact::illegalOpr;
|
duke@1
|
142 }
|
duke@1
|
143
|
duke@1
|
144 if (index->is_register()) {
|
duke@1
|
145 // apply the shift and accumulate the displacement
|
duke@1
|
146 if (shift > 0) {
|
roland@4430
|
147 LIR_Opr tmp = new_pointer_register();
|
duke@1
|
148 __ shift_left(index, shift, tmp);
|
duke@1
|
149 index = tmp;
|
duke@1
|
150 }
|
duke@1
|
151 if (disp != 0) {
|
roland@4430
|
152 LIR_Opr tmp = new_pointer_register();
|
duke@1
|
153 if (Assembler::is_simm13(disp)) {
|
roland@4430
|
154 __ add(tmp, LIR_OprFact::intptrConst(disp), tmp);
|
duke@1
|
155 index = tmp;
|
duke@1
|
156 } else {
|
roland@4430
|
157 __ move(LIR_OprFact::intptrConst(disp), tmp);
|
duke@1
|
158 __ add(tmp, index, tmp);
|
duke@1
|
159 index = tmp;
|
duke@1
|
160 }
|
duke@1
|
161 disp = 0;
|
duke@1
|
162 }
|
duke@1
|
163 } else if (disp != 0 && !Assembler::is_simm13(disp)) {
|
duke@1
|
164 // index is illegal so replace it with the displacement loaded into a register
|
roland@4430
|
165 index = new_pointer_register();
|
roland@4430
|
166 __ move(LIR_OprFact::intptrConst(disp), index);
|
duke@1
|
167 disp = 0;
|
duke@1
|
168 }
|
duke@1
|
169
|
duke@1
|
170 // at this point we either have base + index or base + displacement
|
duke@1
|
171 if (disp == 0) {
|
duke@1
|
172 return new LIR_Address(base, index, type);
|
duke@1
|
173 } else {
|
duke@1
|
174 assert(Assembler::is_simm13(disp), "must be");
|
duke@1
|
175 return new LIR_Address(base, disp, type);
|
duke@1
|
176 }
|
duke@1
|
177 }
|
duke@1
|
178
|
duke@1
|
179
|
duke@1
|
180 LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
|
duke@1
|
181 BasicType type, bool needs_card_mark) {
|
kvn@202
|
182 int elem_size = type2aelembytes(type);
|
duke@1
|
183 int shift = exact_log2(elem_size);
|
duke@1
|
184
|
duke@1
|
185 LIR_Opr base_opr;
|
duke@1
|
186 int offset = arrayOopDesc::base_offset_in_bytes(type);
|
duke@1
|
187
|
duke@1
|
188 if (index_opr->is_constant()) {
|
duke@1
|
189 int i = index_opr->as_constant_ptr()->as_jint();
|
duke@1
|
190 int array_offset = i * elem_size;
|
duke@1
|
191 if (Assembler::is_simm13(array_offset + offset)) {
|
duke@1
|
192 base_opr = array_opr;
|
duke@1
|
193 offset = array_offset + offset;
|
duke@1
|
194 } else {
|
duke@1
|
195 base_opr = new_pointer_register();
|
duke@1
|
196 if (Assembler::is_simm13(array_offset)) {
|
duke@1
|
197 __ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr);
|
duke@1
|
198 } else {
|
duke@1
|
199 __ move(LIR_OprFact::intptrConst(array_offset), base_opr);
|
duke@1
|
200 __ add(base_opr, array_opr, base_opr);
|
duke@1
|
201 }
|
duke@1
|
202 }
|
duke@1
|
203 } else {
|
duke@1
|
204 #ifdef _LP64
|
duke@1
|
205 if (index_opr->type() == T_INT) {
|
duke@1
|
206 LIR_Opr tmp = new_register(T_LONG);
|
duke@1
|
207 __ convert(Bytecodes::_i2l, index_opr, tmp);
|
duke@1
|
208 index_opr = tmp;
|
duke@1
|
209 }
|
duke@1
|
210 #endif
|
duke@1
|
211
|
duke@1
|
212 base_opr = new_pointer_register();
|
duke@1
|
213 assert (index_opr->is_register(), "Must be register");
|
duke@1
|
214 if (shift > 0) {
|
duke@1
|
215 __ shift_left(index_opr, shift, base_opr);
|
duke@1
|
216 __ add(base_opr, array_opr, base_opr);
|
duke@1
|
217 } else {
|
duke@1
|
218 __ add(index_opr, array_opr, base_opr);
|
duke@1
|
219 }
|
duke@1
|
220 }
|
duke@1
|
221 if (needs_card_mark) {
|
duke@1
|
222 LIR_Opr ptr = new_pointer_register();
|
duke@1
|
223 __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr);
|
iveresov@5695
|
224 return new LIR_Address(ptr, type);
|
duke@1
|
225 } else {
|
duke@1
|
226 return new LIR_Address(base_opr, offset, type);
|
duke@1
|
227 }
|
duke@1
|
228 }
|
duke@1
|
229
|
iveresov@6453
|
230 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {
|
iveresov@6453
|
231 LIR_Opr r;
|
iveresov@6453
|
232 if (type == T_LONG) {
|
iveresov@6453
|
233 r = LIR_OprFact::longConst(x);
|
iveresov@6453
|
234 } else if (type == T_INT) {
|
iveresov@6453
|
235 r = LIR_OprFact::intConst(x);
|
iveresov@6453
|
236 } else {
|
iveresov@6453
|
237 ShouldNotReachHere();
|
iveresov@6453
|
238 }
|
iveresov@6453
|
239 if (!Assembler::is_simm13(x)) {
|
iveresov@6453
|
240 LIR_Opr tmp = new_register(type);
|
iveresov@6453
|
241 __ move(r, tmp);
|
iveresov@6453
|
242 return tmp;
|
iveresov@6453
|
243 }
|
iveresov@6453
|
244 return r;
|
iveresov@6453
|
245 }
|
duke@1
|
246
|
iveresov@6453
|
247 void LIRGenerator::increment_counter(address counter, BasicType type, int step) {
|
duke@1
|
248 LIR_Opr pointer = new_pointer_register();
|
duke@1
|
249 __ move(LIR_OprFact::intptrConst(counter), pointer);
|
iveresov@6453
|
250 LIR_Address* addr = new LIR_Address(pointer, type);
|
duke@1
|
251 increment_counter(addr, step);
|
duke@1
|
252 }
|
duke@1
|
253
|
duke@1
|
254 void LIRGenerator::increment_counter(LIR_Address* addr, int step) {
|
iveresov@6453
|
255 LIR_Opr temp = new_register(addr->type());
|
duke@1
|
256 __ move(addr, temp);
|
iveresov@6453
|
257 __ add(temp, load_immediate(step, addr->type()), temp);
|
duke@1
|
258 __ move(temp, addr);
|
duke@1
|
259 }
|
duke@1
|
260
|
duke@1
|
261 void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {
|
duke@1
|
262 LIR_Opr o7opr = FrameMap::O7_opr;
|
duke@1
|
263 __ load(new LIR_Address(base, disp, T_INT), o7opr, info);
|
duke@1
|
264 __ cmp(condition, o7opr, c);
|
duke@1
|
265 }
|
duke@1
|
266
|
duke@1
|
267
|
duke@1
|
268 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {
|
duke@1
|
269 LIR_Opr o7opr = FrameMap::O7_opr;
|
duke@1
|
270 __ load(new LIR_Address(base, disp, type), o7opr, info);
|
duke@1
|
271 __ cmp(condition, reg, o7opr);
|
duke@1
|
272 }
|
duke@1
|
273
|
duke@1
|
274
|
duke@1
|
275 void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) {
|
duke@1
|
276 LIR_Opr o7opr = FrameMap::O7_opr;
|
duke@1
|
277 __ load(new LIR_Address(base, disp, type), o7opr, info);
|
duke@1
|
278 __ cmp(condition, reg, o7opr);
|
duke@1
|
279 }
|
duke@1
|
280
|
duke@1
|
281
|
duke@1
|
282 bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) {
|
duke@1
|
283 assert(left != result, "should be different registers");
|
duke@1
|
284 if (is_power_of_2(c + 1)) {
|
duke@1
|
285 __ shift_left(left, log2_intptr(c + 1), result);
|
duke@1
|
286 __ sub(result, left, result);
|
duke@1
|
287 return true;
|
duke@1
|
288 } else if (is_power_of_2(c - 1)) {
|
duke@1
|
289 __ shift_left(left, log2_intptr(c - 1), result);
|
duke@1
|
290 __ add(result, left, result);
|
duke@1
|
291 return true;
|
duke@1
|
292 }
|
duke@1
|
293 return false;
|
duke@1
|
294 }
|
duke@1
|
295
|
duke@1
|
296
|
duke@1
|
297 void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
|
duke@1
|
298 BasicType t = item->type();
|
duke@1
|
299 LIR_Opr sp_opr = FrameMap::SP_opr;
|
duke@1
|
300 if ((t == T_LONG || t == T_DOUBLE) &&
|
duke@1
|
301 ((in_bytes(offset_from_sp) - STACK_BIAS) % 8 != 0)) {
|
duke@1
|
302 __ unaligned_move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t));
|
duke@1
|
303 } else {
|
duke@1
|
304 __ move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t));
|
duke@1
|
305 }
|
duke@1
|
306 }
|
duke@1
|
307
|
duke@1
|
308 //----------------------------------------------------------------------
|
duke@1
|
309 // visitor functions
|
duke@1
|
310 //----------------------------------------------------------------------
|
duke@1
|
311
|
duke@1
|
312
|
duke@1
|
313 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
|
roland@6745
|
314 assert(x->is_pinned(),"");
|
duke@1
|
315 bool needs_range_check = true;
|
duke@1
|
316 bool use_length = x->length() != NULL;
|
duke@1
|
317 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
|
duke@1
|
318 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
|
duke@1
|
319 !get_jobject_constant(x->value())->is_null_object());
|
duke@1
|
320
|
duke@1
|
321 LIRItem array(x->array(), this);
|
duke@1
|
322 LIRItem index(x->index(), this);
|
duke@1
|
323 LIRItem value(x->value(), this);
|
duke@1
|
324 LIRItem length(this);
|
duke@1
|
325
|
duke@1
|
326 array.load_item();
|
duke@1
|
327 index.load_nonconstant();
|
duke@1
|
328
|
duke@1
|
329 if (use_length) {
|
duke@1
|
330 needs_range_check = x->compute_needs_range_check();
|
duke@1
|
331 if (needs_range_check) {
|
duke@1
|
332 length.set_instruction(x->length());
|
duke@1
|
333 length.load_item();
|
duke@1
|
334 }
|
duke@1
|
335 }
|
duke@1
|
336 if (needs_store_check) {
|
duke@1
|
337 value.load_item();
|
duke@1
|
338 } else {
|
duke@1
|
339 value.load_for_store(x->elt_type());
|
duke@1
|
340 }
|
duke@1
|
341
|
duke@1
|
342 set_no_result(x);
|
duke@1
|
343
|
duke@1
|
344 // the CodeEmitInfo must be duplicated for each different
|
duke@1
|
345 // LIR-instruction because spilling can occur anywhere between two
|
duke@1
|
346 // instructions and so the debug information must be different
|
duke@1
|
347 CodeEmitInfo* range_check_info = state_for(x);
|
duke@1
|
348 CodeEmitInfo* null_check_info = NULL;
|
duke@1
|
349 if (x->needs_null_check()) {
|
duke@1
|
350 null_check_info = new CodeEmitInfo(range_check_info);
|
duke@1
|
351 }
|
duke@1
|
352
|
duke@1
|
353 // emit array address setup early so it schedules better
|
duke@1
|
354 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
|
duke@1
|
355
|
duke@1
|
356 if (GenerateRangeChecks && needs_range_check) {
|
duke@1
|
357 if (use_length) {
|
duke@1
|
358 __ cmp(lir_cond_belowEqual, length.result(), index.result());
|
duke@1
|
359 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
|
duke@1
|
360 } else {
|
duke@1
|
361 array_range_check(array.result(), index.result(), null_check_info, range_check_info);
|
duke@1
|
362 // range_check also does the null check
|
duke@1
|
363 null_check_info = NULL;
|
duke@1
|
364 }
|
duke@1
|
365 }
|
duke@1
|
366
|
duke@1
|
367 if (GenerateArrayStoreCheck && needs_store_check) {
|
duke@1
|
368 LIR_Opr tmp1 = FrameMap::G1_opr;
|
duke@1
|
369 LIR_Opr tmp2 = FrameMap::G3_opr;
|
duke@1
|
370 LIR_Opr tmp3 = FrameMap::G5_opr;
|
duke@1
|
371
|
duke@1
|
372 CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
|
duke@1
|
373 __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info);
|
duke@1
|
374 }
|
duke@1
|
375
|
ysr@1374
|
376 if (obj_store) {
|
ysr@1374
|
377 // Needs GC write barriers.
|
ysr@1374
|
378 pre_barrier(LIR_OprFact::address(array_addr), false, NULL);
|
ysr@1374
|
379 }
|
duke@1
|
380 __ move(value.result(), array_addr, null_check_info);
|
duke@1
|
381 if (obj_store) {
|
never@3172
|
382 // Precise card mark
|
duke@1
|
383 post_barrier(LIR_OprFact::address(array_addr), value.result());
|
duke@1
|
384 }
|
duke@1
|
385 }
|
duke@1
|
386
|
duke@1
|
387
|
duke@1
|
388 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
|
roland@6745
|
389 assert(x->is_pinned(),"");
|
duke@1
|
390 LIRItem obj(x->obj(), this);
|
duke@1
|
391 obj.load_item();
|
duke@1
|
392
|
duke@1
|
393 set_no_result(x);
|
duke@1
|
394
|
duke@1
|
395 LIR_Opr lock = FrameMap::G1_opr;
|
duke@1
|
396 LIR_Opr scratch = FrameMap::G3_opr;
|
duke@1
|
397 LIR_Opr hdr = FrameMap::G4_opr;
|
duke@1
|
398
|
duke@1
|
399 CodeEmitInfo* info_for_exception = NULL;
|
duke@1
|
400 if (x->needs_null_check()) {
|
roland@6745
|
401 info_for_exception = state_for(x);
|
duke@1
|
402 }
|
duke@1
|
403
|
duke@1
|
404 // this CodeEmitInfo must not have the xhandlers because here the
|
duke@1
|
405 // object is already locked (xhandlers expects object to be unlocked)
|
duke@1
|
406 CodeEmitInfo* info = state_for(x, x->state(), true);
|
duke@1
|
407 monitor_enter(obj.result(), lock, hdr, scratch, x->monitor_no(), info_for_exception, info);
|
duke@1
|
408 }
|
duke@1
|
409
|
duke@1
|
410
|
duke@1
|
411 void LIRGenerator::do_MonitorExit(MonitorExit* x) {
|
roland@6745
|
412 assert(x->is_pinned(),"");
|
duke@1
|
413 LIRItem obj(x->obj(), this);
|
duke@1
|
414 obj.dont_load_item();
|
duke@1
|
415
|
duke@1
|
416 set_no_result(x);
|
duke@1
|
417 LIR_Opr lock = FrameMap::G1_opr;
|
duke@1
|
418 LIR_Opr hdr = FrameMap::G3_opr;
|
duke@1
|
419 LIR_Opr obj_temp = FrameMap::G4_opr;
|
bobv@6176
|
420 monitor_exit(obj_temp, lock, hdr, LIR_OprFact::illegalOpr, x->monitor_no());
|
duke@1
|
421 }
|
duke@1
|
422
|
duke@1
|
423
|
duke@1
|
424 // _ineg, _lneg, _fneg, _dneg
|
duke@1
|
425 void LIRGenerator::do_NegateOp(NegateOp* x) {
|
duke@1
|
426 LIRItem value(x->x(), this);
|
duke@1
|
427 value.load_item();
|
duke@1
|
428 LIR_Opr reg = rlock_result(x);
|
duke@1
|
429 __ negate(value.result(), reg);
|
duke@1
|
430 }
|
duke@1
|
431
|
duke@1
|
432
|
duke@1
|
433
|
duke@1
|
434 // for _fadd, _fmul, _fsub, _fdiv, _frem
|
duke@1
|
435 // _dadd, _dmul, _dsub, _ddiv, _drem
|
duke@1
|
436 void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
duke@1
|
437 switch (x->op()) {
|
duke@1
|
438 case Bytecodes::_fadd:
|
duke@1
|
439 case Bytecodes::_fmul:
|
duke@1
|
440 case Bytecodes::_fsub:
|
duke@1
|
441 case Bytecodes::_fdiv:
|
duke@1
|
442 case Bytecodes::_dadd:
|
duke@1
|
443 case Bytecodes::_dmul:
|
duke@1
|
444 case Bytecodes::_dsub:
|
duke@1
|
445 case Bytecodes::_ddiv: {
|
duke@1
|
446 LIRItem left(x->x(), this);
|
duke@1
|
447 LIRItem right(x->y(), this);
|
duke@1
|
448 left.load_item();
|
duke@1
|
449 right.load_item();
|
duke@1
|
450 rlock_result(x);
|
duke@1
|
451 arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result(), x->is_strictfp());
|
duke@1
|
452 }
|
duke@1
|
453 break;
|
duke@1
|
454
|
duke@1
|
455 case Bytecodes::_frem:
|
duke@1
|
456 case Bytecodes::_drem: {
|
duke@1
|
457 address entry;
|
duke@1
|
458 switch (x->op()) {
|
duke@1
|
459 case Bytecodes::_frem:
|
duke@1
|
460 entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);
|
duke@1
|
461 break;
|
duke@1
|
462 case Bytecodes::_drem:
|
duke@1
|
463 entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);
|
duke@1
|
464 break;
|
duke@1
|
465 default:
|
duke@1
|
466 ShouldNotReachHere();
|
duke@1
|
467 }
|
duke@1
|
468 LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), NULL);
|
duke@1
|
469 set_result(x, result);
|
duke@1
|
470 }
|
duke@1
|
471 break;
|
duke@1
|
472
|
duke@1
|
473 default: ShouldNotReachHere();
|
duke@1
|
474 }
|
duke@1
|
475 }
|
duke@1
|
476
|
duke@1
|
477
|
duke@1
|
478 // for _ladd, _lmul, _lsub, _ldiv, _lrem
|
duke@1
|
479 void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
|
duke@1
|
480 switch (x->op()) {
|
duke@1
|
481 case Bytecodes::_lrem:
|
duke@1
|
482 case Bytecodes::_lmul:
|
duke@1
|
483 case Bytecodes::_ldiv: {
|
duke@1
|
484
|
duke@1
|
485 if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) {
|
duke@1
|
486 LIRItem right(x->y(), this);
|
duke@1
|
487 right.load_item();
|
duke@1
|
488
|
duke@1
|
489 CodeEmitInfo* info = state_for(x);
|
duke@1
|
490 LIR_Opr item = right.result();
|
duke@1
|
491 assert(item->is_register(), "must be");
|
duke@1
|
492 __ cmp(lir_cond_equal, item, LIR_OprFact::longConst(0));
|
duke@1
|
493 __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));
|
duke@1
|
494 }
|
duke@1
|
495
|
duke@1
|
496 address entry;
|
duke@1
|
497 switch (x->op()) {
|
duke@1
|
498 case Bytecodes::_lrem:
|
duke@1
|
499 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
|
duke@1
|
500 break; // check if dividend is 0 is done elsewhere
|
duke@1
|
501 case Bytecodes::_ldiv:
|
duke@1
|
502 entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
|
duke@1
|
503 break; // check if dividend is 0 is done elsewhere
|
duke@1
|
504 case Bytecodes::_lmul:
|
duke@1
|
505 entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);
|
duke@1
|
506 break;
|
duke@1
|
507 default:
|
duke@1
|
508 ShouldNotReachHere();
|
duke@1
|
509 }
|
duke@1
|
510
|
duke@1
|
511 // order of arguments to runtime call is reversed.
|
duke@1
|
512 LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL);
|
duke@1
|
513 set_result(x, result);
|
duke@1
|
514 break;
|
duke@1
|
515 }
|
duke@1
|
516 case Bytecodes::_ladd:
|
duke@1
|
517 case Bytecodes::_lsub: {
|
duke@1
|
518 LIRItem left(x->x(), this);
|
duke@1
|
519 LIRItem right(x->y(), this);
|
duke@1
|
520 left.load_item();
|
duke@1
|
521 right.load_item();
|
duke@1
|
522 rlock_result(x);
|
duke@1
|
523
|
duke@1
|
524 arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);
|
duke@1
|
525 break;
|
duke@1
|
526 }
|
duke@1
|
527 default: ShouldNotReachHere();
|
duke@1
|
528 }
|
duke@1
|
529 }
|
duke@1
|
530
|
duke@1
|
531
|
duke@1
|
532 // Returns if item is an int constant that can be represented by a simm13
|
duke@1
|
533 static bool is_simm13(LIR_Opr item) {
|
duke@1
|
534 if (item->is_constant() && item->type() == T_INT) {
|
duke@1
|
535 return Assembler::is_simm13(item->as_constant_ptr()->as_jint());
|
duke@1
|
536 } else {
|
duke@1
|
537 return false;
|
duke@1
|
538 }
|
duke@1
|
539 }
|
duke@1
|
540
|
duke@1
|
541
|
duke@1
|
542 // for: _iadd, _imul, _isub, _idiv, _irem
|
duke@1
|
543 void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {
|
duke@1
|
544 bool is_div_rem = x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem;
|
duke@1
|
545 LIRItem left(x->x(), this);
|
duke@1
|
546 LIRItem right(x->y(), this);
|
duke@1
|
547 // missing test if instr is commutative and if we should swap
|
duke@1
|
548 right.load_nonconstant();
|
duke@1
|
549 assert(right.is_constant() || right.is_register(), "wrong state of right");
|
duke@1
|
550 left.load_item();
|
duke@1
|
551 rlock_result(x);
|
duke@1
|
552 if (is_div_rem) {
|
duke@1
|
553 CodeEmitInfo* info = state_for(x);
|
duke@1
|
554 LIR_Opr tmp = FrameMap::G1_opr;
|
duke@1
|
555 if (x->op() == Bytecodes::_irem) {
|
duke@1
|
556 __ irem(left.result(), right.result(), x->operand(), tmp, info);
|
duke@1
|
557 } else if (x->op() == Bytecodes::_idiv) {
|
duke@1
|
558 __ idiv(left.result(), right.result(), x->operand(), tmp, info);
|
duke@1
|
559 }
|
duke@1
|
560 } else {
|
duke@1
|
561 arithmetic_op_int(x->op(), x->operand(), left.result(), right.result(), FrameMap::G1_opr);
|
duke@1
|
562 }
|
duke@1
|
563 }
|
duke@1
|
564
|
duke@1
|
565
|
duke@1
|
566 void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {
|
duke@1
|
567 ValueTag tag = x->type()->tag();
|
duke@1
|
568 assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");
|
duke@1
|
569 switch (tag) {
|
duke@1
|
570 case floatTag:
|
duke@1
|
571 case doubleTag: do_ArithmeticOp_FPU(x); return;
|
duke@1
|
572 case longTag: do_ArithmeticOp_Long(x); return;
|
duke@1
|
573 case intTag: do_ArithmeticOp_Int(x); return;
|
duke@1
|
574 }
|
duke@1
|
575 ShouldNotReachHere();
|
duke@1
|
576 }
|
duke@1
|
577
|
duke@1
|
578
|
duke@1
|
579 // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr
|
duke@1
|
580 void LIRGenerator::do_ShiftOp(ShiftOp* x) {
|
duke@1
|
581 LIRItem value(x->x(), this);
|
duke@1
|
582 LIRItem count(x->y(), this);
|
duke@1
|
583 // Long shift destroys count register
|
duke@1
|
584 if (value.type()->is_long()) {
|
duke@1
|
585 count.set_destroys_register();
|
duke@1
|
586 }
|
duke@1
|
587 value.load_item();
|
duke@1
|
588 // the old backend doesn't support this
|
duke@1
|
589 if (count.is_constant() && count.type()->as_IntConstant() != NULL && value.type()->is_int()) {
|
duke@1
|
590 jint c = count.get_jint_constant() & 0x1f;
|
duke@1
|
591 assert(c >= 0 && c < 32, "should be small");
|
duke@1
|
592 count.dont_load_item();
|
duke@1
|
593 } else {
|
duke@1
|
594 count.load_item();
|
duke@1
|
595 }
|
duke@1
|
596 LIR_Opr reg = rlock_result(x);
|
duke@1
|
597 shift_op(x->op(), reg, value.result(), count.result(), LIR_OprFact::illegalOpr);
|
duke@1
|
598 }
|
duke@1
|
599
|
duke@1
|
600
|
duke@1
|
601 // _iand, _land, _ior, _lor, _ixor, _lxor
|
duke@1
|
602 void LIRGenerator::do_LogicOp(LogicOp* x) {
|
duke@1
|
603 LIRItem left(x->x(), this);
|
duke@1
|
604 LIRItem right(x->y(), this);
|
duke@1
|
605
|
duke@1
|
606 left.load_item();
|
duke@1
|
607 right.load_nonconstant();
|
duke@1
|
608 LIR_Opr reg = rlock_result(x);
|
duke@1
|
609
|
duke@1
|
610 logic_op(x->op(), reg, left.result(), right.result());
|
duke@1
|
611 }
|
duke@1
|
612
|
duke@1
|
613
|
duke@1
|
614
|
duke@1
|
615 // _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg
|
duke@1
|
616 void LIRGenerator::do_CompareOp(CompareOp* x) {
|
duke@1
|
617 LIRItem left(x->x(), this);
|
duke@1
|
618 LIRItem right(x->y(), this);
|
duke@1
|
619 left.load_item();
|
duke@1
|
620 right.load_item();
|
duke@1
|
621 LIR_Opr reg = rlock_result(x);
|
duke@1
|
622 if (x->x()->type()->is_float_kind()) {
|
duke@1
|
623 Bytecodes::Code code = x->op();
|
duke@1
|
624 __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));
|
duke@1
|
625 } else if (x->x()->type()->tag() == longTag) {
|
duke@1
|
626 __ lcmp2int(left.result(), right.result(), reg);
|
duke@1
|
627 } else {
|
duke@1
|
628 Unimplemented();
|
duke@1
|
629 }
|
duke@1
|
630 }
|
duke@1
|
631
|
duke@1
|
632
|
duke@1
|
633 void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
|
duke@1
|
634 assert(x->number_of_arguments() == 3, "wrong type");
|
duke@1
|
635 LIRItem obj (x->argument_at(0), this); // AtomicLong object
|
duke@1
|
636 LIRItem cmp_value (x->argument_at(1), this); // value to compare with field
|
duke@1
|
637 LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value
|
duke@1
|
638
|
duke@1
|
639 obj.load_item();
|
duke@1
|
640 cmp_value.load_item();
|
duke@1
|
641 new_value.load_item();
|
duke@1
|
642
|
duke@1
|
643 // generate compare-and-swap and produce zero condition if swap occurs
|
duke@1
|
644 int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
|
duke@1
|
645 LIR_Opr addr = FrameMap::O7_opr;
|
duke@1
|
646 __ add(obj.result(), LIR_OprFact::intConst(value_offset), addr);
|
duke@1
|
647 LIR_Opr t1 = FrameMap::G1_opr; // temp for 64-bit value
|
duke@1
|
648 LIR_Opr t2 = FrameMap::G3_opr; // temp for 64-bit value
|
duke@1
|
649 __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
|
duke@1
|
650
|
duke@1
|
651 // generate conditional move of boolean result
|
duke@1
|
652 LIR_Opr result = rlock_result(x);
|
duke@1
|
653 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
|
duke@1
|
654 }
|
duke@1
|
655
|
duke@1
|
656
|
duke@1
|
657 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
|
duke@1
|
658 assert(x->number_of_arguments() == 4, "wrong type");
|
duke@1
|
659 LIRItem obj (x->argument_at(0), this); // object
|
duke@1
|
660 LIRItem offset(x->argument_at(1), this); // offset of field
|
duke@1
|
661 LIRItem cmp (x->argument_at(2), this); // value to compare with field
|
duke@1
|
662 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp
|
duke@1
|
663
|
duke@1
|
664 // Use temps to avoid kills
|
duke@1
|
665 LIR_Opr t1 = FrameMap::G1_opr;
|
duke@1
|
666 LIR_Opr t2 = FrameMap::G3_opr;
|
iveresov@6774
|
667 LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
|
duke@1
|
668
|
duke@1
|
669 // get address of field
|
duke@1
|
670 obj.load_item();
|
duke@1
|
671 offset.load_item();
|
duke@1
|
672 cmp.load_item();
|
duke@1
|
673 val.load_item();
|
duke@1
|
674
|
duke@1
|
675 __ add(obj.result(), offset.result(), addr);
|
duke@1
|
676
|
ysr@1374
|
677 if (type == objectType) { // Write-barrier needed for Object fields.
|
johnc@3917
|
678 pre_barrier(addr, false, NULL);
|
ysr@1374
|
679 }
|
ysr@1374
|
680
|
duke@1
|
681 if (type == objectType)
|
duke@1
|
682 __ cas_obj(addr, cmp.result(), val.result(), t1, t2);
|
duke@1
|
683 else if (type == intType)
|
duke@1
|
684 __ cas_int(addr, cmp.result(), val.result(), t1, t2);
|
duke@1
|
685 else if (type == longType)
|
duke@1
|
686 __ cas_long(addr, cmp.result(), val.result(), t1, t2);
|
duke@1
|
687 else {
|
duke@1
|
688 ShouldNotReachHere();
|
duke@1
|
689 }
|
duke@1
|
690
|
duke@1
|
691 // generate conditional move of boolean result
|
duke@1
|
692 LIR_Opr result = rlock_result(x);
|
duke@1
|
693 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
|
duke@1
|
694 if (type == objectType) { // Write-barrier needed for Object fields.
|
never@3172
|
695 // Precise card mark since could either be object or array
|
ysr@1374
|
696 post_barrier(addr, val.result());
|
duke@1
|
697 }
|
duke@1
|
698 }
|
duke@1
|
699
|
duke@1
|
700
|
duke@1
|
701 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
|
duke@1
|
702 switch (x->id()) {
|
duke@1
|
703 case vmIntrinsics::_dabs:
|
duke@1
|
704 case vmIntrinsics::_dsqrt: {
|
duke@1
|
705 assert(x->number_of_arguments() == 1, "wrong type");
|
duke@1
|
706 LIRItem value(x->argument_at(0), this);
|
duke@1
|
707 value.load_item();
|
duke@1
|
708 LIR_Opr dst = rlock_result(x);
|
duke@1
|
709
|
duke@1
|
710 switch (x->id()) {
|
duke@1
|
711 case vmIntrinsics::_dsqrt: {
|
duke@1
|
712 __ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);
|
duke@1
|
713 break;
|
duke@1
|
714 }
|
duke@1
|
715 case vmIntrinsics::_dabs: {
|
duke@1
|
716 __ abs(value.result(), dst, LIR_OprFact::illegalOpr);
|
duke@1
|
717 break;
|
duke@1
|
718 }
|
duke@1
|
719 }
|
duke@1
|
720 break;
|
duke@1
|
721 }
|
duke@1
|
722 case vmIntrinsics::_dlog10: // fall through
|
duke@1
|
723 case vmIntrinsics::_dlog: // fall through
|
duke@1
|
724 case vmIntrinsics::_dsin: // fall through
|
duke@1
|
725 case vmIntrinsics::_dtan: // fall through
|
duke@1
|
726 case vmIntrinsics::_dcos: {
|
duke@1
|
727 assert(x->number_of_arguments() == 1, "wrong type");
|
duke@1
|
728
|
duke@1
|
729 address runtime_entry = NULL;
|
duke@1
|
730 switch (x->id()) {
|
duke@1
|
731 case vmIntrinsics::_dsin:
|
duke@1
|
732 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
|
duke@1
|
733 break;
|
duke@1
|
734 case vmIntrinsics::_dcos:
|
duke@1
|
735 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
|
duke@1
|
736 break;
|
duke@1
|
737 case vmIntrinsics::_dtan:
|
duke@1
|
738 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
|
duke@1
|
739 break;
|
duke@1
|
740 case vmIntrinsics::_dlog:
|
duke@1
|
741 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
|
duke@1
|
742 break;
|
duke@1
|
743 case vmIntrinsics::_dlog10:
|
duke@1
|
744 runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
|
duke@1
|
745 break;
|
duke@1
|
746 default:
|
duke@1
|
747 ShouldNotReachHere();
|
duke@1
|
748 }
|
duke@1
|
749
|
duke@1
|
750 LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL);
|
duke@1
|
751 set_result(x, result);
|
duke@1
|
752 }
|
duke@1
|
753 }
|
duke@1
|
754 }
|
duke@1
|
755
|
duke@1
|
756
|
duke@1
|
757 void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
duke@1
|
758 assert(x->number_of_arguments() == 5, "wrong type");
|
never@3683
|
759
|
never@3683
|
760 // Make all state_for calls early since they can emit code
|
never@3683
|
761 CodeEmitInfo* info = state_for(x, x->state());
|
never@3683
|
762
|
duke@1
|
763 // Note: spill caller save before setting the item
|
duke@1
|
764 LIRItem src (x->argument_at(0), this);
|
duke@1
|
765 LIRItem src_pos (x->argument_at(1), this);
|
duke@1
|
766 LIRItem dst (x->argument_at(2), this);
|
duke@1
|
767 LIRItem dst_pos (x->argument_at(3), this);
|
duke@1
|
768 LIRItem length (x->argument_at(4), this);
|
duke@1
|
769 // load all values in callee_save_registers, as this makes the
|
duke@1
|
770 // parameter passing to the fast case simpler
|
duke@1
|
771 src.load_item_force (rlock_callee_saved(T_OBJECT));
|
duke@1
|
772 src_pos.load_item_force (rlock_callee_saved(T_INT));
|
duke@1
|
773 dst.load_item_force (rlock_callee_saved(T_OBJECT));
|
duke@1
|
774 dst_pos.load_item_force (rlock_callee_saved(T_INT));
|
duke@1
|
775 length.load_item_force (rlock_callee_saved(T_INT));
|
duke@1
|
776
|
duke@1
|
777 int flags;
|
duke@1
|
778 ciArrayKlass* expected_type;
|
duke@1
|
779 arraycopy_helper(x, &flags, &expected_type);
|
duke@1
|
780
|
duke@1
|
781 __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
|
duke@1
|
782 length.result(), rlock_callee_saved(T_INT),
|
duke@1
|
783 expected_type, flags, info);
|
duke@1
|
784 set_no_result(x);
|
duke@1
|
785 }
|
duke@1
|
786
|
duke@1
|
787 // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
|
duke@1
|
788 // _i2b, _i2c, _i2s
|
duke@1
|
789 void LIRGenerator::do_Convert(Convert* x) {
|
duke@1
|
790
|
duke@1
|
791 switch (x->op()) {
|
duke@1
|
792 case Bytecodes::_f2l:
|
duke@1
|
793 case Bytecodes::_d2l:
|
duke@1
|
794 case Bytecodes::_d2i:
|
duke@1
|
795 case Bytecodes::_l2f:
|
duke@1
|
796 case Bytecodes::_l2d: {
|
duke@1
|
797
|
duke@1
|
798 address entry;
|
duke@1
|
799 switch (x->op()) {
|
duke@1
|
800 case Bytecodes::_l2f:
|
duke@1
|
801 entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f);
|
duke@1
|
802 break;
|
duke@1
|
803 case Bytecodes::_l2d:
|
duke@1
|
804 entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2d);
|
duke@1
|
805 break;
|
duke@1
|
806 case Bytecodes::_f2l:
|
duke@1
|
807 entry = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);
|
duke@1
|
808 break;
|
duke@1
|
809 case Bytecodes::_d2l:
|
duke@1
|
810 entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);
|
duke@1
|
811 break;
|
duke@1
|
812 case Bytecodes::_d2i:
|
duke@1
|
813 entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2i);
|
duke@1
|
814 break;
|
duke@1
|
815 default:
|
duke@1
|
816 ShouldNotReachHere();
|
duke@1
|
817 }
|
duke@1
|
818 LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL);
|
duke@1
|
819 set_result(x, result);
|
duke@1
|
820 break;
|
duke@1
|
821 }
|
duke@1
|
822
|
duke@1
|
823 case Bytecodes::_i2f:
|
duke@1
|
824 case Bytecodes::_i2d: {
|
duke@1
|
825 LIRItem value(x->value(), this);
|
duke@1
|
826
|
duke@1
|
827 LIR_Opr reg = rlock_result(x);
|
duke@1
|
828 // To convert an int to double, we need to load the 32-bit int
|
duke@1
|
829 // from memory into a single precision floating point register
|
duke@1
|
830 // (even numbered). Then the sparc fitod instruction takes care
|
duke@1
|
831 // of the conversion. This is a bit ugly, but is the best way to
|
duke@1
|
832 // get the int value in a single precision floating point register
|
duke@1
|
833 value.load_item();
|
duke@1
|
834 LIR_Opr tmp = force_to_spill(value.result(), T_FLOAT);
|
duke@1
|
835 __ convert(x->op(), tmp, reg);
|
duke@1
|
836 break;
|
duke@1
|
837 }
|
duke@1
|
838 break;
|
duke@1
|
839
|
duke@1
|
840 case Bytecodes::_i2l:
|
duke@1
|
841 case Bytecodes::_i2b:
|
duke@1
|
842 case Bytecodes::_i2c:
|
duke@1
|
843 case Bytecodes::_i2s:
|
duke@1
|
844 case Bytecodes::_l2i:
|
duke@1
|
845 case Bytecodes::_f2d:
|
duke@1
|
846 case Bytecodes::_d2f: { // inline code
|
duke@1
|
847 LIRItem value(x->value(), this);
|
duke@1
|
848
|
duke@1
|
849 value.load_item();
|
duke@1
|
850 LIR_Opr reg = rlock_result(x);
|
duke@1
|
851 __ convert(x->op(), value.result(), reg, false);
|
duke@1
|
852 }
|
duke@1
|
853 break;
|
duke@1
|
854
|
duke@1
|
855 case Bytecodes::_f2i: {
|
duke@1
|
856 LIRItem value (x->value(), this);
|
duke@1
|
857 value.set_destroys_register();
|
duke@1
|
858 value.load_item();
|
duke@1
|
859 LIR_Opr reg = rlock_result(x);
|
duke@1
|
860 set_vreg_flag(reg, must_start_in_memory);
|
duke@1
|
861 __ convert(x->op(), value.result(), reg, false);
|
duke@1
|
862 }
|
duke@1
|
863 break;
|
duke@1
|
864
|
duke@1
|
865 default: ShouldNotReachHere();
|
duke@1
|
866 }
|
duke@1
|
867 }
|
duke@1
|
868
|
duke@1
|
869
|
duke@1
|
870 void LIRGenerator::do_NewInstance(NewInstance* x) {
|
duke@1
|
871 // This instruction can be deoptimized in the slow path : use
|
duke@1
|
872 // O0 as result register.
|
duke@1
|
873 const LIR_Opr reg = result_register_for(x->type());
|
roland@6745
|
874 #ifndef PRODUCT
|
duke@1
|
875 if (PrintNotLoaded && !x->klass()->is_loaded()) {
|
roland@6745
|
876 tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci());
|
duke@1
|
877 }
|
roland@6745
|
878 #endif
|
duke@1
|
879 CodeEmitInfo* info = state_for(x, x->state());
|
duke@1
|
880 LIR_Opr tmp1 = FrameMap::G1_oop_opr;
|
duke@1
|
881 LIR_Opr tmp2 = FrameMap::G3_oop_opr;
|
duke@1
|
882 LIR_Opr tmp3 = FrameMap::G4_oop_opr;
|
duke@1
|
883 LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
duke@1
|
884 LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
duke@1
|
885 new_instance(reg, x->klass(), tmp1, tmp2, tmp3, tmp4, klass_reg, info);
|
duke@1
|
886 LIR_Opr result = rlock_result(x);
|
duke@1
|
887 __ move(reg, result);
|
duke@1
|
888 }
|
duke@1
|
889
|
duke@1
|
890
|
duke@1
|
891 void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
never@3683
|
892 // Evaluate state_for early since it may emit code
|
never@3683
|
893 CodeEmitInfo* info = state_for(x, x->state());
|
never@3683
|
894
|
duke@1
|
895 LIRItem length(x->length(), this);
|
duke@1
|
896 length.load_item();
|
duke@1
|
897
|
duke@1
|
898 LIR_Opr reg = result_register_for(x->type());
|
duke@1
|
899 LIR_Opr tmp1 = FrameMap::G1_oop_opr;
|
duke@1
|
900 LIR_Opr tmp2 = FrameMap::G3_oop_opr;
|
duke@1
|
901 LIR_Opr tmp3 = FrameMap::G4_oop_opr;
|
duke@1
|
902 LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
duke@1
|
903 LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
duke@1
|
904 LIR_Opr len = length.result();
|
duke@1
|
905 BasicType elem_type = x->elt_type();
|
duke@1
|
906
|
jrose@3908
|
907 __ oop2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);
|
duke@1
|
908
|
duke@1
|
909 CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
|
duke@1
|
910 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
|
duke@1
|
911
|
duke@1
|
912 LIR_Opr result = rlock_result(x);
|
duke@1
|
913 __ move(reg, result);
|
duke@1
|
914 }
|
duke@1
|
915
|
duke@1
|
916
|
duke@1
|
917 void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
never@3683
|
918 // Evaluate state_for early since it may emit code.
|
never@3683
|
919 CodeEmitInfo* info = state_for(x, x->state());
|
duke@1
|
920 // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
|
duke@1
|
921 // and therefore provide the state before the parameters have been consumed
|
duke@1
|
922 CodeEmitInfo* patching_info = NULL;
|
duke@1
|
923 if (!x->klass()->is_loaded() || PatchALot) {
|
duke@1
|
924 patching_info = state_for(x, x->state_before());
|
duke@1
|
925 }
|
duke@1
|
926
|
never@3683
|
927 LIRItem length(x->length(), this);
|
duke@1
|
928 length.load_item();
|
duke@1
|
929
|
duke@1
|
930 const LIR_Opr reg = result_register_for(x->type());
|
duke@1
|
931 LIR_Opr tmp1 = FrameMap::G1_oop_opr;
|
duke@1
|
932 LIR_Opr tmp2 = FrameMap::G3_oop_opr;
|
duke@1
|
933 LIR_Opr tmp3 = FrameMap::G4_oop_opr;
|
duke@1
|
934 LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
duke@1
|
935 LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
duke@1
|
936 LIR_Opr len = length.result();
|
duke@1
|
937
|
duke@1
|
938 CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
|
duke@1
|
939 ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
|
duke@1
|
940 if (obj == ciEnv::unloaded_ciobjarrayklass()) {
|
duke@1
|
941 BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
|
duke@1
|
942 }
|
duke@1
|
943 jobject2reg_with_patching(klass_reg, obj, patching_info);
|
duke@1
|
944 __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);
|
duke@1
|
945
|
duke@1
|
946 LIR_Opr result = rlock_result(x);
|
duke@1
|
947 __ move(reg, result);
|
duke@1
|
948 }
|
duke@1
|
949
|
duke@1
|
950
|
duke@1
|
951 void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
duke@1
|
952 Values* dims = x->dims();
|
duke@1
|
953 int i = dims->length();
|
duke@1
|
954 LIRItemList* items = new LIRItemList(dims->length(), NULL);
|
duke@1
|
955 while (i-- > 0) {
|
duke@1
|
956 LIRItem* size = new LIRItem(dims->at(i), this);
|
duke@1
|
957 items->at_put(i, size);
|
duke@1
|
958 }
|
duke@1
|
959
|
never@3683
|
960 // Evaluate state_for early since it may emit code.
|
duke@1
|
961 CodeEmitInfo* patching_info = NULL;
|
duke@1
|
962 if (!x->klass()->is_loaded() || PatchALot) {
|
duke@1
|
963 patching_info = state_for(x, x->state_before());
|
duke@1
|
964
|
duke@1
|
965 // cannot re-use same xhandlers for multiple CodeEmitInfos, so
|
never@3688
|
966 // clone all handlers. This is handled transparently in other
|
never@3688
|
967 // places by the CodeEmitInfo cloning logic but is handled
|
never@3688
|
968 // specially here because a stub isn't being used.
|
duke@1
|
969 x->set_exception_handlers(new XHandlers(x->exception_handlers()));
|
duke@1
|
970 }
|
never@3688
|
971 CodeEmitInfo* info = state_for(x, x->state());
|
duke@1
|
972
|
duke@1
|
973 i = dims->length();
|
duke@1
|
974 while (i-- > 0) {
|
duke@1
|
975 LIRItem* size = items->at(i);
|
duke@1
|
976 size->load_item();
|
duke@1
|
977 store_stack_parameter (size->result(),
|
duke@1
|
978 in_ByteSize(STACK_BIAS +
|
never@1066
|
979 frame::memory_parameter_word_sp_offset * wordSize +
|
never@1066
|
980 i * sizeof(jint)));
|
duke@1
|
981 }
|
duke@1
|
982
|
duke@1
|
983 // This instruction can be deoptimized in the slow path : use
|
duke@1
|
984 // O0 as result register.
|
duke@1
|
985 const LIR_Opr reg = result_register_for(x->type());
|
duke@1
|
986 jobject2reg_with_patching(reg, x->klass(), patching_info);
|
duke@1
|
987 LIR_Opr rank = FrameMap::O1_opr;
|
duke@1
|
988 __ move(LIR_OprFact::intConst(x->rank()), rank);
|
duke@1
|
989 LIR_Opr varargs = FrameMap::as_pointer_opr(O2);
|
duke@1
|
990 int offset_from_sp = (frame::memory_parameter_word_sp_offset * wordSize) + STACK_BIAS;
|
duke@1
|
991 __ add(FrameMap::SP_opr,
|
duke@1
|
992 LIR_OprFact::intptrConst(offset_from_sp),
|
duke@1
|
993 varargs);
|
duke@1
|
994 LIR_OprList* args = new LIR_OprList(3);
|
duke@1
|
995 args->append(reg);
|
duke@1
|
996 args->append(rank);
|
duke@1
|
997 args->append(varargs);
|
duke@1
|
998 __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),
|
duke@1
|
999 LIR_OprFact::illegalOpr,
|
duke@1
|
1000 reg, args, info);
|
duke@1
|
1001
|
duke@1
|
1002 LIR_Opr result = rlock_result(x);
|
duke@1
|
1003 __ move(reg, result);
|
duke@1
|
1004 }
|
duke@1
|
1005
|
duke@1
|
1006
|
duke@1
|
1007 void LIRGenerator::do_BlockBegin(BlockBegin* x) {
|
duke@1
|
1008 }
|
duke@1
|
1009
|
duke@1
|
1010
|
duke@1
|
1011 void LIRGenerator::do_CheckCast(CheckCast* x) {
|
duke@1
|
1012 LIRItem obj(x->obj(), this);
|
duke@1
|
1013 CodeEmitInfo* patching_info = NULL;
|
duke@1
|
1014 if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) {
|
duke@1
|
1015 // must do this before locking the destination register as an oop register,
|
duke@1
|
1016 // and before the obj is loaded (so x->obj()->item() is valid for creating a debug info location)
|
duke@1
|
1017 patching_info = state_for(x, x->state_before());
|
duke@1
|
1018 }
|
duke@1
|
1019 obj.load_item();
|
duke@1
|
1020 LIR_Opr out_reg = rlock_result(x);
|
duke@1
|
1021 CodeStub* stub;
|
roland@6745
|
1022 CodeEmitInfo* info_for_exception = state_for(x);
|
duke@1
|
1023
|
duke@1
|
1024 if (x->is_incompatible_class_change_check()) {
|
duke@1
|
1025 assert(patching_info == NULL, "can't patch this");
|
duke@1
|
1026 stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);
|
duke@1
|
1027 } else {
|
duke@1
|
1028 stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);
|
duke@1
|
1029 }
|
duke@1
|
1030 LIR_Opr tmp1 = FrameMap::G1_oop_opr;
|
duke@1
|
1031 LIR_Opr tmp2 = FrameMap::G3_oop_opr;
|
duke@1
|
1032 LIR_Opr tmp3 = FrameMap::G4_oop_opr;
|
duke@1
|
1033 __ checkcast(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,
|
duke@1
|
1034 x->direct_compare(), info_for_exception, patching_info, stub,
|
duke@1
|
1035 x->profiled_method(), x->profiled_bci());
|
duke@1
|
1036 }
|
duke@1
|
1037
|
duke@1
|
1038
|
duke@1
|
1039 void LIRGenerator::do_InstanceOf(InstanceOf* x) {
|
duke@1
|
1040 LIRItem obj(x->obj(), this);
|
duke@1
|
1041 CodeEmitInfo* patching_info = NULL;
|
duke@1
|
1042 if (!x->klass()->is_loaded() || PatchALot) {
|
duke@1
|
1043 patching_info = state_for(x, x->state_before());
|
duke@1
|
1044 }
|
duke@1
|
1045 // ensure the result register is not the input register because the result is initialized before the patching safepoint
|
duke@1
|
1046 obj.load_item();
|
duke@1
|
1047 LIR_Opr out_reg = rlock_result(x);
|
duke@1
|
1048 LIR_Opr tmp1 = FrameMap::G1_oop_opr;
|
duke@1
|
1049 LIR_Opr tmp2 = FrameMap::G3_oop_opr;
|
duke@1
|
1050 LIR_Opr tmp3 = FrameMap::G4_oop_opr;
|
iveresov@6461
|
1051 __ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,
|
iveresov@6461
|
1052 x->direct_compare(), patching_info,
|
iveresov@6461
|
1053 x->profiled_method(), x->profiled_bci());
|
duke@1
|
1054 }
|
duke@1
|
1055
|
duke@1
|
1056
|
duke@1
|
1057 void LIRGenerator::do_If(If* x) {
|
duke@1
|
1058 assert(x->number_of_sux() == 2, "inconsistency");
|
duke@1
|
1059 ValueTag tag = x->x()->type()->tag();
|
duke@1
|
1060 LIRItem xitem(x->x(), this);
|
duke@1
|
1061 LIRItem yitem(x->y(), this);
|
duke@1
|
1062 LIRItem* xin = &xitem;
|
duke@1
|
1063 LIRItem* yin = &yitem;
|
duke@1
|
1064 If::Condition cond = x->cond();
|
duke@1
|
1065
|
duke@1
|
1066 if (tag == longTag) {
|
duke@1
|
1067 // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
|
duke@1
|
1068 // mirror for other conditions
|
duke@1
|
1069 if (cond == If::gtr || cond == If::leq) {
|
duke@1
|
1070 // swap inputs
|
duke@1
|
1071 cond = Instruction::mirror(cond);
|
duke@1
|
1072 xin = &yitem;
|
duke@1
|
1073 yin = &xitem;
|
duke@1
|
1074 }
|
duke@1
|
1075 xin->set_destroys_register();
|
duke@1
|
1076 }
|
duke@1
|
1077
|
duke@1
|
1078 LIR_Opr left = LIR_OprFact::illegalOpr;
|
duke@1
|
1079 LIR_Opr right = LIR_OprFact::illegalOpr;
|
duke@1
|
1080
|
duke@1
|
1081 xin->load_item();
|
duke@1
|
1082 left = xin->result();
|
duke@1
|
1083
|
duke@1
|
1084 if (is_simm13(yin->result())) {
|
duke@1
|
1085 // inline int constants which are small enough to be immediate operands
|
duke@1
|
1086 right = LIR_OprFact::value_type(yin->value()->type());
|
duke@1
|
1087 } else if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 &&
|
duke@1
|
1088 (cond == If::eql || cond == If::neq)) {
|
duke@1
|
1089 // inline long zero
|
duke@1
|
1090 right = LIR_OprFact::value_type(yin->value()->type());
|
duke@1
|
1091 } else if (tag == objectTag && yin->is_constant() && (yin->get_jobject_constant()->is_null_object())) {
|
duke@1
|
1092 right = LIR_OprFact::value_type(yin->value()->type());
|
duke@1
|
1093 } else {
|
duke@1
|
1094 yin->load_item();
|
duke@1
|
1095 right = yin->result();
|
duke@1
|
1096 }
|
duke@1
|
1097 set_no_result(x);
|
duke@1
|
1098
|
duke@1
|
1099 // add safepoint before generating condition code so it can be recomputed
|
duke@1
|
1100 if (x->is_safepoint()) {
|
duke@1
|
1101 // increment backedge counter if needed
|
iveresov@6453
|
1102 increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());
|
duke@1
|
1103 __ safepoint(new_register(T_INT), state_for(x, x->state_before()));
|
duke@1
|
1104 }
|
duke@1
|
1105
|
duke@1
|
1106 __ cmp(lir_cond(cond), left, right);
|
iveresov@6453
|
1107 // Generate branch profiling. Profiling code doesn't kill flags.
|
duke@1
|
1108 profile_branch(x, cond);
|
duke@1
|
1109 move_to_phi(x->state());
|
duke@1
|
1110 if (x->x()->type()->is_float_kind()) {
|
duke@1
|
1111 __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux());
|
duke@1
|
1112 } else {
|
duke@1
|
1113 __ branch(lir_cond(cond), right->type(), x->tsux());
|
duke@1
|
1114 }
|
duke@1
|
1115 assert(x->default_sux() == x->fsux(), "wrong destination above");
|
duke@1
|
1116 __ jump(x->default_sux());
|
duke@1
|
1117 }
|
duke@1
|
1118
|
duke@1
|
1119
|
duke@1
|
1120 LIR_Opr LIRGenerator::getThreadPointer() {
|
duke@1
|
1121 return FrameMap::as_pointer_opr(G2);
|
duke@1
|
1122 }
|
duke@1
|
1123
|
duke@1
|
1124
|
duke@1
|
1125 void LIRGenerator::trace_block_entry(BlockBegin* block) {
|
duke@1
|
1126 __ move(LIR_OprFact::intConst(block->block_id()), FrameMap::O0_opr);
|
duke@1
|
1127 LIR_OprList* args = new LIR_OprList(1);
|
duke@1
|
1128 args->append(FrameMap::O0_opr);
|
duke@1
|
1129 address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);
|
duke@1
|
1130 __ call_runtime_leaf(func, rlock_callee_saved(T_INT), LIR_OprFact::illegalOpr, args);
|
duke@1
|
1131 }
|
duke@1
|
1132
|
duke@1
|
1133
|
duke@1
|
1134 void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,
|
duke@1
|
1135 CodeEmitInfo* info) {
|
duke@1
|
1136 #ifdef _LP64
|
duke@1
|
1137 __ store(value, address, info);
|
duke@1
|
1138 #else
|
duke@1
|
1139 __ volatile_store_mem_reg(value, address, info);
|
duke@1
|
1140 #endif
|
duke@1
|
1141 }
|
duke@1
|
1142
|
duke@1
|
1143 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
|
duke@1
|
1144 CodeEmitInfo* info) {
|
duke@1
|
1145 #ifdef _LP64
|
duke@1
|
1146 __ load(address, result, info);
|
duke@1
|
1147 #else
|
duke@1
|
1148 __ volatile_load_mem_reg(address, result, info);
|
duke@1
|
1149 #endif
|
duke@1
|
1150 }
|
duke@1
|
1151
|
duke@1
|
1152
|
duke@1
|
1153 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
|
duke@1
|
1154 BasicType type, bool is_volatile) {
|
duke@1
|
1155 LIR_Opr base_op = src;
|
duke@1
|
1156 LIR_Opr index_op = offset;
|
duke@1
|
1157
|
duke@1
|
1158 bool is_obj = (type == T_ARRAY || type == T_OBJECT);
|
duke@1
|
1159 #ifndef _LP64
|
duke@1
|
1160 if (is_volatile && type == T_LONG) {
|
duke@1
|
1161 __ volatile_store_unsafe_reg(data, src, offset, type, NULL, lir_patch_none);
|
duke@1
|
1162 } else
|
duke@1
|
1163 #endif
|
duke@1
|
1164 {
|
duke@1
|
1165 if (type == T_BOOLEAN) {
|
duke@1
|
1166 type = T_BYTE;
|
duke@1
|
1167 }
|
duke@1
|
1168 LIR_Address* addr;
|
duke@1
|
1169 if (type == T_ARRAY || type == T_OBJECT) {
|
duke@1
|
1170 LIR_Opr tmp = new_pointer_register();
|
duke@1
|
1171 __ add(base_op, index_op, tmp);
|
iveresov@5695
|
1172 addr = new LIR_Address(tmp, type);
|
duke@1
|
1173 } else {
|
duke@1
|
1174 addr = new LIR_Address(base_op, index_op, type);
|
duke@1
|
1175 }
|
duke@1
|
1176
|
ysr@1374
|
1177 if (is_obj) {
|
ysr@1374
|
1178 pre_barrier(LIR_OprFact::address(addr), false, NULL);
|
ysr@1374
|
1179 // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));
|
ysr@1374
|
1180 }
|
duke@1
|
1181 __ move(data, addr);
|
duke@1
|
1182 if (is_obj) {
|
duke@1
|
1183 // This address is precise
|
duke@1
|
1184 post_barrier(LIR_OprFact::address(addr), data);
|
duke@1
|
1185 }
|
duke@1
|
1186 }
|
duke@1
|
1187 }
|
duke@1
|
1188
|
duke@1
|
1189
|
duke@1
|
1190 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
|
duke@1
|
1191 BasicType type, bool is_volatile) {
|
duke@1
|
1192 #ifndef _LP64
|
duke@1
|
1193 if (is_volatile && type == T_LONG) {
|
duke@1
|
1194 __ volatile_load_unsafe_reg(src, offset, dst, type, NULL, lir_patch_none);
|
duke@1
|
1195 } else
|
duke@1
|
1196 #endif
|
duke@1
|
1197 {
|
duke@1
|
1198 LIR_Address* addr = new LIR_Address(src, offset, type);
|
duke@1
|
1199 __ load(addr, dst);
|
duke@1
|
1200 }
|
duke@1
|
1201 }
|