Mercurial > hg > truffle
comparison src/cpu/sparc/vm/sparc.ad @ 4137:04b9a2566eec
Merge with hsx23/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 21:40:27 +0100 |
parents | db2e64ca2d5a |
children | 1dc233a8c7fe |
comparison
equal
deleted
inserted
replaced
3737:9dc19b7d89a3 | 4137:04b9a2566eec |
---|---|
423 | 423 |
424 // Paired floating point registers--they show up in the same order as the floats, | 424 // Paired floating point registers--they show up in the same order as the floats, |
425 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs. | 425 // but they are used with the "Op_RegD" type, and always occur in even/odd pairs. |
426 // This class is usable for mis-aligned loads as happen in I2C adapters. | 426 // This class is usable for mis-aligned loads as happen in I2C adapters. |
427 reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, | 427 reg_class dflt_low_reg(R_F0, R_F1, R_F2, R_F3, R_F4, R_F5, R_F6, R_F7, R_F8, R_F9, R_F10,R_F11,R_F12,R_F13,R_F14,R_F15, |
428 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31 ); | 428 R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29); |
429 %} | 429 %} |
430 | 430 |
431 //----------DEFINITION BLOCK--------------------------------------------------- | 431 //----------DEFINITION BLOCK--------------------------------------------------- |
432 // Define name --> value mappings to inform the ADLC of an integer valued name | 432 // Define name --> value mappings to inform the ADLC of an integer valued name |
433 // Current support includes integer values in the range [0, 0x7FFFFFFF] | 433 // Current support includes integer values in the range [0, 0x7FFFFFFF] |
458 // definitions necessary in the rest of the architecture description | 458 // definitions necessary in the rest of the architecture description |
459 source_hpp %{ | 459 source_hpp %{ |
460 // Must be visible to the DFA in dfa_sparc.cpp | 460 // Must be visible to the DFA in dfa_sparc.cpp |
461 extern bool can_branch_register( Node *bol, Node *cmp ); | 461 extern bool can_branch_register( Node *bol, Node *cmp ); |
462 | 462 |
463 extern bool use_block_zeroing(Node* count); | |
464 | |
463 // Macros to extract hi & lo halves from a long pair. | 465 // Macros to extract hi & lo halves from a long pair. |
464 // G0 is not part of any long pair, so assert on that. | 466 // G0 is not part of any long pair, so assert on that. |
465 // Prevents accidentally using G1 instead of G0. | 467 // Prevents accidentally using G1 instead of G0. |
466 #define LONG_HI_REG(x) (x) | 468 #define LONG_HI_REG(x) (x) |
467 #define LONG_LO_REG(x) (x) | 469 #define LONG_LO_REG(x) (x) |
468 | 470 |
469 %} | 471 %} |
470 | 472 |
471 source %{ | 473 source %{ |
472 #define __ _masm. | 474 #define __ _masm. |
473 | |
474 // Block initializing store | |
475 #define ASI_BLK_INIT_QUAD_LDD_P 0xE2 | |
476 | 475 |
477 // tertiary op of a LoadP or StoreP encoding | 476 // tertiary op of a LoadP or StoreP encoding |
478 #define REGP_OP true | 477 #define REGP_OP true |
479 | 478 |
480 static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding); | 479 static FloatRegister reg_to_SingleFloatRegister_object(int register_encoding); |
520 if( !x->in(i)->is_Load() ) | 519 if( !x->in(i)->is_Load() ) |
521 return false; | 520 return false; |
522 return true; | 521 return true; |
523 } | 522 } |
524 return false; | 523 return false; |
524 } | |
525 | |
526 bool use_block_zeroing(Node* count) { | |
527 // Use BIS for zeroing if count is not constant | |
528 // or it is >= BlockZeroingLowLimit. | |
529 return UseBlockZeroing && (count->find_intptr_t_con(BlockZeroingLowLimit) >= BlockZeroingLowLimit); | |
525 } | 530 } |
526 | 531 |
527 // **************************************************************************** | 532 // **************************************************************************** |
528 | 533 |
529 // REQUIRED FUNCTIONALITY | 534 // REQUIRED FUNCTIONALITY |
559 else | 564 else |
560 klass_load_size = 3*BytesPerInstWord; | 565 klass_load_size = 3*BytesPerInstWord; |
561 } else { | 566 } else { |
562 klass_load_size = 1*BytesPerInstWord; | 567 klass_load_size = 1*BytesPerInstWord; |
563 } | 568 } |
564 if( Assembler::is_simm13(v_off) ) { | 569 if (Assembler::is_simm13(v_off)) { |
565 return klass_load_size + | 570 return klass_load_size + |
566 (2*BytesPerInstWord + // ld_ptr, ld_ptr | 571 (2*BytesPerInstWord + // ld_ptr, ld_ptr |
567 NativeCall::instruction_size); // call; delay slot | 572 NativeCall::instruction_size); // call; delay slot |
568 } else { | 573 } else { |
569 return klass_load_size + | 574 return klass_load_size + |
833 !(n->ideal_Opcode()==Op_LoadD_unaligned && ld_op==Op_LoadF) && | 838 !(n->ideal_Opcode()==Op_LoadD_unaligned && ld_op==Op_LoadF) && |
834 !(n->ideal_Opcode()==Op_ConvI2F && ld_op==Op_LoadF) && | 839 !(n->ideal_Opcode()==Op_ConvI2F && ld_op==Op_LoadF) && |
835 !(n->ideal_Opcode()==Op_ConvI2D && ld_op==Op_LoadF) && | 840 !(n->ideal_Opcode()==Op_ConvI2D && ld_op==Op_LoadF) && |
836 !(n->ideal_Opcode()==Op_PrefetchRead && ld_op==Op_LoadI) && | 841 !(n->ideal_Opcode()==Op_PrefetchRead && ld_op==Op_LoadI) && |
837 !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) && | 842 !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) && |
843 !(n->ideal_Opcode()==Op_PrefetchAllocation && ld_op==Op_LoadI) && | |
838 !(n->ideal_Opcode()==Op_Load2I && ld_op==Op_LoadD) && | 844 !(n->ideal_Opcode()==Op_Load2I && ld_op==Op_LoadD) && |
839 !(n->ideal_Opcode()==Op_Load4C && ld_op==Op_LoadD) && | 845 !(n->ideal_Opcode()==Op_Load4C && ld_op==Op_LoadD) && |
840 !(n->ideal_Opcode()==Op_Load4S && ld_op==Op_LoadD) && | 846 !(n->ideal_Opcode()==Op_Load4S && ld_op==Op_LoadD) && |
841 !(n->ideal_Opcode()==Op_Load8B && ld_op==Op_LoadD) && | 847 !(n->ideal_Opcode()==Op_Load8B && ld_op==Op_LoadD) && |
842 !(n->rule() == loadUB_rule)) { | 848 !(n->rule() == loadUB_rule)) { |
1011 void emit_lo(CodeBuffer &cbuf, int val) { } | 1017 void emit_lo(CodeBuffer &cbuf, int val) { } |
1012 void emit_hi(CodeBuffer &cbuf, int val) { } | 1018 void emit_hi(CodeBuffer &cbuf, int val) { } |
1013 | 1019 |
1014 | 1020 |
1015 //============================================================================= | 1021 //============================================================================= |
1016 const bool Matcher::constant_table_absolute_addressing = false; | 1022 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask(); |
1017 const RegMask& MachConstantBaseNode::_out_RegMask = PTR_REG_mask; | 1023 |
1024 int Compile::ConstantTable::calculate_table_base_offset() const { | |
1025 if (UseRDPCForConstantTableBase) { | |
1026 // The table base offset might be less but then it fits into | |
1027 // simm13 anyway and we are good (cf. MachConstantBaseNode::emit). | |
1028 return Assembler::min_simm13(); | |
1029 } else { | |
1030 int offset = -(size() / 2); | |
1031 if (!Assembler::is_simm13(offset)) { | |
1032 offset = Assembler::min_simm13(); | |
1033 } | |
1034 return offset; | |
1035 } | |
1036 } | |
1018 | 1037 |
1019 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { | 1038 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { |
1020 Compile* C = ra_->C; | 1039 Compile* C = ra_->C; |
1021 Compile::ConstantTable& constant_table = C->constant_table(); | 1040 Compile::ConstantTable& constant_table = C->constant_table(); |
1022 MacroAssembler _masm(&cbuf); | 1041 MacroAssembler _masm(&cbuf); |
1023 | 1042 |
1024 Register r = as_Register(ra_->get_encode(this)); | 1043 Register r = as_Register(ra_->get_encode(this)); |
1025 CodeSection* cs = __ code()->consts(); | 1044 CodeSection* consts_section = __ code()->consts(); |
1026 int consts_size = cs->align_at_start(cs->size()); | 1045 int consts_size = consts_section->align_at_start(consts_section->size()); |
1046 assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size)); | |
1027 | 1047 |
1028 if (UseRDPCForConstantTableBase) { | 1048 if (UseRDPCForConstantTableBase) { |
1029 // For the following RDPC logic to work correctly the consts | 1049 // For the following RDPC logic to work correctly the consts |
1030 // section must be allocated right before the insts section. This | 1050 // section must be allocated right before the insts section. This |
1031 // assert checks for that. The layout and the SECT_* constants | 1051 // assert checks for that. The layout and the SECT_* constants |
1032 // are defined in src/share/vm/asm/codeBuffer.hpp. | 1052 // are defined in src/share/vm/asm/codeBuffer.hpp. |
1033 assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be"); | 1053 assert(CodeBuffer::SECT_CONSTS + 1 == CodeBuffer::SECT_INSTS, "must be"); |
1034 int offset = __ offset(); | 1054 int insts_offset = __ offset(); |
1055 | |
1056 // Layout: | |
1057 // | |
1058 // |----------- consts section ------------|----------- insts section -----------... | |
1059 // |------ constant table -----|- padding -|------------------x---- | |
1060 // \ current PC (RDPC instruction) | |
1061 // |<------------- consts_size ----------->|<- insts_offset ->| | |
1062 // \ table base | |
1063 // The table base offset is later added to the load displacement | |
1064 // so it has to be negative. | |
1065 int table_base_offset = -(consts_size + insts_offset); | |
1035 int disp; | 1066 int disp; |
1036 | 1067 |
1037 // If the displacement from the current PC to the constant table | 1068 // If the displacement from the current PC to the constant table |
1038 // base fits into simm13 we set the constant table base to the | 1069 // base fits into simm13 we set the constant table base to the |
1039 // current PC. | 1070 // current PC. |
1040 if (__ is_simm13(-(consts_size + offset))) { | 1071 if (Assembler::is_simm13(table_base_offset)) { |
1041 constant_table.set_table_base_offset(-(consts_size + offset)); | 1072 constant_table.set_table_base_offset(table_base_offset); |
1042 disp = 0; | 1073 disp = 0; |
1043 } else { | 1074 } else { |
1044 // If the offset of the top constant (last entry in the table) | 1075 // Otherwise we set the constant table base offset to the |
1045 // fits into simm13 we set the constant table base to the actual | 1076 // maximum negative displacement of load instructions to keep |
1046 // table base. | 1077 // the disp as small as possible: |
1047 if (__ is_simm13(constant_table.top_offset())) { | 1078 // |
1048 constant_table.set_table_base_offset(0); | 1079 // |<------------- consts_size ----------->|<- insts_offset ->| |
1049 disp = consts_size + offset; | 1080 // |<--------- min_simm13 --------->|<-------- disp --------->| |
1050 } else { | 1081 // \ table base |
1051 // Otherwise we set the constant table base in the middle of the | 1082 table_base_offset = Assembler::min_simm13(); |
1052 // constant table. | 1083 constant_table.set_table_base_offset(table_base_offset); |
1053 int half_consts_size = consts_size / 2; | 1084 disp = (consts_size + insts_offset) + table_base_offset; |
1054 assert(half_consts_size * 2 == consts_size, "sanity"); | |
1055 constant_table.set_table_base_offset(-half_consts_size); // table base offset gets added to the load displacement. | |
1056 disp = half_consts_size + offset; | |
1057 } | |
1058 } | 1085 } |
1059 | 1086 |
1060 __ rdpc(r); | 1087 __ rdpc(r); |
1061 | 1088 |
1062 if (disp != 0) { | 1089 if (disp != 0) { |
1064 __ sub(r, __ ensure_simm13_or_reg(disp, O7), r); | 1091 __ sub(r, __ ensure_simm13_or_reg(disp, O7), r); |
1065 } | 1092 } |
1066 } | 1093 } |
1067 else { | 1094 else { |
1068 // Materialize the constant table base. | 1095 // Materialize the constant table base. |
1069 assert(constant_table.size() == consts_size, err_msg("must be: %d == %d", constant_table.size(), consts_size)); | 1096 address baseaddr = consts_section->start() + -(constant_table.table_base_offset()); |
1070 address baseaddr = cs->start() + -(constant_table.table_base_offset()); | |
1071 RelocationHolder rspec = internal_word_Relocation::spec(baseaddr); | 1097 RelocationHolder rspec = internal_word_Relocation::spec(baseaddr); |
1072 AddressLiteral base(baseaddr, rspec); | 1098 AddressLiteral base(baseaddr, rspec); |
1073 __ set(base, r); | 1099 __ set(base, r); |
1074 } | 1100 } |
1075 } | 1101 } |
1161 __ sethi(-framesize & ~0x3ff, G3); | 1187 __ sethi(-framesize & ~0x3ff, G3); |
1162 __ add(G3, -framesize & 0x3ff, G3); | 1188 __ add(G3, -framesize & 0x3ff, G3); |
1163 __ save(SP, G3, SP); | 1189 __ save(SP, G3, SP); |
1164 } | 1190 } |
1165 C->set_frame_complete( __ offset() ); | 1191 C->set_frame_complete( __ offset() ); |
1192 | |
1193 if (!UseRDPCForConstantTableBase && C->has_mach_constant_base_node()) { | |
1194 // NOTE: We set the table base offset here because users might be | |
1195 // emitted before MachConstantBaseNode. | |
1196 Compile::ConstantTable& constant_table = C->constant_table(); | |
1197 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); | |
1198 } | |
1166 } | 1199 } |
1167 | 1200 |
1168 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { | 1201 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { |
1169 return MachNode::size(ra_); | 1202 return MachNode::size(ra_); |
1170 } | 1203 } |
1324 src_second_rc = rc_float; | 1357 src_second_rc = rc_float; |
1325 } | 1358 } |
1326 | 1359 |
1327 // -------------------------------------- | 1360 // -------------------------------------- |
1328 // Check for float->int copy; requires a trip through memory | 1361 // Check for float->int copy; requires a trip through memory |
1329 if( src_first_rc == rc_float && dst_first_rc == rc_int ) { | 1362 if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) { |
1330 int offset = frame::register_save_words*wordSize; | 1363 int offset = frame::register_save_words*wordSize; |
1331 if( cbuf ) { | 1364 if (cbuf) { |
1332 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); | 1365 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); |
1333 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); | 1366 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); |
1334 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); | 1367 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); |
1335 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); | 1368 emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); |
1336 } | 1369 } |
1337 #ifndef PRODUCT | 1370 #ifndef PRODUCT |
1338 else if( !do_size ) { | 1371 else if (!do_size) { |
1339 if( size != 0 ) st->print("\n\t"); | 1372 if (size != 0) st->print("\n\t"); |
1340 st->print( "SUB R_SP,16,R_SP\n"); | 1373 st->print( "SUB R_SP,16,R_SP\n"); |
1341 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); | 1374 impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); |
1342 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); | 1375 impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); |
1343 st->print("\tADD R_SP,16,R_SP\n"); | 1376 st->print("\tADD R_SP,16,R_SP\n"); |
1344 } | 1377 } |
1345 #endif | 1378 #endif |
1346 size += 16; | 1379 size += 16; |
1380 } | |
1381 | |
1382 // Check for float->int copy on T4 | |
1383 if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) { | |
1384 // Further check for aligned-adjacent pair, so we can use a double move | |
1385 if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second) | |
1386 return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mdtox_opf,"MOVDTOX",size, st); | |
1387 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mstouw_opf,"MOVSTOUW",size, st); | |
1388 } | |
1389 // Check for int->float copy on T4 | |
1390 if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) { | |
1391 // Further check for aligned-adjacent pair, so we can use a double move | |
1392 if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second) | |
1393 return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mxtod_opf,"MOVXTOD",size, st); | |
1394 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mwtos_opf,"MOVWTOS",size, st); | |
1347 } | 1395 } |
1348 | 1396 |
1349 // -------------------------------------- | 1397 // -------------------------------------- |
1350 // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations. | 1398 // In the 32-bit 1-reg-longs build ONLY, I see mis-aligned long destinations. |
1351 // In such cases, I have to do the big-endian swap. For aligned targets, the | 1399 // In such cases, I have to do the big-endian swap. For aligned targets, the |
1676 } | 1724 } |
1677 #endif | 1725 #endif |
1678 | 1726 |
1679 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | 1727 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
1680 MacroAssembler _masm(&cbuf); | 1728 MacroAssembler _masm(&cbuf); |
1681 Label L; | |
1682 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); | 1729 Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode()); |
1683 Register temp_reg = G3; | 1730 Register temp_reg = G3; |
1684 assert( G5_ic_reg != temp_reg, "conflicting registers" ); | 1731 assert( G5_ic_reg != temp_reg, "conflicting registers" ); |
1685 | 1732 |
1686 // Load klass from receiver | 1733 // Load klass from receiver |
1818 | 1865 |
1819 // Is this branch offset short enough that a short branch can be used? | 1866 // Is this branch offset short enough that a short branch can be used? |
1820 // | 1867 // |
1821 // NOTE: If the platform does not provide any short branch variants, then | 1868 // NOTE: If the platform does not provide any short branch variants, then |
1822 // this method should return false for offset 0. | 1869 // this method should return false for offset 0. |
1823 bool Matcher::is_short_branch_offset(int rule, int offset) { | 1870 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { |
1824 return false; | 1871 // The passed offset is relative to address of the branch. |
1872 // Don't need to adjust the offset. | |
1873 return UseCBCond && Assembler::is_simm12(offset); | |
1825 } | 1874 } |
1826 | 1875 |
1827 const bool Matcher::isSimpleConstant64(jlong value) { | 1876 const bool Matcher::isSimpleConstant64(jlong value) { |
1828 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. | 1877 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. |
1829 // Depends on optimizations in MacroAssembler::setx. | 1878 // Depends on optimizations in MacroAssembler::setx. |
1835 // No scaling for the parameter the ClearArray node. | 1884 // No scaling for the parameter the ClearArray node. |
1836 const bool Matcher::init_array_count_is_in_bytes = true; | 1885 const bool Matcher::init_array_count_is_in_bytes = true; |
1837 | 1886 |
1838 // Threshold size for cleararray. | 1887 // Threshold size for cleararray. |
1839 const int Matcher::init_array_short_size = 8 * BytesPerLong; | 1888 const int Matcher::init_array_short_size = 8 * BytesPerLong; |
1889 | |
1890 // No additional cost for CMOVL. | |
1891 const int Matcher::long_cmove_cost() { return 0; } | |
1892 | |
1893 // CMOVF/CMOVD are expensive on T4 and on SPARC64. | |
1894 const int Matcher::float_cmove_cost() { | |
1895 return (VM_Version::is_T4() || VM_Version::is_sparc64()) ? ConditionalMoveLimit : 0; | |
1896 } | |
1840 | 1897 |
1841 // Should the Matcher clone shifts on addressing modes, expecting them to | 1898 // Should the Matcher clone shifts on addressing modes, expecting them to |
1842 // be subsumed into complex addressing expressions or compute them into | 1899 // be subsumed into complex addressing expressions or compute them into |
1843 // registers? True for Intel but false for most RISCs | 1900 // registers? True for Intel but false for most RISCs |
1844 const bool Matcher::clone_shift_expressions = false; | 1901 const bool Matcher::clone_shift_expressions = false; |
1965 ShouldNotReachHere(); | 2022 ShouldNotReachHere(); |
1966 return RegMask(); | 2023 return RegMask(); |
1967 } | 2024 } |
1968 | 2025 |
1969 const RegMask Matcher::method_handle_invoke_SP_save_mask() { | 2026 const RegMask Matcher::method_handle_invoke_SP_save_mask() { |
1970 return L7_REGP_mask; | 2027 return L7_REGP_mask(); |
1971 } | 2028 } |
1972 | 2029 |
1973 %} | 2030 %} |
1974 | 2031 |
1975 | 2032 |
2040 emit_form3_mem_reg(cbuf, this, $primary, -1, | 2097 emit_form3_mem_reg(cbuf, this, $primary, -1, |
2041 $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/); | 2098 $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/); |
2042 %} | 2099 %} |
2043 | 2100 |
2044 enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{ | 2101 enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{ |
2045 assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); | 2102 assert(Assembler::is_simm13($mem$$disp ), "need disp and disp+4"); |
2046 assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); | 2103 assert(Assembler::is_simm13($mem$$disp+4), "need disp and disp+4"); |
2047 guarantee($mem$$index == R_G0_enc, "double index?"); | 2104 guarantee($mem$$index == R_G0_enc, "double index?"); |
2048 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc ); | 2105 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc ); |
2049 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg ); | 2106 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg ); |
2050 emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 ); | 2107 emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 ); |
2051 emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc ); | 2108 emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc ); |
2052 %} | 2109 %} |
2053 | 2110 |
2054 enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{ | 2111 enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{ |
2055 assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); | 2112 assert(Assembler::is_simm13($mem$$disp ), "need disp and disp+4"); |
2056 assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" ); | 2113 assert(Assembler::is_simm13($mem$$disp+4), "need disp and disp+4"); |
2057 guarantee($mem$$index == R_G0_enc, "double index?"); | 2114 guarantee($mem$$index == R_G0_enc, "double index?"); |
2058 // Load long with 2 instructions | 2115 // Load long with 2 instructions |
2059 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 ); | 2116 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 ); |
2060 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 ); | 2117 emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 ); |
2061 %} | 2118 %} |
2298 MacroAssembler _masm(&cbuf); | 2355 MacroAssembler _masm(&cbuf); |
2299 __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); | 2356 __ call(StubRoutines::Sparc::partial_subtype_check(), relocInfo::runtime_call_type); |
2300 __ delayed()->nop(); | 2357 __ delayed()->nop(); |
2301 %} | 2358 %} |
2302 | 2359 |
2303 enc_class enc_bp( Label labl, cmpOp cmp, flagsReg cc ) %{ | 2360 enc_class enc_bp( label labl, cmpOp cmp, flagsReg cc ) %{ |
2304 MacroAssembler _masm(&cbuf); | 2361 MacroAssembler _masm(&cbuf); |
2305 Label &L = *($labl$$label); | 2362 Label* L = $labl$$label; |
2306 Assembler::Predict predict_taken = | 2363 Assembler::Predict predict_taken = |
2307 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | 2364 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; |
2308 | 2365 |
2309 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, L); | 2366 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); |
2310 __ delayed()->nop(); | 2367 __ delayed()->nop(); |
2311 %} | 2368 %} |
2312 | 2369 |
2313 enc_class enc_bpl( Label labl, cmpOp cmp, flagsRegL cc ) %{ | 2370 enc_class enc_bpr( label labl, cmpOp_reg cmp, iRegI op1 ) %{ |
2314 MacroAssembler _masm(&cbuf); | 2371 MacroAssembler _masm(&cbuf); |
2315 Label &L = *($labl$$label); | 2372 Label* L = $labl$$label; |
2316 Assembler::Predict predict_taken = | 2373 Assembler::Predict predict_taken = |
2317 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | 2374 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; |
2318 | 2375 |
2319 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, L); | 2376 __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), *L); |
2320 __ delayed()->nop(); | |
2321 %} | |
2322 | |
2323 enc_class enc_bpx( Label labl, cmpOp cmp, flagsRegP cc ) %{ | |
2324 MacroAssembler _masm(&cbuf); | |
2325 Label &L = *($labl$$label); | |
2326 Assembler::Predict predict_taken = | |
2327 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2328 | |
2329 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, L); | |
2330 __ delayed()->nop(); | |
2331 %} | |
2332 | |
2333 enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{ | |
2334 MacroAssembler _masm(&cbuf); | |
2335 Label &L = *($labl$$label); | |
2336 Assembler::Predict predict_taken = | |
2337 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2338 | |
2339 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L); | |
2340 __ delayed()->nop(); | |
2341 %} | |
2342 | |
2343 enc_class enc_ba( Label labl ) %{ | |
2344 MacroAssembler _masm(&cbuf); | |
2345 Label &L = *($labl$$label); | |
2346 __ ba(false, L); | |
2347 __ delayed()->nop(); | |
2348 %} | |
2349 | |
2350 enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{ | |
2351 MacroAssembler _masm(&cbuf); | |
2352 Label &L = *$labl$$label; | |
2353 Assembler::Predict predict_taken = | |
2354 cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn; | |
2355 | |
2356 __ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), L); | |
2357 __ delayed()->nop(); | 2377 __ delayed()->nop(); |
2358 %} | 2378 %} |
2359 | 2379 |
2360 enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ | 2380 enc_class enc_cmov_reg( cmpOp cmp, iRegI dst, iRegI src, immI pcc) %{ |
2361 int op = (Assembler::arith_op << 30) | | 2381 int op = (Assembler::arith_op << 30) | |
2568 } else { | 2588 } else { |
2569 klass_load_size = 1*BytesPerInstWord; | 2589 klass_load_size = 1*BytesPerInstWord; |
2570 } | 2590 } |
2571 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); | 2591 int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); |
2572 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); | 2592 int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); |
2573 if( __ is_simm13(v_off) ) { | 2593 if (Assembler::is_simm13(v_off)) { |
2574 __ ld_ptr(G3, v_off, G5_method); | 2594 __ ld_ptr(G3, v_off, G5_method); |
2575 } else { | 2595 } else { |
2576 // Generate 2 instructions | 2596 // Generate 2 instructions |
2577 __ Assembler::sethi(v_off & ~0x3ff, G5_method); | 2597 __ Assembler::sethi(v_off & ~0x3ff, G5_method); |
2578 __ or3(G5_method, v_off & 0x3ff, G5_method); | 2598 __ or3(G5_method, v_off & 0x3ff, G5_method); |
2832 | 2852 |
2833 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) | 2853 // Convert condition code fcc0 into -1,0,1; unordered reports less-than (-1) |
2834 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); | 2854 __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst); |
2835 %} | 2855 %} |
2836 | 2856 |
2837 // Compiler ensures base is doubleword aligned and cnt is count of doublewords | |
2838 enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{ | |
2839 MacroAssembler _masm(&cbuf); | |
2840 Register nof_bytes_arg = reg_to_register_object($cnt$$reg); | |
2841 Register nof_bytes_tmp = reg_to_register_object($temp$$reg); | |
2842 Register base_pointer_arg = reg_to_register_object($base$$reg); | |
2843 | |
2844 Label loop; | |
2845 __ mov(nof_bytes_arg, nof_bytes_tmp); | |
2846 | |
2847 // Loop and clear, walking backwards through the array. | |
2848 // nof_bytes_tmp (if >0) is always the number of bytes to zero | |
2849 __ bind(loop); | |
2850 __ deccc(nof_bytes_tmp, 8); | |
2851 __ br(Assembler::greaterEqual, true, Assembler::pt, loop); | |
2852 __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp); | |
2853 // %%%% this mini-loop must not cross a cache boundary! | |
2854 %} | |
2855 | |
2856 | 2857 |
2857 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{ | 2858 enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{ |
2858 Label Ldone, Lloop; | 2859 Label Ldone, Lloop; |
2859 MacroAssembler _masm(&cbuf); | 2860 MacroAssembler _masm(&cbuf); |
2860 | 2861 |
2969 | 2970 |
2970 __ cmp(str1_reg, str2_reg); //same char[] ? | 2971 __ cmp(str1_reg, str2_reg); //same char[] ? |
2971 __ brx(Assembler::equal, true, Assembler::pn, Ldone); | 2972 __ brx(Assembler::equal, true, Assembler::pn, Ldone); |
2972 __ delayed()->add(G0, 1, result_reg); | 2973 __ delayed()->add(G0, 1, result_reg); |
2973 | 2974 |
2974 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone); | 2975 __ cmp_zero_and_br(Assembler::zero, cnt_reg, Ldone, true, Assembler::pn); |
2975 __ delayed()->add(G0, 1, result_reg); // count == 0 | 2976 __ delayed()->add(G0, 1, result_reg); // count == 0 |
2976 | 2977 |
2977 //rename registers | 2978 //rename registers |
2978 Register limit_reg = cnt_reg; | 2979 Register limit_reg = cnt_reg; |
2979 Register chr1_reg = result_reg; | 2980 Register chr1_reg = result_reg; |
2989 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count | 2990 __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count |
2990 | 2991 |
2991 // Compare char[] arrays aligned to 4 bytes. | 2992 // Compare char[] arrays aligned to 4 bytes. |
2992 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, | 2993 __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg, |
2993 chr1_reg, chr2_reg, Ldone); | 2994 chr1_reg, chr2_reg, Ldone); |
2994 __ ba(false,Ldone); | 2995 __ ba(Ldone); |
2995 __ delayed()->add(G0, 1, result_reg); | 2996 __ delayed()->add(G0, 1, result_reg); |
2996 | 2997 |
2997 // char by char compare | 2998 // char by char compare |
2998 __ bind(Lchar); | 2999 __ bind(Lchar); |
2999 __ add(str1_reg, limit_reg, str1_reg); | 3000 __ add(str1_reg, limit_reg, str1_reg); |
3048 // return false if the two arrays are not equal length | 3049 // return false if the two arrays are not equal length |
3049 __ cmp(tmp1_reg, tmp2_reg); | 3050 __ cmp(tmp1_reg, tmp2_reg); |
3050 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); | 3051 __ br(Assembler::notEqual, true, Assembler::pn, Ldone); |
3051 __ delayed()->mov(G0, result_reg); // not equal | 3052 __ delayed()->mov(G0, result_reg); // not equal |
3052 | 3053 |
3053 __ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone); | 3054 __ cmp_zero_and_br(Assembler::zero, tmp1_reg, Ldone, true, Assembler::pn); |
3054 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal | 3055 __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal |
3055 | 3056 |
3056 // load array addresses | 3057 // load array addresses |
3057 __ add(ary1_reg, base_offset, ary1_reg); | 3058 __ add(ary1_reg, base_offset, ary1_reg); |
3058 __ add(ary2_reg, base_offset, ary2_reg); | 3059 __ add(ary2_reg, base_offset, ary2_reg); |
3335 //----------Operand Attributes------------------------------------------------- | 3336 //----------Operand Attributes------------------------------------------------- |
3336 op_attrib op_cost(1); // Required cost attribute | 3337 op_attrib op_cost(1); // Required cost attribute |
3337 | 3338 |
3338 //----------Instruction Attributes--------------------------------------------- | 3339 //----------Instruction Attributes--------------------------------------------- |
3339 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute | 3340 ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute |
3340 ins_attrib ins_size(32); // Required size attribute (in bits) | 3341 ins_attrib ins_size(32); // Required size attribute (in bits) |
3341 ins_attrib ins_pc_relative(0); // Required PC Relative flag | 3342 ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back |
3342 ins_attrib ins_short_branch(0); // Required flag: is this instruction a | 3343 ins_attrib ins_short_branch(0); // Required flag: is this instruction a |
3343 // non-matching short branch variant of some | 3344 // non-matching short branch variant of some |
3344 // long branch? | 3345 // long branch? |
3345 | 3346 |
3346 //----------OPERANDS----------------------------------------------------------- | 3347 //----------OPERANDS----------------------------------------------------------- |
3347 // Operand definitions must precede instruction definitions for correct parsing | 3348 // Operand definitions must precede instruction definitions for correct parsing |
3348 // in the ADLC because operands constitute user defined types which are used in | 3349 // in the ADLC because operands constitute user defined types which are used in |
3360 interface(CONST_INTER); | 3361 interface(CONST_INTER); |
3361 %} | 3362 %} |
3362 | 3363 |
3363 // Integer Immediate: 8-bit | 3364 // Integer Immediate: 8-bit |
3364 operand immI8() %{ | 3365 operand immI8() %{ |
3365 predicate(Assembler::is_simm(n->get_int(), 8)); | 3366 predicate(Assembler::is_simm8(n->get_int())); |
3366 match(ConI); | 3367 match(ConI); |
3367 op_cost(0); | 3368 op_cost(0); |
3368 format %{ %} | 3369 format %{ %} |
3369 interface(CONST_INTER); | 3370 interface(CONST_INTER); |
3370 %} | 3371 %} |
3389 interface(CONST_INTER); | 3390 interface(CONST_INTER); |
3390 %} | 3391 %} |
3391 | 3392 |
3392 // Integer Immediate: 16-bit | 3393 // Integer Immediate: 16-bit |
3393 operand immI16() %{ | 3394 operand immI16() %{ |
3394 predicate(Assembler::is_simm(n->get_int(), 16)); | 3395 predicate(Assembler::is_simm16(n->get_int())); |
3395 match(ConI); | 3396 match(ConI); |
3396 op_cost(0); | 3397 op_cost(0); |
3397 format %{ %} | 3398 format %{ %} |
3398 interface(CONST_INTER); | 3399 interface(CONST_INTER); |
3399 %} | 3400 %} |
3417 interface(CONST_INTER); | 3418 interface(CONST_INTER); |
3418 %} | 3419 %} |
3419 | 3420 |
3420 // Integer Immediate: 11-bit | 3421 // Integer Immediate: 11-bit |
3421 operand immI11() %{ | 3422 operand immI11() %{ |
3422 predicate(Assembler::is_simm(n->get_int(),11)); | 3423 predicate(Assembler::is_simm11(n->get_int())); |
3424 match(ConI); | |
3425 op_cost(0); | |
3426 format %{ %} | |
3427 interface(CONST_INTER); | |
3428 %} | |
3429 | |
3430 // Integer Immediate: 5-bit | |
3431 operand immI5() %{ | |
3432 predicate(Assembler::is_simm5(n->get_int())); | |
3423 match(ConI); | 3433 match(ConI); |
3424 op_cost(0); | 3434 op_cost(0); |
3425 format %{ %} | 3435 format %{ %} |
3426 interface(CONST_INTER); | 3436 interface(CONST_INTER); |
3427 %} | 3437 %} |
3643 operand immL0() %{ | 3653 operand immL0() %{ |
3644 predicate(n->get_long() == 0L); | 3654 predicate(n->get_long() == 0L); |
3645 match(ConL); | 3655 match(ConL); |
3646 op_cost(0); | 3656 op_cost(0); |
3647 // formats are generated automatically for constants and base registers | 3657 // formats are generated automatically for constants and base registers |
3658 format %{ %} | |
3659 interface(CONST_INTER); | |
3660 %} | |
3661 | |
3662 // Integer Immediate: 5-bit | |
3663 operand immL5() %{ | |
3664 predicate(n->get_long() == (int)n->get_long() && Assembler::is_simm5((int)n->get_long())); | |
3665 match(ConL); | |
3666 op_cost(0); | |
3648 format %{ %} | 3667 format %{ %} |
3649 interface(CONST_INTER); | 3668 interface(CONST_INTER); |
3650 %} | 3669 %} |
3651 | 3670 |
3652 // Long Immediate: 13-bit | 3671 // Long Immediate: 13-bit |
5179 op1 : E(read); | 5198 op1 : E(read); |
5180 BR : R; | 5199 BR : R; |
5181 MS : R; | 5200 MS : R; |
5182 %} | 5201 %} |
5183 | 5202 |
5203 // Compare and branch | |
5204 pipe_class cmp_br_reg_reg(Universe br, cmpOp cmp, iRegI src1, iRegI src2, label labl, flagsReg cr) %{ | |
5205 instruction_count(2); has_delay_slot; | |
5206 cr : E(write); | |
5207 src1 : R(read); | |
5208 src2 : R(read); | |
5209 IALU : R; | |
5210 BR : R; | |
5211 %} | |
5212 | |
5213 // Compare and branch | |
5214 pipe_class cmp_br_reg_imm(Universe br, cmpOp cmp, iRegI src1, immI13 src2, label labl, flagsReg cr) %{ | |
5215 instruction_count(2); has_delay_slot; | |
5216 cr : E(write); | |
5217 src1 : R(read); | |
5218 IALU : R; | |
5219 BR : R; | |
5220 %} | |
5221 | |
5222 // Compare and branch using cbcond | |
5223 pipe_class cbcond_reg_reg(Universe br, cmpOp cmp, iRegI src1, iRegI src2, label labl) %{ | |
5224 single_instruction; | |
5225 src1 : E(read); | |
5226 src2 : E(read); | |
5227 IALU : R; | |
5228 BR : R; | |
5229 %} | |
5230 | |
5231 // Compare and branch using cbcond | |
5232 pipe_class cbcond_reg_imm(Universe br, cmpOp cmp, iRegI src1, immI5 src2, label labl) %{ | |
5233 single_instruction; | |
5234 src1 : E(read); | |
5235 IALU : R; | |
5236 BR : R; | |
5237 %} | |
5238 | |
5184 pipe_class br_fcc(Universe br, cmpOpF cc, flagsReg cr, label labl) %{ | 5239 pipe_class br_fcc(Universe br, cmpOpF cc, flagsReg cr, label labl) %{ |
5185 single_instruction_with_delay_slot; | 5240 single_instruction_with_delay_slot; |
5186 cr : E(read); | 5241 cr : E(read); |
5187 BR : R; | 5242 BR : R; |
5188 %} | 5243 %} |
6234 // Must be safe to execute with invalid address (cannot fault). | 6289 // Must be safe to execute with invalid address (cannot fault). |
6235 | 6290 |
6236 instruct prefetchr( memory mem ) %{ | 6291 instruct prefetchr( memory mem ) %{ |
6237 match( PrefetchRead mem ); | 6292 match( PrefetchRead mem ); |
6238 ins_cost(MEMORY_REF_COST); | 6293 ins_cost(MEMORY_REF_COST); |
6294 size(4); | |
6239 | 6295 |
6240 format %{ "PREFETCH $mem,0\t! Prefetch read-many" %} | 6296 format %{ "PREFETCH $mem,0\t! Prefetch read-many" %} |
6241 opcode(Assembler::prefetch_op3); | 6297 opcode(Assembler::prefetch_op3); |
6242 ins_encode( form3_mem_prefetch_read( mem ) ); | 6298 ins_encode( form3_mem_prefetch_read( mem ) ); |
6243 ins_pipe(iload_mem); | 6299 ins_pipe(iload_mem); |
6244 %} | 6300 %} |
6245 | 6301 |
6246 instruct prefetchw( memory mem ) %{ | 6302 instruct prefetchw( memory mem ) %{ |
6247 predicate(AllocatePrefetchStyle != 3 ); | |
6248 match( PrefetchWrite mem ); | 6303 match( PrefetchWrite mem ); |
6249 ins_cost(MEMORY_REF_COST); | 6304 ins_cost(MEMORY_REF_COST); |
6305 size(4); | |
6250 | 6306 |
6251 format %{ "PREFETCH $mem,2\t! Prefetch write-many (and read)" %} | 6307 format %{ "PREFETCH $mem,2\t! Prefetch write-many (and read)" %} |
6252 opcode(Assembler::prefetch_op3); | 6308 opcode(Assembler::prefetch_op3); |
6253 ins_encode( form3_mem_prefetch_write( mem ) ); | 6309 ins_encode( form3_mem_prefetch_write( mem ) ); |
6254 ins_pipe(iload_mem); | 6310 ins_pipe(iload_mem); |
6255 %} | 6311 %} |
6256 | 6312 |
6257 // Use BIS instruction to prefetch. | 6313 // Prefetch instructions for allocation. |
6258 instruct prefetchw_bis( memory mem ) %{ | 6314 |
6259 predicate(AllocatePrefetchStyle == 3); | 6315 instruct prefetchAlloc( memory mem ) %{ |
6260 match( PrefetchWrite mem ); | 6316 predicate(AllocatePrefetchInstr == 0); |
6317 match( PrefetchAllocation mem ); | |
6261 ins_cost(MEMORY_REF_COST); | 6318 ins_cost(MEMORY_REF_COST); |
6262 | 6319 size(4); |
6263 format %{ "STXA G0,$mem\t! // Block initializing store" %} | 6320 |
6264 ins_encode %{ | 6321 format %{ "PREFETCH $mem,2\t! Prefetch allocation" %} |
6265 Register base = as_Register($mem$$base); | 6322 opcode(Assembler::prefetch_op3); |
6266 int disp = $mem$$disp; | 6323 ins_encode( form3_mem_prefetch_write( mem ) ); |
6267 if (disp != 0) { | 6324 ins_pipe(iload_mem); |
6268 __ add(base, AllocatePrefetchStepSize, base); | 6325 %} |
6269 } | 6326 |
6270 __ stxa(G0, base, G0, ASI_BLK_INIT_QUAD_LDD_P); | 6327 // Use BIS instruction to prefetch for allocation. |
6328 // Could fault, need space at the end of TLAB. | |
6329 instruct prefetchAlloc_bis( iRegP dst ) %{ | |
6330 predicate(AllocatePrefetchInstr == 1); | |
6331 match( PrefetchAllocation dst ); | |
6332 ins_cost(MEMORY_REF_COST); | |
6333 size(4); | |
6334 | |
6335 format %{ "STXA [$dst]\t! // Prefetch allocation using BIS" %} | |
6336 ins_encode %{ | |
6337 __ stxa(G0, $dst$$Register, G0, Assembler::ASI_ST_BLKINIT_PRIMARY); | |
6271 %} | 6338 %} |
6272 ins_pipe(istore_mem_reg); | 6339 ins_pipe(istore_mem_reg); |
6273 %} | 6340 %} |
6341 | |
6342 // Next code is used for finding next cache line address to prefetch. | |
6343 #ifndef _LP64 | |
6344 instruct cacheLineAdr( iRegP dst, iRegP src, immI13 mask ) %{ | |
6345 match(Set dst (CastX2P (AndI (CastP2X src) mask))); | |
6346 ins_cost(DEFAULT_COST); | |
6347 size(4); | |
6348 | |
6349 format %{ "AND $src,$mask,$dst\t! next cache line address" %} | |
6350 ins_encode %{ | |
6351 __ and3($src$$Register, $mask$$constant, $dst$$Register); | |
6352 %} | |
6353 ins_pipe(ialu_reg_imm); | |
6354 %} | |
6355 #else | |
6356 instruct cacheLineAdr( iRegP dst, iRegP src, immL13 mask ) %{ | |
6357 match(Set dst (CastX2P (AndL (CastP2X src) mask))); | |
6358 ins_cost(DEFAULT_COST); | |
6359 size(4); | |
6360 | |
6361 format %{ "AND $src,$mask,$dst\t! next cache line address" %} | |
6362 ins_encode %{ | |
6363 __ and3($src$$Register, $mask$$constant, $dst$$Register); | |
6364 %} | |
6365 ins_pipe(ialu_reg_imm); | |
6366 %} | |
6367 #endif | |
6274 | 6368 |
6275 //----------Store Instructions------------------------------------------------- | 6369 //----------Store Instructions------------------------------------------------- |
6276 // Store Byte | 6370 // Store Byte |
6277 instruct storeB(memory mem, iRegI src) %{ | 6371 instruct storeB(memory mem, iRegI src) %{ |
6278 match(Set mem (StoreB mem src)); | 6372 match(Set mem (StoreB mem src)); |
6627 ins_encode( enc_membar_acquire ); | 6721 ins_encode( enc_membar_acquire ); |
6628 ins_pipe(long_memory_op); | 6722 ins_pipe(long_memory_op); |
6629 %} | 6723 %} |
6630 | 6724 |
6631 instruct membar_acquire_lock() %{ | 6725 instruct membar_acquire_lock() %{ |
6632 match(MemBarAcquire); | 6726 match(MemBarAcquireLock); |
6633 predicate(Matcher::prior_fast_lock(n)); | |
6634 ins_cost(0); | 6727 ins_cost(0); |
6635 | 6728 |
6636 size(0); | 6729 size(0); |
6637 format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %} | 6730 format %{ "!MEMBAR-acquire (CAS in prior FastLock so empty encoding)" %} |
6638 ins_encode( ); | 6731 ins_encode( ); |
6648 ins_encode( enc_membar_release ); | 6741 ins_encode( enc_membar_release ); |
6649 ins_pipe(long_memory_op); | 6742 ins_pipe(long_memory_op); |
6650 %} | 6743 %} |
6651 | 6744 |
6652 instruct membar_release_lock() %{ | 6745 instruct membar_release_lock() %{ |
6653 match(MemBarRelease); | 6746 match(MemBarReleaseLock); |
6654 predicate(Matcher::post_fast_unlock(n)); | |
6655 ins_cost(0); | 6747 ins_cost(0); |
6656 | 6748 |
6657 size(0); | 6749 size(0); |
6658 format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %} | 6750 format %{ "!MEMBAR-release (CAS in succeeding FastUnlock so empty encoding)" %} |
6659 ins_encode( ); | 6751 ins_encode( ); |
8162 "MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %} | 8254 "MOVlt $tmp,$p\t! p' < 0 ? p'+y : p'" %} |
8163 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); | 8255 ins_encode( enc_cadd_cmpLTMask(p, q, y, tmp) ); |
8164 ins_pipe( cadd_cmpltmask ); | 8256 ins_pipe( cadd_cmpltmask ); |
8165 %} | 8257 %} |
8166 | 8258 |
8259 | |
8260 //----------------------------------------------------------------- | |
8261 // Direct raw moves between float and general registers using VIS3. | |
8262 | |
8263 // ins_pipe(faddF_reg); | |
8264 instruct MoveF2I_reg_reg(iRegI dst, regF src) %{ | |
8265 predicate(UseVIS >= 3); | |
8266 match(Set dst (MoveF2I src)); | |
8267 | |
8268 format %{ "MOVSTOUW $src,$dst\t! MoveF2I" %} | |
8269 ins_encode %{ | |
8270 __ movstouw($src$$FloatRegister, $dst$$Register); | |
8271 %} | |
8272 ins_pipe(ialu_reg_reg); | |
8273 %} | |
8274 | |
8275 instruct MoveI2F_reg_reg(regF dst, iRegI src) %{ | |
8276 predicate(UseVIS >= 3); | |
8277 match(Set dst (MoveI2F src)); | |
8278 | |
8279 format %{ "MOVWTOS $src,$dst\t! MoveI2F" %} | |
8280 ins_encode %{ | |
8281 __ movwtos($src$$Register, $dst$$FloatRegister); | |
8282 %} | |
8283 ins_pipe(ialu_reg_reg); | |
8284 %} | |
8285 | |
8286 instruct MoveD2L_reg_reg(iRegL dst, regD src) %{ | |
8287 predicate(UseVIS >= 3); | |
8288 match(Set dst (MoveD2L src)); | |
8289 | |
8290 format %{ "MOVDTOX $src,$dst\t! MoveD2L" %} | |
8291 ins_encode %{ | |
8292 __ movdtox(as_DoubleFloatRegister($src$$reg), $dst$$Register); | |
8293 %} | |
8294 ins_pipe(ialu_reg_reg); | |
8295 %} | |
8296 | |
8297 instruct MoveL2D_reg_reg(regD dst, iRegL src) %{ | |
8298 predicate(UseVIS >= 3); | |
8299 match(Set dst (MoveL2D src)); | |
8300 | |
8301 format %{ "MOVXTOD $src,$dst\t! MoveL2D" %} | |
8302 ins_encode %{ | |
8303 __ movxtod($src$$Register, as_DoubleFloatRegister($dst$$reg)); | |
8304 %} | |
8305 ins_pipe(ialu_reg_reg); | |
8306 %} | |
8307 | |
8308 | |
8309 // Raw moves between float and general registers using stack. | |
8310 | |
8311 instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{ | |
8312 match(Set dst (MoveF2I src)); | |
8313 effect(DEF dst, USE src); | |
8314 ins_cost(MEMORY_REF_COST); | |
8315 | |
8316 size(4); | |
8317 format %{ "LDUW $src,$dst\t! MoveF2I" %} | |
8318 opcode(Assembler::lduw_op3); | |
8319 ins_encode(simple_form3_mem_reg( src, dst ) ); | |
8320 ins_pipe(iload_mem); | |
8321 %} | |
8322 | |
8323 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ | |
8324 match(Set dst (MoveI2F src)); | |
8325 effect(DEF dst, USE src); | |
8326 ins_cost(MEMORY_REF_COST); | |
8327 | |
8328 size(4); | |
8329 format %{ "LDF $src,$dst\t! MoveI2F" %} | |
8330 opcode(Assembler::ldf_op3); | |
8331 ins_encode(simple_form3_mem_reg(src, dst)); | |
8332 ins_pipe(floadF_stk); | |
8333 %} | |
8334 | |
8335 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{ | |
8336 match(Set dst (MoveD2L src)); | |
8337 effect(DEF dst, USE src); | |
8338 ins_cost(MEMORY_REF_COST); | |
8339 | |
8340 size(4); | |
8341 format %{ "LDX $src,$dst\t! MoveD2L" %} | |
8342 opcode(Assembler::ldx_op3); | |
8343 ins_encode(simple_form3_mem_reg( src, dst ) ); | |
8344 ins_pipe(iload_mem); | |
8345 %} | |
8346 | |
8347 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ | |
8348 match(Set dst (MoveL2D src)); | |
8349 effect(DEF dst, USE src); | |
8350 ins_cost(MEMORY_REF_COST); | |
8351 | |
8352 size(4); | |
8353 format %{ "LDDF $src,$dst\t! MoveL2D" %} | |
8354 opcode(Assembler::lddf_op3); | |
8355 ins_encode(simple_form3_mem_reg(src, dst)); | |
8356 ins_pipe(floadD_stk); | |
8357 %} | |
8358 | |
8359 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ | |
8360 match(Set dst (MoveF2I src)); | |
8361 effect(DEF dst, USE src); | |
8362 ins_cost(MEMORY_REF_COST); | |
8363 | |
8364 size(4); | |
8365 format %{ "STF $src,$dst\t! MoveF2I" %} | |
8366 opcode(Assembler::stf_op3); | |
8367 ins_encode(simple_form3_mem_reg(dst, src)); | |
8368 ins_pipe(fstoreF_stk_reg); | |
8369 %} | |
8370 | |
8371 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ | |
8372 match(Set dst (MoveI2F src)); | |
8373 effect(DEF dst, USE src); | |
8374 ins_cost(MEMORY_REF_COST); | |
8375 | |
8376 size(4); | |
8377 format %{ "STW $src,$dst\t! MoveI2F" %} | |
8378 opcode(Assembler::stw_op3); | |
8379 ins_encode(simple_form3_mem_reg( dst, src ) ); | |
8380 ins_pipe(istore_mem_reg); | |
8381 %} | |
8382 | |
8383 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ | |
8384 match(Set dst (MoveD2L src)); | |
8385 effect(DEF dst, USE src); | |
8386 ins_cost(MEMORY_REF_COST); | |
8387 | |
8388 size(4); | |
8389 format %{ "STDF $src,$dst\t! MoveD2L" %} | |
8390 opcode(Assembler::stdf_op3); | |
8391 ins_encode(simple_form3_mem_reg(dst, src)); | |
8392 ins_pipe(fstoreD_stk_reg); | |
8393 %} | |
8394 | |
8395 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ | |
8396 match(Set dst (MoveL2D src)); | |
8397 effect(DEF dst, USE src); | |
8398 ins_cost(MEMORY_REF_COST); | |
8399 | |
8400 size(4); | |
8401 format %{ "STX $src,$dst\t! MoveL2D" %} | |
8402 opcode(Assembler::stx_op3); | |
8403 ins_encode(simple_form3_mem_reg( dst, src ) ); | |
8404 ins_pipe(istore_mem_reg); | |
8405 %} | |
8406 | |
8407 | |
8167 //----------Arithmetic Conversion Instructions--------------------------------- | 8408 //----------Arithmetic Conversion Instructions--------------------------------- |
8168 // The conversions operations are all Alpha sorted. Please keep it that way! | 8409 // The conversions operations are all Alpha sorted. Please keep it that way! |
8169 | 8410 |
8170 instruct convD2F_reg(regF dst, regD src) %{ | 8411 instruct convD2F_reg(regF dst, regD src) %{ |
8171 match(Set dst (ConvD2F src)); | 8412 match(Set dst (ConvD2F src)); |
8189 "skip:" %} | 8430 "skip:" %} |
8190 ins_encode(form_d2i_helper(src,dst)); | 8431 ins_encode(form_d2i_helper(src,dst)); |
8191 ins_pipe(fcvtD2I); | 8432 ins_pipe(fcvtD2I); |
8192 %} | 8433 %} |
8193 | 8434 |
8194 instruct convD2I_reg(stackSlotI dst, regD src) %{ | 8435 instruct convD2I_stk(stackSlotI dst, regD src) %{ |
8195 match(Set dst (ConvD2I src)); | 8436 match(Set dst (ConvD2I src)); |
8196 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | 8437 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); |
8197 expand %{ | 8438 expand %{ |
8198 regF tmp; | 8439 regF tmp; |
8199 convD2I_helper(tmp, src); | 8440 convD2I_helper(tmp, src); |
8200 regF_to_stkI(dst, tmp); | 8441 regF_to_stkI(dst, tmp); |
8201 %} | 8442 %} |
8202 %} | 8443 %} |
8444 | |
8445 instruct convD2I_reg(iRegI dst, regD src) %{ | |
8446 predicate(UseVIS >= 3); | |
8447 match(Set dst (ConvD2I src)); | |
8448 ins_cost(DEFAULT_COST*2 + BRANCH_COST); | |
8449 expand %{ | |
8450 regF tmp; | |
8451 convD2I_helper(tmp, src); | |
8452 MoveF2I_reg_reg(dst, tmp); | |
8453 %} | |
8454 %} | |
8455 | |
8203 | 8456 |
8204 // Convert a double to a long in a double register. | 8457 // Convert a double to a long in a double register. |
8205 // If the double is a NAN, stuff a zero in instead. | 8458 // If the double is a NAN, stuff a zero in instead. |
8206 instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{ | 8459 instruct convD2L_helper(regD dst, regD src, flagsRegF0 fcc0) %{ |
8207 effect(DEF dst, USE src, KILL fcc0); | 8460 effect(DEF dst, USE src, KILL fcc0); |
8213 "skip:" %} | 8466 "skip:" %} |
8214 ins_encode(form_d2l_helper(src,dst)); | 8467 ins_encode(form_d2l_helper(src,dst)); |
8215 ins_pipe(fcvtD2L); | 8468 ins_pipe(fcvtD2L); |
8216 %} | 8469 %} |
8217 | 8470 |
8218 | 8471 instruct convD2L_stk(stackSlotL dst, regD src) %{ |
8219 // Double to Long conversion | |
8220 instruct convD2L_reg(stackSlotL dst, regD src) %{ | |
8221 match(Set dst (ConvD2L src)); | 8472 match(Set dst (ConvD2L src)); |
8222 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | 8473 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); |
8223 expand %{ | 8474 expand %{ |
8224 regD tmp; | 8475 regD tmp; |
8225 convD2L_helper(tmp, src); | 8476 convD2L_helper(tmp, src); |
8226 regD_to_stkL(dst, tmp); | 8477 regD_to_stkL(dst, tmp); |
8227 %} | 8478 %} |
8228 %} | 8479 %} |
8229 | 8480 |
8481 instruct convD2L_reg(iRegL dst, regD src) %{ | |
8482 predicate(UseVIS >= 3); | |
8483 match(Set dst (ConvD2L src)); | |
8484 ins_cost(DEFAULT_COST*2 + BRANCH_COST); | |
8485 expand %{ | |
8486 regD tmp; | |
8487 convD2L_helper(tmp, src); | |
8488 MoveD2L_reg_reg(dst, tmp); | |
8489 %} | |
8490 %} | |
8491 | |
8230 | 8492 |
8231 instruct convF2D_reg(regD dst, regF src) %{ | 8493 instruct convF2D_reg(regD dst, regF src) %{ |
8232 match(Set dst (ConvF2D src)); | 8494 match(Set dst (ConvF2D src)); |
8233 format %{ "FSTOD $src,$dst" %} | 8495 format %{ "FSTOD $src,$dst" %} |
8234 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf); | 8496 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fstod_opf); |
8235 ins_encode(form3_opf_rs2F_rdD(src, dst)); | 8497 ins_encode(form3_opf_rs2F_rdD(src, dst)); |
8236 ins_pipe(fcvtF2D); | 8498 ins_pipe(fcvtF2D); |
8237 %} | 8499 %} |
8238 | 8500 |
8239 | 8501 |
8502 // Convert a float to an int in a float register. | |
8503 // If the float is a NAN, stuff a zero in instead. | |
8240 instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{ | 8504 instruct convF2I_helper(regF dst, regF src, flagsRegF0 fcc0) %{ |
8241 effect(DEF dst, USE src, KILL fcc0); | 8505 effect(DEF dst, USE src, KILL fcc0); |
8242 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" | 8506 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" |
8243 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | 8507 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" |
8244 "FSTOI $src,$dst\t! convert in delay slot\n\t" | 8508 "FSTOI $src,$dst\t! convert in delay slot\n\t" |
8247 "skip:" %} | 8511 "skip:" %} |
8248 ins_encode(form_f2i_helper(src,dst)); | 8512 ins_encode(form_f2i_helper(src,dst)); |
8249 ins_pipe(fcvtF2I); | 8513 ins_pipe(fcvtF2I); |
8250 %} | 8514 %} |
8251 | 8515 |
8252 instruct convF2I_reg(stackSlotI dst, regF src) %{ | 8516 instruct convF2I_stk(stackSlotI dst, regF src) %{ |
8253 match(Set dst (ConvF2I src)); | 8517 match(Set dst (ConvF2I src)); |
8254 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | 8518 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); |
8255 expand %{ | 8519 expand %{ |
8256 regF tmp; | 8520 regF tmp; |
8257 convF2I_helper(tmp, src); | 8521 convF2I_helper(tmp, src); |
8258 regF_to_stkI(dst, tmp); | 8522 regF_to_stkI(dst, tmp); |
8259 %} | 8523 %} |
8260 %} | 8524 %} |
8261 | 8525 |
8262 | 8526 instruct convF2I_reg(iRegI dst, regF src) %{ |
8527 predicate(UseVIS >= 3); | |
8528 match(Set dst (ConvF2I src)); | |
8529 ins_cost(DEFAULT_COST*2 + BRANCH_COST); | |
8530 expand %{ | |
8531 regF tmp; | |
8532 convF2I_helper(tmp, src); | |
8533 MoveF2I_reg_reg(dst, tmp); | |
8534 %} | |
8535 %} | |
8536 | |
8537 | |
8538 // Convert a float to a long in a float register. | |
8539 // If the float is a NAN, stuff a zero in instead. | |
8263 instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{ | 8540 instruct convF2L_helper(regD dst, regF src, flagsRegF0 fcc0) %{ |
8264 effect(DEF dst, USE src, KILL fcc0); | 8541 effect(DEF dst, USE src, KILL fcc0); |
8265 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" | 8542 format %{ "FCMPs fcc0,$src,$src\t! check for NAN\n\t" |
8266 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" | 8543 "FBO,pt fcc0,skip\t! branch on ordered, predict taken\n\t" |
8267 "FSTOX $src,$dst\t! convert in delay slot\n\t" | 8544 "FSTOX $src,$dst\t! convert in delay slot\n\t" |
8270 "skip:" %} | 8547 "skip:" %} |
8271 ins_encode(form_f2l_helper(src,dst)); | 8548 ins_encode(form_f2l_helper(src,dst)); |
8272 ins_pipe(fcvtF2L); | 8549 ins_pipe(fcvtF2L); |
8273 %} | 8550 %} |
8274 | 8551 |
8275 // Float to Long conversion | 8552 instruct convF2L_stk(stackSlotL dst, regF src) %{ |
8276 instruct convF2L_reg(stackSlotL dst, regF src) %{ | |
8277 match(Set dst (ConvF2L src)); | 8553 match(Set dst (ConvF2L src)); |
8278 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); | 8554 ins_cost(DEFAULT_COST*2 + MEMORY_REF_COST*2 + BRANCH_COST); |
8279 expand %{ | 8555 expand %{ |
8280 regD tmp; | 8556 regD tmp; |
8281 convF2L_helper(tmp, src); | 8557 convF2L_helper(tmp, src); |
8282 regD_to_stkL(dst, tmp); | 8558 regD_to_stkL(dst, tmp); |
8283 %} | 8559 %} |
8284 %} | 8560 %} |
8285 | 8561 |
8562 instruct convF2L_reg(iRegL dst, regF src) %{ | |
8563 predicate(UseVIS >= 3); | |
8564 match(Set dst (ConvF2L src)); | |
8565 ins_cost(DEFAULT_COST*2 + BRANCH_COST); | |
8566 expand %{ | |
8567 regD tmp; | |
8568 convF2L_helper(tmp, src); | |
8569 MoveD2L_reg_reg(dst, tmp); | |
8570 %} | |
8571 %} | |
8572 | |
8286 | 8573 |
8287 instruct convI2D_helper(regD dst, regF tmp) %{ | 8574 instruct convI2D_helper(regD dst, regF tmp) %{ |
8288 effect(USE tmp, DEF dst); | 8575 effect(USE tmp, DEF dst); |
8289 format %{ "FITOD $tmp,$dst" %} | 8576 format %{ "FITOD $tmp,$dst" %} |
8290 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); | 8577 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitod_opf); |
8291 ins_encode(form3_opf_rs2F_rdD(tmp, dst)); | 8578 ins_encode(form3_opf_rs2F_rdD(tmp, dst)); |
8292 ins_pipe(fcvtI2D); | 8579 ins_pipe(fcvtI2D); |
8293 %} | 8580 %} |
8294 | 8581 |
8295 instruct convI2D_reg(stackSlotI src, regD dst) %{ | 8582 instruct convI2D_stk(stackSlotI src, regD dst) %{ |
8296 match(Set dst (ConvI2D src)); | 8583 match(Set dst (ConvI2D src)); |
8297 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | 8584 ins_cost(DEFAULT_COST + MEMORY_REF_COST); |
8298 expand %{ | 8585 expand %{ |
8299 regF tmp; | 8586 regF tmp; |
8300 stkI_to_regF( tmp, src); | 8587 stkI_to_regF(tmp, src); |
8301 convI2D_helper( dst, tmp); | 8588 convI2D_helper(dst, tmp); |
8302 %} | 8589 %} |
8303 %} | 8590 %} |
8304 | 8591 |
8305 instruct convI2D_mem( regD_low dst, memory mem ) %{ | 8592 instruct convI2D_reg(regD_low dst, iRegI src) %{ |
8593 predicate(UseVIS >= 3); | |
8594 match(Set dst (ConvI2D src)); | |
8595 expand %{ | |
8596 regF tmp; | |
8597 MoveI2F_reg_reg(tmp, src); | |
8598 convI2D_helper(dst, tmp); | |
8599 %} | |
8600 %} | |
8601 | |
8602 instruct convI2D_mem(regD_low dst, memory mem) %{ | |
8306 match(Set dst (ConvI2D (LoadI mem))); | 8603 match(Set dst (ConvI2D (LoadI mem))); |
8307 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | 8604 ins_cost(DEFAULT_COST + MEMORY_REF_COST); |
8308 size(8); | 8605 size(8); |
8309 format %{ "LDF $mem,$dst\n\t" | 8606 format %{ "LDF $mem,$dst\n\t" |
8310 "FITOD $dst,$dst" %} | 8607 "FITOD $dst,$dst" %} |
8320 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf); | 8617 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fitos_opf); |
8321 ins_encode(form3_opf_rs2F_rdF(tmp, dst)); | 8618 ins_encode(form3_opf_rs2F_rdF(tmp, dst)); |
8322 ins_pipe(fcvtI2F); | 8619 ins_pipe(fcvtI2F); |
8323 %} | 8620 %} |
8324 | 8621 |
8325 instruct convI2F_reg( regF dst, stackSlotI src ) %{ | 8622 instruct convI2F_stk(regF dst, stackSlotI src) %{ |
8326 match(Set dst (ConvI2F src)); | 8623 match(Set dst (ConvI2F src)); |
8327 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | 8624 ins_cost(DEFAULT_COST + MEMORY_REF_COST); |
8328 expand %{ | 8625 expand %{ |
8329 regF tmp; | 8626 regF tmp; |
8330 stkI_to_regF(tmp,src); | 8627 stkI_to_regF(tmp,src); |
8628 convI2F_helper(dst, tmp); | |
8629 %} | |
8630 %} | |
8631 | |
8632 instruct convI2F_reg(regF dst, iRegI src) %{ | |
8633 predicate(UseVIS >= 3); | |
8634 match(Set dst (ConvI2F src)); | |
8635 ins_cost(DEFAULT_COST); | |
8636 expand %{ | |
8637 regF tmp; | |
8638 MoveI2F_reg_reg(tmp, src); | |
8331 convI2F_helper(dst, tmp); | 8639 convI2F_helper(dst, tmp); |
8332 %} | 8640 %} |
8333 %} | 8641 %} |
8334 | 8642 |
8335 instruct convI2F_mem( regF dst, memory mem ) %{ | 8643 instruct convI2F_mem( regF dst, memory mem ) %{ |
8369 size(4); | 8677 size(4); |
8370 format %{ "SRL $src,0,$dst\t! zero-extend long" %} | 8678 format %{ "SRL $src,0,$dst\t! zero-extend long" %} |
8371 opcode(Assembler::srl_op3, Assembler::arith_op); | 8679 opcode(Assembler::srl_op3, Assembler::arith_op); |
8372 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); | 8680 ins_encode( form3_rs1_rs2_rd( src, R_G0, dst ) ); |
8373 ins_pipe(ialu_reg_reg); | 8681 ins_pipe(ialu_reg_reg); |
8374 %} | |
8375 | |
8376 instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{ | |
8377 match(Set dst (MoveF2I src)); | |
8378 effect(DEF dst, USE src); | |
8379 ins_cost(MEMORY_REF_COST); | |
8380 | |
8381 size(4); | |
8382 format %{ "LDUW $src,$dst\t! MoveF2I" %} | |
8383 opcode(Assembler::lduw_op3); | |
8384 ins_encode(simple_form3_mem_reg( src, dst ) ); | |
8385 ins_pipe(iload_mem); | |
8386 %} | |
8387 | |
8388 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ | |
8389 match(Set dst (MoveI2F src)); | |
8390 effect(DEF dst, USE src); | |
8391 ins_cost(MEMORY_REF_COST); | |
8392 | |
8393 size(4); | |
8394 format %{ "LDF $src,$dst\t! MoveI2F" %} | |
8395 opcode(Assembler::ldf_op3); | |
8396 ins_encode(simple_form3_mem_reg(src, dst)); | |
8397 ins_pipe(floadF_stk); | |
8398 %} | |
8399 | |
8400 instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{ | |
8401 match(Set dst (MoveD2L src)); | |
8402 effect(DEF dst, USE src); | |
8403 ins_cost(MEMORY_REF_COST); | |
8404 | |
8405 size(4); | |
8406 format %{ "LDX $src,$dst\t! MoveD2L" %} | |
8407 opcode(Assembler::ldx_op3); | |
8408 ins_encode(simple_form3_mem_reg( src, dst ) ); | |
8409 ins_pipe(iload_mem); | |
8410 %} | |
8411 | |
8412 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ | |
8413 match(Set dst (MoveL2D src)); | |
8414 effect(DEF dst, USE src); | |
8415 ins_cost(MEMORY_REF_COST); | |
8416 | |
8417 size(4); | |
8418 format %{ "LDDF $src,$dst\t! MoveL2D" %} | |
8419 opcode(Assembler::lddf_op3); | |
8420 ins_encode(simple_form3_mem_reg(src, dst)); | |
8421 ins_pipe(floadD_stk); | |
8422 %} | |
8423 | |
8424 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ | |
8425 match(Set dst (MoveF2I src)); | |
8426 effect(DEF dst, USE src); | |
8427 ins_cost(MEMORY_REF_COST); | |
8428 | |
8429 size(4); | |
8430 format %{ "STF $src,$dst\t!MoveF2I" %} | |
8431 opcode(Assembler::stf_op3); | |
8432 ins_encode(simple_form3_mem_reg(dst, src)); | |
8433 ins_pipe(fstoreF_stk_reg); | |
8434 %} | |
8435 | |
8436 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ | |
8437 match(Set dst (MoveI2F src)); | |
8438 effect(DEF dst, USE src); | |
8439 ins_cost(MEMORY_REF_COST); | |
8440 | |
8441 size(4); | |
8442 format %{ "STW $src,$dst\t!MoveI2F" %} | |
8443 opcode(Assembler::stw_op3); | |
8444 ins_encode(simple_form3_mem_reg( dst, src ) ); | |
8445 ins_pipe(istore_mem_reg); | |
8446 %} | |
8447 | |
8448 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ | |
8449 match(Set dst (MoveD2L src)); | |
8450 effect(DEF dst, USE src); | |
8451 ins_cost(MEMORY_REF_COST); | |
8452 | |
8453 size(4); | |
8454 format %{ "STDF $src,$dst\t!MoveD2L" %} | |
8455 opcode(Assembler::stdf_op3); | |
8456 ins_encode(simple_form3_mem_reg(dst, src)); | |
8457 ins_pipe(fstoreD_stk_reg); | |
8458 %} | |
8459 | |
8460 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ | |
8461 match(Set dst (MoveL2D src)); | |
8462 effect(DEF dst, USE src); | |
8463 ins_cost(MEMORY_REF_COST); | |
8464 | |
8465 size(4); | |
8466 format %{ "STX $src,$dst\t!MoveL2D" %} | |
8467 opcode(Assembler::stx_op3); | |
8468 ins_encode(simple_form3_mem_reg( dst, src ) ); | |
8469 ins_pipe(istore_mem_reg); | |
8470 %} | 8682 %} |
8471 | 8683 |
8472 | 8684 |
8473 //----------- | 8685 //----------- |
8474 // Long to Double conversion using V8 opcodes. | 8686 // Long to Double conversion using V8 opcodes. |
8587 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf); | 8799 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtod_opf); |
8588 ins_encode(form3_opf_rs2D_rdD(tmp, dst)); | 8800 ins_encode(form3_opf_rs2D_rdD(tmp, dst)); |
8589 ins_pipe(fcvtL2D); | 8801 ins_pipe(fcvtL2D); |
8590 %} | 8802 %} |
8591 | 8803 |
8592 instruct convL2D_reg_fast_fxtof(regD dst, stackSlotL src) %{ | 8804 instruct convL2D_stk_fast_fxtof(regD dst, stackSlotL src) %{ |
8593 predicate(VM_Version::has_fast_fxtof()); | 8805 predicate(VM_Version::has_fast_fxtof()); |
8594 match(Set dst (ConvL2D src)); | 8806 match(Set dst (ConvL2D src)); |
8595 ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST); | 8807 ins_cost(DEFAULT_COST + 3 * MEMORY_REF_COST); |
8596 expand %{ | 8808 expand %{ |
8597 regD tmp; | 8809 regD tmp; |
8598 stkL_to_regD(tmp, src); | 8810 stkL_to_regD(tmp, src); |
8599 convL2D_helper(dst, tmp); | 8811 convL2D_helper(dst, tmp); |
8600 %} | 8812 %} |
8601 %} | 8813 %} |
8602 | 8814 |
8603 //----------- | 8815 instruct convL2D_reg(regD dst, iRegL src) %{ |
8604 // Long to Float conversion using V8 opcodes. | 8816 predicate(UseVIS >= 3); |
8605 // Still useful because cheetah traps and becomes | 8817 match(Set dst (ConvL2D src)); |
8606 // amazingly slow for some common numbers. | 8818 expand %{ |
8819 regD tmp; | |
8820 MoveL2D_reg_reg(tmp, src); | |
8821 convL2D_helper(dst, tmp); | |
8822 %} | |
8823 %} | |
8607 | 8824 |
8608 // Long to Float conversion using fast fxtof | 8825 // Long to Float conversion using fast fxtof |
8609 instruct convL2F_helper(regF dst, regD tmp) %{ | 8826 instruct convL2F_helper(regF dst, regD tmp) %{ |
8610 effect(DEF dst, USE tmp); | 8827 effect(DEF dst, USE tmp); |
8611 size(4); | 8828 size(4); |
8613 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf); | 8830 opcode(Assembler::fpop1_op3, Assembler::arith_op, Assembler::fxtos_opf); |
8614 ins_encode(form3_opf_rs2D_rdF(tmp, dst)); | 8831 ins_encode(form3_opf_rs2D_rdF(tmp, dst)); |
8615 ins_pipe(fcvtL2F); | 8832 ins_pipe(fcvtL2F); |
8616 %} | 8833 %} |
8617 | 8834 |
8618 instruct convL2F_reg_fast_fxtof(regF dst, stackSlotL src) %{ | 8835 instruct convL2F_stk_fast_fxtof(regF dst, stackSlotL src) %{ |
8619 match(Set dst (ConvL2F src)); | 8836 match(Set dst (ConvL2F src)); |
8620 ins_cost(DEFAULT_COST + MEMORY_REF_COST); | 8837 ins_cost(DEFAULT_COST + MEMORY_REF_COST); |
8621 expand %{ | 8838 expand %{ |
8622 regD tmp; | 8839 regD tmp; |
8623 stkL_to_regD(tmp, src); | 8840 stkL_to_regD(tmp, src); |
8624 convL2F_helper(dst, tmp); | 8841 convL2F_helper(dst, tmp); |
8625 %} | 8842 %} |
8626 %} | 8843 %} |
8844 | |
8845 instruct convL2F_reg(regF dst, iRegL src) %{ | |
8846 predicate(UseVIS >= 3); | |
8847 match(Set dst (ConvL2F src)); | |
8848 ins_cost(DEFAULT_COST); | |
8849 expand %{ | |
8850 regD tmp; | |
8851 MoveL2D_reg_reg(tmp, src); | |
8852 convL2F_helper(dst, tmp); | |
8853 %} | |
8854 %} | |
8855 | |
8627 //----------- | 8856 //----------- |
8628 | 8857 |
8629 instruct convL2I_reg(iRegI dst, iRegL src) %{ | 8858 instruct convL2I_reg(iRegI dst, iRegL src) %{ |
8630 match(Set dst (ConvL2I src)); | 8859 match(Set dst (ConvL2I src)); |
8631 #ifndef _LP64 | 8860 #ifndef _LP64 |
9047 | 9276 |
9048 ins_cost(350); | 9277 ins_cost(350); |
9049 | 9278 |
9050 format %{ "ADD $constanttablebase, $constantoffset, O7\n\t" | 9279 format %{ "ADD $constanttablebase, $constantoffset, O7\n\t" |
9051 "LD [O7 + $switch_val], O7\n\t" | 9280 "LD [O7 + $switch_val], O7\n\t" |
9052 "JUMP O7" | 9281 "JUMP O7" %} |
9053 %} | |
9054 ins_encode %{ | 9282 ins_encode %{ |
9055 // Calculate table address into a register. | 9283 // Calculate table address into a register. |
9056 Register table_reg; | 9284 Register table_reg; |
9057 Register label_reg = O7; | 9285 Register label_reg = O7; |
9058 if (constant_offset() == 0) { | 9286 // If we are calculating the size of this instruction don't trust |
9287 // zero offsets because they might change when | |
9288 // MachConstantBaseNode decides to optimize the constant table | |
9289 // base. | |
9290 if ((constant_offset() == 0) && !Compile::current()->in_scratch_emit_size()) { | |
9059 table_reg = $constanttablebase; | 9291 table_reg = $constanttablebase; |
9060 } else { | 9292 } else { |
9061 table_reg = O7; | 9293 table_reg = O7; |
9062 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset, O7); | 9294 RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset, O7); |
9063 __ add($constanttablebase, con_offset, table_reg); | 9295 __ add($constanttablebase, con_offset, table_reg); |
9066 // Jump to base address + switch value | 9298 // Jump to base address + switch value |
9067 __ ld_ptr(table_reg, $switch_val$$Register, label_reg); | 9299 __ ld_ptr(table_reg, $switch_val$$Register, label_reg); |
9068 __ jmp(label_reg, G0); | 9300 __ jmp(label_reg, G0); |
9069 __ delayed()->nop(); | 9301 __ delayed()->nop(); |
9070 %} | 9302 %} |
9071 ins_pc_relative(1); | |
9072 ins_pipe(ialu_reg_reg); | 9303 ins_pipe(ialu_reg_reg); |
9073 %} | 9304 %} |
9074 | 9305 |
9075 // Direct Branch. Use V8 version with longer range. | 9306 // Direct Branch. Use V8 version with longer range. |
9076 instruct branch(label labl) %{ | 9307 instruct branch(label labl) %{ |
9078 effect(USE labl); | 9309 effect(USE labl); |
9079 | 9310 |
9080 size(8); | 9311 size(8); |
9081 ins_cost(BRANCH_COST); | 9312 ins_cost(BRANCH_COST); |
9082 format %{ "BA $labl" %} | 9313 format %{ "BA $labl" %} |
9083 // Prim = bits 24-22, Secnd = bits 31-30, Tert = cond | 9314 ins_encode %{ |
9084 opcode(Assembler::br_op2, Assembler::branch_op, Assembler::always); | 9315 Label* L = $labl$$label; |
9085 ins_encode( enc_ba( labl ) ); | 9316 __ ba(*L); |
9086 ins_pc_relative(1); | 9317 __ delayed()->nop(); |
9318 %} | |
9087 ins_pipe(br); | 9319 ins_pipe(br); |
9320 %} | |
9321 | |
9322 // Direct Branch, short with no delay slot | |
9323 instruct branch_short(label labl) %{ | |
9324 match(Goto); | |
9325 predicate(UseCBCond); | |
9326 effect(USE labl); | |
9327 | |
9328 size(4); | |
9329 ins_cost(BRANCH_COST); | |
9330 format %{ "BA $labl\t! short branch" %} | |
9331 ins_encode %{ | |
9332 Label* L = $labl$$label; | |
9333 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9334 __ ba_short(*L); | |
9335 %} | |
9336 ins_short_branch(1); | |
9337 ins_avoid_back_to_back(1); | |
9338 ins_pipe(cbcond_reg_imm); | |
9088 %} | 9339 %} |
9089 | 9340 |
9090 // Conditional Direct Branch | 9341 // Conditional Direct Branch |
9091 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ | 9342 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{ |
9092 match(If cmp icc); | 9343 match(If cmp icc); |
9095 size(8); | 9346 size(8); |
9096 ins_cost(BRANCH_COST); | 9347 ins_cost(BRANCH_COST); |
9097 format %{ "BP$cmp $icc,$labl" %} | 9348 format %{ "BP$cmp $icc,$labl" %} |
9098 // Prim = bits 24-22, Secnd = bits 31-30 | 9349 // Prim = bits 24-22, Secnd = bits 31-30 |
9099 ins_encode( enc_bp( labl, cmp, icc ) ); | 9350 ins_encode( enc_bp( labl, cmp, icc ) ); |
9100 ins_pc_relative(1); | |
9101 ins_pipe(br_cc); | 9351 ins_pipe(br_cc); |
9352 %} | |
9353 | |
9354 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9355 match(If cmp icc); | |
9356 effect(USE labl); | |
9357 | |
9358 ins_cost(BRANCH_COST); | |
9359 format %{ "BP$cmp $icc,$labl" %} | |
9360 // Prim = bits 24-22, Secnd = bits 31-30 | |
9361 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9362 ins_pipe(br_cc); | |
9363 %} | |
9364 | |
9365 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ | |
9366 match(If cmp pcc); | |
9367 effect(USE labl); | |
9368 | |
9369 size(8); | |
9370 ins_cost(BRANCH_COST); | |
9371 format %{ "BP$cmp $pcc,$labl" %} | |
9372 ins_encode %{ | |
9373 Label* L = $labl$$label; | |
9374 Assembler::Predict predict_taken = | |
9375 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9376 | |
9377 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); | |
9378 __ delayed()->nop(); | |
9379 %} | |
9380 ins_pipe(br_cc); | |
9381 %} | |
9382 | |
9383 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ | |
9384 match(If cmp fcc); | |
9385 effect(USE labl); | |
9386 | |
9387 size(8); | |
9388 ins_cost(BRANCH_COST); | |
9389 format %{ "FBP$cmp $fcc,$labl" %} | |
9390 ins_encode %{ | |
9391 Label* L = $labl$$label; | |
9392 Assembler::Predict predict_taken = | |
9393 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9394 | |
9395 __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); | |
9396 __ delayed()->nop(); | |
9397 %} | |
9398 ins_pipe(br_fcc); | |
9399 %} | |
9400 | |
9401 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ | |
9402 match(CountedLoopEnd cmp icc); | |
9403 effect(USE labl); | |
9404 | |
9405 size(8); | |
9406 ins_cost(BRANCH_COST); | |
9407 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9408 // Prim = bits 24-22, Secnd = bits 31-30 | |
9409 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9410 ins_pipe(br_cc); | |
9411 %} | |
9412 | |
9413 instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9414 match(CountedLoopEnd cmp icc); | |
9415 effect(USE labl); | |
9416 | |
9417 size(8); | |
9418 ins_cost(BRANCH_COST); | |
9419 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9420 // Prim = bits 24-22, Secnd = bits 31-30 | |
9421 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9422 ins_pipe(br_cc); | |
9423 %} | |
9424 | |
9425 // Compare and branch instructions | |
9426 instruct cmpI_reg_branch(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ | |
9427 match(If cmp (CmpI op1 op2)); | |
9428 effect(USE labl, KILL icc); | |
9429 | |
9430 size(12); | |
9431 ins_cost(BRANCH_COST); | |
9432 format %{ "CMP $op1,$op2\t! int\n\t" | |
9433 "BP$cmp $labl" %} | |
9434 ins_encode %{ | |
9435 Label* L = $labl$$label; | |
9436 Assembler::Predict predict_taken = | |
9437 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9438 __ cmp($op1$$Register, $op2$$Register); | |
9439 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9440 __ delayed()->nop(); | |
9441 %} | |
9442 ins_pipe(cmp_br_reg_reg); | |
9443 %} | |
9444 | |
9445 instruct cmpI_imm_branch(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ | |
9446 match(If cmp (CmpI op1 op2)); | |
9447 effect(USE labl, KILL icc); | |
9448 | |
9449 size(12); | |
9450 ins_cost(BRANCH_COST); | |
9451 format %{ "CMP $op1,$op2\t! int\n\t" | |
9452 "BP$cmp $labl" %} | |
9453 ins_encode %{ | |
9454 Label* L = $labl$$label; | |
9455 Assembler::Predict predict_taken = | |
9456 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9457 __ cmp($op1$$Register, $op2$$constant); | |
9458 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9459 __ delayed()->nop(); | |
9460 %} | |
9461 ins_pipe(cmp_br_reg_imm); | |
9462 %} | |
9463 | |
9464 instruct cmpU_reg_branch(cmpOpU cmp, iRegI op1, iRegI op2, label labl, flagsRegU icc) %{ | |
9465 match(If cmp (CmpU op1 op2)); | |
9466 effect(USE labl, KILL icc); | |
9467 | |
9468 size(12); | |
9469 ins_cost(BRANCH_COST); | |
9470 format %{ "CMP $op1,$op2\t! unsigned\n\t" | |
9471 "BP$cmp $labl" %} | |
9472 ins_encode %{ | |
9473 Label* L = $labl$$label; | |
9474 Assembler::Predict predict_taken = | |
9475 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9476 __ cmp($op1$$Register, $op2$$Register); | |
9477 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9478 __ delayed()->nop(); | |
9479 %} | |
9480 ins_pipe(cmp_br_reg_reg); | |
9481 %} | |
9482 | |
9483 instruct cmpU_imm_branch(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU icc) %{ | |
9484 match(If cmp (CmpU op1 op2)); | |
9485 effect(USE labl, KILL icc); | |
9486 | |
9487 size(12); | |
9488 ins_cost(BRANCH_COST); | |
9489 format %{ "CMP $op1,$op2\t! unsigned\n\t" | |
9490 "BP$cmp $labl" %} | |
9491 ins_encode %{ | |
9492 Label* L = $labl$$label; | |
9493 Assembler::Predict predict_taken = | |
9494 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9495 __ cmp($op1$$Register, $op2$$constant); | |
9496 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9497 __ delayed()->nop(); | |
9498 %} | |
9499 ins_pipe(cmp_br_reg_imm); | |
9500 %} | |
9501 | |
9502 instruct cmpL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ | |
9503 match(If cmp (CmpL op1 op2)); | |
9504 effect(USE labl, KILL xcc); | |
9505 | |
9506 size(12); | |
9507 ins_cost(BRANCH_COST); | |
9508 format %{ "CMP $op1,$op2\t! long\n\t" | |
9509 "BP$cmp $labl" %} | |
9510 ins_encode %{ | |
9511 Label* L = $labl$$label; | |
9512 Assembler::Predict predict_taken = | |
9513 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9514 __ cmp($op1$$Register, $op2$$Register); | |
9515 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); | |
9516 __ delayed()->nop(); | |
9517 %} | |
9518 ins_pipe(cmp_br_reg_reg); | |
9519 %} | |
9520 | |
9521 instruct cmpL_imm_branch(cmpOp cmp, iRegL op1, immL5 op2, label labl, flagsRegL xcc) %{ | |
9522 match(If cmp (CmpL op1 op2)); | |
9523 effect(USE labl, KILL xcc); | |
9524 | |
9525 size(12); | |
9526 ins_cost(BRANCH_COST); | |
9527 format %{ "CMP $op1,$op2\t! long\n\t" | |
9528 "BP$cmp $labl" %} | |
9529 ins_encode %{ | |
9530 Label* L = $labl$$label; | |
9531 Assembler::Predict predict_taken = | |
9532 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9533 __ cmp($op1$$Register, $op2$$constant); | |
9534 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); | |
9535 __ delayed()->nop(); | |
9536 %} | |
9537 ins_pipe(cmp_br_reg_imm); | |
9538 %} | |
9539 | |
9540 // Compare Pointers and branch | |
9541 instruct cmpP_reg_branch(cmpOpP cmp, iRegP op1, iRegP op2, label labl, flagsRegP pcc) %{ | |
9542 match(If cmp (CmpP op1 op2)); | |
9543 effect(USE labl, KILL pcc); | |
9544 | |
9545 size(12); | |
9546 ins_cost(BRANCH_COST); | |
9547 format %{ "CMP $op1,$op2\t! ptr\n\t" | |
9548 "B$cmp $labl" %} | |
9549 ins_encode %{ | |
9550 Label* L = $labl$$label; | |
9551 Assembler::Predict predict_taken = | |
9552 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9553 __ cmp($op1$$Register, $op2$$Register); | |
9554 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); | |
9555 __ delayed()->nop(); | |
9556 %} | |
9557 ins_pipe(cmp_br_reg_reg); | |
9558 %} | |
9559 | |
9560 instruct cmpP_null_branch(cmpOpP cmp, iRegP op1, immP0 null, label labl, flagsRegP pcc) %{ | |
9561 match(If cmp (CmpP op1 null)); | |
9562 effect(USE labl, KILL pcc); | |
9563 | |
9564 size(12); | |
9565 ins_cost(BRANCH_COST); | |
9566 format %{ "CMP $op1,0\t! ptr\n\t" | |
9567 "B$cmp $labl" %} | |
9568 ins_encode %{ | |
9569 Label* L = $labl$$label; | |
9570 Assembler::Predict predict_taken = | |
9571 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9572 __ cmp($op1$$Register, G0); | |
9573 // bpr() is not used here since it has shorter distance. | |
9574 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); | |
9575 __ delayed()->nop(); | |
9576 %} | |
9577 ins_pipe(cmp_br_reg_reg); | |
9578 %} | |
9579 | |
9580 instruct cmpN_reg_branch(cmpOp cmp, iRegN op1, iRegN op2, label labl, flagsReg icc) %{ | |
9581 match(If cmp (CmpN op1 op2)); | |
9582 effect(USE labl, KILL icc); | |
9583 | |
9584 size(12); | |
9585 ins_cost(BRANCH_COST); | |
9586 format %{ "CMP $op1,$op2\t! compressed ptr\n\t" | |
9587 "BP$cmp $labl" %} | |
9588 ins_encode %{ | |
9589 Label* L = $labl$$label; | |
9590 Assembler::Predict predict_taken = | |
9591 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9592 __ cmp($op1$$Register, $op2$$Register); | |
9593 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9594 __ delayed()->nop(); | |
9595 %} | |
9596 ins_pipe(cmp_br_reg_reg); | |
9597 %} | |
9598 | |
9599 instruct cmpN_null_branch(cmpOp cmp, iRegN op1, immN0 null, label labl, flagsReg icc) %{ | |
9600 match(If cmp (CmpN op1 null)); | |
9601 effect(USE labl, KILL icc); | |
9602 | |
9603 size(12); | |
9604 ins_cost(BRANCH_COST); | |
9605 format %{ "CMP $op1,0\t! compressed ptr\n\t" | |
9606 "BP$cmp $labl" %} | |
9607 ins_encode %{ | |
9608 Label* L = $labl$$label; | |
9609 Assembler::Predict predict_taken = | |
9610 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9611 __ cmp($op1$$Register, G0); | |
9612 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9613 __ delayed()->nop(); | |
9614 %} | |
9615 ins_pipe(cmp_br_reg_reg); | |
9616 %} | |
9617 | |
9618 // Loop back branch | |
9619 instruct cmpI_reg_branchLoopEnd(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ | |
9620 match(CountedLoopEnd cmp (CmpI op1 op2)); | |
9621 effect(USE labl, KILL icc); | |
9622 | |
9623 size(12); | |
9624 ins_cost(BRANCH_COST); | |
9625 format %{ "CMP $op1,$op2\t! int\n\t" | |
9626 "BP$cmp $labl\t! Loop end" %} | |
9627 ins_encode %{ | |
9628 Label* L = $labl$$label; | |
9629 Assembler::Predict predict_taken = | |
9630 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9631 __ cmp($op1$$Register, $op2$$Register); | |
9632 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9633 __ delayed()->nop(); | |
9634 %} | |
9635 ins_pipe(cmp_br_reg_reg); | |
9636 %} | |
9637 | |
9638 instruct cmpI_imm_branchLoopEnd(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ | |
9639 match(CountedLoopEnd cmp (CmpI op1 op2)); | |
9640 effect(USE labl, KILL icc); | |
9641 | |
9642 size(12); | |
9643 ins_cost(BRANCH_COST); | |
9644 format %{ "CMP $op1,$op2\t! int\n\t" | |
9645 "BP$cmp $labl\t! Loop end" %} | |
9646 ins_encode %{ | |
9647 Label* L = $labl$$label; | |
9648 Assembler::Predict predict_taken = | |
9649 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9650 __ cmp($op1$$Register, $op2$$constant); | |
9651 __ bp((Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L); | |
9652 __ delayed()->nop(); | |
9653 %} | |
9654 ins_pipe(cmp_br_reg_imm); | |
9655 %} | |
9656 | |
9657 // Short compare and branch instructions | |
9658 instruct cmpI_reg_branch_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ | |
9659 match(If cmp (CmpI op1 op2)); | |
9660 predicate(UseCBCond); | |
9661 effect(USE labl, KILL icc); | |
9662 | |
9663 size(4); | |
9664 ins_cost(BRANCH_COST); | |
9665 format %{ "CWB$cmp $op1,$op2,$labl\t! int" %} | |
9666 ins_encode %{ | |
9667 Label* L = $labl$$label; | |
9668 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9669 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); | |
9670 %} | |
9671 ins_short_branch(1); | |
9672 ins_avoid_back_to_back(1); | |
9673 ins_pipe(cbcond_reg_reg); | |
9674 %} | |
9675 | |
9676 instruct cmpI_imm_branch_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ | |
9677 match(If cmp (CmpI op1 op2)); | |
9678 predicate(UseCBCond); | |
9679 effect(USE labl, KILL icc); | |
9680 | |
9681 size(4); | |
9682 ins_cost(BRANCH_COST); | |
9683 format %{ "CWB$cmp $op1,$op2,$labl\t! int" %} | |
9684 ins_encode %{ | |
9685 Label* L = $labl$$label; | |
9686 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9687 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); | |
9688 %} | |
9689 ins_short_branch(1); | |
9690 ins_avoid_back_to_back(1); | |
9691 ins_pipe(cbcond_reg_imm); | |
9692 %} | |
9693 | |
9694 instruct cmpU_reg_branch_short(cmpOpU cmp, iRegI op1, iRegI op2, label labl, flagsRegU icc) %{ | |
9695 match(If cmp (CmpU op1 op2)); | |
9696 predicate(UseCBCond); | |
9697 effect(USE labl, KILL icc); | |
9698 | |
9699 size(4); | |
9700 ins_cost(BRANCH_COST); | |
9701 format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %} | |
9702 ins_encode %{ | |
9703 Label* L = $labl$$label; | |
9704 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9705 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); | |
9706 %} | |
9707 ins_short_branch(1); | |
9708 ins_avoid_back_to_back(1); | |
9709 ins_pipe(cbcond_reg_reg); | |
9710 %} | |
9711 | |
9712 instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, flagsRegU icc) %{ | |
9713 match(If cmp (CmpU op1 op2)); | |
9714 predicate(UseCBCond); | |
9715 effect(USE labl, KILL icc); | |
9716 | |
9717 size(4); | |
9718 ins_cost(BRANCH_COST); | |
9719 format %{ "CWB$cmp $op1,$op2,$labl\t! unsigned" %} | |
9720 ins_encode %{ | |
9721 Label* L = $labl$$label; | |
9722 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9723 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); | |
9724 %} | |
9725 ins_short_branch(1); | |
9726 ins_avoid_back_to_back(1); | |
9727 ins_pipe(cbcond_reg_imm); | |
9728 %} | |
9729 | |
9730 instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flagsRegL xcc) %{ | |
9731 match(If cmp (CmpL op1 op2)); | |
9732 predicate(UseCBCond); | |
9733 effect(USE labl, KILL xcc); | |
9734 | |
9735 size(4); | |
9736 ins_cost(BRANCH_COST); | |
9737 format %{ "CXB$cmp $op1,$op2,$labl\t! long" %} | |
9738 ins_encode %{ | |
9739 Label* L = $labl$$label; | |
9740 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9741 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L); | |
9742 %} | |
9743 ins_short_branch(1); | |
9744 ins_avoid_back_to_back(1); | |
9745 ins_pipe(cbcond_reg_reg); | |
9746 %} | |
9747 | |
9748 instruct cmpL_imm_branch_short(cmpOp cmp, iRegL op1, immL5 op2, label labl, flagsRegL xcc) %{ | |
9749 match(If cmp (CmpL op1 op2)); | |
9750 predicate(UseCBCond); | |
9751 effect(USE labl, KILL xcc); | |
9752 | |
9753 size(4); | |
9754 ins_cost(BRANCH_COST); | |
9755 format %{ "CXB$cmp $op1,$op2,$labl\t! long" %} | |
9756 ins_encode %{ | |
9757 Label* L = $labl$$label; | |
9758 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9759 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L); | |
9760 %} | |
9761 ins_short_branch(1); | |
9762 ins_avoid_back_to_back(1); | |
9763 ins_pipe(cbcond_reg_imm); | |
9764 %} | |
9765 | |
9766 // Compare Pointers and branch | |
9767 instruct cmpP_reg_branch_short(cmpOpP cmp, iRegP op1, iRegP op2, label labl, flagsRegP pcc) %{ | |
9768 match(If cmp (CmpP op1 op2)); | |
9769 predicate(UseCBCond); | |
9770 effect(USE labl, KILL pcc); | |
9771 | |
9772 size(4); | |
9773 ins_cost(BRANCH_COST); | |
9774 #ifdef _LP64 | |
9775 format %{ "CXB$cmp $op1,$op2,$labl\t! ptr" %} | |
9776 #else | |
9777 format %{ "CWB$cmp $op1,$op2,$labl\t! ptr" %} | |
9778 #endif | |
9779 ins_encode %{ | |
9780 Label* L = $labl$$label; | |
9781 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9782 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L); | |
9783 %} | |
9784 ins_short_branch(1); | |
9785 ins_avoid_back_to_back(1); | |
9786 ins_pipe(cbcond_reg_reg); | |
9787 %} | |
9788 | |
9789 instruct cmpP_null_branch_short(cmpOpP cmp, iRegP op1, immP0 null, label labl, flagsRegP pcc) %{ | |
9790 match(If cmp (CmpP op1 null)); | |
9791 predicate(UseCBCond); | |
9792 effect(USE labl, KILL pcc); | |
9793 | |
9794 size(4); | |
9795 ins_cost(BRANCH_COST); | |
9796 #ifdef _LP64 | |
9797 format %{ "CXB$cmp $op1,0,$labl\t! ptr" %} | |
9798 #else | |
9799 format %{ "CWB$cmp $op1,0,$labl\t! ptr" %} | |
9800 #endif | |
9801 ins_encode %{ | |
9802 Label* L = $labl$$label; | |
9803 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9804 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L); | |
9805 %} | |
9806 ins_short_branch(1); | |
9807 ins_avoid_back_to_back(1); | |
9808 ins_pipe(cbcond_reg_reg); | |
9809 %} | |
9810 | |
9811 instruct cmpN_reg_branch_short(cmpOp cmp, iRegN op1, iRegN op2, label labl, flagsReg icc) %{ | |
9812 match(If cmp (CmpN op1 op2)); | |
9813 predicate(UseCBCond); | |
9814 effect(USE labl, KILL icc); | |
9815 | |
9816 size(4); | |
9817 ins_cost(BRANCH_COST); | |
9818 format %{ "CWB$cmp $op1,op2,$labl\t! compressed ptr" %} | |
9819 ins_encode %{ | |
9820 Label* L = $labl$$label; | |
9821 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9822 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); | |
9823 %} | |
9824 ins_short_branch(1); | |
9825 ins_avoid_back_to_back(1); | |
9826 ins_pipe(cbcond_reg_reg); | |
9827 %} | |
9828 | |
9829 instruct cmpN_null_branch_short(cmpOp cmp, iRegN op1, immN0 null, label labl, flagsReg icc) %{ | |
9830 match(If cmp (CmpN op1 null)); | |
9831 predicate(UseCBCond); | |
9832 effect(USE labl, KILL icc); | |
9833 | |
9834 size(4); | |
9835 ins_cost(BRANCH_COST); | |
9836 format %{ "CWB$cmp $op1,0,$labl\t! compressed ptr" %} | |
9837 ins_encode %{ | |
9838 Label* L = $labl$$label; | |
9839 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9840 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L); | |
9841 %} | |
9842 ins_short_branch(1); | |
9843 ins_avoid_back_to_back(1); | |
9844 ins_pipe(cbcond_reg_reg); | |
9845 %} | |
9846 | |
9847 // Loop back branch | |
9848 instruct cmpI_reg_branchLoopEnd_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flagsReg icc) %{ | |
9849 match(CountedLoopEnd cmp (CmpI op1 op2)); | |
9850 predicate(UseCBCond); | |
9851 effect(USE labl, KILL icc); | |
9852 | |
9853 size(4); | |
9854 ins_cost(BRANCH_COST); | |
9855 format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %} | |
9856 ins_encode %{ | |
9857 Label* L = $labl$$label; | |
9858 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9859 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); | |
9860 %} | |
9861 ins_short_branch(1); | |
9862 ins_avoid_back_to_back(1); | |
9863 ins_pipe(cbcond_reg_reg); | |
9864 %} | |
9865 | |
9866 instruct cmpI_imm_branchLoopEnd_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flagsReg icc) %{ | |
9867 match(CountedLoopEnd cmp (CmpI op1 op2)); | |
9868 predicate(UseCBCond); | |
9869 effect(USE labl, KILL icc); | |
9870 | |
9871 size(4); | |
9872 ins_cost(BRANCH_COST); | |
9873 format %{ "CWB$cmp $op1,$op2,$labl\t! Loop end" %} | |
9874 ins_encode %{ | |
9875 Label* L = $labl$$label; | |
9876 assert(__ use_cbcond(*L), "back to back cbcond"); | |
9877 __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); | |
9878 %} | |
9879 ins_short_branch(1); | |
9880 ins_avoid_back_to_back(1); | |
9881 ins_pipe(cbcond_reg_imm); | |
9102 %} | 9882 %} |
9103 | 9883 |
9104 // Branch-on-register tests all 64 bits. We assume that values | 9884 // Branch-on-register tests all 64 bits. We assume that values |
9105 // in 64-bit registers always remains zero or sign extended | 9885 // in 64-bit registers always remains zero or sign extended |
9106 // unless our code munges the high bits. Interrupts can chop | 9886 // unless our code munges the high bits. Interrupts can chop |
9112 | 9892 |
9113 size(8); | 9893 size(8); |
9114 ins_cost(BRANCH_COST); | 9894 ins_cost(BRANCH_COST); |
9115 format %{ "BR$cmp $op1,$labl" %} | 9895 format %{ "BR$cmp $op1,$labl" %} |
9116 ins_encode( enc_bpr( labl, cmp, op1 ) ); | 9896 ins_encode( enc_bpr( labl, cmp, op1 ) ); |
9117 ins_pc_relative(1); | |
9118 ins_pipe(br_reg); | 9897 ins_pipe(br_reg); |
9119 %} | 9898 %} |
9120 | 9899 |
9121 instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{ | 9900 instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{ |
9122 match(If cmp (CmpP op1 null)); | 9901 match(If cmp (CmpP op1 null)); |
9125 | 9904 |
9126 size(8); | 9905 size(8); |
9127 ins_cost(BRANCH_COST); | 9906 ins_cost(BRANCH_COST); |
9128 format %{ "BR$cmp $op1,$labl" %} | 9907 format %{ "BR$cmp $op1,$labl" %} |
9129 ins_encode( enc_bpr( labl, cmp, op1 ) ); | 9908 ins_encode( enc_bpr( labl, cmp, op1 ) ); |
9130 ins_pc_relative(1); | |
9131 ins_pipe(br_reg); | 9909 ins_pipe(br_reg); |
9132 %} | 9910 %} |
9133 | 9911 |
9134 instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{ | 9912 instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{ |
9135 match(If cmp (CmpL op1 zero)); | 9913 match(If cmp (CmpL op1 zero)); |
9138 | 9916 |
9139 size(8); | 9917 size(8); |
9140 ins_cost(BRANCH_COST); | 9918 ins_cost(BRANCH_COST); |
9141 format %{ "BR$cmp $op1,$labl" %} | 9919 format %{ "BR$cmp $op1,$labl" %} |
9142 ins_encode( enc_bpr( labl, cmp, op1 ) ); | 9920 ins_encode( enc_bpr( labl, cmp, op1 ) ); |
9143 ins_pc_relative(1); | |
9144 ins_pipe(br_reg); | 9921 ins_pipe(br_reg); |
9145 %} | 9922 %} |
9146 | 9923 |
9147 instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9148 match(If cmp icc); | |
9149 effect(USE labl); | |
9150 | |
9151 format %{ "BP$cmp $icc,$labl" %} | |
9152 // Prim = bits 24-22, Secnd = bits 31-30 | |
9153 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9154 ins_pc_relative(1); | |
9155 ins_pipe(br_cc); | |
9156 %} | |
9157 | |
9158 instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{ | |
9159 match(If cmp pcc); | |
9160 effect(USE labl); | |
9161 | |
9162 size(8); | |
9163 ins_cost(BRANCH_COST); | |
9164 format %{ "BP$cmp $pcc,$labl" %} | |
9165 // Prim = bits 24-22, Secnd = bits 31-30 | |
9166 ins_encode( enc_bpx( labl, cmp, pcc ) ); | |
9167 ins_pc_relative(1); | |
9168 ins_pipe(br_cc); | |
9169 %} | |
9170 | |
9171 instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{ | |
9172 match(If cmp fcc); | |
9173 effect(USE labl); | |
9174 | |
9175 size(8); | |
9176 ins_cost(BRANCH_COST); | |
9177 format %{ "FBP$cmp $fcc,$labl" %} | |
9178 // Prim = bits 24-22, Secnd = bits 31-30 | |
9179 ins_encode( enc_fbp( labl, cmp, fcc ) ); | |
9180 ins_pc_relative(1); | |
9181 ins_pipe(br_fcc); | |
9182 %} | |
9183 | |
9184 instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{ | |
9185 match(CountedLoopEnd cmp icc); | |
9186 effect(USE labl); | |
9187 | |
9188 size(8); | |
9189 ins_cost(BRANCH_COST); | |
9190 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9191 // Prim = bits 24-22, Secnd = bits 31-30 | |
9192 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9193 ins_pc_relative(1); | |
9194 ins_pipe(br_cc); | |
9195 %} | |
9196 | |
9197 instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{ | |
9198 match(CountedLoopEnd cmp icc); | |
9199 effect(USE labl); | |
9200 | |
9201 size(8); | |
9202 ins_cost(BRANCH_COST); | |
9203 format %{ "BP$cmp $icc,$labl\t! Loop end" %} | |
9204 // Prim = bits 24-22, Secnd = bits 31-30 | |
9205 ins_encode( enc_bp( labl, cmp, icc ) ); | |
9206 ins_pc_relative(1); | |
9207 ins_pipe(br_cc); | |
9208 %} | |
9209 | 9924 |
9210 // ============================================================================ | 9925 // ============================================================================ |
9211 // Long Compare | 9926 // Long Compare |
9212 // | 9927 // |
9213 // Currently we hold longs in 2 registers. Comparing such values efficiently | 9928 // Currently we hold longs in 2 registers. Comparing such values efficiently |
9233 effect(USE labl); | 9948 effect(USE labl); |
9234 | 9949 |
9235 size(8); | 9950 size(8); |
9236 ins_cost(BRANCH_COST); | 9951 ins_cost(BRANCH_COST); |
9237 format %{ "BP$cmp $xcc,$labl" %} | 9952 format %{ "BP$cmp $xcc,$labl" %} |
9238 // Prim = bits 24-22, Secnd = bits 31-30 | 9953 ins_encode %{ |
9239 ins_encode( enc_bpl( labl, cmp, xcc ) ); | 9954 Label* L = $labl$$label; |
9240 ins_pc_relative(1); | 9955 Assembler::Predict predict_taken = |
9956 cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn; | |
9957 | |
9958 __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); | |
9959 __ delayed()->nop(); | |
9960 %} | |
9241 ins_pipe(br_cc); | 9961 ins_pipe(br_cc); |
9242 %} | 9962 %} |
9243 | 9963 |
9244 // Manifest a CmpL3 result in an integer register. Very painful. | 9964 // Manifest a CmpL3 result in an integer register. Very painful. |
9245 // This is the test to avoid. | 9965 // This is the test to avoid. |
9363 | 10083 |
9364 size(8); | 10084 size(8); |
9365 ins_cost(CALL_COST); | 10085 ins_cost(CALL_COST); |
9366 format %{ "CALL,static ; NOP ==> " %} | 10086 format %{ "CALL,static ; NOP ==> " %} |
9367 ins_encode( Java_Static_Call( meth ), call_epilog ); | 10087 ins_encode( Java_Static_Call( meth ), call_epilog ); |
9368 ins_pc_relative(1); | |
9369 ins_pipe(simple_call); | 10088 ins_pipe(simple_call); |
9370 %} | 10089 %} |
9371 | 10090 |
9372 // Call Java Static Instruction (method handle version) | 10091 // Call Java Static Instruction (method handle version) |
9373 instruct CallStaticJavaHandle(method meth, l7RegP l7_mh_SP_save) %{ | 10092 instruct CallStaticJavaHandle(method meth, l7RegP l7_mh_SP_save) %{ |
9374 match(CallStaticJava); | 10093 match(CallStaticJava); |
9375 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); | 10094 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); |
9376 effect(USE meth, KILL l7_mh_SP_save); | 10095 effect(USE meth, KILL l7_mh_SP_save); |
9377 | 10096 |
9378 size(8); | 10097 size(16); |
9379 ins_cost(CALL_COST); | 10098 ins_cost(CALL_COST); |
9380 format %{ "CALL,static/MethodHandle" %} | 10099 format %{ "CALL,static/MethodHandle" %} |
9381 ins_encode(preserve_SP, Java_Static_Call(meth), restore_SP, call_epilog); | 10100 ins_encode(preserve_SP, Java_Static_Call(meth), restore_SP, call_epilog); |
9382 ins_pc_relative(1); | |
9383 ins_pipe(simple_call); | 10101 ins_pipe(simple_call); |
9384 %} | 10102 %} |
9385 | 10103 |
9386 // Call Java Dynamic Instruction | 10104 // Call Java Dynamic Instruction |
9387 instruct CallDynamicJavaDirect( method meth ) %{ | 10105 instruct CallDynamicJavaDirect( method meth ) %{ |
9390 | 10108 |
9391 ins_cost(CALL_COST); | 10109 ins_cost(CALL_COST); |
9392 format %{ "SET (empty),R_G5\n\t" | 10110 format %{ "SET (empty),R_G5\n\t" |
9393 "CALL,dynamic ; NOP ==> " %} | 10111 "CALL,dynamic ; NOP ==> " %} |
9394 ins_encode( Java_Dynamic_Call( meth ), call_epilog ); | 10112 ins_encode( Java_Dynamic_Call( meth ), call_epilog ); |
9395 ins_pc_relative(1); | |
9396 ins_pipe(call); | 10113 ins_pipe(call); |
9397 %} | 10114 %} |
9398 | 10115 |
9399 // Call Runtime Instruction | 10116 // Call Runtime Instruction |
9400 instruct CallRuntimeDirect(method meth, l7RegP l7) %{ | 10117 instruct CallRuntimeDirect(method meth, l7RegP l7) %{ |
9402 effect(USE meth, KILL l7); | 10119 effect(USE meth, KILL l7); |
9403 ins_cost(CALL_COST); | 10120 ins_cost(CALL_COST); |
9404 format %{ "CALL,runtime" %} | 10121 format %{ "CALL,runtime" %} |
9405 ins_encode( Java_To_Runtime( meth ), | 10122 ins_encode( Java_To_Runtime( meth ), |
9406 call_epilog, adjust_long_from_native_call ); | 10123 call_epilog, adjust_long_from_native_call ); |
9407 ins_pc_relative(1); | |
9408 ins_pipe(simple_call); | 10124 ins_pipe(simple_call); |
9409 %} | 10125 %} |
9410 | 10126 |
9411 // Call runtime without safepoint - same as CallRuntime | 10127 // Call runtime without safepoint - same as CallRuntime |
9412 instruct CallLeafDirect(method meth, l7RegP l7) %{ | 10128 instruct CallLeafDirect(method meth, l7RegP l7) %{ |
9415 ins_cost(CALL_COST); | 10131 ins_cost(CALL_COST); |
9416 format %{ "CALL,runtime leaf" %} | 10132 format %{ "CALL,runtime leaf" %} |
9417 ins_encode( Java_To_Runtime( meth ), | 10133 ins_encode( Java_To_Runtime( meth ), |
9418 call_epilog, | 10134 call_epilog, |
9419 adjust_long_from_native_call ); | 10135 adjust_long_from_native_call ); |
9420 ins_pc_relative(1); | |
9421 ins_pipe(simple_call); | 10136 ins_pipe(simple_call); |
9422 %} | 10137 %} |
9423 | 10138 |
9424 // Call runtime without safepoint - same as CallLeaf | 10139 // Call runtime without safepoint - same as CallLeaf |
9425 instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{ | 10140 instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{ |
9428 ins_cost(CALL_COST); | 10143 ins_cost(CALL_COST); |
9429 format %{ "CALL,runtime leaf nofp" %} | 10144 format %{ "CALL,runtime leaf nofp" %} |
9430 ins_encode( Java_To_Runtime( meth ), | 10145 ins_encode( Java_To_Runtime( meth ), |
9431 call_epilog, | 10146 call_epilog, |
9432 adjust_long_from_native_call ); | 10147 adjust_long_from_native_call ); |
9433 ins_pc_relative(1); | |
9434 ins_pipe(simple_call); | 10148 ins_pipe(simple_call); |
9435 %} | 10149 %} |
9436 | 10150 |
9437 // Tail Call; Jump from runtime stub to Java code. | 10151 // Tail Call; Jump from runtime stub to Java code. |
9438 // Also known as an 'interprocedural jump'. | 10152 // Also known as an 'interprocedural jump'. |
9553 match(Set pcc (FastLock object box)); | 10267 match(Set pcc (FastLock object box)); |
9554 | 10268 |
9555 effect(KILL scratch, TEMP scratch2); | 10269 effect(KILL scratch, TEMP scratch2); |
9556 ins_cost(100); | 10270 ins_cost(100); |
9557 | 10271 |
9558 size(4*112); // conservative overestimation ... | |
9559 format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | 10272 format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %} |
9560 ins_encode( Fast_Lock(object, box, scratch, scratch2) ); | 10273 ins_encode( Fast_Lock(object, box, scratch, scratch2) ); |
9561 ins_pipe(long_memory_op); | 10274 ins_pipe(long_memory_op); |
9562 %} | 10275 %} |
9563 | 10276 |
9565 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ | 10278 instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{ |
9566 match(Set pcc (FastUnlock object box)); | 10279 match(Set pcc (FastUnlock object box)); |
9567 effect(KILL scratch, TEMP scratch2); | 10280 effect(KILL scratch, TEMP scratch2); |
9568 ins_cost(100); | 10281 ins_cost(100); |
9569 | 10282 |
9570 size(4*120); // conservative overestimation ... | |
9571 format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} | 10283 format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %} |
9572 ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); | 10284 ins_encode( Fast_Unlock(object, box, scratch, scratch2) ); |
9573 ins_pipe(long_memory_op); | 10285 ins_pipe(long_memory_op); |
9574 %} | 10286 %} |
9575 | 10287 |
9576 // Count and Base registers are fixed because the allocator cannot | 10288 // The encodings are generic. |
9577 // kill unknown registers. The encodings are generic. | |
9578 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{ | 10289 instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{ |
10290 predicate(!use_block_zeroing(n->in(2)) ); | |
9579 match(Set dummy (ClearArray cnt base)); | 10291 match(Set dummy (ClearArray cnt base)); |
9580 effect(TEMP temp, KILL ccr); | 10292 effect(TEMP temp, KILL ccr); |
9581 ins_cost(300); | 10293 ins_cost(300); |
9582 format %{ "MOV $cnt,$temp\n" | 10294 format %{ "MOV $cnt,$temp\n" |
9583 "loop: SUBcc $temp,8,$temp\t! Count down a dword of bytes\n" | 10295 "loop: SUBcc $temp,8,$temp\t! Count down a dword of bytes\n" |
9584 " BRge loop\t\t! Clearing loop\n" | 10296 " BRge loop\t\t! Clearing loop\n" |
9585 " STX G0,[$base+$temp]\t! delay slot" %} | 10297 " STX G0,[$base+$temp]\t! delay slot" %} |
9586 ins_encode( enc_Clear_Array(cnt, base, temp) ); | 10298 |
10299 ins_encode %{ | |
10300 // Compiler ensures base is doubleword aligned and cnt is count of doublewords | |
10301 Register nof_bytes_arg = $cnt$$Register; | |
10302 Register nof_bytes_tmp = $temp$$Register; | |
10303 Register base_pointer_arg = $base$$Register; | |
10304 | |
10305 Label loop; | |
10306 __ mov(nof_bytes_arg, nof_bytes_tmp); | |
10307 | |
10308 // Loop and clear, walking backwards through the array. | |
10309 // nof_bytes_tmp (if >0) is always the number of bytes to zero | |
10310 __ bind(loop); | |
10311 __ deccc(nof_bytes_tmp, 8); | |
10312 __ br(Assembler::greaterEqual, true, Assembler::pt, loop); | |
10313 __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp); | |
10314 // %%%% this mini-loop must not cross a cache boundary! | |
10315 %} | |
10316 ins_pipe(long_memory_op); | |
10317 %} | |
10318 | |
10319 instruct clear_array_bis(g1RegX cnt, o0RegP base, Universe dummy, flagsReg ccr) %{ | |
10320 predicate(use_block_zeroing(n->in(2))); | |
10321 match(Set dummy (ClearArray cnt base)); | |
10322 effect(USE_KILL cnt, USE_KILL base, KILL ccr); | |
10323 ins_cost(300); | |
10324 format %{ "CLEAR [$base, $cnt]\t! ClearArray" %} | |
10325 | |
10326 ins_encode %{ | |
10327 | |
10328 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); | |
10329 Register to = $base$$Register; | |
10330 Register count = $cnt$$Register; | |
10331 | |
10332 Label Ldone; | |
10333 __ nop(); // Separate short branches | |
10334 // Use BIS for zeroing (temp is not used). | |
10335 __ bis_zeroing(to, count, G0, Ldone); | |
10336 __ bind(Ldone); | |
10337 | |
10338 %} | |
10339 ins_pipe(long_memory_op); | |
10340 %} | |
10341 | |
10342 instruct clear_array_bis_2(g1RegX cnt, o0RegP base, iRegX tmp, Universe dummy, flagsReg ccr) %{ | |
10343 predicate(use_block_zeroing(n->in(2)) && !Assembler::is_simm13((int)BlockZeroingLowLimit)); | |
10344 match(Set dummy (ClearArray cnt base)); | |
10345 effect(TEMP tmp, USE_KILL cnt, USE_KILL base, KILL ccr); | |
10346 ins_cost(300); | |
10347 format %{ "CLEAR [$base, $cnt]\t! ClearArray" %} | |
10348 | |
10349 ins_encode %{ | |
10350 | |
10351 assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); | |
10352 Register to = $base$$Register; | |
10353 Register count = $cnt$$Register; | |
10354 Register temp = $tmp$$Register; | |
10355 | |
10356 Label Ldone; | |
10357 __ nop(); // Separate short branches | |
10358 // Use BIS for zeroing | |
10359 __ bis_zeroing(to, count, temp, Ldone); | |
10360 __ bind(Ldone); | |
10361 | |
10362 %} | |
9587 ins_pipe(long_memory_op); | 10363 ins_pipe(long_memory_op); |
9588 %} | 10364 %} |
9589 | 10365 |
9590 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, | 10366 instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result, |
9591 o7RegI tmp, flagsReg ccr) %{ | 10367 o7RegI tmp, flagsReg ccr) %{ |
9736 __ popc(Rdst, Rdst); | 10512 __ popc(Rdst, Rdst); |
9737 %} | 10513 %} |
9738 ins_pipe(ialu_reg); | 10514 ins_pipe(ialu_reg); |
9739 %} | 10515 %} |
9740 | 10516 |
9741 instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{ | 10517 instruct countTrailingZerosL(iRegIsafe dst, iRegL src, flagsReg cr) %{ |
9742 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported | 10518 predicate(UsePopCountInstruction); // See Matcher::match_rule_supported |
9743 match(Set dst (CountTrailingZerosL src)); | 10519 match(Set dst (CountTrailingZerosL src)); |
9744 effect(TEMP dst, KILL cr); | 10520 effect(TEMP dst, KILL cr); |
9745 | 10521 |
9746 // return popc(~x & (x - 1)); | 10522 // return popc(~x & (x - 1)); |