comparison src/cpu/sparc/vm/sparc.ad @ 2029:6ce496c8fc07

Merge
author coleenp
date Thu, 16 Dec 2010 09:31:55 -0500
parents 5fe0781a8560
children 7737fa7ec2b5
comparison
equal deleted inserted replaced
2028:450ece4d8a10 2029:6ce496c8fc07
665 offset = atype->is_ptr()->_offset; 665 offset = atype->is_ptr()->_offset;
666 if (offset != Type::OffsetBot) offset += disp32; 666 if (offset != Type::OffsetBot) offset += disp32;
667 return offset; 667 return offset;
668 } 668 }
669 669
670 static inline jdouble replicate_immI(int con, int count, int width) {
671 // Load a constant replicated "count" times with width "width"
672 int bit_width = width * 8;
673 jlong elt_val = con;
674 elt_val &= (((jlong) 1) << bit_width) - 1; // mask off sign bits
675 jlong val = elt_val;
676 for (int i = 0; i < count - 1; i++) {
677 val <<= bit_width;
678 val |= elt_val;
679 }
680 jdouble dval = *((jdouble*) &val); // coerce to double type
681 return dval;
682 }
683
670 // Standard Sparc opcode form2 field breakdown 684 // Standard Sparc opcode form2 field breakdown
671 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) { 685 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) {
672 f0 &= (1<<19)-1; // Mask displacement to 19 bits 686 f0 &= (1<<19)-1; // Mask displacement to 19 bits
673 int op = (f30 << 30) | 687 int op = (f30 << 30) |
674 (f29 << 29) | 688 (f29 << 29) |
1006 void emit_lo(CodeBuffer &cbuf, int val) { } 1020 void emit_lo(CodeBuffer &cbuf, int val) { }
1007 void emit_hi(CodeBuffer &cbuf, int val) { } 1021 void emit_hi(CodeBuffer &cbuf, int val) { }
1008 1022
1009 1023
1010 //============================================================================= 1024 //=============================================================================
1025 const bool Matcher::constant_table_absolute_addressing = false;
1026 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask;
1027
1028 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1029 Compile* C = ra_->C;
1030 Compile::ConstantTable& constant_table = C->constant_table();
1031 MacroAssembler _masm(&cbuf);
1032
1033 Register r = as_Register(ra_->get_encode(this));
1034 CodeSection* cs = __ code()->consts();
1035 int consts_size = cs->align_at_start(cs->size());
1036
1037 if (UseRDPCForConstantTableBase) {
1038 // For the following RDPC logic to work correctly the consts
1039 // section must be allocated right before the insts section. This
1040 // assert checks for that. The layout and the SECT_* constants
1041 // are defined in src/share/vm/asm/codeBuffer.hpp.
1042 assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be");
1043 int offset = __ offset();
1044 int disp;
1045
1046 // If the displacement from the current PC to the constant table
1047 // base fits into simm13 we set the constant table base to the
1048 // current PC.
1049 if (__ is_simm13(-(consts_size + offset))) {
1050 constant_table.set_table_base_offset(-(consts_size + offset));
1051 disp = 0;
1052 } else {
1053 // If the offset of the top constant (last entry in the table)
1054 // fits into simm13 we set the constant table base to the actual
1055 // table base.
1056 if (__ is_simm13(constant_table.top_offset())) {
1057 constant_table.set_table_base_offset(0);
1058 disp = consts_size + offset;
1059 } else {
1060 // Otherwise we set the constant table base in the middle of the
1061 // constant table.
1062 int half_consts_size = consts_size / 2;
1063 assert(half_consts_size * 2 == consts_size, "sanity");
1064 constant_table.set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement.
1065 disp = half_consts_size + offset;
1066 }
1067 }
1068
1069 __ rdpc(r);
1070
1071 if (disp != 0) {
1072 assert(r != O7, "need temporary");
1073 __ sub(r, __ ensure_simm13_or_reg(disp, O7), r);
1074 }
1075 }
1076 else {
1077 // Materialize the constant table base.
1078 assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size));
1079 address baseaddr = cs->start() + -(constant_table.table_base_offset());
1080 RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1081 AddressLiteral base(baseaddr, rspec);
1082 __ set(base, r);
1083 }
1084 }
1085
1086 uint MachConstantBaseNode::size(PhaseRegAlloc*) const {
1087 if (UseRDPCForConstantTableBase) {
1088 // This is really the worst case but generally it's only 1 instruction.
1089 return 4 /*rdpc*/ + 4 /*sub*/ + MacroAssembler::worst_case_size_of_set();
1090 } else {
1091 return MacroAssembler::worst_case_size_of_set();
1092 }
1093 }
1094
1095 #ifndef PRODUCT
1096 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1097 char reg[128];
1098 ra_->dump_register(this, reg);
1099 if (UseRDPCForConstantTableBase) {
1100 st->print("RDPC %s\t! constant table base", reg);
1101 } else {
1102 st->print("SET &constanttable,%s\t! constant table base", reg);
1103 }
1104 }
1105 #endif
1106
1107
1108 //=============================================================================
1011 1109
1012 #ifndef PRODUCT 1110 #ifndef PRODUCT
1013 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { 1111 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
1014 Compile* C = ra_->C; 1112 Compile* C = ra_->C;
1015 1113
2245 2343
2246 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L); 2344 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L);
2247 __ delayed()->nop(); 2345 __ delayed()->nop();
2248 %} 2346 %}
2249 2347
2250 enc_class jump_enc( iRegX switch_val, o7RegI table) %{
2251 MacroAssembler _masm(&cbuf);
2252
2253 Register switch_reg = as_Register($switch_val$$reg);
2254 Register table_reg = O7;
2255
2256 address table_base = __ address_table_constant(_index2label);
2257 RelocationHolder rspec = internal_word_Relocation::spec(table_base);
2258
2259 // Move table address into a register.
2260 __ set(table_base, table_reg, rspec);
2261
2262 // Jump to base address + switch value
2263 __ ld_ptr(table_reg, switch_reg, table_reg);
2264 __ jmp(table_reg, G0);
2265 __ delayed()->nop();
2266
2267 %}
2268
2269 enc_class enc_ba( Label labl ) %{ 2348 enc_class enc_ba( Label labl ) %{
2270 MacroAssembler _masm(&cbuf); 2349 MacroAssembler _masm(&cbuf);
2271 Label &L = *($labl$$label); 2350 Label &L = *($labl$$label);
2272 __ ba(false, L); 2351 __ ba(false, L);
2273 __ delayed()->nop(); 2352 __ delayed()->nop();
2382 (0 << 11) | // cc1, cc0 bits for 'icc' 2461 (0 << 11) | // cc1, cc0 bits for 'icc'
2383 ($src$$reg << 0); 2462 ($src$$reg << 0);
2384 cbuf.insts()->emit_int32(op); 2463 cbuf.insts()->emit_int32(op);
2385 %} 2464 %}
2386 2465
2387 // Utility encoding for loading a 64 bit Pointer into a register
2388 // The 64 bit pointer is stored in the generated code stream
2389 enc_class SetPtr( immP src, iRegP rd ) %{
2390 Register dest = reg_to_register_object($rd$$reg);
2391 MacroAssembler _masm(&cbuf);
2392 // [RGV] This next line should be generated from ADLC
2393 if ( _opnds[1]->constant_is_oop() ) {
2394 intptr_t val = $src$$constant;
2395 __ set_oop_constant((jobject)val, dest);
2396 } else { // non-oop pointers, e.g. card mark base, heap top
2397 __ set($src$$constant, dest);
2398 }
2399 %}
2400
2401 enc_class Set13( immI13 src, iRegI rd ) %{ 2466 enc_class Set13( immI13 src, iRegI rd ) %{
2402 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant ); 2467 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, $src$$constant );
2403 %} 2468 %}
2404 2469
2405 enc_class SetHi22( immI src, iRegI rd ) %{ 2470 enc_class SetHi22( immI src, iRegI rd ) %{
2407 %} 2472 %}
2408 2473
2409 enc_class Set32( immI src, iRegI rd ) %{ 2474 enc_class Set32( immI src, iRegI rd ) %{
2410 MacroAssembler _masm(&cbuf); 2475 MacroAssembler _masm(&cbuf);
2411 __ set($src$$constant, reg_to_register_object($rd$$reg)); 2476 __ set($src$$constant, reg_to_register_object($rd$$reg));
2412 %}
2413
2414 enc_class SetNull( iRegI rd ) %{
2415 emit3_simm13( cbuf, Assembler::arith_op, $rd$$reg, Assembler::or_op3, 0, 0 );
2416 %} 2477 %}
2417 2478
2418 enc_class call_epilog %{ 2479 enc_class call_epilog %{
2419 if( VerifyStackAtCalls ) { 2480 if( VerifyStackAtCalls ) {
2420 MacroAssembler _masm(&cbuf); 2481 MacroAssembler _masm(&cbuf);
2774 FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg) 2835 FloatRegister Fsrc2 = $primary ? reg_to_SingleFloatRegister_object($src2$$reg)
2775 : reg_to_DoubleFloatRegister_object($src2$$reg); 2836 : reg_to_DoubleFloatRegister_object($src2$$reg);
2776 2837
2777 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) 2838 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1)
2778 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); 2839 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
2779 %}
2780
2781 enc_class LdImmL (immL src, iRegL dst, o7RegL tmp) %{ // Load Immediate
2782 MacroAssembler _masm(&cbuf);
2783 Register dest = reg_to_register_object($dst$$reg);
2784 Register temp = reg_to_register_object($tmp$$reg);
2785 __ set64( $src$$constant, dest, temp );
2786 %}
2787
2788 enc_class LdReplImmI(immI src, regD dst, o7RegP tmp, int count, int width) %{
2789 // Load a constant replicated "count" times with width "width"
2790 int bit_width = $width$$constant * 8;
2791 jlong elt_val = $src$$constant;
2792 elt_val &= (((jlong)1) << bit_width) - 1; // mask off sign bits
2793 jlong val = elt_val;
2794 for (int i = 0; i < $count$$constant - 1; i++) {
2795 val <<= bit_width;
2796 val |= elt_val;
2797 }
2798 jdouble dval = *(jdouble*)&val; // coerce to double type
2799 MacroAssembler _masm(&cbuf);
2800 address double_address = __ double_constant(dval);
2801 RelocationHolder rspec = internal_word_Relocation::spec(double_address);
2802 AddressLiteral addrlit(double_address, rspec);
2803
2804 __ sethi(addrlit, $tmp$$Register);
2805 // XXX This is a quick fix for 6833573.
2806 //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
2807 __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec);
2808 %} 2840 %}
2809 2841
2810 // Compiler ensures base is doubleword aligned and cnt is count of doublewords 2842 // Compiler ensures base is doubleword aligned and cnt is count of doublewords
2811 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ 2843 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
2812 MacroAssembler _masm(&cbuf); 2844 MacroAssembler _masm(&cbuf);
3519 // formats are generated automatically for constants and base registers 3551 // formats are generated automatically for constants and base registers
3520 format %{ %} 3552 format %{ %}
3521 interface(CONST_INTER); 3553 interface(CONST_INTER);
3522 %} 3554 %}
3523 3555
3556 // Pointer Immediate: 32 or 64-bit
3557 operand immP_set() %{
3558 predicate(!VM_Version::is_niagara1_plus());
3559 match(ConP);
3560
3561 op_cost(5);
3562 // formats are generated automatically for constants and base registers
3563 format %{ %}
3564 interface(CONST_INTER);
3565 %}
3566
3567 // Pointer Immediate: 32 or 64-bit
3568 // From Niagara2 processors on a load should be better than materializing.
3569 operand immP_load() %{
3570 predicate(VM_Version::is_niagara1_plus());
3571 match(ConP);
3572
3573 op_cost(5);
3574 // formats are generated automatically for constants and base registers
3575 format %{ %}
3576 interface(CONST_INTER);
3577 %}
3578
3524 operand immP13() %{ 3579 operand immP13() %{
3525 predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095)); 3580 predicate((-4096 < n->get_ptr()) && (n->get_ptr() <= 4095));
3526 match(ConP); 3581 match(ConP);
3527 op_cost(0); 3582 op_cost(0);
3528 3583
3607 %} 3662 %}
3608 3663
3609 // Long Immediate: low 32-bit mask 3664 // Long Immediate: low 32-bit mask
3610 operand immL_32bits() %{ 3665 operand immL_32bits() %{
3611 predicate(n->get_long() == 0xFFFFFFFFL); 3666 predicate(n->get_long() == 0xFFFFFFFFL);
3667 match(ConL);
3668 op_cost(0);
3669
3670 format %{ %}
3671 interface(CONST_INTER);
3672 %}
3673
3674 // Long Immediate: cheap (materialize in <= 3 instructions)
3675 operand immL_cheap() %{
3676 predicate(!VM_Version::is_niagara1_plus() || MacroAssembler::size_of_set64(n->get_long()) <= 3);
3677 match(ConL);
3678 op_cost(0);
3679
3680 format %{ %}
3681 interface(CONST_INTER);
3682 %}
3683
3684 // Long Immediate: expensive (materialize in > 3 instructions)
3685 operand immL_expensive() %{
3686 predicate(VM_Version::is_niagara1_plus() && MacroAssembler::size_of_set64(n->get_long()) > 3);
3612 match(ConL); 3687 match(ConL);
3613 op_cost(0); 3688 op_cost(0);
3614 3689
3615 format %{ %} 3690 format %{ %}
3616 interface(CONST_INTER); 3691 interface(CONST_INTER);
5979 format %{ "MOV $src,$dst" %} 6054 format %{ "MOV $src,$dst" %}
5980 ins_encode( Set13( src, dst ) ); 6055 ins_encode( Set13( src, dst ) );
5981 ins_pipe(ialu_imm); 6056 ins_pipe(ialu_imm);
5982 %} 6057 %}
5983 6058
5984 instruct loadConP(iRegP dst, immP src) %{ 6059 #ifndef _LP64
5985 match(Set dst src); 6060 instruct loadConP(iRegP dst, immP con) %{
6061 match(Set dst con);
5986 ins_cost(DEFAULT_COST * 3/2); 6062 ins_cost(DEFAULT_COST * 3/2);
5987 format %{ "SET $src,$dst\t!ptr" %} 6063 format %{ "SET $con,$dst\t!ptr" %}
5988 // This rule does not use "expand" unlike loadConI because then 6064 ins_encode %{
5989 // the result type is not known to be an Oop. An ADLC 6065 // [RGV] This next line should be generated from ADLC
5990 // enhancement will be needed to make that work - not worth it! 6066 if (_opnds[1]->constant_is_oop()) {
5991 6067 intptr_t val = $con$$constant;
5992 ins_encode( SetPtr( src, dst ) ); 6068 __ set_oop_constant((jobject) val, $dst$$Register);
6069 } else { // non-oop pointers, e.g. card mark base, heap top
6070 __ set($con$$constant, $dst$$Register);
6071 }
6072 %}
5993 ins_pipe(loadConP); 6073 ins_pipe(loadConP);
5994 6074 %}
5995 %} 6075 #else
6076 instruct loadConP_set(iRegP dst, immP_set con) %{
6077 match(Set dst con);
6078 ins_cost(DEFAULT_COST * 3/2);
6079 format %{ "SET $con,$dst\t! ptr" %}
6080 ins_encode %{
6081 // [RGV] This next line should be generated from ADLC
6082 if (_opnds[1]->constant_is_oop()) {
6083 intptr_t val = $con$$constant;
6084 __ set_oop_constant((jobject) val, $dst$$Register);
6085 } else { // non-oop pointers, e.g. card mark base, heap top
6086 __ set($con$$constant, $dst$$Register);
6087 }
6088 %}
6089 ins_pipe(loadConP);
6090 %}
6091
6092 instruct loadConP_load(iRegP dst, immP_load con) %{
6093 match(Set dst con);
6094 ins_cost(MEMORY_REF_COST);
6095 format %{ "LD [$constanttablebase + $constantoffset],$dst\t! load from constant table: ptr=$con" %}
6096 ins_encode %{
6097 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
6098 __ ld_ptr($constanttablebase, con_offset, $dst$$Register);
6099 %}
6100 ins_pipe(loadConP);
6101 %}
6102 #endif // _LP64
5996 6103
5997 instruct loadConP0(iRegP dst, immP0 src) %{ 6104 instruct loadConP0(iRegP dst, immP0 src) %{
5998 match(Set dst src); 6105 match(Set dst src);
5999 6106
6000 size(4); 6107 size(4);
6001 format %{ "CLR $dst\t!ptr" %} 6108 format %{ "CLR $dst\t!ptr" %}
6002 ins_encode( SetNull( dst ) ); 6109 ins_encode %{
6110 __ clr($dst$$Register);
6111 %}
6003 ins_pipe(ialu_imm); 6112 ins_pipe(ialu_imm);
6004 %} 6113 %}
6005 6114
6006 instruct loadConP_poll(iRegP dst, immP_poll src) %{ 6115 instruct loadConP_poll(iRegP dst, immP_poll src) %{
6007 match(Set dst src); 6116 match(Set dst src);
6017 instruct loadConN0(iRegN dst, immN0 src) %{ 6126 instruct loadConN0(iRegN dst, immN0 src) %{
6018 match(Set dst src); 6127 match(Set dst src);
6019 6128
6020 size(4); 6129 size(4);
6021 format %{ "CLR $dst\t! compressed NULL ptr" %} 6130 format %{ "CLR $dst\t! compressed NULL ptr" %}
6022 ins_encode( SetNull( dst ) ); 6131 ins_encode %{
6132 __ clr($dst$$Register);
6133 %}
6023 ins_pipe(ialu_imm); 6134 ins_pipe(ialu_imm);
6024 %} 6135 %}
6025 6136
6026 instruct loadConN(iRegN dst, immN src) %{ 6137 instruct loadConN(iRegN dst, immN src) %{
6027 match(Set dst src); 6138 match(Set dst src);
6032 __ set_narrow_oop((jobject)$src$$constant, dst); 6143 __ set_narrow_oop((jobject)$src$$constant, dst);
6033 %} 6144 %}
6034 ins_pipe(ialu_hi_lo_reg); 6145 ins_pipe(ialu_hi_lo_reg);
6035 %} 6146 %}
6036 6147
6037 instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ 6148 // Materialize long value (predicated by immL_cheap).
6038 // %%% maybe this should work like loadConD 6149 instruct loadConL_set64(iRegL dst, immL_cheap con, o7RegL tmp) %{
6039 match(Set dst src); 6150 match(Set dst con);
6040 effect(KILL tmp); 6151 effect(KILL tmp);
6041 ins_cost(DEFAULT_COST * 4); 6152 ins_cost(DEFAULT_COST * 3);
6042 format %{ "SET64 $src,$dst KILL $tmp\t! long" %} 6153 format %{ "SET64 $con,$dst KILL $tmp\t! cheap long" %}
6043 ins_encode( LdImmL(src, dst, tmp) ); 6154 ins_encode %{
6155 __ set64($con$$constant, $dst$$Register, $tmp$$Register);
6156 %}
6157 ins_pipe(loadConL);
6158 %}
6159
6160 // Load long value from constant table (predicated by immL_expensive).
6161 instruct loadConL_ldx(iRegL dst, immL_expensive con) %{
6162 match(Set dst con);
6163 ins_cost(MEMORY_REF_COST);
6164 format %{ "LDX [$constanttablebase + $constantoffset],$dst\t! load from constant table: long=$con" %}
6165 ins_encode %{
6166 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $dst$$Register);
6167 __ ldx($constanttablebase, con_offset, $dst$$Register);
6168 %}
6044 ins_pipe(loadConL); 6169 ins_pipe(loadConL);
6045 %} 6170 %}
6046 6171
6047 instruct loadConL0( iRegL dst, immL0 src ) %{ 6172 instruct loadConL0( iRegL dst, immL0 src ) %{
6048 match(Set dst src); 6173 match(Set dst src);
6061 format %{ "MOV $src,$dst\t! long" %} 6186 format %{ "MOV $src,$dst\t! long" %}
6062 ins_encode( Set13( src, dst ) ); 6187 ins_encode( Set13( src, dst ) );
6063 ins_pipe(ialu_imm); 6188 ins_pipe(ialu_imm);
6064 %} 6189 %}
6065 6190
6066 instruct loadConF(regF dst, immF src, o7RegP tmp) %{ 6191 instruct loadConF(regF dst, immF con, o7RegI tmp) %{
6067 match(Set dst src); 6192 match(Set dst con);
6068 effect(KILL tmp); 6193 effect(KILL tmp);
6069 6194 format %{ "LDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: float=$con" %}
6070 #ifdef _LP64
6071 size(8*4);
6072 #else
6073 size(2*4);
6074 #endif
6075
6076 format %{ "SETHI hi(&$src),$tmp\t!get float $src from table\n\t"
6077 "LDF [$tmp+lo(&$src)],$dst" %}
6078 ins_encode %{ 6195 ins_encode %{
6079 address float_address = __ float_constant($src$$constant); 6196 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register);
6080 RelocationHolder rspec = internal_word_Relocation::spec(float_address); 6197 __ ldf(FloatRegisterImpl::S, $constanttablebase, con_offset, $dst$$FloatRegister);
6081 AddressLiteral addrlit(float_address, rspec);
6082
6083 __ sethi(addrlit, $tmp$$Register);
6084 __ ldf(FloatRegisterImpl::S, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec);
6085 %} 6198 %}
6086 ins_pipe(loadConFD); 6199 ins_pipe(loadConFD);
6087 %} 6200 %}
6088 6201
6089 instruct loadConD(regD dst, immD src, o7RegP tmp) %{ 6202 instruct loadConD(regD dst, immD con, o7RegI tmp) %{
6090 match(Set dst src); 6203 match(Set dst con);
6091 effect(KILL tmp); 6204 effect(KILL tmp);
6092 6205 format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: double=$con" %}
6093 #ifdef _LP64
6094 size(8*4);
6095 #else
6096 size(2*4);
6097 #endif
6098
6099 format %{ "SETHI hi(&$src),$tmp\t!get double $src from table\n\t"
6100 "LDDF [$tmp+lo(&$src)],$dst" %}
6101 ins_encode %{ 6206 ins_encode %{
6102 address double_address = __ double_constant($src$$constant);
6103 RelocationHolder rspec = internal_word_Relocation::spec(double_address);
6104 AddressLiteral addrlit(double_address, rspec);
6105
6106 __ sethi(addrlit, $tmp$$Register);
6107 // XXX This is a quick fix for 6833573. 6207 // XXX This is a quick fix for 6833573.
6108 //__ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), $dst$$FloatRegister, rspec); 6208 //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset($con), $dst$$FloatRegister);
6109 __ ldf(FloatRegisterImpl::D, $tmp$$Register, addrlit.low10(), as_DoubleFloatRegister($dst$$reg), rspec); 6209 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset($con), $tmp$$Register);
6210 __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
6110 %} 6211 %}
6111 ins_pipe(loadConFD); 6212 ins_pipe(loadConFD);
6112 %} 6213 %}
6113 6214
6114 // Prefetch instructions. 6215 // Prefetch instructions.
8556 regL_to_stkD(dst, tmp); 8657 regL_to_stkD(dst, tmp);
8557 %} 8658 %}
8558 %} 8659 %}
8559 8660
8560 // Replicate scalar constant to packed byte values in Double register 8661 // Replicate scalar constant to packed byte values in Double register
8561 instruct Repl8B_immI(regD dst, immI13 src, o7RegP tmp) %{ 8662 instruct Repl8B_immI(regD dst, immI13 con, o7RegI tmp) %{
8562 match(Set dst (Replicate8B src)); 8663 match(Set dst (Replicate8B con));
8563 #ifdef _LP64 8664 effect(KILL tmp);
8564 size(36); 8665 format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
8565 #else 8666 ins_encode %{
8566 size(8); 8667 // XXX This is a quick fix for 6833573.
8567 #endif 8668 //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
8568 format %{ "SETHI hi(&Repl8($src)),$tmp\t!get Repl8B($src) from table\n\t" 8669 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 8, 1)), $tmp$$Register);
8569 "LDDF [$tmp+lo(&Repl8($src))],$dst" %} 8670 __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
8570 ins_encode( LdReplImmI(src, dst, tmp, (8), (1)) ); 8671 %}
8571 ins_pipe(loadConFD); 8672 ins_pipe(loadConFD);
8572 %} 8673 %}
8573 8674
8574 // Replicate scalar to packed char values into stack slot 8675 // Replicate scalar to packed char values into stack slot
8575 instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{ 8676 instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{
8592 regL_to_stkD(dst, tmp); 8693 regL_to_stkD(dst, tmp);
8593 %} 8694 %}
8594 %} 8695 %}
8595 8696
8596 // Replicate scalar constant to packed char values in Double register 8697 // Replicate scalar constant to packed char values in Double register
8597 instruct Repl4C_immI(regD dst, immI src, o7RegP tmp) %{ 8698 instruct Repl4C_immI(regD dst, immI con, o7RegI tmp) %{
8598 match(Set dst (Replicate4C src)); 8699 match(Set dst (Replicate4C con));
8599 #ifdef _LP64 8700 effect(KILL tmp);
8600 size(36); 8701 format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %}
8601 #else 8702 ins_encode %{
8602 size(8); 8703 // XXX This is a quick fix for 6833573.
8603 #endif 8704 //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
8604 format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4C($src) from table\n\t" 8705 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
8605 "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 8706 __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
8606 ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 8707 %}
8607 ins_pipe(loadConFD); 8708 ins_pipe(loadConFD);
8608 %} 8709 %}
8609 8710
8610 // Replicate scalar to packed short values into stack slot 8711 // Replicate scalar to packed short values into stack slot
8611 instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{ 8712 instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{
8628 regL_to_stkD(dst, tmp); 8729 regL_to_stkD(dst, tmp);
8629 %} 8730 %}
8630 %} 8731 %}
8631 8732
8632 // Replicate scalar constant to packed short values in Double register 8733 // Replicate scalar constant to packed short values in Double register
8633 instruct Repl4S_immI(regD dst, immI src, o7RegP tmp) %{ 8734 instruct Repl4S_immI(regD dst, immI con, o7RegI tmp) %{
8634 match(Set dst (Replicate4S src)); 8735 match(Set dst (Replicate4S con));
8635 #ifdef _LP64 8736 effect(KILL tmp);
8636 size(36); 8737 format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
8637 #else 8738 ins_encode %{
8638 size(8); 8739 // XXX This is a quick fix for 6833573.
8639 #endif 8740 //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
8640 format %{ "SETHI hi(&Repl4($src)),$tmp\t!get Repl4S($src) from table\n\t" 8741 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
8641 "LDDF [$tmp+lo(&Repl4($src))],$dst" %} 8742 __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
8642 ins_encode( LdReplImmI(src, dst, tmp, (4), (2)) ); 8743 %}
8643 ins_pipe(loadConFD); 8744 ins_pipe(loadConFD);
8644 %} 8745 %}
8645 8746
8646 // Replicate scalar to packed int values in Double register 8747 // Replicate scalar to packed int values in Double register
8647 instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{ 8748 instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{
8662 regL_to_stkD(dst, tmp); 8763 regL_to_stkD(dst, tmp);
8663 %} 8764 %}
8664 %} 8765 %}
8665 8766
8666 // Replicate scalar zero constant to packed int values in Double register 8767 // Replicate scalar zero constant to packed int values in Double register
8667 instruct Repl2I_immI(regD dst, immI src, o7RegP tmp) %{ 8768 instruct Repl2I_immI(regD dst, immI con, o7RegI tmp) %{
8668 match(Set dst (Replicate2I src)); 8769 match(Set dst (Replicate2I con));
8669 #ifdef _LP64 8770 effect(KILL tmp);
8670 size(36); 8771 format %{ "LDDF [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
8671 #else 8772 ins_encode %{
8672 size(8); 8773 // XXX This is a quick fix for 6833573.
8673 #endif 8774 //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
8674 format %{ "SETHI hi(&Repl2($src)),$tmp\t!get Repl2I($src) from table\n\t" 8775 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 2, 4)), $tmp$$Register);
8675 "LDDF [$tmp+lo(&Repl2($src))],$dst" %} 8776 __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
8676 ins_encode( LdReplImmI(src, dst, tmp, (2), (4)) ); 8777 %}
8677 ins_pipe(loadConFD); 8778 ins_pipe(loadConFD);
8678 %} 8779 %}
8679 8780
8680 //----------Control Flow Instructions------------------------------------------ 8781 //----------Control Flow Instructions------------------------------------------
8681 // Compare Instructions 8782 // Compare Instructions
8927 instruct jumpXtnd(iRegX switch_val, o7RegI table) %{ 9028 instruct jumpXtnd(iRegX switch_val, o7RegI table) %{
8928 match(Jump switch_val); 9029 match(Jump switch_val);
8929 9030
8930 ins_cost(350); 9031 ins_cost(350);
8931 9032
8932 format %{ "SETHI [hi(table_base)],O7\n\t" 9033 format %{ "ADD $constanttablebase, $constantoffset, O7\n\t"
8933 "ADD O7, lo(table_base), O7\n\t" 9034 "LD [O7 + $switch_val], O7\n\t"
8934 "LD [O7+$switch_val], O7\n\t"
8935 "JUMP O7" 9035 "JUMP O7"
8936 %} 9036 %}
8937 ins_encode( jump_enc( switch_val, table) ); 9037 ins_encode %{
9038 // Calculate table address into a register.
9039 Register table_reg;
9040 Register label_reg = O7;
9041 if (constant_offset() == 0) {
9042 table_reg = $constanttablebase;
9043 } else {
9044 table_reg = O7;
9045 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset, O7);
9046 __ add($constanttablebase, con_offset, table_reg);
9047 }
9048
9049 // Jump to base address + switch value
9050 __ ld_ptr(table_reg, $switch_val$$Register, label_reg);
9051 __ jmp(label_reg, G0);
9052 __ delayed()->nop();
9053 %}
8938 ins_pc_relative(1); 9054 ins_pc_relative(1);
8939 ins_pipe(ialu_reg_reg); 9055 ins_pipe(ialu_reg_reg);
8940 %} 9056 %}
8941 9057
8942 // Direct Branch. Use V8 version with longer range. 9058 // Direct Branch. Use V8 version with longer range.