src/cpu/sparc/vm/sparc.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6961690 Cdiff src/cpu/sparc/vm/sparc.ad
src/cpu/sparc/vm/sparc.ad
Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:
*** 665,674 ****
--- 665,688 ----
offset = atype->is_ptr()->_offset;
if (offset != Type::OffsetBot) offset += disp32;
return offset;
}
+ static inline jdouble replicate_immI(int con, int count, int width) {
+ // Load a constant replicated "count" times with width "width"
+ int bit_width = width * 8;
+ jlong elt_val = con;
+ elt_val &= (((jlong) 1) << bit_width) - 1; // mask off sign bits
+ jlong val = elt_val;
+ for (int i = 0; i < count - 1; i++) {
+ val <<= bit_width;
+ val |= elt_val;
+ }
+ jdouble dval = *((jdouble*) &val); // coerce to double type
+ return dval;
+ }
+
// Standard Sparc opcode form2 field breakdown
static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) {
f0 &= (1<<19)-1; // Mask displacement to 19 bits
int op = (f30 << 30) |
(f29 << 29) |
*** 1006,1015 ****
--- 1020,1107 ----
void emit_lo(CodeBuffer &cbuf, int val) { }
void emit_hi(CodeBuffer &cbuf, int val) { }
//=============================================================================
+ const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask;
+
+ void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
+ emit_constant_table(cbuf);
+ MacroAssembler _masm(&cbuf);
+
+ Register r = as_Register(ra_->get_encode(this));
+ CodeSection* cs = __ code()->consts();
+ int consts_size = cs->align_at_start(cs->size());
+
+ if (UseRDPCForConstantTableBase) {
+ int offset = __ offset();
+ int disp;
+
+ // If the displacement from the current PC to the constant table
+ // base fits into simm13 we set the constant table base to the
+ // current PC.
+ if (__ is_simm13(-(consts_size + offset))) {
+ set_table_base_offset(-(consts_size + offset));
+ disp = 0;
+ } else {
+ // If the offset of the top constant (last entry in the table)
+ // fits into simm13 we set the constant table base to the actual
+ // table base.
+ if (__ is_simm13(top_constant_offset())) {
+ set_table_base_offset(0);
+ disp = consts_size + offset;
+ } else {
+ // Otherwise we set the constant table base in the middle of the
+ // constant table.
+ int half_consts_size = consts_size / 2;
+ assert(half_consts_size * 2 == consts_size, "sanity");
+ set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement.
+ disp = half_consts_size + offset;
+ }
+ }
+
+ __ get_pc(r);
+
+ if (disp != 0) {
+ assert(r != O7, "need temporary");
+ __ sub(r, __ ensure_simm13_or_reg(disp, O7), r);
+ }
+ }
+ else {
+ // Materialize the constant table base.
+ // Set the constant table base in the middle of the constant
+ // table.
+ int half_consts_size = consts_size / 2;
+ assert(half_consts_size * 2 == consts_size, "sanity");
+ set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement.
+
+ address baseaddr = cs->start() + half_consts_size;
+ RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
+ AddressLiteral base(baseaddr, rspec);
+ __ set(base, r);
+ }
+ }
+
+ uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
+ Unimplemented();
+ return 0;
+ }
+
+ #ifndef PRODUCT
+ void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
+ char reg[128];
+ ra_->dump_register(this, reg);
+ if (UseRDPCForConstantTableBase) {
+ st->print("RDPC %s\t! constant table base", reg);
+ } else {
+ st->print("SET &constanttable,%s\t! constant table base", reg);
+ }
+ }
+ #endif
+
+
+ //=============================================================================
#ifndef PRODUCT
void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
Compile* C = ra_->C;
*** 2245,2273 ****
__ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L);
__ delayed()->nop();
%}
- enc_class jump_enc( iRegX switch_val, o7RegI table) %{
- MacroAssembler _masm(&cbuf);
-
- Register switch_reg = as_Register($switch_val$$reg);
- Register table_reg = O7;
-
- address table_base = __ address_table_constant(_index2label);
- RelocationHolder rspec = internal_word_Relocation::spec(table_base);
-
- // Move table address into a register.
- __ set(table_base, table_reg, rspec);
-
- // Jump to base address + switch value
- __ ld_ptr(table_reg, switch_reg, table_reg);
- __ jmp(table_reg, G0);
- __ delayed()->nop();
-
- %}
-
enc_class enc_ba( Label labl ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
__ ba(false, L);
__ delayed()->nop();
--- 2337,2346 ----
*** 2382,2405 ****
(0 << 11) | // cc1, cc0 bits for 'icc'
($src$$reg << 0);
cbuf.insts()->emit_int32(op);
%}
- // Utility encoding for loading a 64 bit Pointer into a register
- // The 64 bit pointer is stored in the generated code stream
- enc_class SetPtr( immP src, iRegP rd ) %{
- Register dest = reg_to_register_object($rd$$reg);
- MacroAssembler _masm(&cbuf);
- // [RGV] This next line should be generated from ADLC
- if ( _opnds[1]->constant_is_oop() ) {
- intptr_t val = $src$$constant;
- __ set_oop_constant((jobject)val, dest);
- } else { // non-oop pointers, e.g. card mark base, heap top
- __ set($src$$constant, dest);
- }
- %}
-
enc_class Set13( immI13 src, iRegI rd ) %{
emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant );
%}
enc_class SetHi22( immI src, iRegI rd ) %{
--- 2455,2464 ----
*** 2409,2422 ****
enc_class Set32( immI src, iRegI rd ) %{
MacroAssembler _masm(&cbuf);
__ set($src$$constant, reg_to_register_object($rd$$reg));
%}
- enc_class SetNull( iRegI rd ) %{
- emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 );
- %}
-
enc_class call_epilog %{
if( VerifyStackAtCalls ) {
MacroAssembler _masm(&cbuf);
int framesize = ra_->C->frame_slots() << LogBytesPerInt;
Register temp_reg = G3;
--- 2468,2477 ----
*** 2776,2814 ****
// Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1)
__ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
%}
- enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate
- MacroAssembler _masm(&cbuf);
- Register dest = reg_to_register_object($dst$$reg);
- Register temp = reg_to_register_object($tmp$$reg);
- __ set64( $src$$constant, dest, temp );
- %}
-
- enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{
- // Load a constant replicated "count" times with width "width"
- int bit_width = $width$$constant * 8;
- jlong elt_val = $src$$constant;
- elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits
- jlong val = elt_val;
- for (int i = 0; i < $count$$constant - 1; i++) {
- val <<= bit_width;
- val |= elt_val;
- }
- jdouble dval = *(jdouble*)&val; // coerce to double type
- MacroAssembler _masm(&cbuf);
- address double_address = __ double_constant(dval);
- RelocationHolder rspec = internal_word_Relocation::spec(double_address);
- AddressLiteral addrlit(double_address, rspec);
-
- __ sethi(addrlit, $tmp$$Register);
- // XXX This is a quick fix for 6833573.
- //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
- __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
- %}
-
// Compiler ensures base is doubleword aligned and cnt is count of doublewords
enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
MacroAssembler _masm(&cbuf);
Register nof_bytes_arg = reg_to_register_object($cnt$$reg);
Register nof_bytes_tmp = reg_to_register_object($temp$$reg);
--- 2831,2840 ----
*** 3614,3623 ****
--- 3640,3669 ----
format %{ %}
interface(CONST_INTER);
%}
+ // Long Immediate: cheap (materialize in <= 3 instructions)
+ operand immL_cheap() %{
+ predicate(MacroAssembler::size_of_set64(n->get_long()) <= 3);
+ match(ConL);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+ %}
+
+ // Long Immediate: expensive (materialize in > 3 instructions)
+ operand immL_expensive() %{
+ predicate(MacroAssembler::size_of_set64(n->get_long()) > 3);
+ match(ConL);
+ op_cost(0);
+
+ format %{ %}
+ interface(CONST_INTER);
+ %}
+
// Double Immediate
operand immD() %{
match(ConD);
op_cost(40);
*** 5979,6007 ****
format %{ "MOV $src,$dst" %}
ins_encode( Set13( src, dst ) );
ins_pipe(ialu_imm);
%}
! instruct loadConP(iRegP dst, immP src) %{
! match(Set dst src);
ins_cost(DEFAULT_COST * 3/2);
! format %{ "SET $src,$dst\t!ptr" %}
! // This rule does not use "expand" unlike loadConI because then
! // the result type is not known to be an Oop. An ADLC
! // enhancement will be needed to make that work - not worth it!
!
! ins_encode( SetPtr( src, dst ) );
ins_pipe(loadConP);
-
%}
instruct loadConP0(iRegP dst, immP0 src) %{
match(Set dst src);
size(4);
format %{ "CLR $dst\t!ptr" %}
! ins_encode( SetNull( dst ) );
ins_pipe(ialu_imm);
%}
instruct loadConP_poll(iRegP dst, immP_poll src) %{
match(Set dst src);
--- 6025,6067 ----
format %{ "MOV $src,$dst" %}
ins_encode( Set13( src, dst ) );
ins_pipe(ialu_imm);
%}
! instruct loadConP(iRegP dst, immP con) %{
! match(Set dst con);
! #ifndef _LP64
ins_cost(DEFAULT_COST * 3/2);
! format %{ "SET $con,$dst\t!ptr" %}
! ins_encode %{
! // [RGV] This next line should be generated from ADLC
! if (_opnds[1]->constant_is_oop()) {
! intptr_t val = $con$$constant;
! __ set_oop_constant((jobject) val, $dst$$Register);
! } else { // non-oop pointers, e.g. card mark base, heap top
! __ set($con$$constant, $dst$$Register);
! }
! %}
! #else
! ins_cost(MEMORY_REF_COST);
! size(4);
! format %{ "LD [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
! ins_encode %{
! __ ld_ptr($constanttablebase, $constantoffset($con), $dst$$Register);
! %}
! #endif
ins_pipe(loadConP);
%}
instruct loadConP0(iRegP dst, immP0 src) %{
match(Set dst src);
size(4);
format %{ "CLR $dst\t!ptr" %}
! ins_encode %{
! __ clr($dst$$Register);
! %}
ins_pipe(ialu_imm);
%}
instruct loadConP_poll(iRegP dst, immP_poll src) %{
match(Set dst src);
*** 6017,6027 ****
instruct loadConN0(iRegN dst, immN0 src) %{
match(Set dst src);
size(4);
format %{ "CLR $dst\t! compressed NULL ptr" %}
! ins_encode( SetNull( dst ) );
ins_pipe(ialu_imm);
%}
instruct loadConN(iRegN dst, immN src) %{
match(Set dst src);
--- 6077,6089 ----
instruct loadConN0(iRegN dst, immN0 src) %{
match(Set dst src);
size(4);
format %{ "CLR $dst\t! compressed NULL ptr" %}
! ins_encode %{
! __ clr($dst$$Register);
! %}
ins_pipe(ialu_imm);
%}
instruct loadConN(iRegN dst, immN src) %{
match(Set dst src);
*** 6032,6048 ****
__ set_narrow_oop((jobject)$src$$constant, dst);
%}
ins_pipe(ialu_hi_lo_reg);
%}
! instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
! // %%% maybe this should work like loadConD
! match(Set dst src);
effect(KILL tmp);
! ins_cost(DEFAULT_COST * 4);
! format %{ "SET64 $src,$dst KILL $tmp\t! long" %}
! ins_encode( LdImmL(src, dst, tmp) );
ins_pipe(loadConL);
%}
instruct loadConL0( iRegL dst, immL0 src ) %{
match(Set dst src);
--- 6094,6123 ----
__ set_narrow_oop((jobject)$src$$constant, dst);
%}
ins_pipe(ialu_hi_lo_reg);
%}
! // Materialize long value (predicated by immL_cheap).
! instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{
! match(Set dst con);
effect(KILL tmp);
! ins_cost(DEFAULT_COST * 3);
! format %{ "SET64 $con,$dst KILL $tmp\t! long" %}
! ins_encode %{
! __ set64($con$$constant, $dst$$Register, $tmp$$Register);
! %}
! ins_pipe(loadConL);
! %}
!
! // Load long value from constant table (predicated by immL_expensive).
! instruct loadConL_ldx(iRegL dst, immL_expensive con) %{
! match(Set dst con);
! ins_cost(MEMORY_REF_COST);
! format %{ "LDX [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %}
! ins_encode %{
! __ ldx($constanttablebase, $constantoffset($con), $dst$$Register);
! %}
ins_pipe(loadConL);
%}
instruct loadConL0( iRegL dst, immL0 src ) %{
match(Set dst src);
*** 6061,6114 ****
format %{ "MOV $src,$dst\t! long" %}
ins_encode( Set13( src, dst ) );
ins_pipe(ialu_imm);
%}
! instruct loadConF(regF dst, immF src, o7RegP tmp) %{
! match(Set dst src);
! effect(KILL tmp);
!
! #ifdef _LP64
! size(8*4);
! #else
! size(2*4);
! #endif
!
! format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t"
! "LDF [$tmp+lo(&$src)],$dst" %}
ins_encode %{
! address float_address = __ float_constant($src$$constant);
! RelocationHolder rspec = internal_word_Relocation::spec(float_address);
! AddressLiteral addrlit(float_address, rspec);
!
! __ sethi(addrlit, $tmp$$Register);
! __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
%}
ins_pipe(loadConFD);
%}
! instruct loadConD(regD dst, immD src, o7RegP tmp) %{
! match(Set dst src);
! effect(KILL tmp);
!
! #ifdef _LP64
! size(8*4);
! #else
! size(2*4);
! #endif
!
! format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t"
! "LDDF [$tmp+lo(&$src)],$dst" %}
ins_encode %{
- address double_address = __ double_constant($src$$constant);
- RelocationHolder rspec = internal_word_Relocation::spec(double_address);
- AddressLiteral addrlit(double_address, rspec);
-
- __ sethi(addrlit, $tmp$$Register);
// XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
! __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
%}
ins_pipe(loadConFD);
%}
// Prefetch instructions.
--- 6136,6163 ----
format %{ "MOV $src,$dst\t! long" %}
ins_encode( Set13( src, dst ) );
ins_pipe(ialu_imm);
%}
! instruct loadConF(regF dst, immF con) %{
! match(Set dst con);
! size(4);
! format %{ "LDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %}
ins_encode %{
! __ ldf(FloatRegisterImpl::S, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
%}
ins_pipe(loadConFD);
%}
! instruct loadConD(regD dst, immD con) %{
! match(Set dst con);
! size(4);
! format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %}
ins_encode %{
// XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
! __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), as_DoubleFloatRegister($dst$$reg));
%}
ins_pipe(loadConFD);
%}
// Prefetch instructions.
*** 8556,8575 ****
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed byte values in Double register
! instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{
! match(Set dst (Replicate8B src));
! #ifdef _LP64
! size(36);
! #else
! size(8);
! #endif
! format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t"
! "LDDF [$tmp+lo(&Repl8($src))],$dst" %}
! ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) );
ins_pipe(loadConFD);
%}
// Replicate scalar to packed char values into stack slot
instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{
--- 8605,8623 ----
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed byte values in Double register
! instruct Repl8B_immI(regD dst, immI13 con) %{
! match(Set dst (Replicate8B con));
! size(4);
! format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
! ins_encode %{
! // XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
! __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), as_DoubleFloatRegister($dst$$reg));
! %}
ins_pipe(loadConFD);
%}
// Replicate scalar to packed char values into stack slot
instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{
*** 8592,8611 ****
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed char values in Double register
! instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{
! match(Set dst (Replicate4C src));
! #ifdef _LP64
! size(36);
! #else
! size(8);
! #endif
! format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t"
! "LDDF [$tmp+lo(&Repl4($src))],$dst" %}
! ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
ins_pipe(loadConFD);
%}
// Replicate scalar to packed short values into stack slot
instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{
--- 8640,8658 ----
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed char values in Double register
! instruct Repl4C_immI(regD dst, immI con) %{
! match(Set dst (Replicate4C con));
! size(4);
! format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %}
! ins_encode %{
! // XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
! __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg));
! %}
ins_pipe(loadConFD);
%}
// Replicate scalar to packed short values into stack slot
instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{
*** 8628,8647 ****
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed short values in Double register
! instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{
! match(Set dst (Replicate4S src));
! #ifdef _LP64
! size(36);
! #else
! size(8);
! #endif
! format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t"
! "LDDF [$tmp+lo(&Repl4($src))],$dst" %}
! ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) );
ins_pipe(loadConFD);
%}
// Replicate scalar to packed int values in Double register
instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{
--- 8675,8693 ----
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar constant to packed short values in Double register
! instruct Repl4S_immI(regD dst, immI con) %{
! match(Set dst (Replicate4S con));
! size(4);
! format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
! ins_encode %{
! // XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
! __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), as_DoubleFloatRegister($dst$$reg));
! %}
ins_pipe(loadConFD);
%}
// Replicate scalar to packed int values in Double register
instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{
*** 8662,8681 ****
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar zero constant to packed int values in Double register
! instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{
! match(Set dst (Replicate2I src));
! #ifdef _LP64
! size(36);
! #else
! size(8);
! #endif
! format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t"
! "LDDF [$tmp+lo(&Repl2($src))],$dst" %}
! ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) );
ins_pipe(loadConFD);
%}
//----------Control Flow Instructions------------------------------------------
// Compare Instructions
--- 8708,8726 ----
regL_to_stkD(dst, tmp);
%}
%}
// Replicate scalar zero constant to packed int values in Double register
! instruct Repl2I_immI(regD dst, immI con) %{
! match(Set dst (Replicate2I con));
! size(4);
! format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
! ins_encode %{
! // XXX This is a quick fix for 6833573.
! //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
! __ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), as_DoubleFloatRegister($dst$$reg));
! %}
ins_pipe(loadConFD);
%}
//----------Control Flow Instructions------------------------------------------
// Compare Instructions
*** 8927,8942 ****
instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
match(Jump switch_val);
ins_cost(350);
! format %{ "SETHI [hi(table_base)],O7\n\t"
! "ADD O7, lo(table_base), O7\n\t"
! "LD [O7+$switch_val], O7\n\t"
"JUMP O7"
%}
! ins_encode( jump_enc( switch_val, table) );
ins_pc_relative(1);
ins_pipe(ialu_reg_reg);
%}
// Direct Branch. Use V8 version with longer range.
--- 8972,9001 ----
instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
match(Jump switch_val);
ins_cost(350);
! format %{ "ADD $constanttablebase, $constantoffset, O7\n\t"
! "LD [O7 + $switch_val], O7\n\t"
"JUMP O7"
%}
! ins_encode %{
! // Calculate table address into a register.
! Register table_reg;
! Register label_reg = O7;
! if (constant_offset() == 0) {
! table_reg = $constanttablebase;
! } else {
! table_reg = O7;
! __ add($constanttablebase, $constantoffset, table_reg);
! }
!
! // Jump to base address + switch value
! __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
! __ jmp(label_reg, G0);
! __ delayed()->nop();
! %}
ins_pc_relative(1);
ins_pipe(ialu_reg_reg);
%}
// Direct Branch. Use V8 version with longer range.
src/cpu/sparc/vm/sparc.ad
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File