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