< prev index next >
src/cpu/sparc/vm/sparc.ad
Print this page
@@ -1,7 +1,7 @@
//
-// Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
@@ -309,11 +309,10 @@
reg_class o7_regI(R_O7);
// ----------------------------
// Pointer Register Classes
// ----------------------------
-#ifdef _LP64
// 64-bit build means 64-bit pointers means hi/lo pairs
reg_class ptr_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5,
R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5,
R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7,
R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5 );
@@ -342,58 +341,22 @@
reg_class o0_regP(R_O0H,R_O0);
reg_class o1_regP(R_O1H,R_O1);
reg_class o2_regP(R_O2H,R_O2);
reg_class o7_regP(R_O7H,R_O7);
-#else // _LP64
-// 32-bit build means 32-bit pointers means 1 register.
-reg_class ptr_reg( R_G1, R_G3,R_G4,R_G5,
- R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,
- R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,
- R_I0,R_I1,R_I2,R_I3,R_I4,R_I5);
-// Lock encodings use G3 and G4 internally
-reg_class lock_ptr_reg(R_G1, R_G5,
- R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,
- R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,
- R_I0,R_I1,R_I2,R_I3,R_I4,R_I5);
-// Special class for storeP instructions, which can store SP or RPC to TLS.
-// It is also used for memory addressing, allowing direct TLS addressing.
-reg_class sp_ptr_reg( R_G1,R_G2,R_G3,R_G4,R_G5,
- R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_SP,
- R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7,
- R_I0,R_I1,R_I2,R_I3,R_I4,R_I5,R_FP);
-// R_L7 is the lowest-priority callee-save (i.e., NS) register
-// We use it to save R_G2 across calls out of Java.
-reg_class l7_regP(R_L7);
-
-// Other special pointer regs
-reg_class g1_regP(R_G1);
-reg_class g2_regP(R_G2);
-reg_class g3_regP(R_G3);
-reg_class g4_regP(R_G4);
-reg_class g5_regP(R_G5);
-reg_class i0_regP(R_I0);
-reg_class o0_regP(R_O0);
-reg_class o1_regP(R_O1);
-reg_class o2_regP(R_O2);
-reg_class o7_regP(R_O7);
-#endif // _LP64
-
// ----------------------------
// Long Register Classes
// ----------------------------
// Longs in 1 register. Aligned adjacent hi/lo pairs.
// Note: O7 is never in this class; it is sometimes used as an encoding temp.
reg_class long_reg( R_G1H,R_G1, R_G3H,R_G3, R_G4H,R_G4, R_G5H,R_G5
,R_O0H,R_O0, R_O1H,R_O1, R_O2H,R_O2, R_O3H,R_O3, R_O4H,R_O4, R_O5H,R_O5
-#ifdef _LP64
// 64-bit, longs in 1 register: use all 64-bit integer registers
// 32-bit, longs in 1 register: cannot use I's and L's. Restrict to O's and G's.
,R_L0H,R_L0, R_L1H,R_L1, R_L2H,R_L2, R_L3H,R_L3, R_L4H,R_L4, R_L5H,R_L5, R_L6H,R_L6, R_L7H,R_L7
,R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5
-#endif // _LP64
);
reg_class g1_regL(R_G1H,R_G1);
reg_class g3_regL(R_G3H,R_G3);
reg_class o2_regL(R_O2H,R_O2);
@@ -531,14 +494,12 @@
// release. There's no obvious reason why an interrupt will ever fill these
// bits with non-zero junk (the registers are reloaded with standard LD
// instructions which either zero-fill or sign-fill).
bool can_branch_register( Node *bol, Node *cmp ) {
if( !BranchOnRegister ) return false;
-#ifdef _LP64
if( cmp->Opcode() == Op_CmpP )
return true; // No problems with pointer compares
-#endif
if( cmp->Opcode() == Op_CmpL )
return true; // No problems with long compares
if( !SparcV9RegsHiBitsZero ) return false;
if( bol->as_Bool()->_test._test != BoolTest::ne &&
@@ -615,19 +576,15 @@
}
}
}
int MachCallRuntimeNode::ret_addr_offset() {
-#ifdef _LP64
if (MacroAssembler::is_far_target(entry_point())) {
return NativeFarCall::instruction_size;
} else {
return NativeCall::instruction_size;
}
-#else
- return NativeCall::instruction_size; // call; delay slot
-#endif
}
// Indicate if the safepoint node needs the polling page as an input.
// Since Sparc does not have absolute addressing, it does.
bool SafePointNode::needs_polling_address_input() {
@@ -1022,36 +979,19 @@
if (preserve_g2) __ mov(L7, G2);
#ifdef ASSERT
if (preserve_g2 && (VerifyCompiledCode || VerifyOops)) {
-#ifdef _LP64
// Trash argument dump slots.
__ set(0xb0b8ac0db0b8ac0d, G1);
__ mov(G1, G5);
__ stx(G1, SP, STACK_BIAS + 0x80);
__ stx(G1, SP, STACK_BIAS + 0x88);
__ stx(G1, SP, STACK_BIAS + 0x90);
__ stx(G1, SP, STACK_BIAS + 0x98);
__ stx(G1, SP, STACK_BIAS + 0xA0);
__ stx(G1, SP, STACK_BIAS + 0xA8);
-#else // _LP64
- // this is also a native call, so smash the first 7 stack locations,
- // and the various registers
-
- // Note: [SP+0x40] is sp[callee_aggregate_return_pointer_sp_offset],
- // while [SP+0x44..0x58] are the argument dump slots.
- __ set((intptr_t)0xbaadf00d, G1);
- __ mov(G1, G5);
- __ sllx(G1, 32, G1);
- __ or3(G1, G5, G1);
- __ mov(G1, G5);
- __ stx(G1, SP, 0x40);
- __ stx(G1, SP, 0x48);
- __ stx(G1, SP, 0x50);
- __ stw(G1, SP, 0x58); // Do not trash [SP+0x5C] which is a usable spill slot
-#endif // _LP64
}
#endif /*ASSERT*/
}
//=============================================================================
@@ -1260,15 +1200,11 @@
void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
Compile* C = ra_->C;
if(do_polling() && ra_->C->is_method_compilation()) {
st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t");
-#ifdef _LP64
st->print("LDX [L0],G0\t!Poll for Safepointing\n\t");
-#else
- st->print("LDUW [L0],G0\t!Poll for Safepointing\n\t");
-#endif
}
if(do_polling()) {
if (UseCBCond && !ra_->C->is_method_compilation()) {
st->print("NOP\n\t");
@@ -1470,79 +1406,14 @@
// In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations.
// In such cases, I have to do the big-endian swap. For aligned targets, the
// hardware does the flop for me. Doubles are always aligned, so no problem
// there. Misaligned sources only come from native-long-returns (handled
// special below).
-#ifndef _LP64
- if (src_first_rc == rc_int && // source is already big-endian
- src_second_rc != rc_bad && // 64-bit move
- ((dst_first & 1) != 0 || dst_second != dst_first + 1)) { // misaligned dst
- assert((src_first & 1) == 0 && src_second == src_first + 1, "source must be aligned");
- // Do the big-endian flop.
- OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ;
- enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc;
- }
-#endif
// --------------------------------------
// Check for integer reg-reg copy
if (src_first_rc == rc_int && dst_first_rc == rc_int) {
-#ifndef _LP64
- if (src_first == R_O0_num && src_second == R_O1_num) { // Check for the evil O0/O1 native long-return case
- // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
- // as stored in memory. On a big-endian machine like SPARC, this means that the _second
- // operand contains the least significant word of the 64-bit value and vice versa.
- OptoReg::Name tmp = OptoReg::Name(R_O7_num);
- assert((dst_first & 1) == 0 && dst_second == dst_first + 1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" );
- // Shift O0 left in-place, zero-extend O1, then OR them into the dst
- if ( cbuf ) {
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020);
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000);
- emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second]);
-#ifndef PRODUCT
- } else {
- print_helper(st, "SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp));
- print_helper(st, "SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second));
- print_helper(st, "OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first));
-#endif
- }
- return;
- } else if (dst_first == R_I0_num && dst_second == R_I1_num) {
- // returning a long value in I0/I1
- // a SpillCopy must be able to target a return instruction's reg_class
- // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
- // as stored in memory. On a big-endian machine like SPARC, this means that the _second
- // operand contains the least significant word of the 64-bit value and vice versa.
- OptoReg::Name tdest = dst_first;
-
- if (src_first == dst_first) {
- tdest = OptoReg::Name(R_O7_num);
- }
-
- if (cbuf) {
- assert((src_first & 1) == 0 && (src_first + 1) == src_second, "return value was in an aligned-adjacent 64-bit reg");
- // Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1
- // ShrL_reg_imm6
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000);
- // ShrR_reg_imm6 src, 0, dst
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000);
- if (tdest != dst_first) {
- emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest]);
- }
- }
-#ifndef PRODUCT
- else {
- print_helper(st, "SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest));
- print_helper(st, "SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second));
- if (tdest != dst_first) {
- print_helper(st, "MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first));
- }
- }
-#endif // PRODUCT
- return size+8;
- }
-#endif // !_LP64
// Else normal reg-reg copy
assert(src_second != dst_first, "smashed second before evacuating it");
impl_mov_helper(cbuf, src_first, dst_first, Assembler::or_op3, 0, "MOV ", st);
assert((src_first & 1) == 0 && (dst_first & 1) == 0, "never move second-halves of int registers");
// This moves an aligned adjacent pair.
@@ -1612,62 +1483,10 @@
if (src_second == dst_second) {
return; // Self copy; no move
}
assert(src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad");
-#ifndef _LP64
- // In the LP64 build, all registers can be moved as aligned/adjacent
- // pairs, so there's never any need to move the high bits separately.
- // The 32-bit builds have to deal with the 32-bit ABI which can force
- // all sorts of silly alignment problems.
-
- // Check for integer reg-reg copy. Hi bits are stuck up in the top
- // 32-bits of a 64-bit register, but are needed in low bits of another
- // register (else it's a hi-bits-to-hi-bits copy which should have
- // happened already as part of a 64-bit move)
- if (src_second_rc == rc_int && dst_second_rc == rc_int) {
- assert((src_second & 1) == 1, "its the evil O0/O1 native return case");
- assert((dst_second & 1) == 0, "should have moved with 1 64-bit move");
- // Shift src_second down to dst_second's low bits.
- if (cbuf) {
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
-#ifndef PRODUCT
- } else {
- print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second - 1), OptoReg::regname(dst_second));
-#endif
- }
- return;
- }
-
- // Check for high word integer store. Must down-shift the hi bits
- // into a temp register, then fall into the case of storing int bits.
- if (src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second & 1) == 1) {
- // Shift src_second down to dst_second's low bits.
- if (cbuf) {
- emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
-#ifndef PRODUCT
- } else {
- print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second-1), OptoReg::regname(R_O7_num));
-#endif
- }
- src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num!
- }
-
- // Check for high word integer load
- if (dst_second_rc == rc_int && src_second_rc == rc_stack)
- return impl_helper(this, cbuf, ra_, true, ra_->reg2offset(src_second), dst_second, Assembler::lduw_op3, "LDUW", size, st);
-
- // Check for high word integer store
- if (src_second_rc == rc_int && dst_second_rc == rc_stack)
- return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stw_op3, "STW ", size, st);
-
- // Check for high word float store
- if (src_second_rc == rc_float && dst_second_rc == rc_stack)
- return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stf_op3, "STF ", size, st);
-
-#endif // !_LP64
-
Unimplemented();
}
uint MachSpillCopyNode::implementation(CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
@@ -1741,11 +1560,10 @@
//=============================================================================
#ifndef PRODUCT
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:");
-#ifdef _LP64
if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
if (Universe::narrow_klass_base() != 0) {
st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
@@ -1760,15 +1578,10 @@
} else {
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
}
st->print_cr("\tCMP R_G5,R_G3" );
st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2");
-#else // _LP64
- st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
- st->print_cr("\tCMP R_G5,R_G3" );
- st->print ("\tTne icc,R_G0+ST_RESERVED_FOR_USER_0+2");
-#endif // _LP64
}
#endif
void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
MacroAssembler _masm(&cbuf);
@@ -1872,13 +1685,11 @@
case Op_PopCountI:
case Op_PopCountL:
if (!UsePopCountInstruction)
return false;
case Op_CompareAndSwapL:
-#ifdef _LP64
case Op_CompareAndSwapP:
-#endif
if (!VM_Version::supports_cx8())
return false;
break;
}
@@ -2025,15 +1836,11 @@
// If CPU can load and store mis-aligned doubles directly then no fixup is
// needed. Else we split the double into 2 integer pieces and move it
// piece-by-piece. Only happens when passing doubles into C code as the
// Java calling convention forces doubles to be aligned.
-#ifdef _LP64
const bool Matcher::misaligned_doubles_ok = true;
-#else
-const bool Matcher::misaligned_doubles_ok = false;
-#endif
// No-op on SPARC.
void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {
}
@@ -2048,15 +1855,11 @@
// Do ints take an entire long register or just half?
// Note that we if-def off of _LP64.
// The relevant question is how the int is callee-saved. In _LP64
// the whole long is written but de-opt'ing will have to extract
// the relevant 32 bits, in not-_LP64 only the low 32 bits is written.
-#ifdef _LP64
const bool Matcher::int_in_long = true;
-#else
-const bool Matcher::int_in_long = false;
-#endif
// Return whether or not this register is ever used as an argument. This
// function is used on startup to build the trampoline stubs in generateOptoStub.
// Registers not mentioned will be killed by the VM call in the trampoline, and
// arguments in those registers not be available to the callee.
@@ -2066,11 +1869,10 @@
reg == R_I1_num ||
reg == R_I2_num ||
reg == R_I3_num ||
reg == R_I4_num ||
reg == R_I5_num ) return true;
-#ifdef _LP64
// 64-bit builds can pass 64-bit pointers and longs in
// the high I registers
if( reg == R_I0H_num ||
reg == R_I1H_num ||
reg == R_I2H_num ||
@@ -2080,18 +1882,10 @@
if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) {
return true;
}
-#else
- // 32-bit builds with longs-in-one-entry pass longs in G1 & G4.
- // Longs cannot be passed in O regs, because O regs become I regs
- // after a 'save' and I regs get their high bits chopped off on
- // interrupt.
- if( reg == R_G1H_num || reg == R_G1_num ) return true;
- if( reg == R_G4H_num || reg == R_G4_num ) return true;
-#endif
// A few float args in registers
if( reg >= R_F0_num && reg <= R_F7_num ) return true;
return false;
}
@@ -2150,23 +1944,15 @@
%}
// The intptr_t operand types, defined by textual substitution.
// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.)
-#ifdef _LP64
#define immX immL
#define immX13 immL13
#define immX13m7 immL13m7
#define iRegX iRegL
#define g1RegX g1RegL
-#else
-#define immX immI
-#define immX13 immI13
-#define immX13m7 immI13m7
-#define iRegX iRegI
-#define g1RegX g1RegI
-#endif
//----------ENCODING BLOCK-----------------------------------------------------
// This block specifies the encoding classes used by the compiler to output
// byte streams. Encoding classes are parameterized macros used by
// Machine Instruction Nodes in order to generate the bit encoding of the
@@ -2324,20 +2110,18 @@
enc_class move_return_pc_to_o1() %{
emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::add_op3, R_O7_enc, frame::pc_return_offset );
%}
-#ifdef _LP64
/* %%% merge with enc_to_bool */
enc_class enc_convP2B( iRegI dst, iRegP src ) %{
MacroAssembler _masm(&cbuf);
Register src_reg = reg_to_register_object($src$$reg);
Register dst_reg = reg_to_register_object($dst$$reg);
__ movr(Assembler::rc_nz, src_reg, 1, dst_reg);
%}
-#endif
enc_class enc_cadd_cmpLTMask( iRegI p, iRegI q, iRegI y, iRegI tmp ) %{
// (Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)))
MacroAssembler _masm(&cbuf);
@@ -2624,20 +2408,10 @@
// Long values come back from native calls in O0:O1 in the 32-bit VM, copy the value
// to G1 so the register allocator will not have to deal with the misaligned register
// pair.
enc_class adjust_long_from_native_call %{
-#ifndef _LP64
- if (returns_long()) {
- // sllx O0,32,O0
- emit3_simm13( cbuf, Assembler::arith_op, R_O0_enc, Assembler::sllx_op3, R_O0_enc, 0x1020 );
- // srl O1,0,O1
- emit3_simm13( cbuf, Assembler::arith_op, R_O1_enc, Assembler::srl_op3, R_O1_enc, 0x0000 );
- // or O0,O1,G1
- emit3 ( cbuf, Assembler::arith_op, R_G1_enc, Assembler:: or_op3, R_O0_enc, 0, R_O1_enc );
- }
-#endif
%}
enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime
// CALL directly to the runtime
// The user of this is responsible for ensuring that R_L7 is empty (killed).
@@ -3100,15 +2874,11 @@
// Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
cisc_spilling_operand_name(indOffset);
// Number of stack slots consumed by a Monitor enter
-#ifdef _LP64
sync_stack_slots(2);
-#else
- sync_stack_slots(1);
-#endif
// Compiled code's Frame Pointer
frame_pointer(R_SP);
// Stack alignment requirement
@@ -3122,17 +2892,12 @@
in_preserve_stack_slots(0);
// Number of outgoing stack slots killed above the out_preserve_stack_slots
// for calls to C. Supports the var-args backing area for register parms.
// ADLC doesn't support parsing expressions, so I folded the math by hand.
-#ifdef _LP64
// (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (0)) * 2-stack-slots-per-word
varargs_C_out_slots_killed(12);
-#else
- // (callee_register_argument_save_area_words (6) + callee_aggregate_return_pointer_words (1)) * 1-stack-slots-per-word
- varargs_C_out_slots_killed( 7);
-#endif
// The after-PROLOG location of the return address. Location of
// return address specifies a type (REG or STACK) and a number
// representing the register number (i.e. - use a register name) or
// stack slot.
@@ -3159,39 +2924,25 @@
// native calls in O0:O1 and returned to the interpreter in I0:I1. The copying
// to and from the register pairs is done by the appropriate call and epilog
// opcodes. This simplifies the register allocator.
c_return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
-#ifdef _LP64
static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
-#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
-#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
%}
// Location of compiled Java return values. Same as C
return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
-#ifdef _LP64
static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
-#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
-#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
%}
%}
@@ -3442,11 +3193,10 @@
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
-#ifdef _LP64
// Pointer Immediate: 64-bit
operand immP_set() %{
predicate(!VM_Version::is_niagara_plus());
match(ConP);
@@ -3476,11 +3226,10 @@
op_cost(5);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
-#endif
operand immP13() %{
predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095));
match(ConP);
op_cost(0);
@@ -3917,15 +3666,11 @@
// Condition Code Register, pointer comparisons.
operand flagsRegP() %{
constraint(ALLOC_IN_RC(int_flags));
match(RegFlags);
-#ifdef _LP64
format %{ "xcc_P" %}
-#else
- format %{ "icc_P" %}
-#endif
interface(REG_INTER);
%}
// Condition Code Register, long comparisons.
operand flagsRegL() %{
@@ -4498,20 +4243,18 @@
cr : R(read); // This is really E, with a 1 cycle stall
BR : R(2);
MS : R(2);
%}
-#ifdef _LP64
pipe_class ialu_clr_and_mover( iRegI dst, iRegP src ) %{
instruction_count(1); multiple_bundles;
dst : C(write)+1;
src : R(read)+1;
IALU : R(1);
BR : E(2);
MS : E(2);
%}
-#endif
// Integer ALU reg operation
pipe_class ialu_move_reg_L_to_I(iRegI dst, iRegL src) %{
single_instruction; may_have_no_code;
dst : E(write);
@@ -4612,17 +4355,12 @@
fixed_latency(6);
%}
// Polling Address
pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
-#ifdef _LP64
instruction_count(0); multiple_bundles;
fixed_latency(6);
-#else
- dst : E(write);
- IALU : R;
-#endif
%}
// Long Constant small
pipe_class loadConLlo( iRegL dst, immL src ) %{
instruction_count(2);
@@ -5359,11 +5097,10 @@
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
-#ifdef _LP64
// Load pointer from stack slot, 64-bit encoding
instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
format %{ "LDX $src,$dst\t!ptr" %}
@@ -5379,31 +5116,10 @@
format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
-#else // _LP64
-// Load pointer from stack slot, 32-bit encoding
-instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
- match(Set dst src);
- ins_cost(MEMORY_REF_COST);
- format %{ "LDUW $src,$dst\t!ptr" %}
- opcode(Assembler::lduw_op3, Assembler::ldst_op);
- ins_encode(simple_form3_mem_reg( src, dst ) );
- ins_pipe(iload_mem);
-%}
-
-// Store pointer to stack slot
-instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
- match(Set dst src);
- ins_cost(MEMORY_REF_COST);
- format %{ "STW $src,$dst\t!ptr" %}
- opcode(Assembler::stw_op3, Assembler::ldst_op);
- ins_encode(simple_form3_mem_reg( dst, src ) );
- ins_pipe(istore_mem_reg);
-%}
-#endif // _LP64
//------------Special Nop instructions for bundling - no match rules-----------
// Nop using the A0 functional unit
instruct Nop_A0() %{
ins_cost(0);
@@ -5856,21 +5572,14 @@
instruct loadP(iRegP dst, memory mem) %{
match(Set dst (LoadP mem));
ins_cost(MEMORY_REF_COST);
size(4);
-#ifndef _LP64
- format %{ "LDUW $mem,$dst\t! ptr" %}
- ins_encode %{
- __ lduw($mem$$Address, $dst$$Register);
- %}
-#else
format %{ "LDX $mem,$dst\t! ptr" %}
ins_encode %{
__ ldx($mem$$Address, $dst$$Register);
%}
-#endif
ins_pipe(iload_mem);
%}
// Load Compressed Pointer
instruct loadN(iRegN dst, memory mem) %{
@@ -5889,21 +5598,14 @@
instruct loadKlass(iRegP dst, memory mem) %{
match(Set dst (LoadKlass mem));
ins_cost(MEMORY_REF_COST);
size(4);
-#ifndef _LP64
- format %{ "LDUW $mem,$dst\t! klass ptr" %}
- ins_encode %{
- __ lduw($mem$$Address, $dst$$Register);
- %}
-#else
format %{ "LDX $mem,$dst\t! klass ptr" %}
ins_encode %{
__ ldx($mem$$Address, $dst$$Register);
%}
-#endif
ins_pipe(iload_mem);
%}
// Load narrow Klass Pointer
instruct loadNKlass(iRegN dst, memory mem) %{
@@ -5967,30 +5669,10 @@
format %{ "MOV $src,$dst" %}
ins_encode( Set13( src, dst ) );
ins_pipe(ialu_imm);
%}
-#ifndef _LP64
-instruct loadConP(iRegP dst, immP con) %{
- match(Set dst con);
- ins_cost(DEFAULT_COST * 3/2);
- format %{ "SET $con,$dst\t!ptr" %}
- ins_encode %{
- relocInfo::relocType constant_reloc = _opnds[1]->constant_reloc();
- intptr_t val = $con$$constant;
- if (constant_reloc == relocInfo::oop_type) {
- __ set_oop_constant((jobject) val, $dst$$Register);
- } else if (constant_reloc == relocInfo::metadata_type) {
- __ set_metadata_constant((Metadata*)val, $dst$$Register);
- } else { // non-oop pointers, e.g. card mark base, heap top
- assert(constant_reloc == relocInfo::none, "unexpected reloc type");
- __ set(val, $dst$$Register);
- }
- %}
- ins_pipe(loadConP);
-%}
-#else
instruct loadConP_set(iRegP dst, immP_set con) %{
match(Set dst con);
ins_cost(DEFAULT_COST * 3/2);
format %{ "SET $con,$dst\t! ptr" %}
ins_encode %{
@@ -6030,11 +5712,10 @@
__ set($con$$constant, $dst$$Register);
}
%}
ins_pipe(loadConP);
%}
-#endif // _LP64
instruct loadConP0(iRegP dst, immP0 src) %{
match(Set dst src);
size(4);
@@ -6184,23 +5865,10 @@
%}
ins_pipe(istore_mem_reg);
%}
// Next code is used for finding next cache line address to prefetch.
-#ifndef _LP64
-instruct cacheLineAdr( iRegP dst, iRegP src, immI13 mask ) %{
- match(Set dst (CastX2P (AndI (CastP2X src) mask)));
- ins_cost(DEFAULT_COST);
- size(4);
-
- format %{ "AND $src,$mask,$dst\t! next cache line address" %}
- ins_encode %{
- __ and3($src$$Register, $mask$$constant, $dst$$Register);
- %}
- ins_pipe(ialu_reg_imm);
-%}
-#else
instruct cacheLineAdr( iRegP dst, iRegP src, immL13 mask ) %{
match(Set dst (CastX2P (AndL (CastP2X src) mask)));
ins_cost(DEFAULT_COST);
size(4);
@@ -6208,11 +5876,10 @@
ins_encode %{
__ and3($src$$Register, $mask$$constant, $dst$$Register);
%}
ins_pipe(ialu_reg_imm);
%}
-#endif
//----------Store Instructions-------------------------------------------------
// Store Byte
instruct storeB(memory mem, iRegI src) %{
match(Set mem (StoreB mem src));
@@ -6320,32 +5987,22 @@
// Store Pointer
instruct storeP(memory dst, sp_ptr_RegP src) %{
match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST);
-#ifndef _LP64
- format %{ "STW $src,$dst\t! ptr" %}
- opcode(Assembler::stw_op3, 0, REGP_OP);
-#else
format %{ "STX $src,$dst\t! ptr" %}
opcode(Assembler::stx_op3, 0, REGP_OP);
-#endif
ins_encode( form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_spORreg);
%}
instruct storeP0(memory dst, immP0 src) %{
match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST);
-#ifndef _LP64
- format %{ "STW $src,$dst\t! ptr" %}
- opcode(Assembler::stw_op3, 0, REGP_OP);
-#else
format %{ "STX $src,$dst\t! ptr" %}
opcode(Assembler::stx_op3, 0, REGP_OP);
-#endif
ins_encode( form3_mem_reg( dst, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
// Store Compressed Pointer
@@ -7092,17 +6749,12 @@
// LoadP-locked. Same as a regular pointer load when used with a compare-swap
instruct loadPLocked(iRegP dst, memory mem) %{
match(Set dst (LoadPLocked mem));
ins_cost(MEMORY_REF_COST);
-#ifndef _LP64
- format %{ "LDUW $mem,$dst\t! ptr" %}
- opcode(Assembler::lduw_op3, 0, REGP_OP);
-#else
format %{ "LDX $mem,$dst\t! ptr" %}
opcode(Assembler::ldx_op3, 0, REGP_OP);
-#endif
ins_encode( form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{
@@ -7169,30 +6821,23 @@
enc_iflags_ne_to_boolean(res) );
ins_pipe( long_memory_op );
%}
instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
-#ifdef _LP64
predicate(VM_Version::supports_cx8());
-#endif
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect( USE mem_ptr, KILL ccr, KILL tmp1);
format %{
"MOV $newval,O7\n\t"
"CASA_PTR [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
"CMP $oldval,O7\t\t! See if we made progress\n\t"
"MOV 1,$res\n\t"
"MOVne xcc,R_G0,$res"
%}
-#ifdef _LP64
ins_encode( enc_casx(mem_ptr, oldval, newval),
enc_lflags_ne_to_boolean(res) );
-#else
- ins_encode( enc_casi(mem_ptr, oldval, newval),
- enc_iflags_ne_to_boolean(res) );
-#endif
ins_pipe( long_memory_op );
%}
instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
@@ -7266,21 +6911,10 @@
__ swap($mem$$Address, $newval$$Register);
%}
ins_pipe( long_memory_op );
%}
-#ifndef _LP64
-instruct xchgP( memory mem, iRegP newval) %{
- match(Set newval (GetAndSetP mem newval));
- format %{ "SWAP [$mem],$newval" %}
- size(4);
- ins_encode %{
- __ swap($mem$$Address, $newval$$Register);
- %}
- ins_pipe( long_memory_op );
-%}
-#endif
instruct xchgN( memory mem, iRegN newval) %{
match(Set newval (GetAndSetN mem newval));
format %{ "SWAP [$mem],$newval" %}
size(4);
@@ -7738,29 +7372,18 @@
ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) );
ins_pipe(ialu_reg_imm);
%}
// Register Shift Right Immediate with a CastP2X
-#ifdef _LP64
instruct shrP_reg_imm6(iRegL dst, iRegP src1, immU6 src2) %{
match(Set dst (URShiftL (CastP2X src1) src2));
size(4);
format %{ "SRLX $src1,$src2,$dst\t! Cast ptr $src1 to long and shift" %}
opcode(Assembler::srlx_op3, Assembler::arith_op);
ins_encode( form3_sd_rs1_imm6_rd( src1, src2, dst ) );
ins_pipe(ialu_reg_imm);
%}
-#else
-instruct shrP_reg_imm5(iRegI dst, iRegP src1, immU5 src2) %{
- match(Set dst (URShiftI (CastP2X src1) src2));
- size(4);
- format %{ "SRL $src1,$src2,$dst\t! Cast ptr $src1 to int and shift" %}
- opcode(Assembler::srl_op3, Assembler::arith_op);
- ins_encode( form3_rs1_imm5_rd( src1, src2, dst ) );
- ins_pipe(ialu_reg_imm);
-%}
-#endif
//----------Floating Point Arithmetic Instructions-----------------------------
// Add float single precision
@@ -7999,25 +7622,10 @@
opcode(Assembler::or_op3, Assembler::arith_op);
ins_encode( form3_rs1_simm13_rd( src1, con, dst ) );
ins_pipe(ialu_reg_imm);
%}
-#ifndef _LP64
-
-// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
-instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
- match(Set dst (OrI src1 (CastP2X src2)));
-
- size(4);
- format %{ "OR $src1,$src2,$dst" %}
- opcode(Assembler::or_op3, Assembler::arith_op);
- ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
- ins_pipe(ialu_reg_reg);
-%}
-
-#else
-
instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
match(Set dst (OrL src1 (CastP2X src2)));
ins_cost(DEFAULT_COST);
size(4);
@@ -8025,12 +7633,10 @@
opcode(Assembler::or_op3, Assembler::arith_op);
ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
ins_pipe(ialu_reg_reg);
%}
-#endif
-
// Xor Instructions
// Register Xor
instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (XorI src1 src2));
@@ -8086,30 +7692,18 @@
"ADDX R_G0,0,$dst" %}
ins_encode( enc_to_bool( src, dst ) );
ins_pipe(ialu_reg_ialu);
%}
-#ifndef _LP64
-instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
- match(Set dst (Conv2B src));
- effect( KILL ccr );
- ins_cost(DEFAULT_COST*2);
- format %{ "CMP R_G0,$src\n\t"
- "ADDX R_G0,0,$dst" %}
- ins_encode( enc_to_bool( src, dst ) );
- ins_pipe(ialu_reg_ialu);
-%}
-#else
instruct convP2B( iRegI dst, iRegP src ) %{
match(Set dst (Conv2B src));
ins_cost(DEFAULT_COST*2);
format %{ "MOV $src,$dst\n\t"
"MOVRNZ $src,1,$dst" %}
ins_encode( form3_g0_rs2_rd_move( src, dst ), enc_convP2B( dst, src ) );
ins_pipe(ialu_clr_and_mover);
%}
-#endif
instruct cmpLTMask0( iRegI dst, iRegI src, immI0 zero, flagsReg ccr ) %{
match(Set dst (CmpLTMask src zero));
effect(KILL ccr);
size(4);
@@ -8748,20 +8342,14 @@
//-----------
instruct convL2I_reg(iRegI dst, iRegL src) %{
match(Set dst (ConvL2I src));
-#ifndef _LP64
- format %{ "MOV $src.lo,$dst\t! long->int" %}
- ins_encode( form3_g0_rs2_rd_move_lo2( src, dst ) );
- ins_pipe(ialu_move_reg_I_to_L);
-#else
size(4);
format %{ "SRA $src,R_G0,$dst\t! long->int" %}
ins_encode( form3_rs1_rd_signextend_lo1( src, dst ) );
ins_pipe(ialu_reg);
-#endif
%}
// Register Shift Right Immediate
instruct shrL_reg_imm6_L2I(iRegI dst, iRegL src, immI_32_63 cnt) %{
match(Set dst (ConvL2I (RShiftL src cnt)));
@@ -9526,15 +9114,11 @@
predicate(UseCBCond);
effect(USE labl, KILL pcc);
size(4);
ins_cost(BRANCH_COST);
-#ifdef _LP64
format %{ "CXB$cmp $op1,$op2,$labl\t! ptr" %}
-#else
- format %{ "CWB$cmp $op1,$op2,$labl\t! ptr" %}
-#endif
ins_encode %{
Label* L = $labl$$label;
assert(__ use_cbcond(*L), "back to back cbcond");
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L);
%}
@@ -9548,15 +9132,11 @@
predicate(UseCBCond);
effect(USE labl, KILL pcc);
size(4);
ins_cost(BRANCH_COST);
-#ifdef _LP64
format %{ "CXB$cmp $op1,0,$labl\t! ptr" %}
-#else
- format %{ "CWB$cmp $op1,0,$labl\t! ptr" %}
-#endif
ins_encode %{
Label* L = $labl$$label;
assert(__ use_cbcond(*L), "back to back cbcond");
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L);
%}
@@ -9820,15 +9400,11 @@
instruct safePoint_poll(iRegP poll) %{
match(SafePoint poll);
effect(USE poll);
size(4);
-#ifdef _LP64
format %{ "LDX [$poll],R_G0\t! Safepoint: poll for GC" %}
-#else
- format %{ "LDUW [$poll],R_G0\t! Safepoint: poll for GC" %}
-#endif
ins_encode %{
__ relocate(relocInfo::poll_type);
__ ld_ptr($poll$$Register, 0, G0);
%}
ins_pipe(loadPollP);
< prev index next >