--- a/hotspot/src/cpu/x86/vm/x86_32.ad Wed Aug 10 14:06:57 2011 -0700
+++ b/hotspot/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);