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