提交 c4e786c3 编写于 作者: N never

6754519: don't emit flag fixup for NaN when condition being tested doesn't need it

Reviewed-by: kvn, rasbold
上级 603f73ef
...@@ -1743,7 +1743,7 @@ const bool Matcher::convL2FSupported(void) { ...@@ -1743,7 +1743,7 @@ const bool Matcher::convL2FSupported(void) {
// //
// NOTE: If the platform does not provide any short branch variants, then // NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0. // 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; return false;
} }
...@@ -1926,18 +1926,23 @@ encode %{ ...@@ -1926,18 +1926,23 @@ encode %{
$mem$$base, $mem$$disp, $mem$$index, $dst$$reg); $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) %{ 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); $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
%} %}
enc_class form3_mem_prefetch_read( memory mem ) %{ 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*/); $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
%} %}
enc_class form3_mem_prefetch_write( memory mem ) %{ 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*/); $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
%} %}
...@@ -1945,8 +1950,8 @@ encode %{ ...@@ -1945,8 +1950,8 @@ encode %{
assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" ); assert( Assembler::is_simm13($mem$$disp ), "need disp and disp+4" );
assert( Assembler::is_simm13($mem$$disp+4), "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?"); 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, -1, $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, R_G0_enc, $reg$$reg );
emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 ); 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 ); emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
%} %}
...@@ -1956,14 +1961,14 @@ encode %{ ...@@ -1956,14 +1961,14 @@ encode %{
assert( Assembler::is_simm13($mem$$disp+4), "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?"); guarantee($mem$$index == R_G0_enc, "double index?");
// Load long with 2 instructions // 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, -1, $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+4, R_G0_enc, $reg$$reg+1 );
%} %}
//%%% form3_mem_plus_4_reg is a hack--get rid of it //%%% form3_mem_plus_4_reg is a hack--get rid of it
enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{ enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
guarantee($mem$$disp, "cannot offset a reg-reg operand by 4"); 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 ) %{ enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
...@@ -5062,7 +5067,7 @@ instruct stkI_to_regF(regF dst, stackSlotI src) %{ ...@@ -5062,7 +5067,7 @@ instruct stkI_to_regF(regF dst, stackSlotI src) %{
size(4); size(4);
format %{ "LDF $src,$dst\t! stkI to regF" %} format %{ "LDF $src,$dst\t! stkI to regF" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode(form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk); ins_pipe(floadF_stk);
%} %}
...@@ -5073,7 +5078,7 @@ instruct stkL_to_regD(regD dst, stackSlotL src) %{ ...@@ -5073,7 +5078,7 @@ instruct stkL_to_regD(regD dst, stackSlotL src) %{
size(4); size(4);
format %{ "LDDF $src,$dst\t! stkL to regD" %} format %{ "LDDF $src,$dst\t! stkL to regD" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk); ins_pipe(floadD_stk);
%} %}
...@@ -5084,7 +5089,7 @@ instruct regF_to_stkI(stackSlotI dst, regF src) %{ ...@@ -5084,7 +5089,7 @@ instruct regF_to_stkI(stackSlotI dst, regF src) %{
size(4); size(4);
format %{ "STF $src,$dst\t! regF to stkI" %} format %{ "STF $src,$dst\t! regF to stkI" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg); ins_pipe(fstoreF_stk_reg);
%} %}
...@@ -5095,7 +5100,7 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{ ...@@ -5095,7 +5100,7 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
size(4); size(4);
format %{ "STDF $src,$dst\t! regD to stkL" %} format %{ "STDF $src,$dst\t! regD to stkL" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg); ins_pipe(fstoreD_stk_reg);
%} %}
...@@ -5106,7 +5111,7 @@ instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{ ...@@ -5106,7 +5111,7 @@ instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
format %{ "STW $src,$dst.hi\t! long\n\t" format %{ "STW $src,$dst.hi\t! long\n\t"
"STW R_G0,$dst.lo" %} "STW R_G0,$dst.lo" %}
opcode(Assembler::stw_op3); 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); ins_pipe(lstoreI_stk_reg);
%} %}
...@@ -5117,7 +5122,7 @@ instruct regL_to_stkD(stackSlotD dst, iRegL src) %{ ...@@ -5117,7 +5122,7 @@ instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
size(4); size(4);
format %{ "STX $src,$dst\t! regL to stkD" %} format %{ "STX $src,$dst\t! regL to stkD" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_stk_reg); ins_pipe(istore_stk_reg);
%} %}
...@@ -5131,7 +5136,7 @@ instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{ ...@@ -5131,7 +5136,7 @@ instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{
size(4); size(4);
format %{ "LDUW $src,$dst\t!stk" %} format %{ "LDUW $src,$dst\t!stk" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode( form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5143,7 +5148,7 @@ instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{ ...@@ -5143,7 +5148,7 @@ instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{
size(4); size(4);
format %{ "STW $src,$dst\t!stk" %} format %{ "STW $src,$dst\t!stk" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5155,7 +5160,7 @@ instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{ ...@@ -5155,7 +5160,7 @@ instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{
size(4); size(4);
format %{ "LDX $src,$dst\t! long" %} format %{ "LDX $src,$dst\t! long" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode( form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5167,7 +5172,7 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{ ...@@ -5167,7 +5172,7 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
size(4); size(4);
format %{ "STX $src,$dst\t! long" %} format %{ "STX $src,$dst\t! long" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5179,7 +5184,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ ...@@ -5179,7 +5184,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
size(4); size(4);
format %{ "LDX $src,$dst\t!ptr" %} format %{ "LDX $src,$dst\t!ptr" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode( form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5190,7 +5195,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ ...@@ -5190,7 +5195,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
size(4); size(4);
format %{ "STX $src,$dst\t!ptr" %} format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
#else // _LP64 #else // _LP64
...@@ -5200,7 +5205,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ ...@@ -5200,7 +5205,7 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
format %{ "LDUW $src,$dst\t!ptr" %} format %{ "LDUW $src,$dst\t!ptr" %}
opcode(Assembler::lduw_op3, Assembler::ldst_op); 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); ins_pipe(iload_mem);
%} %}
...@@ -5210,7 +5215,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ ...@@ -5210,7 +5215,7 @@ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
format %{ "STW $src,$dst\t!ptr" %} format %{ "STW $src,$dst\t!ptr" %}
opcode(Assembler::stw_op3, Assembler::ldst_op); 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); ins_pipe(istore_mem_reg);
%} %}
#endif // _LP64 #endif // _LP64
...@@ -5273,7 +5278,7 @@ instruct loadB(iRegI dst, memory mem) %{ ...@@ -5273,7 +5278,7 @@ instruct loadB(iRegI dst, memory mem) %{
size(4); size(4);
format %{ "LDSB $mem,$dst" %} format %{ "LDSB $mem,$dst" %}
opcode(Assembler::ldsb_op3); opcode(Assembler::ldsb_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5285,7 +5290,7 @@ instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{ ...@@ -5285,7 +5290,7 @@ instruct loadUB(iRegI dst, memory mem, immI_255 bytemask) %{
size(4); size(4);
format %{ "LDUB $mem,$dst" %} format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3); opcode(Assembler::ldub_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5297,7 +5302,7 @@ instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{ ...@@ -5297,7 +5302,7 @@ instruct loadUBL(iRegL dst, memory mem, immL_FF bytemask) %{
size(4); size(4);
format %{ "LDUB $mem,$dst" %} format %{ "LDUB $mem,$dst" %}
opcode(Assembler::ldub_op3); opcode(Assembler::ldub_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5309,7 +5314,7 @@ instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{ ...@@ -5309,7 +5314,7 @@ instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{
size(4); size(4);
format %{ "LDUH $mem,$dst" %} format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3); opcode(Assembler::lduh_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5321,7 +5326,7 @@ instruct loadC(iRegI dst, memory mem) %{ ...@@ -5321,7 +5326,7 @@ instruct loadC(iRegI dst, memory mem) %{
size(4); size(4);
format %{ "LDUH $mem,$dst" %} format %{ "LDUH $mem,$dst" %}
opcode(Assembler::lduh_op3); opcode(Assembler::lduh_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5333,7 +5338,7 @@ instruct loadI(iRegI dst, memory mem) %{ ...@@ -5333,7 +5338,7 @@ instruct loadI(iRegI dst, memory mem) %{
format %{ "LDUW $mem,$dst" %} format %{ "LDUW $mem,$dst" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5344,7 +5349,7 @@ instruct loadL(iRegL dst, memory mem ) %{ ...@@ -5344,7 +5349,7 @@ instruct loadL(iRegL dst, memory mem ) %{
size(4); size(4);
format %{ "LDX $mem,$dst\t! long" %} format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5359,7 +5364,7 @@ instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{ ...@@ -5359,7 +5364,7 @@ instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{
"\tSLLX #32, $dst, $dst\n" "\tSLLX #32, $dst, $dst\n"
"\tOR $dst, R_O7, $dst" %} "\tOR $dst, R_O7, $dst" %}
opcode(Assembler::lduw_op3); 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); ins_pipe(iload_mem);
%} %}
...@@ -5370,7 +5375,7 @@ instruct loadA8B(regD dst, memory mem) %{ ...@@ -5370,7 +5375,7 @@ instruct loadA8B(regD dst, memory mem) %{
size(4); size(4);
format %{ "LDDF $mem,$dst\t! packed8B" %} format %{ "LDDF $mem,$dst\t! packed8B" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem); ins_pipe(floadD_mem);
%} %}
...@@ -5381,7 +5386,7 @@ instruct loadA4C(regD dst, memory mem) %{ ...@@ -5381,7 +5386,7 @@ instruct loadA4C(regD dst, memory mem) %{
size(4); size(4);
format %{ "LDDF $mem,$dst\t! packed4C" %} format %{ "LDDF $mem,$dst\t! packed4C" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem); ins_pipe(floadD_mem);
%} %}
...@@ -5392,7 +5397,7 @@ instruct loadA4S(regD dst, memory mem) %{ ...@@ -5392,7 +5397,7 @@ instruct loadA4S(regD dst, memory mem) %{
size(4); size(4);
format %{ "LDDF $mem,$dst\t! packed4S" %} format %{ "LDDF $mem,$dst\t! packed4S" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem); ins_pipe(floadD_mem);
%} %}
...@@ -5403,7 +5408,7 @@ instruct loadA2I(regD dst, memory mem) %{ ...@@ -5403,7 +5408,7 @@ instruct loadA2I(regD dst, memory mem) %{
size(4); size(4);
format %{ "LDDF $mem,$dst\t! packed2I" %} format %{ "LDDF $mem,$dst\t! packed2I" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem); ins_pipe(floadD_mem);
%} %}
...@@ -5415,7 +5420,7 @@ instruct loadRange(iRegI dst, memory mem) %{ ...@@ -5415,7 +5420,7 @@ instruct loadRange(iRegI dst, memory mem) %{
size(4); size(4);
format %{ "LDUW $mem,$dst\t! range" %} format %{ "LDUW $mem,$dst\t! range" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -5427,7 +5432,7 @@ instruct loadI_freg(regF dst, memory mem) %{ ...@@ -5427,7 +5432,7 @@ instruct loadI_freg(regF dst, memory mem) %{
format %{ "LDF $mem,$dst\t! for fitos/fitod" %} format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem); ins_pipe(floadF_mem);
%} %}
...@@ -5514,7 +5519,7 @@ instruct loadS(iRegI dst, memory mem) %{ ...@@ -5514,7 +5519,7 @@ instruct loadS(iRegI dst, memory mem) %{
size(4); size(4);
format %{ "LDSH $mem,$dst" %} format %{ "LDSH $mem,$dst" %}
opcode(Assembler::ldsh_op3); opcode(Assembler::ldsh_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mask_mem); ins_pipe(iload_mask_mem);
%} %}
...@@ -5526,7 +5531,7 @@ instruct loadD(regD dst, memory mem) %{ ...@@ -5526,7 +5531,7 @@ instruct loadD(regD dst, memory mem) %{
size(4); size(4);
format %{ "LDDF $mem,$dst" %} format %{ "LDDF $mem,$dst" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadD_mem); ins_pipe(floadD_mem);
%} %}
...@@ -5550,7 +5555,7 @@ instruct loadF(regF dst, memory mem) %{ ...@@ -5550,7 +5555,7 @@ instruct loadF(regF dst, memory mem) %{
size(4); size(4);
format %{ "LDF $mem,$dst" %} format %{ "LDF $mem,$dst" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(floadF_mem); ins_pipe(floadF_mem);
%} %}
...@@ -5719,7 +5724,7 @@ instruct storeB(memory mem, iRegI src) %{ ...@@ -5719,7 +5724,7 @@ instruct storeB(memory mem, iRegI src) %{
size(4); size(4);
format %{ "STB $src,$mem\t! byte" %} format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3); opcode(Assembler::stb_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5730,7 +5735,7 @@ instruct storeB0(memory mem, immI0 src) %{ ...@@ -5730,7 +5735,7 @@ instruct storeB0(memory mem, immI0 src) %{
size(4); size(4);
format %{ "STB $src,$mem\t! byte" %} format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3); 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); ins_pipe(istore_mem_zero);
%} %}
...@@ -5741,7 +5746,7 @@ instruct storeCM0(memory mem, immI0 src) %{ ...@@ -5741,7 +5746,7 @@ instruct storeCM0(memory mem, immI0 src) %{
size(4); size(4);
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %} format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
opcode(Assembler::stb_op3); 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); ins_pipe(istore_mem_zero);
%} %}
...@@ -5753,7 +5758,7 @@ instruct storeC(memory mem, iRegI src) %{ ...@@ -5753,7 +5758,7 @@ instruct storeC(memory mem, iRegI src) %{
size(4); size(4);
format %{ "STH $src,$mem\t! short" %} format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3); opcode(Assembler::sth_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5764,7 +5769,7 @@ instruct storeC0(memory mem, immI0 src) %{ ...@@ -5764,7 +5769,7 @@ instruct storeC0(memory mem, immI0 src) %{
size(4); size(4);
format %{ "STH $src,$mem\t! short" %} format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3); 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); ins_pipe(istore_mem_zero);
%} %}
...@@ -5776,7 +5781,7 @@ instruct storeI(memory mem, iRegI src) %{ ...@@ -5776,7 +5781,7 @@ instruct storeI(memory mem, iRegI src) %{
size(4); size(4);
format %{ "STW $src,$mem" %} format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5787,7 +5792,7 @@ instruct storeL(memory mem, iRegL src) %{ ...@@ -5787,7 +5792,7 @@ instruct storeL(memory mem, iRegL src) %{
size(4); size(4);
format %{ "STX $src,$mem\t! long" %} format %{ "STX $src,$mem\t! long" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -5798,7 +5803,7 @@ instruct storeI0(memory mem, immI0 src) %{ ...@@ -5798,7 +5803,7 @@ instruct storeI0(memory mem, immI0 src) %{
size(4); size(4);
format %{ "STW $src,$mem" %} format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3); 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); ins_pipe(istore_mem_zero);
%} %}
...@@ -5809,7 +5814,7 @@ instruct storeL0(memory mem, immL0 src) %{ ...@@ -5809,7 +5814,7 @@ instruct storeL0(memory mem, immL0 src) %{
size(4); size(4);
format %{ "STX $src,$mem" %} format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3); 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); ins_pipe(istore_mem_zero);
%} %}
...@@ -5821,7 +5826,7 @@ instruct storeI_Freg(memory mem, regF src) %{ ...@@ -5821,7 +5826,7 @@ instruct storeI_Freg(memory mem, regF src) %{
size(4); size(4);
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %} format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg); ins_pipe(fstoreF_mem_reg);
%} %}
...@@ -5904,7 +5909,7 @@ instruct storeD( memory mem, regD src) %{ ...@@ -5904,7 +5909,7 @@ instruct storeD( memory mem, regD src) %{
size(4); size(4);
format %{ "STDF $src,$mem" %} format %{ "STDF $src,$mem" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg); ins_pipe(fstoreD_mem_reg);
%} %}
...@@ -5915,7 +5920,7 @@ instruct storeD0( memory mem, immD0 src) %{ ...@@ -5915,7 +5920,7 @@ instruct storeD0( memory mem, immD0 src) %{
size(4); size(4);
format %{ "STX $src,$mem" %} format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3); 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); ins_pipe(fstoreD_mem_zero);
%} %}
...@@ -5927,7 +5932,7 @@ instruct storeF( memory mem, regF src) %{ ...@@ -5927,7 +5932,7 @@ instruct storeF( memory mem, regF src) %{
size(4); size(4);
format %{ "STF $src,$mem" %} format %{ "STF $src,$mem" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreF_mem_reg); ins_pipe(fstoreF_mem_reg);
%} %}
...@@ -5938,7 +5943,7 @@ instruct storeF0( memory mem, immF0 src) %{ ...@@ -5938,7 +5943,7 @@ instruct storeF0( memory mem, immF0 src) %{
size(4); size(4);
format %{ "STW $src,$mem\t! storeF0" %} format %{ "STW $src,$mem\t! storeF0" %}
opcode(Assembler::stw_op3); 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); ins_pipe(fstoreF_mem_zero);
%} %}
...@@ -5949,7 +5954,7 @@ instruct storeA8B(memory mem, regD src) %{ ...@@ -5949,7 +5954,7 @@ instruct storeA8B(memory mem, regD src) %{
size(4); size(4);
format %{ "STDF $src,$mem\t! packed8B" %} format %{ "STDF $src,$mem\t! packed8B" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg); ins_pipe(fstoreD_mem_reg);
%} %}
...@@ -6004,7 +6009,7 @@ instruct storeA8B0(memory mem, immI0 zero) %{ ...@@ -6004,7 +6009,7 @@ instruct storeA8B0(memory mem, immI0 zero) %{
size(4); size(4);
format %{ "STX $zero,$mem\t! packed8B" %} format %{ "STX $zero,$mem\t! packed8B" %}
opcode(Assembler::stx_op3); 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); ins_pipe(fstoreD_mem_zero);
%} %}
...@@ -6015,7 +6020,7 @@ instruct storeA4C(memory mem, regD src) %{ ...@@ -6015,7 +6020,7 @@ instruct storeA4C(memory mem, regD src) %{
size(4); size(4);
format %{ "STDF $src,$mem\t! packed4C" %} format %{ "STDF $src,$mem\t! packed4C" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg); ins_pipe(fstoreD_mem_reg);
%} %}
...@@ -6026,7 +6031,7 @@ instruct storeA4C0(memory mem, immI0 zero) %{ ...@@ -6026,7 +6031,7 @@ instruct storeA4C0(memory mem, immI0 zero) %{
size(4); size(4);
format %{ "STX $zero,$mem\t! packed4C" %} format %{ "STX $zero,$mem\t! packed4C" %}
opcode(Assembler::stx_op3); 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); ins_pipe(fstoreD_mem_zero);
%} %}
...@@ -6037,7 +6042,7 @@ instruct storeA2I(memory mem, regD src) %{ ...@@ -6037,7 +6042,7 @@ instruct storeA2I(memory mem, regD src) %{
size(4); size(4);
format %{ "STDF $src,$mem\t! packed2I" %} format %{ "STDF $src,$mem\t! packed2I" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode( form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg); ins_pipe(fstoreD_mem_reg);
%} %}
...@@ -6048,7 +6053,7 @@ instruct storeA2I0(memory mem, immI0 zero) %{ ...@@ -6048,7 +6053,7 @@ instruct storeA2I0(memory mem, immI0 zero) %{
size(4); size(4);
format %{ "STX $zero,$mem\t! packed2I" %} format %{ "STX $zero,$mem\t! packed2I" %}
opcode(Assembler::stx_op3); 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); ins_pipe(fstoreD_mem_zero);
%} %}
...@@ -6162,7 +6167,7 @@ instruct stfSSD(stackSlotD stkSlot, regD src) %{ ...@@ -6162,7 +6167,7 @@ instruct stfSSD(stackSlotD stkSlot, regD src) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
format %{ "STDF $src,$stkSlot\t!stk" %} format %{ "STDF $src,$stkSlot\t!stk" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(form3_mem_reg(stkSlot, src)); ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreD_stk_reg); ins_pipe(fstoreD_stk_reg);
%} %}
...@@ -6172,7 +6177,7 @@ instruct ldfSSD(regD dst, stackSlotD stkSlot) %{ ...@@ -6172,7 +6177,7 @@ instruct ldfSSD(regD dst, stackSlotD stkSlot) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
format %{ "LDDF $stkSlot,$dst\t!stk" %} format %{ "LDDF $stkSlot,$dst\t!stk" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(form3_mem_reg(stkSlot, dst)); ins_encode(simple_form3_mem_reg(stkSlot, dst));
ins_pipe(floadD_stk); ins_pipe(floadD_stk);
%} %}
...@@ -6182,7 +6187,7 @@ instruct stfSSF(stackSlotF stkSlot, regF src) %{ ...@@ -6182,7 +6187,7 @@ instruct stfSSF(stackSlotF stkSlot, regF src) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
format %{ "STF $src,$stkSlot\t!stk" %} format %{ "STF $src,$stkSlot\t!stk" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(form3_mem_reg(stkSlot, src)); ins_encode(simple_form3_mem_reg(stkSlot, src));
ins_pipe(fstoreF_stk_reg); ins_pipe(fstoreF_stk_reg);
%} %}
...@@ -6584,7 +6589,7 @@ instruct loadLLocked(iRegL dst, memory mem) %{ ...@@ -6584,7 +6589,7 @@ instruct loadLLocked(iRegL dst, memory mem) %{
size(4); size(4);
format %{ "LDX $mem,$dst\t! long" %} format %{ "LDX $mem,$dst\t! long" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode( form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -7666,7 +7671,7 @@ instruct convI2D_mem( regD_low dst, memory mem ) %{ ...@@ -7666,7 +7671,7 @@ instruct convI2D_mem( regD_low dst, memory mem ) %{
format %{ "LDF $mem,$dst\n\t" format %{ "LDF $mem,$dst\n\t"
"FITOD $dst,$dst" %} "FITOD $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitod_opf); 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); ins_pipe(floadF_mem);
%} %}
...@@ -7696,7 +7701,7 @@ instruct convI2F_mem( regF dst, memory mem ) %{ ...@@ -7696,7 +7701,7 @@ instruct convI2F_mem( regF dst, memory mem ) %{
format %{ "LDF $mem,$dst\n\t" format %{ "LDF $mem,$dst\n\t"
"FITOS $dst,$dst" %} "FITOS $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitos_opf); 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); ins_pipe(floadF_mem);
%} %}
...@@ -7738,7 +7743,7 @@ instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{ ...@@ -7738,7 +7743,7 @@ instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
size(4); size(4);
format %{ "LDUW $src,$dst\t! MoveF2I" %} format %{ "LDUW $src,$dst\t! MoveF2I" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode( form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -7750,7 +7755,7 @@ instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ ...@@ -7750,7 +7755,7 @@ instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
size(4); size(4);
format %{ "LDF $src,$dst\t! MoveI2F" %} format %{ "LDF $src,$dst\t! MoveI2F" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode(form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadF_stk); ins_pipe(floadF_stk);
%} %}
...@@ -7762,7 +7767,7 @@ instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{ ...@@ -7762,7 +7767,7 @@ instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
size(4); size(4);
format %{ "LDX $src,$dst\t! MoveD2L" %} format %{ "LDX $src,$dst\t! MoveD2L" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode( form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
...@@ -7774,7 +7779,7 @@ instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ ...@@ -7774,7 +7779,7 @@ instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
size(4); size(4);
format %{ "LDDF $src,$dst\t! MoveL2D" %} format %{ "LDDF $src,$dst\t! MoveL2D" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
ins_pipe(floadD_stk); ins_pipe(floadD_stk);
%} %}
...@@ -7786,7 +7791,7 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ ...@@ -7786,7 +7791,7 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
size(4); size(4);
format %{ "STF $src,$dst\t!MoveF2I" %} format %{ "STF $src,$dst\t!MoveF2I" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreF_stk_reg); ins_pipe(fstoreF_stk_reg);
%} %}
...@@ -7798,7 +7803,7 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ ...@@ -7798,7 +7803,7 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
size(4); size(4);
format %{ "STW $src,$dst\t!MoveI2F" %} format %{ "STW $src,$dst\t!MoveI2F" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
...@@ -7810,7 +7815,7 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ ...@@ -7810,7 +7815,7 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
size(4); size(4);
format %{ "STDF $src,$dst\t!MoveD2L" %} format %{ "STDF $src,$dst\t!MoveD2L" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
ins_pipe(fstoreD_stk_reg); ins_pipe(fstoreD_stk_reg);
%} %}
...@@ -7822,7 +7827,7 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ ...@@ -7822,7 +7827,7 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
size(4); size(4);
format %{ "STX $src,$dst\t!MoveL2D" %} format %{ "STX $src,$dst\t!MoveL2D" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode( form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
ins_pipe(istore_mem_reg); ins_pipe(istore_mem_reg);
%} %}
......
...@@ -495,8 +495,8 @@ void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { ...@@ -495,8 +495,8 @@ void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) {
void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
Compile* C = ra_->C; Compile* C = ra_->C;
if( C->in_24_bit_fp_mode() ) { if( C->in_24_bit_fp_mode() ) {
tty->print("FLDCW 24 bit fpu control word"); st->print("FLDCW 24 bit fpu control word");
tty->print_cr(""); tty->print("\t"); st->print_cr(""); st->print("\t");
} }
int framesize = C->frame_slots() << LogBytesPerInt; int framesize = C->frame_slots() << LogBytesPerInt;
...@@ -510,22 +510,22 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { ...@@ -510,22 +510,22 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
// stack. But the stack safety zone should account for that. // stack. But the stack safety zone should account for that.
// See bugs 4446381, 4468289, 4497237. // See bugs 4446381, 4468289, 4497237.
if (C->need_stack_bang(framesize)) { if (C->need_stack_bang(framesize)) {
tty->print_cr("# stack bang"); tty->print("\t"); st->print_cr("# stack bang"); st->print("\t");
} }
tty->print_cr("PUSHL EBP"); tty->print("\t"); st->print_cr("PUSHL EBP"); st->print("\t");
if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
tty->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check"); st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check");
tty->print_cr(""); tty->print("\t"); st->print_cr(""); st->print("\t");
framesize -= wordSize; framesize -= wordSize;
} }
if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
if (framesize) { if (framesize) {
tty->print("SUB ESP,%d\t# Create frame",framesize); st->print("SUB ESP,%d\t# Create frame",framesize);
} }
} else { } else {
tty->print("SUB ESP,%d\t# Create frame",framesize); st->print("SUB ESP,%d\t# Create frame",framesize);
} }
} }
#endif #endif
...@@ -725,18 +725,19 @@ static enum RC rc_class( OptoReg::Name reg ) { ...@@ -725,18 +725,19 @@ static enum RC rc_class( OptoReg::Name reg ) {
return rc_xmm; return rc_xmm;
} }
static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) { static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
int opcode, const char *op_str, int size, outputStream* st ) {
if( cbuf ) { if( cbuf ) {
emit_opcode (*cbuf, opcode ); emit_opcode (*cbuf, opcode );
encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false); encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
if( opcode == 0x8B || opcode == 0x89 ) { // MOV if( opcode == 0x8B || opcode == 0x89 ) { // MOV
if( is_load ) tty->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset); if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
else tty->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]); else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
} else { // FLD, FST, PUSH, POP } else { // FLD, FST, PUSH, POP
tty->print("%s [ESP + #%d]",op_str,offset); st->print("%s [ESP + #%d]",op_str,offset);
} }
#endif #endif
} }
...@@ -746,7 +747,7 @@ static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset ...@@ -746,7 +747,7 @@ static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset
// Helper for XMM registers. Extra opcode bits, limited syntax. // Helper for XMM registers. Extra opcode bits, limited syntax.
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
int offset, int reg_lo, int reg_hi, int size ) { int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
if( cbuf ) { if( cbuf ) {
if( reg_lo+1 == reg_hi ) { // double move? if( reg_lo+1 == reg_hi ) { // double move?
if( is_load && !UseXmmLoadAndClearUpper ) if( is_load && !UseXmmLoadAndClearUpper )
...@@ -764,17 +765,17 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, ...@@ -764,17 +765,17 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false); encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
if( reg_lo+1 == reg_hi ) { // double move? if( reg_lo+1 == reg_hi ) { // double move?
if( is_load ) tty->print("%s %s,[ESP + #%d]", if( is_load ) st->print("%s %s,[ESP + #%d]",
UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD", UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
Matcher::regName[reg_lo], offset); Matcher::regName[reg_lo], offset);
else tty->print("MOVSD [ESP + #%d],%s", else st->print("MOVSD [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]); offset, Matcher::regName[reg_lo]);
} else { } else {
if( is_load ) tty->print("MOVSS %s,[ESP + #%d]", if( is_load ) st->print("MOVSS %s,[ESP + #%d]",
Matcher::regName[reg_lo], offset); Matcher::regName[reg_lo], offset);
else tty->print("MOVSS [ESP + #%d],%s", else st->print("MOVSS [ESP + #%d],%s",
offset, Matcher::regName[reg_lo]); offset, Matcher::regName[reg_lo]);
} }
#endif #endif
...@@ -785,7 +786,7 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, ...@@ -785,7 +786,7 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
int src_hi, int dst_hi, int size ) { int src_hi, int dst_hi, int size, outputStream* st ) {
if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
if( cbuf ) { if( cbuf ) {
if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) { if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
...@@ -796,11 +797,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst ...@@ -796,11 +797,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else { } else {
tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} }
#endif #endif
} }
...@@ -813,11 +814,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst ...@@ -813,11 +814,11 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
tty->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} else { } else {
tty->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
} }
#endif #endif
} }
...@@ -825,28 +826,29 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst ...@@ -825,28 +826,29 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
} }
} }
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) { static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
if( cbuf ) { if( cbuf ) {
emit_opcode(*cbuf, 0x8B ); emit_opcode(*cbuf, 0x8B );
emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] ); emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
tty->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]); st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]);
#endif #endif
} }
return size+2; return size+2;
} }
static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) { static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
int offset, int size, outputStream* st ) {
if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there
if( cbuf ) { if( cbuf ) {
emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it) emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it)
emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] ); emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else if( !do_size ) {
if( size != 0 ) tty->print("\n\t"); if( size != 0 ) st->print("\n\t");
tty->print("FLD %s",Matcher::regName[src_lo]); st->print("FLD %s",Matcher::regName[src_lo]);
#endif #endif
} }
size += 2; size += 2;
...@@ -864,7 +866,7 @@ static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int ...@@ -864,7 +866,7 @@ static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int
assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" ); assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
} }
return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size); return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
} }
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const { uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
...@@ -892,16 +894,16 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -892,16 +894,16 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
if( src_second == dst_first ) { // overlapping stack copy ranges if( src_second == dst_first ) { // overlapping stack copy ranges
assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" ); assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size); size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size); size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
} }
// move low bits // move low bits
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size); size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size); size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size); size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size); size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
} }
return size; return size;
} }
...@@ -909,15 +911,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -909,15 +911,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
// -------------------------------------- // --------------------------------------
// Check for integer reg-reg copy // Check for integer reg-reg copy
if( src_first_rc == rc_int && dst_first_rc == rc_int ) if( src_first_rc == rc_int && dst_first_rc == rc_int )
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size); size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
// Check for integer store // Check for integer store
if( src_first_rc == rc_int && dst_first_rc == rc_stack ) if( src_first_rc == rc_int && dst_first_rc == rc_stack )
size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size); size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
// Check for integer load // Check for integer load
if( dst_first_rc == rc_int && src_first_rc == rc_stack ) if( dst_first_rc == rc_int && src_first_rc == rc_stack )
size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size); size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
// -------------------------------------- // --------------------------------------
// Check for float reg-reg copy // Check for float reg-reg copy
...@@ -951,7 +953,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -951,7 +953,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
// Check for float store // Check for float store
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size); return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
} }
// Check for float load // Check for float load
...@@ -987,17 +989,17 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -987,17 +989,17 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
(src_first+1 == src_second && dst_first+1 == dst_second), (src_first+1 == src_second && dst_first+1 == dst_second),
"no non-adjacent float-moves" ); "no non-adjacent float-moves" );
return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size); return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
} }
// Check for xmm store // Check for xmm store
if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size); return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
} }
// Check for float xmm load // Check for float xmm load
if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) { if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size); return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
} }
// Copy from float reg to xmm reg // Copy from float reg to xmm reg
...@@ -1017,10 +1019,10 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -1017,10 +1019,10 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
} }
size += 4; size += 4;
size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size); size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
// Copy from the temp memory to the xmm reg. // Copy from the temp memory to the xmm reg.
size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size); size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
if( cbuf ) { if( cbuf ) {
emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8] emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8]
...@@ -1047,15 +1049,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo ...@@ -1047,15 +1049,15 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
// Check for second word int-int move // Check for second word int-int move
if( src_second_rc == rc_int && dst_second_rc == rc_int ) if( src_second_rc == rc_int && dst_second_rc == rc_int )
return impl_mov_helper(cbuf,do_size,src_second,dst_second,size); return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
// Check for second word integer store // Check for second word integer store
if( src_second_rc == rc_int && dst_second_rc == rc_stack ) if( src_second_rc == rc_int && dst_second_rc == rc_stack )
return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size); return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
// Check for second word integer load // Check for second word integer load
if( dst_second_rc == rc_int && src_second_rc == rc_stack ) if( dst_second_rc == rc_int && src_second_rc == rc_stack )
return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size); return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
Unimplemented(); Unimplemented();
...@@ -1318,7 +1320,11 @@ const uint Matcher::vector_ideal_reg(void) { ...@@ -1318,7 +1320,11 @@ const uint Matcher::vector_ideal_reg(void) {
// //
// NOTE: If the platform does not provide any short branch variants, then // NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0. // 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) {
// the short version of jmpConUCF2 contains multiple branches,
// making the reach slightly less
if (rule == jmpConUCF2_rule)
return (-126 <= offset && offset <= 125);
return (-128 <= offset && offset <= 127); return (-128 <= offset && offset <= 127);
} }
...@@ -5272,6 +5278,15 @@ operand eFlagsRegU() %{ ...@@ -5272,6 +5278,15 @@ operand eFlagsRegU() %{
interface(REG_INTER); interface(REG_INTER);
%} %}
operand eFlagsRegUCF() %{
constraint(ALLOC_IN_RC(int_flags));
match(RegFlags);
predicate(false);
format %{ "EFLAGS_U_CF" %}
interface(REG_INTER);
%}
// Condition Code Register used by long compare // Condition Code Register used by long compare
operand flagsReg_long_LTGE() %{ operand flagsReg_long_LTGE() %{
constraint(ALLOC_IN_RC(int_flags)); constraint(ALLOC_IN_RC(int_flags));
...@@ -5749,12 +5764,12 @@ operand cmpOp() %{ ...@@ -5749,12 +5764,12 @@ operand cmpOp() %{
format %{ "" %} format %{ "" %}
interface(COND_INTER) %{ interface(COND_INTER) %{
equal(0x4); equal(0x4, "e");
not_equal(0x5); not_equal(0x5, "ne");
less(0xC); less(0xC, "l");
greater_equal(0xD); greater_equal(0xD, "ge");
less_equal(0xE); less_equal(0xE, "le");
greater(0xF); greater(0xF, "g");
%} %}
%} %}
...@@ -5766,12 +5781,47 @@ operand cmpOpU() %{ ...@@ -5766,12 +5781,47 @@ operand cmpOpU() %{
format %{ "" %} format %{ "" %}
interface(COND_INTER) %{ interface(COND_INTER) %{
equal(0x4); equal(0x4, "e");
not_equal(0x5); not_equal(0x5, "ne");
less(0x2); less(0x2, "b");
greater_equal(0x3); greater_equal(0x3, "nb");
less_equal(0x6); less_equal(0x6, "be");
greater(0x7); greater(0x7, "nbe");
%}
%}
// Floating comparisons that don't require any fixup for the unordered case
operand cmpOpUCF() %{
match(Bool);
predicate(n->as_Bool()->_test._test == BoolTest::lt ||
n->as_Bool()->_test._test == BoolTest::ge ||
n->as_Bool()->_test._test == BoolTest::le ||
n->as_Bool()->_test._test == BoolTest::gt);
format %{ "" %}
interface(COND_INTER) %{
equal(0x4, "e");
not_equal(0x5, "ne");
less(0x2, "b");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
%}
%}
// Floating comparisons that can be fixed up with extra conditional jumps
operand cmpOpUCF2() %{
match(Bool);
predicate(n->as_Bool()->_test._test == BoolTest::ne ||
n->as_Bool()->_test._test == BoolTest::eq);
format %{ "" %}
interface(COND_INTER) %{
equal(0x4, "e");
not_equal(0x5, "ne");
less(0x2, "b");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
%} %}
%} %}
...@@ -5796,12 +5846,12 @@ operand cmpOp_commute() %{ ...@@ -5796,12 +5846,12 @@ operand cmpOp_commute() %{
format %{ "" %} format %{ "" %}
interface(COND_INTER) %{ interface(COND_INTER) %{
equal(0x4); equal(0x4, "e");
not_equal(0x5); not_equal(0x5, "ne");
less(0xF); less(0xF, "g");
greater_equal(0xE); greater_equal(0xE, "le");
less_equal(0xD); less_equal(0xD, "ge");
greater(0xC); greater(0xC, "l");
%} %}
%} %}
...@@ -7357,7 +7407,7 @@ instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{ ...@@ -7357,7 +7407,7 @@ instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
ins_pipe( pipe_cmov_reg ); ins_pipe( pipe_cmov_reg );
%} %}
instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{ instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200); ins_cost(200);
...@@ -7367,6 +7417,15 @@ instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{ ...@@ -7367,6 +7417,15 @@ instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
ins_pipe( pipe_cmov_reg ); ins_pipe( pipe_cmov_reg );
%} %}
instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovI_regU(cop, cr, dst, src);
%}
%}
// Conditional move // Conditional move
instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{ instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
...@@ -7379,7 +7438,7 @@ instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{ ...@@ -7379,7 +7438,7 @@ instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
%} %}
// Conditional move // Conditional move
instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{ instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250); ins_cost(250);
...@@ -7389,6 +7448,15 @@ instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{ ...@@ -7389,6 +7448,15 @@ instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
ins_pipe( pipe_cmov_mem ); ins_pipe( pipe_cmov_mem );
%} %}
instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250);
expand %{
cmovI_memU(cop, cr, dst, src);
%}
%}
// Conditional move // Conditional move
instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
...@@ -7416,7 +7484,7 @@ instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ ...@@ -7416,7 +7484,7 @@ instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
%} %}
// Conditional move // Conditional move
instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{ instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
ins_cost(200); ins_cost(200);
...@@ -7426,6 +7494,15 @@ instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{ ...@@ -7426,6 +7494,15 @@ instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
ins_pipe( pipe_cmov_reg ); ins_pipe( pipe_cmov_reg );
%} %}
instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovP_regU(cop, cr, dst, src);
%}
%}
// DISABLED: Requires the ADLC to emit a bottom_type call that // DISABLED: Requires the ADLC to emit a bottom_type call that
// correctly meets the two pointer arguments; one is an incoming // correctly meets the two pointer arguments; one is an incoming
// register but the other is a memory operand. ALSO appears to // register but the other is a memory operand. ALSO appears to
...@@ -7555,6 +7632,15 @@ instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{ ...@@ -7555,6 +7632,15 @@ instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
predicate (UseSSE>=1);
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
fcmovX_regU(cop, cr, dst, src);
%}
%}
// unsigned version // unsigned version
instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{ instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
predicate (UseSSE>=2); predicate (UseSSE>=2);
...@@ -7573,6 +7659,15 @@ instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{ ...@@ -7573,6 +7659,15 @@ instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
predicate (UseSSE>=2);
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
fcmovXD_regU(cop, cr, dst, src);
%}
%}
instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{ instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
predicate(VM_Version::supports_cmov() ); predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
...@@ -7595,6 +7690,15 @@ instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{ ...@@ -7595,6 +7690,15 @@ instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{
ins_pipe( pipe_cmov_reg_long ); ins_pipe( pipe_cmov_reg_long );
%} %}
instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
predicate(VM_Version::supports_cmov() );
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovL_regU(cop, cr, dst, src);
%}
%}
//----------Arithmetic Instructions-------------------------------------------- //----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions---------------------------------------------- //----------Addition Instructions----------------------------------------------
// Integer Addition Instructions // Integer Addition Instructions
...@@ -9200,6 +9304,18 @@ instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{ ...@@ -9200,6 +9304,18 @@ instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
predicate(VM_Version::supports_cmov() && UseSSE <=1);
match(Set cr (CmpD src1 src2));
ins_cost(150);
format %{ "FLD $src1\n\t"
"FUCOMIP ST,$src2 // P6 instruction" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
ins_encode( Push_Reg_D(src1),
OpcP, RegOpc(src2));
ins_pipe( pipe_slow );
%}
// Compare & branch // Compare & branch
instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{ instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
predicate(UseSSE<=1); predicate(UseSSE<=1);
...@@ -9264,6 +9380,16 @@ instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{ ...@@ -9264,6 +9380,16 @@ instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
predicate(UseSSE>=2);
match(Set cr (CmpD dst src));
ins_cost(100);
format %{ "COMISD $dst,$src" %}
opcode(0x66, 0x0F, 0x2F);
ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs // float compare and set condition codes in EFLAGS by XMM regs
instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{ instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=2); predicate(UseSSE>=2);
...@@ -9280,6 +9406,16 @@ instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{ ...@@ -9280,6 +9406,16 @@ instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
predicate(UseSSE>=2);
match(Set cr (CmpD dst (LoadD src)));
ins_cost(100);
format %{ "COMISD $dst,$src" %}
opcode(0x66, 0x0F, 0x2F);
ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM // Compare into -1,0,1 in XMM
instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{ instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
predicate(UseSSE>=2); predicate(UseSSE>=2);
...@@ -10167,6 +10303,18 @@ instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{ ...@@ -10167,6 +10303,18 @@ instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
predicate(VM_Version::supports_cmov() && UseSSE == 0);
match(Set cr (CmpF src1 src2));
ins_cost(100);
format %{ "FLD $src1\n\t"
"FUCOMIP ST,$src2 // P6 instruction" %}
opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
ins_encode( Push_Reg_D(src1),
OpcP, RegOpc(src2));
ins_pipe( pipe_slow );
%}
// Compare & branch // Compare & branch
instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{ instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
...@@ -10232,6 +10380,16 @@ instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{ ...@@ -10232,6 +10380,16 @@ instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
predicate(UseSSE>=1);
match(Set cr (CmpF dst src));
ins_cost(100);
format %{ "COMISS $dst,$src" %}
opcode(0x0F, 0x2F);
ins_encode(OpcP, OpcS, RegReg(dst, src));
ins_pipe( pipe_slow );
%}
// float compare and set condition codes in EFLAGS by XMM regs // float compare and set condition codes in EFLAGS by XMM regs
instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{ instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
predicate(UseSSE>=1); predicate(UseSSE>=1);
...@@ -10248,6 +10406,16 @@ instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{ ...@@ -10248,6 +10406,16 @@ instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
predicate(UseSSE>=1);
match(Set cr (CmpF dst (LoadF src)));
ins_cost(100);
format %{ "COMISS $dst,$src" %}
opcode(0x0F, 0x2F);
ins_encode(OpcP, OpcS, RegMem(dst, src));
ins_pipe( pipe_slow );
%}
// Compare into -1,0,1 in XMM // Compare into -1,0,1 in XMM
instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{ instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
predicate(UseSSE>=1); predicate(UseSSE>=1);
...@@ -12099,6 +12267,19 @@ instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ ...@@ -12099,6 +12267,19 @@ instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_pc_relative(1); ins_pc_relative(1);
%} %}
instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
ins_cost(200);
format %{ "J$cop,u $labl\t# Loop end" %}
size(6);
opcode(0x0F, 0x80);
ins_encode( Jcc( cop, labl) );
ins_pipe( pipe_jcc );
ins_pc_relative(1);
%}
// Jump Direct Conditional - using unsigned comparison // Jump Direct Conditional - using unsigned comparison
instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
match(If cop cmp); match(If cop cmp);
...@@ -12108,8 +12289,63 @@ instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ ...@@ -12108,8 +12289,63 @@ instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
format %{ "J$cop,u $labl" %} format %{ "J$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); opcode(0x0F, 0x80);
ins_encode( Jcc( cop, labl) ); ins_encode(Jcc(cop, labl));
ins_pipe( pipe_jcc ); ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(200);
format %{ "J$cop,u $labl" %}
size(6);
opcode(0x0F, 0x80);
ins_encode(Jcc(cop, labl));
ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(200);
format %{ $$template
if ($cop$$cmpcode == Assembler::notEqual) {
$$emit$$"JP,u $labl\n\t"
$$emit$$"J$cop,u $labl"
} else {
$$emit$$"JP,u done\n\t"
$$emit$$"J$cop,u $labl\n\t"
$$emit$$"done:"
}
%}
size(12);
opcode(0x0F, 0x80);
ins_encode %{
Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, Assembler::parity);
int parity_disp = -1;
bool ok = false;
if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6;
ok = true;
} else {
ShouldNotReachHere();
}
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
emit_d32(cbuf, disp);
%}
ins_pipe(pipe_jcc);
ins_pc_relative(1); ins_pc_relative(1);
%} %}
...@@ -12208,7 +12444,7 @@ instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{ ...@@ -12208,7 +12444,7 @@ instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{
effect(USE labl); effect(USE labl);
ins_cost(300); ins_cost(300);
format %{ "J$cop,s $labl" %} format %{ "J$cop,s $labl\t# Loop end" %}
size(2); size(2);
opcode(0x70); opcode(0x70);
ins_encode( JccShort( cop, labl) ); ins_encode( JccShort( cop, labl) );
...@@ -12223,7 +12459,21 @@ instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ ...@@ -12223,7 +12459,21 @@ instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
effect(USE labl); effect(USE labl);
ins_cost(300); ins_cost(300);
format %{ "J$cop,us $labl" %} format %{ "J$cop,us $labl\t# Loop end" %}
size(2);
opcode(0x70);
ins_encode( JccShort( cop, labl) );
ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1);
%}
instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
ins_cost(300);
format %{ "J$cop,us $labl\t# Loop end" %}
size(2); size(2);
opcode(0x70); opcode(0x70);
ins_encode( JccShort( cop, labl) ); ins_encode( JccShort( cop, labl) );
...@@ -12247,6 +12497,60 @@ instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ ...@@ -12247,6 +12497,60 @@ instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
ins_short_branch(1); ins_short_branch(1);
%} %}
instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(300);
format %{ "J$cop,us $labl" %}
size(2);
opcode(0x70);
ins_encode( JccShort( cop, labl) );
ins_pipe( pipe_jcc );
ins_pc_relative(1);
ins_short_branch(1);
%}
instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(300);
format %{ $$template
if ($cop$$cmpcode == Assembler::notEqual) {
$$emit$$"JP,u,s $labl\n\t"
$$emit$$"J$cop,u,s $labl"
} else {
$$emit$$"JP,u,s done\n\t"
$$emit$$"J$cop,u,s $labl\n\t"
$$emit$$"done:"
}
%}
size(4);
opcode(0x70);
ins_encode %{
Label* l = $labl$$label;
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2;
} else {
ShouldNotReachHere();
}
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
%}
ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1);
%}
// ============================================================================ // ============================================================================
// Long Compare // Long Compare
// //
......
...@@ -2004,9 +2004,12 @@ const uint Matcher::vector_ideal_reg(void) { ...@@ -2004,9 +2004,12 @@ const uint Matcher::vector_ideal_reg(void) {
// //
// NOTE: If the platform does not provide any short branch variants, then // NOTE: If the platform does not provide any short branch variants, then
// this method should return false for offset 0. // 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) {
{ // the short version of jmpConUCF2 contains multiple branches,
return -0x80 <= offset && offset < 0x80; // making the reach slightly less
if (rule == jmpConUCF2_rule)
return (-126 <= offset && offset <= 125);
return (-128 <= offset && offset <= 127);
} }
const bool Matcher::isSimpleConstant64(jlong value) { const bool Matcher::isSimpleConstant64(jlong value) {
...@@ -5134,6 +5137,15 @@ operand rFlagsRegU() ...@@ -5134,6 +5137,15 @@ operand rFlagsRegU()
interface(REG_INTER); interface(REG_INTER);
%} %}
operand rFlagsRegUCF() %{
constraint(ALLOC_IN_RC(int_flags));
match(RegFlags);
predicate(false);
format %{ "RFLAGS_U_CF" %}
interface(REG_INTER);
%}
// Float register operands // Float register operands
operand regF() operand regF()
%{ %{
...@@ -5405,12 +5417,12 @@ operand cmpOp() ...@@ -5405,12 +5417,12 @@ operand cmpOp()
format %{ "" %} format %{ "" %}
interface(COND_INTER) %{ interface(COND_INTER) %{
equal(0x4); equal(0x4, "e");
not_equal(0x5); not_equal(0x5, "ne");
less(0xC); less(0xC, "l");
greater_equal(0xD); greater_equal(0xD, "ge");
less_equal(0xE); less_equal(0xE, "le");
greater(0xF); greater(0xF, "g");
%} %}
%} %}
...@@ -5423,12 +5435,48 @@ operand cmpOpU() ...@@ -5423,12 +5435,48 @@ operand cmpOpU()
format %{ "" %} format %{ "" %}
interface(COND_INTER) %{ interface(COND_INTER) %{
equal(0x4); equal(0x4, "e");
not_equal(0x5); not_equal(0x5, "ne");
less(0x2); less(0x2, "b");
greater_equal(0x3); greater_equal(0x3, "nb");
less_equal(0x6); less_equal(0x6, "be");
greater(0x7); greater(0x7, "nbe");
%}
%}
// Floating comparisons that don't require any fixup for the unordered case
operand cmpOpUCF() %{
match(Bool);
predicate(n->as_Bool()->_test._test == BoolTest::lt ||
n->as_Bool()->_test._test == BoolTest::ge ||
n->as_Bool()->_test._test == BoolTest::le ||
n->as_Bool()->_test._test == BoolTest::gt);
format %{ "" %}
interface(COND_INTER) %{
equal(0x4, "e");
not_equal(0x5, "ne");
less(0x2, "b");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
%}
%}
// Floating comparisons that can be fixed up with extra conditional jumps
operand cmpOpUCF2() %{
match(Bool);
predicate(n->as_Bool()->_test._test == BoolTest::ne ||
n->as_Bool()->_test._test == BoolTest::eq);
format %{ "" %}
interface(COND_INTER) %{
equal(0x4, "e");
not_equal(0x5, "ne");
less(0x2, "b");
greater_equal(0x3, "nb");
less_equal(0x6, "be");
greater(0x7, "nbe");
%} %}
%} %}
...@@ -7176,8 +7224,7 @@ instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) ...@@ -7176,8 +7224,7 @@ instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
ins_pipe(pipe_cmov_reg); ins_pipe(pipe_cmov_reg);
%} %}
instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop) instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
%{
match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200); // XXX ins_cost(200); // XXX
...@@ -7187,9 +7234,16 @@ instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop) ...@@ -7187,9 +7234,16 @@ instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
ins_pipe(pipe_cmov_reg); ins_pipe(pipe_cmov_reg);
%} %}
instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovI_regU(cop, cr, dst, src);
%}
%}
// Conditional move // Conditional move
instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
%{
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250); // XXX ins_cost(250); // XXX
...@@ -7211,6 +7265,14 @@ instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) ...@@ -7211,6 +7265,14 @@ instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
ins_pipe(pipe_cmov_mem); ins_pipe(pipe_cmov_mem);
%} %}
instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
ins_cost(250);
expand %{
cmovI_memU(cop, cr, dst, src);
%}
%}
// Conditional move // Conditional move
instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
%{ %{
...@@ -7224,7 +7286,7 @@ instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) ...@@ -7224,7 +7286,7 @@ instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
%} %}
// Conditional move // Conditional move
instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop) instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
%{ %{
match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
...@@ -7235,6 +7297,14 @@ instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop) ...@@ -7235,6 +7297,14 @@ instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
ins_pipe(pipe_cmov_reg); ins_pipe(pipe_cmov_reg);
%} %}
instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovN_regU(cop, cr, dst, src);
%}
%}
// Conditional move // Conditional move
instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
%{ %{
...@@ -7248,7 +7318,7 @@ instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) ...@@ -7248,7 +7318,7 @@ instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
%} %}
// Conditional move // Conditional move
instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop) instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
%{ %{
match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
...@@ -7259,6 +7329,14 @@ instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop) ...@@ -7259,6 +7329,14 @@ instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
ins_pipe(pipe_cmov_reg); // XXX ins_pipe(pipe_cmov_reg); // XXX
%} %}
instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovP_regU(cop, cr, dst, src);
%}
%}
// DISABLED: Requires the ADLC to emit a bottom_type call that // DISABLED: Requires the ADLC to emit a bottom_type call that
// correctly meets the two pointer arguments; one is an incoming // correctly meets the two pointer arguments; one is an incoming
// register but the other is a memory operand. ALSO appears to // register but the other is a memory operand. ALSO appears to
...@@ -7319,6 +7397,14 @@ instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) ...@@ -7319,6 +7397,14 @@ instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
ins_pipe(pipe_cmov_reg); // XXX ins_pipe(pipe_cmov_reg); // XXX
%} %}
instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovL_regU(cop, cr, dst, src);
%}
%}
instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
%{ %{
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
...@@ -7330,6 +7416,14 @@ instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) ...@@ -7330,6 +7416,14 @@ instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
ins_pipe(pipe_cmov_mem); // XXX ins_pipe(pipe_cmov_mem); // XXX
%} %}
instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
ins_cost(200);
expand %{
cmovL_memU(cop, cr, dst, src);
%}
%}
instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
%{ %{
match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
...@@ -7366,6 +7460,14 @@ instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) ...@@ -7366,6 +7460,14 @@ instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovF_regU(cop, cr, dst, src);
%}
%}
instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
%{ %{
match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
...@@ -7390,6 +7492,14 @@ instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) ...@@ -7390,6 +7492,14 @@ instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
ins_cost(200);
expand %{
cmovD_regU(cop, cr, dst, src);
%}
%}
//----------Arithmetic Instructions-------------------------------------------- //----------Arithmetic Instructions--------------------------------------------
//----------Addition Instructions---------------------------------------------- //----------Addition Instructions----------------------------------------------
...@@ -9716,6 +9826,17 @@ instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) ...@@ -9716,6 +9826,17 @@ instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
match(Set cr (CmpF src1 src2));
ins_cost(145);
format %{ "ucomiss $src1, $src2" %}
ins_encode %{
__ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
%{ %{
match(Set cr (CmpF src1 (LoadF src2))); match(Set cr (CmpF src1 (LoadF src2)));
...@@ -9733,6 +9854,16 @@ instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) ...@@ -9733,6 +9854,16 @@ instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
match(Set cr (CmpF src1 (LoadF src2)));
ins_cost(100);
format %{ "ucomiss $src1, $src2" %}
opcode(0x0F, 0x2E);
ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
ins_pipe(pipe_slow);
%}
instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
%{ %{
match(Set cr (CmpF src1 src2)); match(Set cr (CmpF src1 src2));
...@@ -9750,6 +9881,16 @@ instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) ...@@ -9750,6 +9881,16 @@ instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
match(Set cr (CmpF src1 src2));
ins_cost(100);
format %{ "ucomiss $src1, $src2" %}
opcode(0x0F, 0x2E);
ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
ins_pipe(pipe_slow);
%}
instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
%{ %{
match(Set cr (CmpD src1 src2)); match(Set cr (CmpD src1 src2));
...@@ -9767,6 +9908,17 @@ instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) ...@@ -9767,6 +9908,17 @@ instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
match(Set cr (CmpD src1 src2));
ins_cost(100);
format %{ "ucomisd $src1, $src2 test" %}
ins_encode %{
__ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
%{ %{
match(Set cr (CmpD src1 (LoadD src2))); match(Set cr (CmpD src1 (LoadD src2)));
...@@ -9784,6 +9936,16 @@ instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) ...@@ -9784,6 +9936,16 @@ instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
match(Set cr (CmpD src1 (LoadD src2)));
ins_cost(100);
format %{ "ucomisd $src1, $src2" %}
opcode(0x66, 0x0F, 0x2E);
ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
ins_pipe(pipe_slow);
%}
instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
%{ %{
match(Set cr (CmpD src1 src2)); match(Set cr (CmpD src1 src2));
...@@ -9801,6 +9963,16 @@ instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) ...@@ -9801,6 +9963,16 @@ instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
ins_pipe(pipe_slow); ins_pipe(pipe_slow);
%} %}
instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
match(Set cr (CmpD src1 src2));
ins_cost(100);
format %{ "ucomisd $src1, [$src2]" %}
opcode(0x66, 0x0F, 0x2E);
ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
ins_pipe(pipe_slow);
%}
// Compare into -1,0,1 // Compare into -1,0,1
instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
%{ %{
...@@ -11406,8 +11578,7 @@ instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) ...@@ -11406,8 +11578,7 @@ instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
%{
match(CountedLoopEnd cop cmp); match(CountedLoopEnd cop cmp);
effect(USE labl); effect(USE labl);
...@@ -11420,14 +11591,39 @@ instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) ...@@ -11420,14 +11591,39 @@ instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
ins_pc_relative(1); ins_pc_relative(1);
%} %}
instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
ins_cost(200);
format %{ "j$cop,u $labl\t# loop end" %}
size(6);
opcode(0x0F, 0x80);
ins_encode(Jcc(cop, labl));
ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
// Jump Direct Conditional - using unsigned comparison // Jump Direct Conditional - using unsigned comparison
instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
%{
match(If cop cmp); match(If cop cmp);
effect(USE labl); effect(USE labl);
ins_cost(300); ins_cost(300);
format %{ "j$cop,u $labl" %} format %{ "j$cop,u $labl" %}
size(6);
opcode(0x0F, 0x80);
ins_encode(Jcc(cop, labl));
ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(200);
format %{ "j$cop,u $labl" %}
size(6); size(6);
opcode(0x0F, 0x80); opcode(0x0F, 0x80);
ins_encode(Jcc(cop, labl)); ins_encode(Jcc(cop, labl));
...@@ -11435,6 +11631,46 @@ instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) ...@@ -11435,6 +11631,46 @@ instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
ins_pc_relative(1); ins_pc_relative(1);
%} %}
instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(200);
format %{ $$template
if ($cop$$cmpcode == Assembler::notEqual) {
$$emit$$"jp,u $labl\n\t"
$$emit$$"j$cop,u $labl"
} else {
$$emit$$"jp,u done\n\t"
$$emit$$"j$cop,u $labl\n\t"
$$emit$$"done:"
}
%}
size(12);
opcode(0x0F, 0x80);
ins_encode %{
Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6;
} else {
ShouldNotReachHere();
}
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
emit_d32(cbuf, disp);
%}
ins_pipe(pipe_jcc);
ins_pc_relative(1);
%}
// ============================================================================ // ============================================================================
// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
// superklass array for an instance of the superklass. Set a hidden // superklass array for an instance of the superklass. Set a hidden
...@@ -11505,8 +11741,7 @@ instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, ...@@ -11505,8 +11741,7 @@ instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
// specific code section of the file. // specific code section of the file.
// Jump Direct - Label defines a relative address from JMP+1 // Jump Direct - Label defines a relative address from JMP+1
instruct jmpDir_short(label labl) instruct jmpDir_short(label labl) %{
%{
match(Goto); match(Goto);
effect(USE labl); effect(USE labl);
...@@ -11521,8 +11756,7 @@ instruct jmpDir_short(label labl) ...@@ -11521,8 +11756,7 @@ instruct jmpDir_short(label labl)
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
%{
match(If cop cr); match(If cop cr);
effect(USE labl); effect(USE labl);
...@@ -11537,13 +11771,12 @@ instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) ...@@ -11537,13 +11771,12 @@ instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
%{
match(CountedLoopEnd cop cr); match(CountedLoopEnd cop cr);
effect(USE labl); effect(USE labl);
ins_cost(300); ins_cost(300);
format %{ "j$cop,s $labl" %} format %{ "j$cop,s $labl\t# loop end" %}
size(2); size(2);
opcode(0x70); opcode(0x70);
ins_encode(JccShort(cop, labl)); ins_encode(JccShort(cop, labl));
...@@ -11553,13 +11786,26 @@ instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) ...@@ -11553,13 +11786,26 @@ instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
%} %}
// Jump Direct Conditional - Label defines a relative address from Jcc+1 // Jump Direct Conditional - Label defines a relative address from Jcc+1
instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
%{
match(CountedLoopEnd cop cmp); match(CountedLoopEnd cop cmp);
effect(USE labl); effect(USE labl);
ins_cost(300); ins_cost(300);
format %{ "j$cop,us $labl" %} format %{ "j$cop,us $labl\t# loop end" %}
size(2);
opcode(0x70);
ins_encode(JccShort(cop, labl));
ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1);
%}
instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(CountedLoopEnd cop cmp);
effect(USE labl);
ins_cost(300);
format %{ "j$cop,us $labl\t# loop end" %}
size(2); size(2);
opcode(0x70); opcode(0x70);
ins_encode(JccShort(cop, labl)); ins_encode(JccShort(cop, labl));
...@@ -11569,8 +11815,7 @@ instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) ...@@ -11569,8 +11815,7 @@ instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
%} %}
// Jump Direct Conditional - using unsigned comparison // Jump Direct Conditional - using unsigned comparison
instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
%{
match(If cop cmp); match(If cop cmp);
effect(USE labl); effect(USE labl);
...@@ -11584,6 +11829,60 @@ instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) ...@@ -11584,6 +11829,60 @@ instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
ins_short_branch(1); ins_short_branch(1);
%} %}
instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(300);
format %{ "j$cop,us $labl" %}
size(2);
opcode(0x70);
ins_encode(JccShort(cop, labl));
ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1);
%}
instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
match(If cop cmp);
effect(USE labl);
ins_cost(300);
format %{ $$template
if ($cop$$cmpcode == Assembler::notEqual) {
$$emit$$"jp,u,s $labl\n\t"
$$emit$$"j$cop,u,s $labl"
} else {
$$emit$$"jp,u,s done\n\t"
$$emit$$"j$cop,u,s $labl\n\t"
$$emit$$"done:"
}
%}
size(4);
opcode(0x70);
ins_encode %{
Label* l = $labl$$label;
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2;
} else {
ShouldNotReachHere();
}
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
%}
ins_pipe(pipe_jcc);
ins_pc_relative(1);
ins_short_branch(1);
%}
// ============================================================================ // ============================================================================
// inlined locking and unlocking // inlined locking and unlocking
......
...@@ -33,7 +33,6 @@ ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc) ...@@ -33,7 +33,6 @@ ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc)
_globalNames(archDesc.globalNames()) { _globalNames(archDesc.globalNames()) {
_AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
_AD._warnings = 0; // No warnings either _AD._warnings = 0; // No warnings either
_linenum = 0; // Will increment to first line
_curline = _ptr = NULL; // No pointers into buffer yet _curline = _ptr = NULL; // No pointers into buffer yet
_preproc_depth = 0; _preproc_depth = 0;
...@@ -76,7 +75,7 @@ ADLParser::~ADLParser() { ...@@ -76,7 +75,7 @@ ADLParser::~ADLParser() {
} }
if (!_AD._quiet_mode) if (!_AD._quiet_mode)
fprintf(stderr,"-----------------------------------------------------------------------------\n"); fprintf(stderr,"-----------------------------------------------------------------------------\n");
_AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine _AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine
// Write out information we have stored // Write out information we have stored
// // UNIXism == fsync(stderr); // // UNIXism == fsync(stderr);
...@@ -148,7 +147,7 @@ void ADLParser::instr_parse(void) { ...@@ -148,7 +147,7 @@ void ADLParser::instr_parse(void) {
if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL ) if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
return; return;
instr = new InstructForm(ident); // Create new instruction form instr = new InstructForm(ident); // Create new instruction form
instr->_linenum = _linenum; instr->_linenum = linenum();
_globalNames.Insert(ident, instr); // Add name to the name table _globalNames.Insert(ident, instr); // Add name to the name table
// Debugging Stuff // Debugging Stuff
if (_AD._adl_debug > 1) if (_AD._adl_debug > 1)
...@@ -404,7 +403,7 @@ void ADLParser::oper_parse(void) { ...@@ -404,7 +403,7 @@ void ADLParser::oper_parse(void) {
if( (ident = get_unique_ident(_globalNames,"operand")) == NULL ) if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
return; return;
oper = new OperandForm(ident); // Create new operand form oper = new OperandForm(ident); // Create new operand form
oper->_linenum = _linenum; oper->_linenum = linenum();
_globalNames.Insert(ident, oper); // Add name to the name table _globalNames.Insert(ident, oper); // Add name to the name table
// Debugging Stuff // Debugging Stuff
...@@ -774,7 +773,7 @@ void ADLParser::reg_parse(void) { ...@@ -774,7 +773,7 @@ void ADLParser::reg_parse(void) {
// Create the RegisterForm for the architecture description. // Create the RegisterForm for the architecture description.
RegisterForm *regBlock = new RegisterForm(); // Build new Source object RegisterForm *regBlock = new RegisterForm(); // Build new Source object
regBlock->_linenum = _linenum; regBlock->_linenum = linenum();
_AD.addForm(regBlock); _AD.addForm(regBlock);
skipws(); // Skip leading whitespace skipws(); // Skip leading whitespace
...@@ -847,7 +846,7 @@ void ADLParser::enc_class_parse(void) { ...@@ -847,7 +846,7 @@ void ADLParser::enc_class_parse(void) {
} }
EncClass *encoding = _AD._encode->add_EncClass(ec_name); EncClass *encoding = _AD._encode->add_EncClass(ec_name);
encoding->_linenum = _linenum; encoding->_linenum = linenum();
skipws(); // Skip leading whitespace skipws(); // Skip leading whitespace
// Check for optional parameter list // Check for optional parameter list
...@@ -905,7 +904,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) { ...@@ -905,7 +904,7 @@ void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
// Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
if (_AD._adlocation_debug) { if (_AD._adlocation_debug) {
const char* file = _AD._ADL_file._name; const char* file = _AD._ADL_file._name;
int line = _linenum; int line = linenum();
char* location = (char *)malloc(strlen(file) + 100); char* location = (char *)malloc(strlen(file) + 100);
sprintf(location, "#line %d \"%s\"\n", line, file); sprintf(location, "#line %d \"%s\"\n", line, file);
encoding->add_code(location); encoding->add_code(location);
...@@ -2776,7 +2775,7 @@ InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) { ...@@ -2776,7 +2775,7 @@ InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
EncClass *encoding = _AD._encode->add_EncClass(ec_name); EncClass *encoding = _AD._encode->add_EncClass(ec_name);
encoding->_linenum = _linenum; encoding->_linenum = linenum();
// synthesize the arguments list for the enc_class from the // synthesize the arguments list for the enc_class from the
// arguments to the instruct definition. // arguments to the instruct definition.
...@@ -2852,7 +2851,7 @@ InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) { ...@@ -2852,7 +2851,7 @@ InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
skipws(); skipws();
InsEncode *encrule = new InsEncode(); // Encode class for instruction InsEncode *encrule = new InsEncode(); // Encode class for instruction
encrule->_linenum = _linenum; encrule->_linenum = linenum();
char *ec_name = NULL; // String representation of encode rule char *ec_name = NULL; // String representation of encode rule
// identifier is optional. // identifier is optional.
while (_curchar != ')') { while (_curchar != ')') {
...@@ -3203,6 +3202,12 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3203,6 +3202,12 @@ Interface *ADLParser::cond_interface_parse(void) {
char *greater_equal; char *greater_equal;
char *less_equal; char *less_equal;
char *greater; char *greater;
const char *equal_format = "eq";
const char *not_equal_format = "ne";
const char *less_format = "lt";
const char *greater_equal_format = "ge";
const char *less_equal_format = "le";
const char *greater_format = "gt";
if (_curchar != '%') { if (_curchar != '%') {
parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
...@@ -3222,22 +3227,22 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3222,22 +3227,22 @@ Interface *ADLParser::cond_interface_parse(void) {
return NULL; return NULL;
} }
if ( strcmp(field,"equal") == 0 ) { if ( strcmp(field,"equal") == 0 ) {
equal = interface_field_parse(); equal = interface_field_parse(&equal_format);
} }
else if ( strcmp(field,"not_equal") == 0 ) { else if ( strcmp(field,"not_equal") == 0 ) {
not_equal = interface_field_parse(); not_equal = interface_field_parse(&not_equal_format);
} }
else if ( strcmp(field,"less") == 0 ) { else if ( strcmp(field,"less") == 0 ) {
less = interface_field_parse(); less = interface_field_parse(&less_format);
} }
else if ( strcmp(field,"greater_equal") == 0 ) { else if ( strcmp(field,"greater_equal") == 0 ) {
greater_equal = interface_field_parse(); greater_equal = interface_field_parse(&greater_equal_format);
} }
else if ( strcmp(field,"less_equal") == 0 ) { else if ( strcmp(field,"less_equal") == 0 ) {
less_equal = interface_field_parse(); less_equal = interface_field_parse(&less_equal_format);
} }
else if ( strcmp(field,"greater") == 0 ) { else if ( strcmp(field,"greater") == 0 ) {
greater = interface_field_parse(); greater = interface_field_parse(&greater_format);
} }
else { else {
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
...@@ -3252,14 +3257,18 @@ Interface *ADLParser::cond_interface_parse(void) { ...@@ -3252,14 +3257,18 @@ Interface *ADLParser::cond_interface_parse(void) {
next_char(); // Skip '}' next_char(); // Skip '}'
// Construct desired object and return // Construct desired object and return
Interface *inter = new CondInterface(equal, not_equal, less, greater_equal, Interface *inter = new CondInterface(equal, equal_format,
less_equal, greater); not_equal, not_equal_format,
less, less_format,
greater_equal, greater_equal_format,
less_equal, less_equal_format,
greater, greater_format);
return inter; return inter;
} }
//------------------------------interface_field_parse-------------------------- //------------------------------interface_field_parse--------------------------
char *ADLParser::interface_field_parse(void) { char *ADLParser::interface_field_parse(const char ** format) {
char *iface_field = NULL; char *iface_field = NULL;
// Get interface field // Get interface field
...@@ -3280,6 +3289,32 @@ char *ADLParser::interface_field_parse(void) { ...@@ -3280,6 +3289,32 @@ char *ADLParser::interface_field_parse(void) {
return NULL; return NULL;
} }
skipws(); skipws();
if (format != NULL && _curchar == ',') {
next_char();
skipws();
if (_curchar != '"') {
parse_err(SYNERR, "Missing '\"' in field format .\n");
return NULL;
}
next_char();
char *start = _ptr; // Record start of the next string
while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
if (_curchar == '\\') next_char(); // superquote
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
next_char();
}
if (_curchar != '"') {
parse_err(SYNERR, "Missing '\"' at end of field format .\n");
return NULL;
}
// If a string was found, terminate it and record in FormatRule
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
*format = start;
}
next_char();
skipws();
}
if (_curchar != ')') { if (_curchar != ')') {
parse_err(SYNERR, "Missing ')' after interface field.\n"); parse_err(SYNERR, "Missing ')' after interface field.\n");
return NULL; return NULL;
...@@ -3342,6 +3377,12 @@ FormatRule* ADLParser::format_parse(void) { ...@@ -3342,6 +3377,12 @@ FormatRule* ADLParser::format_parse(void) {
next_char(); // Move past the '{' next_char(); // Move past the '{'
skipws(); skipws();
if (_curchar == '$') {
char* ident = get_rep_var_ident();
if (strcmp(ident, "$$template") == 0) return template_parse();
parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
return NULL;
}
// Check for the opening '"' inside the format description // Check for the opening '"' inside the format description
if ( _curchar == '"' ) { if ( _curchar == '"' ) {
next_char(); // Move past the initial '"' next_char(); // Move past the initial '"'
...@@ -3433,6 +3474,131 @@ FormatRule* ADLParser::format_parse(void) { ...@@ -3433,6 +3474,131 @@ FormatRule* ADLParser::format_parse(void) {
} }
//------------------------------template_parse-----------------------------------
FormatRule* ADLParser::template_parse(void) {
char *desc = NULL;
FormatRule *format = (new FormatRule(desc));
skipws();
while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
// (1)
// Check if there is a string to pass through to output
char *start = _ptr; // Record start of the next string
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
// If at the start of a comment, skip past it
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
skipws_no_preproc();
} else {
// ELSE advance to the next character, or start of the next line
next_char_or_line();
}
}
// If a string was found, terminate it and record in EncClass
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal2);
format->_strings.addName(start);
}
// (2)
// If we are at a replacement variable,
// copy it and record in EncClass
if ( _curchar == '$' ) {
// Found replacement Variable
char *rep_var = get_rep_var_ident_dup();
if (strcmp(rep_var, "$emit") == 0) {
// switch to normal format parsing
next_char();
next_char();
skipws();
// Check for the opening '"' inside the format description
if ( _curchar == '"' ) {
next_char(); // Move past the initial '"'
if( _curchar == '"' ) { // Handle empty format string case
*_ptr = '\0'; // Terminate empty string
format->_strings.addName(_ptr);
}
// Collect the parts of the format description
// (1) strings that are passed through to tty->print
// (2) replacement/substitution variable, preceeded by a '$'
// (3) multi-token ANSIY C style strings
while ( true ) {
if ( _curchar == '%' || _curchar == '\n' ) {
parse_err(SYNERR, "missing '\"' at end of format block");
return NULL;
}
// (1)
// Check if there is a string to pass through to output
char *start = _ptr; // Record start of the next string
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
if (_curchar == '\\') next_char(); // superquote
if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
next_char();
}
// If a string was found, terminate it and record in FormatRule
if ( start != _ptr ) {
*_ptr = '\0'; // Terminate the string
format->_strings.addName(start);
}
// (2)
// If we are at a replacement variable,
// copy it and record in FormatRule
if ( _curchar == '$' ) {
next_char(); // Move past the '$'
char* rep_var = get_ident(); // Nil terminate the variable name
rep_var = strdup(rep_var);// Copy the string
*_ptr = _curchar; // and replace Nil with original character
format->_rep_vars.addName(rep_var);
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal);
}
// (3)
// Allow very long strings to be broken up,
// using the ANSI C syntax "foo\n" <newline> "bar"
if ( _curchar == '"') {
next_char(); // Move past the '"'
skipws(); // Skip white space before next string token
if ( _curchar != '"') {
break;
} else {
// Found one. Skip both " and the whitespace in between.
next_char();
}
}
} // end while part of format description
}
} else {
// Add flag to _strings list indicating we should check _rep_vars
format->_rep_vars.addName(rep_var);
// Add flag to _strings list indicating we should check _rep_vars
format->_strings.addName(NameList::_signal3);
}
} // end while part of format description
}
skipws();
// Past format description, at '%'
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
parse_err(SYNERR, "missing '%}' at end of format block");
return NULL;
}
next_char(); // Move past the '%'
next_char(); // Move past the '}'
// Debug Stuff
if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
skipws();
return format;
}
//------------------------------effect_parse----------------------------------- //------------------------------effect_parse-----------------------------------
void ADLParser::effect_parse(InstructForm *instr) { void ADLParser::effect_parse(InstructForm *instr) {
char* desc = NULL; char* desc = NULL;
...@@ -3777,7 +3943,7 @@ char* ADLParser::find_cpp_block(const char* description) { ...@@ -3777,7 +3943,7 @@ char* ADLParser::find_cpp_block(const char* description) {
skipws_no_preproc(); // Skip leading whitespace skipws_no_preproc(); // Skip leading whitespace
cppBlock = _ptr; // Point to start of expression cppBlock = _ptr; // Point to start of expression
const char* file = _AD._ADL_file._name; const char* file = _AD._ADL_file._name;
int line = _linenum; int line = linenum();
next = _ptr + 1; next = _ptr + 1;
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
next_char_or_line(); next_char_or_line();
...@@ -4297,11 +4463,11 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) { ...@@ -4297,11 +4463,11 @@ void ADLParser::parse_err(int flag, const char *fmt, ...) {
va_start(args, fmt); va_start(args, fmt);
if (flag == 1) if (flag == 1)
_AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else if (flag == 2) else if (flag == 2)
_AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
else else
_AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args); _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
int error_char = _curchar; int error_char = _curchar;
char* error_ptr = _ptr+1; char* error_ptr = _ptr+1;
...@@ -4515,7 +4681,7 @@ void ADLParser::next_char_or_line() { ...@@ -4515,7 +4681,7 @@ void ADLParser::next_char_or_line() {
//---------------------------next_line----------------------------------------- //---------------------------next_line-----------------------------------------
void ADLParser::next_line() { void ADLParser::next_line() {
_curline = _buf.get_line(); _linenum++; _curline = _buf.get_line();
} }
//-------------------------is_literal_constant--------------------------------- //-------------------------is_literal_constant---------------------------------
......
...@@ -70,7 +70,6 @@ class ADLParser { ...@@ -70,7 +70,6 @@ class ADLParser {
protected: protected:
char *_curline; // Start of current line char *_curline; // Start of current line
char *_ptr; // Pointer into current location in File Buffer char *_ptr; // Pointer into current location in File Buffer
int _linenum; // Count of line numbers seen so far
char _curchar; // Current character from buffer char _curchar; // Current character from buffer
FormDict &_globalNames; // Global names FormDict &_globalNames; // Global names
...@@ -160,9 +159,10 @@ protected: ...@@ -160,9 +159,10 @@ protected:
Interface *interface_parse(); // Parse operand interface rule Interface *interface_parse(); // Parse operand interface rule
Interface *mem_interface_parse(); // Parse memory interface rule Interface *mem_interface_parse(); // Parse memory interface rule
Interface *cond_interface_parse(); // Parse conditional interface rule Interface *cond_interface_parse(); // Parse conditional interface rule
char *interface_field_parse();// Parse field contents char *interface_field_parse(const char** format = NULL);// Parse field contents
FormatRule *format_parse(void); // Parse format rule FormatRule *format_parse(void); // Parse format rule
FormatRule *template_parse(void); // Parse format rule
void effect_parse(InstructForm *instr); // Parse effect rule void effect_parse(InstructForm *instr); // Parse effect rule
ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule ExpandRule *expand_parse(InstructForm *instr); // Parse expand rule
RewriteRule *rewrite_parse(void); // Parse rewrite rule RewriteRule *rewrite_parse(void); // Parse rewrite rule
...@@ -263,7 +263,7 @@ public: ...@@ -263,7 +263,7 @@ public:
void parse(void); // Do the parsing & build forms lists void parse(void); // Do the parsing & build forms lists
int getlines( ) { return _linenum; } int linenum() { return _buf.linenum(); }
static bool is_literal_constant(const char *hex_string); static bool is_literal_constant(const char *hex_string);
static bool is_hex_digit(char digit); static bool is_hex_digit(char digit);
......
...@@ -41,6 +41,7 @@ FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(arc ...@@ -41,6 +41,7 @@ FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(arc
exit(1); // Exit on seek error exit(1); // Exit on seek error
} }
_filepos = ftell(_fp->_fp); // Reset current file position _filepos = ftell(_fp->_fp); // Reset current file position
_linenum = 0;
_bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
if( !_bigbuf ) { if( !_bigbuf ) {
...@@ -76,6 +77,7 @@ char *FileBuff::get_line(void) { ...@@ -76,6 +77,7 @@ char *FileBuff::get_line(void) {
// Check for end of file & return NULL // Check for end of file & return NULL
if (_bufeol >= _bufmax) return NULL; if (_bufeol >= _bufmax) return NULL;
_linenum++;
retval = ++_bufeol; // return character following end of previous line retval = ++_bufeol; // return character following end of previous line
if (*retval == '\0') return NULL; // Check for EOF sentinal if (*retval == '\0') return NULL; // Check for EOF sentinal
// Search for newline character which must end each line // Search for newline character which must end each line
......
...@@ -51,6 +51,7 @@ class FileBuff { ...@@ -51,6 +51,7 @@ class FileBuff {
int _err; // Error flag for file seek/read operations int _err; // Error flag for file seek/read operations
long _filepos; // Current offset from start of file long _filepos; // Current offset from start of file
int _linenum;
ArchDesc& _AD; // Reference to Architecture Description ArchDesc& _AD; // Reference to Architecture Description
...@@ -66,6 +67,7 @@ class FileBuff { ...@@ -66,6 +67,7 @@ class FileBuff {
// This returns a pointer to the start of the current line in the buffer, // This returns a pointer to the start of the current line in the buffer,
// and increments bufeol and filepos to point at the end of that line. // and increments bufeol and filepos to point at the end of that line.
char *get_line(void); char *get_line(void);
int linenum() const { return _linenum; }
// This converts a pointer into the buffer to a file offset. It only works // This converts a pointer into the buffer to a file offset. It only works
// when the pointer is valid (i.e. just obtained from getline()). // when the pointer is valid (i.e. just obtained from getline()).
......
...@@ -35,6 +35,8 @@ Arena *Form::generate_arena() { ...@@ -35,6 +35,8 @@ Arena *Form::generate_arena() {
//------------------------------NameList--------------------------------------- //------------------------------NameList---------------------------------------
// reserved user-defined string // reserved user-defined string
const char *NameList::_signal = "$$SIGNAL$$"; const char *NameList::_signal = "$$SIGNAL$$";
const char *NameList::_signal2 = "$$SIGNAL2$$";
const char *NameList::_signal3 = "$$SIGNAL3$$";
// Constructor and Destructor // Constructor and Destructor
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) { NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
......
...@@ -329,6 +329,8 @@ protected: ...@@ -329,6 +329,8 @@ protected:
public: public:
static const char *_signal; // reserved user-defined string static const char *_signal; // reserved user-defined string
static const char *_signal2; // reserved user-defined string
static const char *_signal3; // reserved user-defined string
enum { Not_in_list = -1 }; enum { Not_in_list = -1 };
void addName(const char *name); void addName(const char *name);
......
...@@ -1574,10 +1574,10 @@ Opcode::opcode_type Opcode::as_opcode_type(const char *param) { ...@@ -1574,10 +1574,10 @@ Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
return Opcode::NOT_AN_OPCODE; return Opcode::NOT_AN_OPCODE;
} }
void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) { bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
// Default values previously provided by MachNode::primary()... // Default values previously provided by MachNode::primary()...
const char *description = "default_opcode()"; const char *description = NULL;
const char *value = "-1"; const char *value = NULL;
// Check if user provided any opcode definitions // Check if user provided any opcode definitions
if( this != NULL ) { if( this != NULL ) {
// Update 'value' if user provided a definition in the instruction // Update 'value' if user provided a definition in the instruction
...@@ -1599,7 +1599,10 @@ void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) { ...@@ -1599,7 +1599,10 @@ void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
break; break;
} }
} }
fprintf(fp, "(%s /*%s*/)", value, description); if (value != NULL) {
fprintf(fp, "(%s /*%s*/)", value, description);
}
return value != NULL;
} }
void Opcode::dump() { void Opcode::dump() {
...@@ -2610,14 +2613,19 @@ void MemInterface::output(FILE *fp) { ...@@ -2610,14 +2613,19 @@ void MemInterface::output(FILE *fp) {
} }
//------------------------------CondInterface---------------------------------- //------------------------------CondInterface----------------------------------
CondInterface::CondInterface(char *equal, char *not_equal, CondInterface::CondInterface(const char* equal, const char* equal_format,
char *less, char *greater_equal, const char* not_equal, const char* not_equal_format,
char *less_equal, char *greater) const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
const char* greater, const char* greater_format)
: Interface("COND_INTER"), : Interface("COND_INTER"),
_equal(equal), _not_equal(not_equal), _equal(equal), _equal_format(equal_format),
_less(less), _greater_equal(greater_equal), _not_equal(not_equal), _not_equal_format(not_equal_format),
_less_equal(less_equal), _greater(greater) { _less(less), _less_format(less_format),
// _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
_less_equal(less_equal), _less_equal_format(less_equal_format),
_greater(greater), _greater_format(greater_format) {
} }
CondInterface::~CondInterface() { CondInterface::~CondInterface() {
// not owner of any character arrays // not owner of any character arrays
......
...@@ -397,7 +397,7 @@ public: ...@@ -397,7 +397,7 @@ public:
void output(FILE *fp); void output(FILE *fp);
// --------------------------- FILE *output_routines // --------------------------- FILE *output_routines
void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode); bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
}; };
//------------------------------InsEncode-------------------------------------- //------------------------------InsEncode--------------------------------------
...@@ -779,10 +779,20 @@ public: ...@@ -779,10 +779,20 @@ public:
const char *_greater_equal; const char *_greater_equal;
const char *_less_equal; const char *_less_equal;
const char *_greater; const char *_greater;
const char *_equal_format;
const char *_not_equal_format;
const char *_less_format;
const char *_greater_equal_format;
const char *_less_equal_format;
const char *_greater_format;
// Public Methods // Public Methods
CondInterface(char *equal, char *not_equal, char *less, char *greater_equal, CondInterface(const char* equal, const char* equal_format,
char *less_equal, char *greater); const char* not_equal, const char* not_equal_format,
const char* less, const char* less_format,
const char* greater_equal, const char* greater_equal_format,
const char* less_equal, const char* less_equal_format,
const char* greater, const char* greater_format);
~CondInterface(); ~CondInterface();
void dump(); void dump();
......
...@@ -1619,6 +1619,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { ...@@ -1619,6 +1619,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
} }
// Iterate over the new instruction's operands // Iterate over the new instruction's operands
int prev_pos = -1;
for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) { for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
// Use 'parameter' at current position in list of new instruction's formals // Use 'parameter' at current position in list of new instruction's formals
// instead of 'opid' when looking up info internal to new_inst // instead of 'opid' when looking up info internal to new_inst
...@@ -1642,6 +1643,18 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) { ...@@ -1642,6 +1643,18 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
// ins = (InstructForm *) _globalNames[new_id]; // ins = (InstructForm *) _globalNames[new_id];
exp_pos = node->operand_position_format(opid); exp_pos = node->operand_position_format(opid);
assert(exp_pos != -1, "Bad expand rule"); assert(exp_pos != -1, "Bad expand rule");
if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
// For the add_req calls below to work correctly they need
// to added in the same order that a match would add them.
// This means that they would need to be in the order of
// the components list instead of the formal parameters.
// This is a sort of hidden invariant that previously
// wasn't checked and could lead to incorrectly
// constructed nodes.
syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
node->_ident, new_inst->_ident);
}
prev_pos = exp_pos;
new_pos = new_inst->operand_position(parameter,Component::USE); new_pos = new_inst->operand_position(parameter,Component::USE);
if (new_pos != -1) { if (new_pos != -1) {
...@@ -2306,7 +2319,12 @@ private: ...@@ -2306,7 +2319,12 @@ private:
_processing_noninput = false; _processing_noninput = false;
// A replacement variable, originally '$' // A replacement variable, originally '$'
if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) { if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) ); if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s, used by encoding %s\n",
rep_var, _inst._ident, _encoding._name);
}
} }
else { else {
// Lookup its position in parameter list // Lookup its position in parameter list
...@@ -2348,7 +2366,13 @@ private: ...@@ -2348,7 +2366,13 @@ private:
else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) { else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
// else check if "primary", "secondary", "tertiary" // else check if "primary", "secondary", "tertiary"
assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter"); assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) ); if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
// Missing opcode
_AD.syntax_err( _inst._linenum,
"Missing $%s opcode definition in %s\n",
rep_var, _inst._ident);
}
_constant_status = LITERAL_OUTPUT; _constant_status = LITERAL_OUTPUT;
} }
else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) { else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
......
...@@ -355,17 +355,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts, ...@@ -355,17 +355,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Generate the format rule for condition codes // Generate the format rule for condition codes
static void defineCCodeDump(FILE *fp, int i) { static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i); assert(oper != NULL, "what");
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i); CondInterface* cond = oper->_interface->is_CondInterface();
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i); fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i); fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
} }
// Output code that dumps constant values, increment "i" if type is constant // Output code that dumps constant values, increment "i" if type is constant
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
if (!strcmp(ideal_type, "ConI")) { if (!strcmp(ideal_type, "ConI")) {
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i); fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
++i; ++i;
...@@ -391,7 +393,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { ...@@ -391,7 +393,7 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
++i; ++i;
} }
else if (!strcmp(ideal_type, "Bool")) { else if (!strcmp(ideal_type, "Bool")) {
defineCCodeDump(fp,i); defineCCodeDump(oper, fp,i);
++i; ++i;
} }
...@@ -476,7 +478,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ ...@@ -476,7 +478,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
} }
// ALWAYS! Provide a special case output for condition codes. // ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) { if( oper.is_ideal_bool() ) {
defineCCodeDump(fp,0); defineCCodeDump(&oper, fp,0);
} }
fprintf(fp,"}\n"); fprintf(fp,"}\n");
...@@ -549,7 +551,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_ ...@@ -549,7 +551,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
} }
// ALWAYS! Provide a special case output for condition codes. // ALWAYS! Provide a special case output for condition codes.
if( oper.is_ideal_bool() ) { if( oper.is_ideal_bool() ) {
defineCCodeDump(fp,0); defineCCodeDump(&oper, fp,0);
} }
fprintf(fp, "}\n"); fprintf(fp, "}\n");
fprintf(fp, "#endif\n"); fprintf(fp, "#endif\n");
...@@ -583,10 +585,53 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c ...@@ -583,10 +585,53 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
while( (string = inst._format->_strings.iter()) != NULL ) { while( (string = inst._format->_strings.iter()) != NULL ) {
fprintf(fp," "); fprintf(fp," ");
// Check if this is a standard string or a replacement variable // Check if this is a standard string or a replacement variable
if( string != NameList::_signal ) // Normal string. Pass through. if( string == NameList::_signal ) { // Replacement variable
const char* rep_var = inst._format->_rep_vars.iter();
inst.rep_var_format( fp, rep_var);
} else if( string == NameList::_signal3 ) { // Replacement variable in raw text
const char* rep_var = inst._format->_rep_vars.iter();
const Form *form = inst._localNames[rep_var];
if (form == NULL) {
fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
assert(false, "ShouldNotReachHere()");
}
OpClassForm *opc = form->is_opclass();
assert( opc, "replacement variable was not found in local names");
// Lookup the index position of the replacement variable
int idx = inst.operand_position_format(rep_var);
if ( idx == -1 ) {
assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
assert( false, "ShouldNotReachHere()");
}
if (inst.is_noninput_operand(idx)) {
assert( false, "ShouldNotReachHere()");
} else {
// Output the format call for this operand
fprintf(fp,"opnd_array(%d)",idx);
}
rep_var = inst._format->_rep_vars.iter();
inst._format->_strings.iter();
if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
if ( constant_type == Form::idealD ) {
fprintf(fp,"->constantD()");
} else if ( constant_type == Form::idealF ) {
fprintf(fp,"->constantF()");
} else if ( constant_type == Form::idealL ) {
fprintf(fp,"->constantL()");
} else {
fprintf(fp,"->constant()");
}
} else if ( strcmp(rep_var,"$cmpcode") == 0) {
fprintf(fp,"->ccode()");
} else {
assert( false, "ShouldNotReachHere()");
}
} else if( string == NameList::_signal2 ) // Raw program text
fputs(inst._format->_strings.iter(), fp);
else
fprintf(fp,"st->print(\"%s\");\n", string); fprintf(fp,"st->print(\"%s\");\n", string);
else // Replacement variable
inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
} // Done with all format strings } // Done with all format strings
} // Done generating the user-defined portion of the format } // Done generating the user-defined portion of the format
...@@ -1404,7 +1449,7 @@ void ArchDesc::declareClasses(FILE *fp) { ...@@ -1404,7 +1449,7 @@ void ArchDesc::declareClasses(FILE *fp) {
oper->_components.reset(); oper->_components.reset();
if ((comp = oper->_components.iter()) == NULL) { if ((comp = oper->_components.iter()) == NULL) {
assert(num_consts == 1, "Bad component list detected.\n"); assert(num_consts == 1, "Bad component list detected.\n");
i = dump_spec_constant( fp, type, i ); i = dump_spec_constant( fp, type, i, oper );
// Check that type actually matched // Check that type actually matched
assert( i != 0, "Non-constant operand lacks component list."); assert( i != 0, "Non-constant operand lacks component list.");
} // end if NULL } // end if NULL
...@@ -1414,7 +1459,7 @@ void ArchDesc::declareClasses(FILE *fp) { ...@@ -1414,7 +1459,7 @@ void ArchDesc::declareClasses(FILE *fp) {
oper->_components.reset(); oper->_components.reset();
while((comp = oper->_components.iter()) != NULL) { while((comp = oper->_components.iter()) != NULL) {
type = comp->base_type(_globalNames); type = comp->base_type(_globalNames);
i = dump_spec_constant( fp, type, i ); i = dump_spec_constant( fp, type, i, NULL );
} }
} }
// finish line (3) // finish line (3)
......
...@@ -324,7 +324,7 @@ public: ...@@ -324,7 +324,7 @@ public:
virtual int regnum_to_fpu_offset(int regnum); virtual int regnum_to_fpu_offset(int regnum);
// Is this branch offset small enough to be addressed by a short branch? // Is this branch offset small enough to be addressed by a short branch?
bool is_short_branch_offset(int offset); bool is_short_branch_offset(int rule, int offset);
// Optional scaling for the parameter to the ClearArray/CopyArray node. // Optional scaling for the parameter to the ClearArray/CopyArray node.
static const bool init_array_count_is_in_bytes; static const bool init_array_count_is_in_bytes;
......
...@@ -332,6 +332,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i ...@@ -332,6 +332,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
uint *jmp_end = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); uint *jmp_end = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1); uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); ) DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
blk_starts[0] = 0; blk_starts[0] = 0;
// Initialize the sizes to 0 // Initialize the sizes to 0
...@@ -443,9 +444,9 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i ...@@ -443,9 +444,9 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
uintptr_t target = blk_starts[bnum]; uintptr_t target = blk_starts[bnum];
if( mach->is_pc_relative() ) { if( mach->is_pc_relative() ) {
int offset = target-(blk_starts[i] + jmp_end[i]); int offset = target-(blk_starts[i] + jmp_end[i]);
if (_matcher->is_short_branch_offset(offset)) { if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
// We've got a winner. Replace this branch. // We've got a winner. Replace this branch.
MachNode *replacement = mach->short_branch_version(this); MachNode* replacement = mach->short_branch_version(this);
b->_nodes.map(j, replacement); b->_nodes.map(j, replacement);
mach->subsume_by(replacement); mach->subsume_by(replacement);
...@@ -453,6 +454,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i ...@@ -453,6 +454,7 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
// next pass. // next pass.
jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc)); jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
DEBUG_ONLY( jmp_target[i] = bnum; ); DEBUG_ONLY( jmp_target[i] = bnum; );
DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
} }
} else { } else {
#ifndef PRODUCT #ifndef PRODUCT
...@@ -524,10 +526,10 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i ...@@ -524,10 +526,10 @@ void Compile::Shorten_branches(Label *labels, int& code_size, int& reloc_size, i
for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
if( jmp_target[i] != 0 ) { if( jmp_target[i] != 0 ) {
int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]); int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
if (!_matcher->is_short_branch_offset(offset)) { if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]); tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
} }
assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp"); assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
} }
} }
#endif #endif
...@@ -1069,7 +1071,7 @@ void Compile::Fill_buffer() { ...@@ -1069,7 +1071,7 @@ void Compile::Fill_buffer() {
// If this machine supports different size branch offsets, then pre-compute // If this machine supports different size branch offsets, then pre-compute
// the length of the blocks // the length of the blocks
if( _matcher->is_short_branch_offset(0) ) { if( _matcher->is_short_branch_offset(-1, 0) ) {
Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req); Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
labels_not_set = false; labels_not_set = false;
} }
......
...@@ -53,6 +53,7 @@ Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) { ...@@ -53,6 +53,7 @@ Node *PhaseChaitin::get_spillcopy_wide( Node *def, Node *use, uint uidx ) {
// Bail rather than abort // Bail rather than abort
int ireg = def->ideal_reg(); int ireg = def->ideal_reg();
if( ireg == 0 || ireg == Op_RegFlags ) { if( ireg == 0 || ireg == Op_RegFlags ) {
assert(false, "attempted to spill a non-spillable item");
C->record_method_not_compilable("attempted to spill a non-spillable item"); C->record_method_not_compilable("attempted to spill a non-spillable item");
return NULL; return NULL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册