hotspot/src/cpu/sparc/vm/sparc.ad
Print this page
rev 611 : Merge
@@ -1,7 +1,7 @@
//
-// Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
+// Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
@@ -393,10 +393,11 @@
,R_I0H,R_I0, R_I1H,R_I1, R_I2H,R_I2, R_I3H,R_I3, R_I4H,R_I4, R_I5H,R_I5
#endif // _LP64
);
reg_class g1_regL(R_G1H,R_G1);
+reg_class g3_regL(R_G3H,R_G3);
reg_class o2_regL(R_O2H,R_O2);
reg_class o7_regL(R_O7H,R_O7);
// ----------------------------
// Special Class for Condition Code Flags Register
@@ -466,12 +467,10 @@
#define LONG_LO_REG(x) (x)
%}
source %{
-#pragma ident "@(#)sparc.ad 1.456 07/09/28 10:23:30 JVM"
-
#define __ _masm.
// tertiary op of a LoadP or StoreP encoding
#define REGP_OP true
@@ -544,15 +543,23 @@
NativeCall::instruction_size); // sethi; setlo; call; delay slot
} else {
assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+ int klass_load_size;
+ if (UseCompressedOops) {
+ klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass()
+ } else {
+ klass_load_size = 1*BytesPerInstWord;
+ }
if( Assembler::is_simm13(v_off) ) {
- return (3*BytesPerInstWord + // ld_ptr, ld_ptr, ld_ptr
+ return klass_load_size +
+ (2*BytesPerInstWord + // ld_ptr, ld_ptr
NativeCall::instruction_size); // call; delay slot
} else {
- return (5*BytesPerInstWord + // ld_ptr, set_hi, set, ld_ptr, ld_ptr
+ return klass_load_size +
+ (4*BytesPerInstWord + // set_hi, set, ld_ptr, ld_ptr
NativeCall::instruction_size); // call; delay slot
}
}
}
@@ -1591,11 +1598,17 @@
//=============================================================================
#ifndef PRODUCT
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:");
#ifdef _LP64
+ if (UseCompressedOops) {
+ st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
+ st->print_cr("\tSLL R_G5,3,R_G5");
+ st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ } else {
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
+ }
st->print_cr("\tCMP R_G5,R_G3" );
st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2");
#else // _LP64
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
st->print_cr("\tCMP R_G5,R_G3" );
@@ -1610,11 +1623,11 @@
Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
Register temp_reg = G3;
assert( G5_ic_reg != temp_reg, "conflicting registers" );
// Load klass from reciever
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
+ __ load_klass(O0, temp_reg);
// Compare against expected klass
__ cmp(temp_reg, G5_ic_reg);
// Branch to miss code, checks xcc or icc depending
__ trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0+2);
}
@@ -1729,11 +1742,11 @@
// Is this branch offset short enough that a short branch can be used?
//
// NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
return false;
}
const bool Matcher::isSimpleConstant64(jlong value) {
// Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
@@ -1811,10 +1824,15 @@
reg == R_I1H_num ||
reg == R_I2H_num ||
reg == R_I3H_num ||
reg == R_I4H_num ||
reg == R_I5H_num ) return true;
+
+ if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) {
+ return true;
+ }
+
#else
// 32-bit builds with longs-in-one-entry pass longs in G1 & G4.
// Longs cannot be passed in O regs, because O regs become I regs
// after a 'save' and I regs get their high bits chopped off on
// interrupt.
@@ -1907,48 +1925,53 @@
enc_class form3_mem_reg( memory mem, iRegI dst ) %{
emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
%}
+ enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
+ $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+ %}
+
enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
- emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
%}
enc_class form3_mem_prefetch_read( memory mem ) %{
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
%}
enc_class form3_mem_prefetch_write( memory mem ) %{
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+ emit_form3_mem_reg(cbuf, this, $primary, -1,
$mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
%}
enc_class form3_mem_reg_long_unaligned_marshal( memory mem, iRegL reg ) %{
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
guarantee($mem$$index == R_G0_enc, "double index?");
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg );
emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
%}
enc_class form3_mem_reg_double_unaligned( memory mem, RegD_low reg ) %{
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
guarantee($mem$$index == R_G0_enc, "double index?");
// Load long with 2 instructions
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp, R_G0_enc, $reg$$reg+0 );
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
%}
//%%% form3_mem_plus_4_reg is a hack--get rid of it
enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
- emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+ emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
%}
enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
// Encode a reg-reg copy. If it is useless, then empty encoding.
if( $rs2$$reg != $rd$$reg )
@@ -2474,21 +2497,28 @@
assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
// Just go thru the vtable
// get receiver klass (receiver already checked for non-null)
// If we end up going thru a c2i adapter interpreter expects method in G5
int off = __ offset();
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+ __ load_klass(O0, G3_scratch);
+ int klass_load_size;
+ if (UseCompressedOops) {
+ klass_load_size = 3*BytesPerInstWord;
+ } else {
+ klass_load_size = 1*BytesPerInstWord;
+ }
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
if( __ is_simm13(v_off) ) {
__ ld_ptr(G3, v_off, G5_method);
} else {
// Generate 2 instructions
__ Assembler::sethi(v_off & ~0x3ff, G5_method);
__ or3(G5_method, v_off & 0x3ff, G5_method);
// ld_ptr, set_hi, set
- assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)");
+ assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord,
+ "Unexpected instruction size(s)");
__ ld_ptr(G3, G5_method, G5_method);
}
// NOTE: for vtable dispatches, the vtable entry will never be null.
// However it may very well end up in handle_wrong_method if the
// method is abstract for the particular class.
@@ -2657,11 +2687,11 @@
assert(Roop != Rscratch, "");
assert(Roop != Rmark, "");
assert(Rbox != Rscratch, "");
assert(Rbox != Rmark, "");
- __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
+ __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
%}
enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
MacroAssembler _masm(&cbuf);
@@ -2673,11 +2703,11 @@
assert(Roop != Rscratch, "");
assert(Roop != Rmark, "");
assert(Rbox != Rscratch, "");
assert(Rbox != Rmark, "");
- __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
+ __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
%}
enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
MacroAssembler _masm(&cbuf);
Register Rmem = reg_to_register_object($mem$$reg);
@@ -2685,12 +2715,11 @@
Register Rnew = reg_to_register_object($new$$reg);
// casx_under_lock picks 1 of 3 encodings:
// For 32-bit pointers you get a 32-bit CAS
// For 64-bit pointers you get a 64-bit CASX
- __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
- (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
__ cmp( Rold, Rnew );
%}
enc_class enc_casx( iRegP mem, iRegL old, iRegL new) %{
Register Rmem = reg_to_register_object($mem$$reg);
@@ -2860,16 +2889,16 @@
int value_offset = java_lang_String:: value_offset_in_bytes();
int offset_offset = java_lang_String::offset_offset_in_bytes();
int count_offset = java_lang_String:: count_offset_in_bytes();
// load str1 (jchar*) base address into tmp1_reg
- __ ld_ptr(Address(str1_reg, 0, value_offset), tmp1_reg);
+ __ load_heap_oop(Address(str1_reg, 0, value_offset), tmp1_reg);
__ ld(Address(str1_reg, 0, offset_offset), result_reg);
__ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
__ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted
__ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
+ __ load_heap_oop(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
__ add(result_reg, tmp1_reg, tmp1_reg);
// load str2 (jchar*) base address into tmp2_reg
// __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
__ ld(Address(str2_reg, 0, offset_offset), result_reg);
@@ -3016,10 +3045,11 @@
enc_class enc_membar_volatile %{
MacroAssembler _masm(&cbuf);
__ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) );
%}
+
enc_class enc_repl8b( iRegI src, iRegL dst ) %{
MacroAssembler _masm(&cbuf);
Register src_reg = reg_to_register_object($src$$reg);
Register dst_reg = reg_to_register_object($dst$$reg);
__ sllx(src_reg, 56, dst_reg);
@@ -3189,37 +3219,37 @@
// to and from the register pairs is done by the appropriate call and epilog
// opcodes. This simplifies the register allocator.
c_return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
#ifdef _LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
%}
// Location of compiled Java return values. Same as C
return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
#ifdef _LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
%}
@@ -3408,10 +3438,31 @@
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
+// Pointer Immediate
+operand immN()
+%{
+ match(ConN);
+
+ op_cost(10);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// NULL Pointer Immediate
+operand immN0()
+%{
+ predicate(n->get_narrowcon() == 0);
+ match(ConN);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
operand immL() %{
match(ConL);
op_cost(40);
// formats are generated automatically for constants and base registers
format %{ %}
@@ -3672,10 +3723,18 @@
format %{ %}
interface(REG_INTER);
%}
+operand iRegN() %{
+ constraint(ALLOC_IN_RC(int_reg));
+ match(RegN);
+
+ format %{ %}
+ interface(REG_INTER);
+%}
+
// Long Register
operand iRegL() %{
constraint(ALLOC_IN_RC(long_reg));
match(RegL);
@@ -3705,10 +3764,18 @@
format %{ %}
interface(REG_INTER);
%}
+operand g3RegL() %{
+ constraint(ALLOC_IN_RC(g3_regL));
+ match(iRegL);
+
+ format %{ %}
+ interface(REG_INTER);
+%}
+
// Int Register safe
// This is 64bit safe
operand iRegIsafe() %{
constraint(ALLOC_IN_RC(long_reg));
@@ -5006,66 +5073,66 @@
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! stkI to regF" %}
opcode(Assembler::ldf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk);
%}
instruct stkL_to_regD(regD dst, stackSlotL src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! stkL to regD" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk);
%}
instruct regF_to_stkI(stackSlotI dst, regF src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t! regF to stkI" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg);
%}
instruct regD_to_stkL(stackSlotL dst, regD src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t! regD to stkL" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg);
%}
instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST*2);
size(8);
format %{ "STW $src,$dst.hi\t! long\n\t"
"STW R_G0,$dst.lo" %}
opcode(Assembler::stw_op3);
- ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+ ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
ins_pipe(lstoreI_stk_reg);
%}
instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
// No match rule to avoid chain rule match.
effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! regL to stkD" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_stk_reg);
%}
//---------- Chain stack slots between similar types --------
@@ -5075,11 +5142,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t!stk" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
// Store integer to stack slot
instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{
@@ -5087,11 +5154,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t!stk" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
// Load long from stack slot
instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{
@@ -5099,11 +5166,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
// Store long to stack slot
instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
@@ -5111,11 +5178,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! long" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
#ifdef _LP64
// Load pointer from stack slot, 64-bit encoding
@@ -5123,42 +5190,42 @@
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t!ptr" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
// Store pointer to stack slot
instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
#else // _LP64
// Load pointer from stack slot, 32-bit encoding
instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
format %{ "LDUW $src,$dst\t!ptr" %}
opcode(Assembler::lduw_op3, Assembler::ldst_op);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
// Store pointer to stack slot
instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
match(Set dst src);
ins_cost(MEMORY_REF_COST);
format %{ "STW $src,$dst\t!ptr" %}
opcode(Assembler::stw_op3, Assembler::ldst_op);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
#endif // _LP64
//------------Special Nop instructions for bundling - no match rules-----------
@@ -5217,11 +5284,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSB $mem,$dst" %}
opcode(Assembler::ldsb_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Byte (8bit UNsigned) into an int reg
instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{
@@ -5229,11 +5296,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Byte (8bit UNsigned) into a Long Register
instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{
@@ -5241,11 +5308,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Char (16bit UNsigned) into a Long Register
instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
@@ -5253,11 +5320,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Char (16bit unsigned)
instruct loadC(iRegI dst, memory mem) %{
@@ -5265,11 +5332,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Integer
instruct loadI(iRegI dst, memory mem) %{
@@ -5277,22 +5344,22 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $mem,$dst" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
// Load Long - aligned
instruct loadL(iRegL dst, memory mem ) %{
match(Set dst (LoadL mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
// Load Long - UNaligned
instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{
@@ -5303,55 +5370,55 @@
format %{ "LDUW $mem+4,R_O7\t! misaligned long\n"
"\tLDUW $mem ,$dst\n"
"\tSLLX #32, $dst, $dst\n"
"\tOR $dst, R_O7, $dst" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+ ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
ins_pipe(iload_mem);
%}
// Load Aligned Packed Byte into a Double Register
instruct loadA8B(regD dst, memory mem) %{
match(Set dst (Load8B mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst\t! packed8B" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
// Load Aligned Packed Char into a Double Register
instruct loadA4C(regD dst, memory mem) %{
match(Set dst (Load4C mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst\t! packed4C" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
// Load Aligned Packed Short into a Double Register
instruct loadA4S(regD dst, memory mem) %{
match(Set dst (Load4S mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst\t! packed4S" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
// Load Aligned Packed Int into a Double Register
instruct loadA2I(regD dst, memory mem) %{
match(Set dst (Load2I mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst\t! packed2I" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
// Load Range
instruct loadRange(iRegI dst, memory mem) %{
@@ -5359,11 +5426,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $mem,$dst\t! range" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
// Load Integer into %f register (for fitos/fitod)
instruct loadI_freg(regF dst, memory mem) %{
@@ -5371,11 +5438,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
opcode(Assembler::ldf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem);
%}
// Load Pointer
instruct loadP(iRegP dst, memory mem) %{
@@ -5392,10 +5459,30 @@
#endif
ins_encode( form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
+// Load Compressed Pointer
+instruct loadN(iRegN dst, memory mem) %{
+ match(Set dst (LoadN mem));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "LDUW $mem,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($mem$$base);
+ Register index = as_Register($mem$$index);
+ Register dst = $dst$$Register;
+ if (index != G0) {
+ __ lduw(base, index, dst);
+ } else {
+ __ lduw(base, $mem$$disp, dst);
+ }
+ %}
+ ins_pipe(iload_mem);
+%}
+
// Load Klass Pointer
instruct loadKlass(iRegP dst, memory mem) %{
match(Set dst (LoadKlass mem));
ins_cost(MEMORY_REF_COST);
size(4);
@@ -5409,19 +5496,40 @@
#endif
ins_encode( form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
+// Load narrow Klass Pointer
+instruct loadNKlass(iRegN dst, memory mem) %{
+ match(Set dst (LoadNKlass mem));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "LDUW $mem,$dst\t! compressed klass ptr" %}
+
+ ins_encode %{
+ Register base = as_Register($mem$$base);
+ Register index = as_Register($mem$$index);
+ Register dst = $dst$$Register;
+ if (index != G0) {
+ __ lduw(base, index, dst);
+ } else {
+ __ lduw(base, $mem$$disp, dst);
+ }
+ %}
+ ins_pipe(iload_mem);
+%}
+
// Load Short (16bit signed)
instruct loadS(iRegI dst, memory mem) %{
match(Set dst (LoadS mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDSH $mem,$dst" %}
opcode(Assembler::ldsh_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem);
%}
// Load Double
instruct loadD(regD dst, memory mem) %{
@@ -5429,11 +5537,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst" %}
opcode(Assembler::lddf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem);
%}
// Load Double - UNaligned
instruct loadD_unaligned(regD_low dst, memory mem ) %{
@@ -5453,11 +5561,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst" %}
opcode(Assembler::ldf_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem);
%}
// Load Constant
instruct loadConI( iRegI dst, immI src ) %{
@@ -5508,10 +5616,30 @@
__ sethi(polling_page, false );
%}
ins_pipe(loadConP_poll);
%}
+instruct loadConN0(iRegN dst, immN0 src) %{
+ match(Set dst src);
+
+ size(4);
+ format %{ "CLR $dst\t! compressed NULL ptr" %}
+ ins_encode( SetNull( dst ) );
+ ins_pipe(ialu_imm);
+%}
+
+instruct loadConN(iRegN dst, immN src) %{
+ match(Set dst src);
+ ins_cost(DEFAULT_COST * 3/2);
+ format %{ "SET $src,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register dst = $dst$$Register;
+ __ set_narrow_oop((jobject)$src$$constant, dst);
+ %}
+ ins_pipe(ialu_hi_lo_reg);
+%}
+
instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
// %%% maybe this should work like loadConD
match(Set dst src);
effect(KILL tmp);
ins_cost(DEFAULT_COST * 4);
@@ -5602,33 +5730,33 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
instruct storeB0(memory mem, immI0 src) %{
match(Set mem (StoreB mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
instruct storeCM0(memory mem, immI0 src) %{
match(Set mem (StoreCM mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
opcode(Assembler::stb_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
// Store Char/Short
instruct storeC(memory mem, iRegI src) %{
@@ -5636,22 +5764,22 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
instruct storeC0(memory mem, immI0 src) %{
match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
// Store Integer
instruct storeI(memory mem, iRegI src) %{
@@ -5659,44 +5787,44 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
// Store Long
instruct storeL(memory mem, iRegL src) %{
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem\t! long" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg);
%}
instruct storeI0(memory mem, immI0 src) %{
match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
instruct storeL0(memory mem, immL0 src) %{
match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
// Store Integer from float register (used after fstoi)
instruct storeI_Freg(memory mem, regF src) %{
@@ -5704,11 +5832,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
opcode(Assembler::stf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg);
%}
// Store Pointer
instruct storeP(memory dst, sp_ptr_RegP src) %{
@@ -5741,30 +5869,68 @@
#endif
ins_encode( form3_mem_reg( dst, R_G0 ) );
ins_pipe(istore_mem_zero);
%}
+// Store Compressed Pointer
+instruct storeN(memory dst, iRegN src) %{
+ match(Set dst (StoreN dst src));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "STW $src,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($dst$$base);
+ Register index = as_Register($dst$$index);
+ Register src = $src$$Register;
+ if (index != G0) {
+ __ stw(src, base, index);
+ } else {
+ __ stw(src, base, $dst$$disp);
+ }
+ %}
+ ins_pipe(istore_mem_spORreg);
+%}
+
+instruct storeN0(memory dst, immN0 src) %{
+ match(Set dst (StoreN dst src));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "STW $src,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($dst$$base);
+ Register index = as_Register($dst$$index);
+ if (index != G0) {
+ __ stw(0, base, index);
+ } else {
+ __ stw(0, base, $dst$$disp);
+ }
+ %}
+ ins_pipe(istore_mem_zero);
+%}
+
// Store Double
instruct storeD( memory mem, regD src) %{
match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
instruct storeD0( memory mem, immD0 src) %{
match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
// Store Float
instruct storeF( memory mem, regF src) %{
@@ -5772,88 +5938,132 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem" %}
opcode(Assembler::stf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg);
%}
instruct storeF0( memory mem, immF0 src) %{
match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem\t! storeF0" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreF_mem_zero);
%}
// Store Aligned Packed Bytes in Double register to memory
instruct storeA8B(memory mem, regD src) %{
match(Set mem (Store8B mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem\t! packed8B" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
+// Convert oop pointer into compressed form
+instruct encodeHeapOop(iRegN dst, iRegP src) %{
+ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
+ match(Set dst (EncodeP src));
+ format %{ "encode_heap_oop $src, $dst" %}
+ ins_encode %{
+ __ encode_heap_oop($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
+ predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
+ match(Set dst (EncodeP src));
+ format %{ "encode_heap_oop_not_null $src, $dst" %}
+ ins_encode %{
+ __ encode_heap_oop_not_null($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct decodeHeapOop(iRegP dst, iRegN src) %{
+ predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
+ n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
+ match(Set dst (DecodeN src));
+ format %{ "decode_heap_oop $src, $dst" %}
+ ins_encode %{
+ __ decode_heap_oop($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
+ predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
+ n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
+ match(Set dst (DecodeN src));
+ format %{ "decode_heap_oop_not_null $src, $dst" %}
+ ins_encode %{
+ __ decode_heap_oop_not_null($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+
// Store Zero into Aligned Packed Bytes
instruct storeA8B0(memory mem, immI0 zero) %{
match(Set mem (Store8B mem zero));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $zero,$mem\t! packed8B" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
// Store Aligned Packed Chars/Shorts in Double register to memory
instruct storeA4C(memory mem, regD src) %{
match(Set mem (Store4C mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem\t! packed4C" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
// Store Zero into Aligned Packed Chars/Shorts
instruct storeA4C0(memory mem, immI0 zero) %{
match(Set mem (Store4C mem (Replicate4C zero)));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $zero,$mem\t! packed4C" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
// Store Aligned Packed Ints in Double register to memory
instruct storeA2I(memory mem, regD src) %{
match(Set mem (Store2I mem src));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem\t! packed2I" %}
opcode(Assembler::stdf_op3);
- ins_encode( form3_mem_reg( mem, src ) );
+ ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
// Store Zero into Aligned Packed Ints
instruct storeA2I0(memory mem, immI0 zero) %{
match(Set mem (Store2I mem zero));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $zero,$mem\t! packed2I" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( mem, R_G0 ) );
+ ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
ins_pipe(fstoreD_mem_zero);
%}
//----------MemBar Instructions-----------------------------------------------
@@ -5963,31 +6173,31 @@
// %%%% TO DO: Tell the coalescer that this kind of node is a copy!
match(Set stkSlot src); // chain rule
ins_cost(MEMORY_REF_COST);
format %{ "STDF $src,$stkSlot\t!stk" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(stkSlot, src));
+ ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreD_stk_reg);
%}
instruct ldfSSD(regD dst, stackSlotD stkSlot) %{
// %%%% TO DO: Tell the coalescer that this kind of node is a copy!
match(Set dst stkSlot); // chain rule
ins_cost(MEMORY_REF_COST);
format %{ "LDDF $stkSlot,$dst\t!stk" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(stkSlot, dst));
+ ins_encode(simple_form3_mem_reg(stkSlot, dst));
ins_pipe(floadD_stk);
%}
instruct stfSSF(stackSlotF stkSlot, regF src) %{
// %%%% TO DO: Tell the coalescer that this kind of node is a copy!
match(Set stkSlot src); // chain rule
ins_cost(MEMORY_REF_COST);
format %{ "STF $src,$stkSlot\t!stk" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(stkSlot, src));
+ ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreF_stk_reg);
%}
//----------Conditional Move---------------------------------------------------
// Conditional move
@@ -6023,20 +6233,20 @@
format %{ "MOV$cmp $icc,$src,$dst" %}
ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) );
ins_pipe(ialu_imm);
%}
-instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{
+instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
format %{ "MOV$cmp $icc,$src,$dst" %}
ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
ins_pipe(ialu_reg);
%}
-instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{
+instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);
format %{ "MOV$cmp $icc,$src,$dst" %}
ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) );
@@ -6059,10 +6269,38 @@
format %{ "MOV$cmp $fcc,$src,$dst" %}
ins_encode( enc_cmov_imm_f(cmp,dst,src, fcc) );
ins_pipe(ialu_imm);
%}
+// Conditional move for RegN. Only cmov(reg,reg).
+instruct cmovNP_reg(cmpOpP cmp, flagsRegP pcc, iRegN dst, iRegN src) %{
+ match(Set dst (CMoveN (Binary cmp pcc) (Binary dst src)));
+ ins_cost(150);
+ format %{ "MOV$cmp $pcc,$src,$dst" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) );
+ ins_pipe(ialu_reg);
+%}
+
+// This instruction also works with CmpN so we don't need cmovNN_reg.
+instruct cmovNI_reg(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src) %{
+ match(Set dst (CMoveN (Binary cmp icc) (Binary dst src)));
+ ins_cost(150);
+ size(4);
+ format %{ "MOV$cmp $icc,$src,$dst" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
+ ins_pipe(ialu_reg);
+%}
+
+instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{
+ match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src)));
+ ins_cost(150);
+ size(4);
+ format %{ "MOV$cmp $fcc,$src,$dst" %}
+ ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) );
+ ins_pipe(ialu_reg);
+%}
+
// Conditional move
instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
ins_cost(150);
format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %}
@@ -6076,10 +6314,11 @@
format %{ "MOV$cmp $pcc,$src,$dst\t! ptr" %}
ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::ptr_cc)) );
ins_pipe(ialu_imm);
%}
+// This instruction also works with CmpN so we don't need cmovPN_reg.
instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
@@ -6356,11 +6595,11 @@
match(Set dst (LoadLLocked mem));
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( mem, dst ) );
+ ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem);
%}
instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{
match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
@@ -6369,36 +6608,27 @@
"CMP R_G3,$oldval\t\t! See if we made progress" %}
ins_encode( enc_cas(heap_top_ptr,oldval,newval) );
ins_pipe( long_memory_op );
%}
-instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
- match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
- effect( USE mem_ptr, KILL ccr, KILL tmp1);
- // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
- format %{
- "MOV $newval,R_O7\n\t"
- "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
- "CMP $oldval,R_O7\t\t! See if we made progress\n\t"
- "MOV 1,$res\n\t"
- "MOVne xcc,R_G0,$res"
- %}
- ins_encode( enc_casx(mem_ptr, oldval, newval),
- enc_lflags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
+ match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
+ effect( KILL newval );
+ format %{ "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+ "CMP $oldval,$newval\t\t! See if we made progress" %}
+ ins_encode( enc_cas(mem_ptr,oldval,newval) );
ins_pipe( long_memory_op );
%}
-instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
- match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
- effect( USE mem_ptr, KILL tmp1);
- // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
- format %{
- "MOV $newval,R_O7\n\t"
- "CASXA [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
- "CMP $oldval,R_O7\t\t! See if we made progress"
- %}
- ins_encode( enc_casx(mem_ptr, oldval, newval));
+// Conditional-store of a long value.
+instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
+ match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
+ effect( KILL newval );
+ format %{ "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+ "CMP $oldval,$newval\t\t! See if we made progress" %}
+ ins_encode( enc_cas(mem_ptr,oldval,newval) );
ins_pipe( long_memory_op );
%}
// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
@@ -6434,31 +6664,39 @@
%}
instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
effect( USE mem_ptr, KILL ccr, KILL tmp1);
-#ifdef _LP64
format %{
"MOV $newval,O7\n\t"
- "CASXA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
+ "CASA_PTR [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
"CMP $oldval,O7\t\t! See if we made progress\n\t"
"MOV 1,$res\n\t"
"MOVne xcc,R_G0,$res"
%}
+#ifdef _LP64
ins_encode( enc_casx(mem_ptr, oldval, newval),
enc_lflags_ne_to_boolean(res) );
#else
+ ins_encode( enc_casi(mem_ptr, oldval, newval),
+ enc_iflags_ne_to_boolean(res) );
+#endif
+ ins_pipe( long_memory_op );
+%}
+
+instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
+ match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
+ effect( USE mem_ptr, KILL ccr, KILL tmp1);
format %{
"MOV $newval,O7\n\t"
"CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
"CMP $oldval,O7\t\t! See if we made progress\n\t"
"MOV 1,$res\n\t"
"MOVne icc,R_G0,$res"
%}
ins_encode( enc_casi(mem_ptr, oldval, newval),
enc_iflags_ne_to_boolean(res) );
-#endif
ins_pipe( long_memory_op );
%}
//---------------------
// Subtraction Instructions
@@ -7169,10 +7407,38 @@
opcode(Assembler::or_op3, Assembler::arith_op);
ins_encode( form3_rs1_simm13_rd( src1, con, dst ) );
ins_pipe(ialu_reg_imm);
%}
+#ifndef _LP64
+
+// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
+instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
+ match(Set dst (OrI src1 (CastP2X src2)));
+
+ size(4);
+ format %{ "OR $src1,$src2,$dst" %}
+ opcode(Assembler::or_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+ ins_pipe(ialu_reg_reg);
+%}
+
+#else
+
+instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
+ match(Set dst (OrL src1 (CastP2X src2)));
+
+ ins_cost(DEFAULT_COST);
+ size(4);
+ format %{ "OR $src1,$src2,$dst\t! long" %}
+ opcode(Assembler::or_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+ ins_pipe(ialu_reg_reg);
+%}
+
+#endif
+
// Xor Instructions
// Register Xor
instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
match(Set dst (XorI src1 src2));
@@ -7430,11 +7696,11 @@
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t"
"FITOD $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitod_opf);
- ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+ ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
ins_pipe(floadF_mem);
%}
instruct convI2F_helper(regF dst, regF tmp) %{
@@ -7460,11 +7726,11 @@
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t"
"FITOS $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitos_opf);
- ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+ ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
ins_pipe(floadF_mem);
%}
instruct convI2L_reg(iRegL dst, iRegI src) %{
@@ -7502,11 +7768,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t! MoveF2I" %}
opcode(Assembler::lduw_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
match(Set dst (MoveI2F src));
@@ -7514,11 +7780,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! MoveI2F" %}
opcode(Assembler::ldf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk);
%}
instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
match(Set dst (MoveD2L src));
@@ -7526,11 +7792,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! MoveD2L" %}
opcode(Assembler::ldx_op3);
- ins_encode( form3_mem_reg( src, dst ) );
+ ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem);
%}
instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
match(Set dst (MoveL2D src));
@@ -7538,11 +7804,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! MoveL2D" %}
opcode(Assembler::lddf_op3);
- ins_encode(form3_mem_reg(src, dst));
+ ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk);
%}
instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
match(Set dst (MoveF2I src));
@@ -7550,11 +7816,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t!MoveF2I" %}
opcode(Assembler::stf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg);
%}
instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
match(Set dst (MoveI2F src));
@@ -7562,11 +7828,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t!MoveI2F" %}
opcode(Assembler::stw_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
match(Set dst (MoveD2L src));
@@ -7574,11 +7840,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t!MoveD2L" %}
opcode(Assembler::stdf_op3);
- ins_encode(form3_mem_reg(dst, src));
+ ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg);
%}
instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
match(Set dst (MoveL2D src));
@@ -7586,11 +7852,11 @@
ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t!MoveL2D" %}
opcode(Assembler::stx_op3);
- ins_encode( form3_mem_reg( dst, src ) );
+ ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg);
%}
//-----------
@@ -8047,10 +8313,31 @@
opcode(Assembler::subcc_op3, Assembler::arith_op);
ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
ins_pipe(ialu_cconly_reg_imm);
%}
+// Compare Narrow oops
+instruct compN_iRegN(flagsReg icc, iRegN op1, iRegN op2 ) %{
+ match(Set icc (CmpN op1 op2));
+
+ size(4);
+ format %{ "CMP $op1,$op2\t! compressed ptr" %}
+ opcode(Assembler::subcc_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) );
+ ins_pipe(ialu_cconly_reg_reg);
+%}
+
+instruct compN_iRegN_immN0(flagsReg icc, iRegN op1, immN0 op2 ) %{
+ match(Set icc (CmpN op1 op2));
+
+ size(4);
+ format %{ "CMP $op1,$op2\t! compressed ptr" %}
+ opcode(Assembler::subcc_op3, Assembler::arith_op);
+ ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
+ ins_pipe(ialu_cconly_reg_imm);
+%}
+
//----------Max and Min--------------------------------------------------------
// Min Instructions
// Conditional move for min
instruct cmovI_reg_lt( iRegI op2, iRegI op1, flagsReg icc ) %{
effect( USE_DEF op2, USE op1, USE icc );
@@ -8377,10 +8664,18 @@
format %{ "MOV$cmp $xcc,$src,$dst" %}
ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::xcc)) );
ins_pipe(ialu_imm);
%}
+instruct cmovNL_reg(cmpOp cmp, flagsRegL xcc, iRegN dst, iRegN src) %{
+ match(Set dst (CMoveN (Binary cmp xcc) (Binary dst src)));
+ ins_cost(150);
+ format %{ "MOV$cmp $xcc,$src,$dst" %}
+ ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );
+ ins_pipe(ialu_reg);
+%}
+
instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
ins_cost(150);
format %{ "MOV$cmp $xcc,$src,$dst" %}
ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );
@@ -8607,10 +8902,11 @@
format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %}
ins_encode( enc_PartialSubtypeCheck() );
ins_pipe(partial_subtype_check_pipe);
%}
+
// ============================================================================
// inlined locking and unlocking
instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7RegP scratch ) %{
match(Set pcc (FastLock object box));
@@ -8648,13 +8944,14 @@
" STX G0,[$base+$temp]\t! delay slot" %}
ins_encode( enc_Clear_Array(cnt, base, temp) );
ins_pipe(long_memory_op);
%}
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{
+instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
+ o7RegI tmp3, flagsReg ccr) %{
match(Set result (StrComp str1 str2));
- effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr);
+ effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
ins_cost(300);
format %{ "String Compare $str1,$str2 -> $result" %}
ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
ins_pipe(long_memory_op);
%}