diff -r 6987871cfb9b -r 95134e034042 src/cpu/x86/vm/x86_32.ad --- a/src/cpu/x86/vm/x86_32.ad Wed Aug 10 14:06:57 2011 -0700 +++ b/src/cpu/x86/vm/x86_32.ad Thu Aug 11 12:08:11 2011 -0700 @@ -1369,7 +1369,12 @@ // // NOTE: If the platform does not provide any short branch variants, then // this method should return false for offset 0. -bool Matcher::is_short_branch_offset(int rule, int offset) { +bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { + // The passed offset is relative to address of the branch. + // On 86 a branch displacement is calculated relative to address + // of a next instruction. + offset -= br_size; + // the short version of jmpConUCF2 contains multiple branches, // making the reach slightly less if (rule == jmpConUCF2_rule) @@ -1713,18 +1718,6 @@ else emit_d32(cbuf,con); %} - enc_class Lbl (label labl) %{ // GOTO - Label *l = $labl$$label; - emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4))); - %} - - enc_class LblShort (label labl) %{ // GOTO - Label *l = $labl$$label; - int disp = l->loc_pos() - (cbuf.insts_size()+1); - assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); - emit_d8(cbuf, disp); - %} - enc_class OpcSReg (eRegI dst) %{ // BSWAP emit_cc(cbuf, $secondary, $dst$$reg ); %} @@ -1747,21 +1740,6 @@ emit_rm(cbuf, 0x3, $secondary, $div$$reg ); %} - enc_class Jcc (cmpOp cop, label labl) %{ // JCC - Label *l = $labl$$label; - $$$emit8$primary; - emit_cc(cbuf, $secondary, $cop$$cmpcode); - emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4))); - %} - - enc_class JccShort (cmpOp cop, label labl) %{ // JCC - Label *l = $labl$$label; - emit_cc(cbuf, $primary, $cop$$cmpcode); - int disp = l->loc_pos() - (cbuf.insts_size()+1); - assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); - emit_d8(cbuf, disp); - %} - enc_class enc_cmov(cmpOp cop ) %{ // CMOV $$$emit8$primary; emit_cc(cbuf, $secondary, $cop$$cmpcode); @@ -13055,8 +13033,10 @@ ins_cost(300); format %{ "JMP $labl" %} size(5); - opcode(0xE9); - ins_encode( OpcP, Lbl( labl ) ); + ins_encode %{ + Label* L = $labl$$label; + __ jmp(*L, false); // Always long jump + %} ins_pipe( pipe_jmp ); %} @@ -13068,8 +13048,10 @@ ins_cost(300); format %{ "J$cop $labl" %} size(6); - opcode(0x0F, 0x80); - ins_encode( Jcc( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe( pipe_jcc ); %} @@ -13081,8 +13063,10 @@ ins_cost(300); format %{ "J$cop $labl\t# Loop end" %} size(6); - opcode(0x0F, 0x80); - ins_encode( Jcc( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe( pipe_jcc ); %} @@ -13094,8 +13078,10 @@ ins_cost(300); format %{ "J$cop,u $labl\t# Loop end" %} size(6); - opcode(0x0F, 0x80); - ins_encode( Jcc( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe( pipe_jcc ); %} @@ -13106,8 +13092,10 @@ ins_cost(200); format %{ "J$cop,u $labl\t# Loop end" %} size(6); - opcode(0x0F, 0x80); - ins_encode( Jcc( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe( pipe_jcc ); %} @@ -13119,8 +13107,10 @@ ins_cost(300); format %{ "J$cop,u $labl" %} size(6); - opcode(0x0F, 0x80); - ins_encode(Jcc(cop, labl)); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe(pipe_jcc); %} @@ -13131,8 +13121,10 @@ ins_cost(200); format %{ "J$cop,u $labl" %} size(6); - opcode(0x0F, 0x80); - ins_encode(Jcc(cop, labl)); + ins_encode %{ + Label* L = $labl$$label; + __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump + %} ins_pipe(pipe_jcc); %} @@ -13151,28 +13143,19 @@ $$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->loc_pos() - (cbuf.insts_size() + 4); + __ jcc(Assembler::parity, *l, false); + __ jcc(Assembler::notEqual, *l, false); } else if ($cop$$cmpcode == Assembler::equal) { - parity_disp = 6; - ok = true; + Label done; + __ jccb(Assembler::parity, done); + __ jcc(Assembler::equal, *l, false); + __ bind(done); } else { ShouldNotReachHere(); } - emit_d32(cbuf, parity_disp); - $$$emit8$primary; - emit_cc(cbuf, $secondary, $cop$$cmpcode); - int disp = l->loc_pos() - (cbuf.insts_size() + 4); - emit_d32(cbuf, disp); %} ins_pipe(pipe_jcc); %} @@ -13239,8 +13222,10 @@ ins_cost(300); format %{ "JMP,s $labl" %} size(2); - opcode(0xEB); - ins_encode( OpcP, LblShort( labl ) ); + ins_encode %{ + Label* L = $labl$$label; + __ jmpb(*L); + %} ins_pipe( pipe_jmp ); ins_short_branch(1); %} @@ -13253,8 +13238,10 @@ ins_cost(300); format %{ "J$cop,s $labl" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13267,8 +13254,10 @@ ins_cost(300); format %{ "J$cop,s $labl\t# Loop end" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13281,8 +13270,10 @@ ins_cost(300); format %{ "J$cop,us $labl\t# Loop end" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13294,8 +13285,10 @@ ins_cost(300); format %{ "J$cop,us $labl\t# Loop end" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13308,8 +13301,10 @@ ins_cost(300); format %{ "J$cop,us $labl" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13321,8 +13316,10 @@ ins_cost(300); format %{ "J$cop,us $labl" %} size(2); - opcode(0x70); - ins_encode( JccShort( cop, labl) ); + ins_encode %{ + Label* L = $labl$$label; + __ jccb((Assembler::Condition)($cop$$cmpcode), *L); + %} ins_pipe( pipe_jcc ); ins_short_branch(1); %} @@ -13343,24 +13340,19 @@ } %} 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->loc_pos() - (cbuf.insts_size() + 1); + __ jccb(Assembler::parity, *l); + __ jccb(Assembler::notEqual, *l); } else if ($cop$$cmpcode == Assembler::equal) { - parity_disp = 2; + Label done; + __ jccb(Assembler::parity, done); + __ jccb(Assembler::equal, *l); + __ bind(done); } else { - ShouldNotReachHere(); - } - emit_d8(cbuf, parity_disp); - emit_cc(cbuf, $primary, $cop$$cmpcode); - int disp = l->loc_pos() - (cbuf.insts_size() + 1); - 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"); + ShouldNotReachHere(); + } %} ins_pipe(pipe_jcc); ins_short_branch(1);