src/cpu/x86/vm/x86_32.ad

changeset 3049
95134e034042
parent 3047
f1c12354c3f7
child 3052
1af104d6cf99
equal deleted inserted replaced
3048:6987871cfb9b 3049:95134e034042
1367 1367
1368 // Is this branch offset short enough that a short branch can be used? 1368 // Is this branch offset short enough that a short branch can be used?
1369 // 1369 //
1370 // NOTE: If the platform does not provide any short branch variants, then 1370 // NOTE: If the platform does not provide any short branch variants, then
1371 // this method should return false for offset 0. 1371 // this method should return false for offset 0.
1372 bool Matcher::is_short_branch_offset(int rule, int offset) { 1372 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1373 // The passed offset is relative to address of the branch.
1374 // On 86 a branch displacement is calculated relative to address
1375 // of a next instruction.
1376 offset -= br_size;
1377
1373 // the short version of jmpConUCF2 contains multiple branches, 1378 // the short version of jmpConUCF2 contains multiple branches,
1374 // making the reach slightly less 1379 // making the reach slightly less
1375 if (rule == jmpConUCF2_rule) 1380 if (rule == jmpConUCF2_rule)
1376 return (-126 <= offset && offset <= 125); 1381 return (-126 <= offset && offset <= 125);
1377 return (-128 <= offset && offset <= 127); 1382 return (-128 <= offset && offset <= 127);
1711 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg)); 1716 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg));
1712 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1717 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
1713 else emit_d32(cbuf,con); 1718 else emit_d32(cbuf,con);
1714 %} 1719 %}
1715 1720
1716 enc_class Lbl (label labl) %{ // GOTO
1717 Label *l = $labl$$label;
1718 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4)));
1719 %}
1720
1721 enc_class LblShort (label labl) %{ // GOTO
1722 Label *l = $labl$$label;
1723 int disp = l->loc_pos() - (cbuf.insts_size()+1);
1724 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
1725 emit_d8(cbuf, disp);
1726 %}
1727
1728 enc_class OpcSReg (eRegI dst) %{ // BSWAP 1721 enc_class OpcSReg (eRegI dst) %{ // BSWAP
1729 emit_cc(cbuf, $secondary, $dst$$reg ); 1722 emit_cc(cbuf, $secondary, $dst$$reg );
1730 %} 1723 %}
1731 1724
1732 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP 1725 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP
1743 emit_rm(cbuf, 0x3, destlo, desthi); 1736 emit_rm(cbuf, 0x3, destlo, desthi);
1744 %} 1737 %}
1745 1738
1746 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ... 1739 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ...
1747 emit_rm(cbuf, 0x3, $secondary, $div$$reg ); 1740 emit_rm(cbuf, 0x3, $secondary, $div$$reg );
1748 %}
1749
1750 enc_class Jcc (cmpOp cop, label labl) %{ // JCC
1751 Label *l = $labl$$label;
1752 $$$emit8$primary;
1753 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1754 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4)));
1755 %}
1756
1757 enc_class JccShort (cmpOp cop, label labl) %{ // JCC
1758 Label *l = $labl$$label;
1759 emit_cc(cbuf, $primary, $cop$$cmpcode);
1760 int disp = l->loc_pos() - (cbuf.insts_size()+1);
1761 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
1762 emit_d8(cbuf, disp);
1763 %} 1741 %}
1764 1742
1765 enc_class enc_cmov(cmpOp cop ) %{ // CMOV 1743 enc_class enc_cmov(cmpOp cop ) %{ // CMOV
1766 $$$emit8$primary; 1744 $$$emit8$primary;
1767 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1745 emit_cc(cbuf, $secondary, $cop$$cmpcode);
13053 effect(USE labl); 13031 effect(USE labl);
13054 13032
13055 ins_cost(300); 13033 ins_cost(300);
13056 format %{ "JMP $labl" %} 13034 format %{ "JMP $labl" %}
13057 size(5); 13035 size(5);
13058 opcode(0xE9); 13036 ins_encode %{
13059 ins_encode( OpcP, Lbl( labl ) ); 13037 Label* L = $labl$$label;
13038 __ jmp(*L, false); // Always long jump
13039 %}
13060 ins_pipe( pipe_jmp ); 13040 ins_pipe( pipe_jmp );
13061 %} 13041 %}
13062 13042
13063 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13043 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13064 instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{ 13044 instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{
13066 effect(USE labl); 13046 effect(USE labl);
13067 13047
13068 ins_cost(300); 13048 ins_cost(300);
13069 format %{ "J$cop $labl" %} 13049 format %{ "J$cop $labl" %}
13070 size(6); 13050 size(6);
13071 opcode(0x0F, 0x80); 13051 ins_encode %{
13072 ins_encode( Jcc( cop, labl) ); 13052 Label* L = $labl$$label;
13053 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13054 %}
13073 ins_pipe( pipe_jcc ); 13055 ins_pipe( pipe_jcc );
13074 %} 13056 %}
13075 13057
13076 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13058 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13077 instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{ 13059 instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{
13079 effect(USE labl); 13061 effect(USE labl);
13080 13062
13081 ins_cost(300); 13063 ins_cost(300);
13082 format %{ "J$cop $labl\t# Loop end" %} 13064 format %{ "J$cop $labl\t# Loop end" %}
13083 size(6); 13065 size(6);
13084 opcode(0x0F, 0x80); 13066 ins_encode %{
13085 ins_encode( Jcc( cop, labl) ); 13067 Label* L = $labl$$label;
13068 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13069 %}
13086 ins_pipe( pipe_jcc ); 13070 ins_pipe( pipe_jcc );
13087 %} 13071 %}
13088 13072
13089 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13073 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13090 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13074 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
13092 effect(USE labl); 13076 effect(USE labl);
13093 13077
13094 ins_cost(300); 13078 ins_cost(300);
13095 format %{ "J$cop,u $labl\t# Loop end" %} 13079 format %{ "J$cop,u $labl\t# Loop end" %}
13096 size(6); 13080 size(6);
13097 opcode(0x0F, 0x80); 13081 ins_encode %{
13098 ins_encode( Jcc( cop, labl) ); 13082 Label* L = $labl$$label;
13083 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13084 %}
13099 ins_pipe( pipe_jcc ); 13085 ins_pipe( pipe_jcc );
13100 %} 13086 %}
13101 13087
13102 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13088 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
13103 match(CountedLoopEnd cop cmp); 13089 match(CountedLoopEnd cop cmp);
13104 effect(USE labl); 13090 effect(USE labl);
13105 13091
13106 ins_cost(200); 13092 ins_cost(200);
13107 format %{ "J$cop,u $labl\t# Loop end" %} 13093 format %{ "J$cop,u $labl\t# Loop end" %}
13108 size(6); 13094 size(6);
13109 opcode(0x0F, 0x80); 13095 ins_encode %{
13110 ins_encode( Jcc( cop, labl) ); 13096 Label* L = $labl$$label;
13097 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13098 %}
13111 ins_pipe( pipe_jcc ); 13099 ins_pipe( pipe_jcc );
13112 %} 13100 %}
13113 13101
13114 // Jump Direct Conditional - using unsigned comparison 13102 // Jump Direct Conditional - using unsigned comparison
13115 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13103 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
13117 effect(USE labl); 13105 effect(USE labl);
13118 13106
13119 ins_cost(300); 13107 ins_cost(300);
13120 format %{ "J$cop,u $labl" %} 13108 format %{ "J$cop,u $labl" %}
13121 size(6); 13109 size(6);
13122 opcode(0x0F, 0x80); 13110 ins_encode %{
13123 ins_encode(Jcc(cop, labl)); 13111 Label* L = $labl$$label;
13112 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13113 %}
13124 ins_pipe(pipe_jcc); 13114 ins_pipe(pipe_jcc);
13125 %} 13115 %}
13126 13116
13127 instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13117 instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
13128 match(If cop cmp); 13118 match(If cop cmp);
13129 effect(USE labl); 13119 effect(USE labl);
13130 13120
13131 ins_cost(200); 13121 ins_cost(200);
13132 format %{ "J$cop,u $labl" %} 13122 format %{ "J$cop,u $labl" %}
13133 size(6); 13123 size(6);
13134 opcode(0x0F, 0x80); 13124 ins_encode %{
13135 ins_encode(Jcc(cop, labl)); 13125 Label* L = $labl$$label;
13126 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
13127 %}
13136 ins_pipe(pipe_jcc); 13128 ins_pipe(pipe_jcc);
13137 %} 13129 %}
13138 13130
13139 instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 13131 instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
13140 match(If cop cmp); 13132 match(If cop cmp);
13149 $$emit$$"JP,u done\n\t" 13141 $$emit$$"JP,u done\n\t"
13150 $$emit$$"J$cop,u $labl\n\t" 13142 $$emit$$"J$cop,u $labl\n\t"
13151 $$emit$$"done:" 13143 $$emit$$"done:"
13152 } 13144 }
13153 %} 13145 %}
13154 size(12);
13155 opcode(0x0F, 0x80);
13156 ins_encode %{ 13146 ins_encode %{
13157 Label* l = $labl$$label; 13147 Label* l = $labl$$label;
13158 $$$emit8$primary;
13159 emit_cc(cbuf, $secondary, Assembler::parity);
13160 int parity_disp = -1;
13161 bool ok = false;
13162 if ($cop$$cmpcode == Assembler::notEqual) { 13148 if ($cop$$cmpcode == Assembler::notEqual) {
13163 // the two jumps 6 bytes apart so the jump distances are too 13149 __ jcc(Assembler::parity, *l, false);
13164 parity_disp = l->loc_pos() - (cbuf.insts_size() + 4); 13150 __ jcc(Assembler::notEqual, *l, false);
13165 } else if ($cop$$cmpcode == Assembler::equal) { 13151 } else if ($cop$$cmpcode == Assembler::equal) {
13166 parity_disp = 6; 13152 Label done;
13167 ok = true; 13153 __ jccb(Assembler::parity, done);
13154 __ jcc(Assembler::equal, *l, false);
13155 __ bind(done);
13168 } else { 13156 } else {
13169 ShouldNotReachHere(); 13157 ShouldNotReachHere();
13170 } 13158 }
13171 emit_d32(cbuf, parity_disp);
13172 $$$emit8$primary;
13173 emit_cc(cbuf, $secondary, $cop$$cmpcode);
13174 int disp = l->loc_pos() - (cbuf.insts_size() + 4);
13175 emit_d32(cbuf, disp);
13176 %} 13159 %}
13177 ins_pipe(pipe_jcc); 13160 ins_pipe(pipe_jcc);
13178 %} 13161 %}
13179 13162
13180 // ============================================================================ 13163 // ============================================================================
13237 effect(USE labl); 13220 effect(USE labl);
13238 13221
13239 ins_cost(300); 13222 ins_cost(300);
13240 format %{ "JMP,s $labl" %} 13223 format %{ "JMP,s $labl" %}
13241 size(2); 13224 size(2);
13242 opcode(0xEB); 13225 ins_encode %{
13243 ins_encode( OpcP, LblShort( labl ) ); 13226 Label* L = $labl$$label;
13227 __ jmpb(*L);
13228 %}
13244 ins_pipe( pipe_jmp ); 13229 ins_pipe( pipe_jmp );
13245 ins_short_branch(1); 13230 ins_short_branch(1);
13246 %} 13231 %}
13247 13232
13248 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13233 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13251 effect(USE labl); 13236 effect(USE labl);
13252 13237
13253 ins_cost(300); 13238 ins_cost(300);
13254 format %{ "J$cop,s $labl" %} 13239 format %{ "J$cop,s $labl" %}
13255 size(2); 13240 size(2);
13256 opcode(0x70); 13241 ins_encode %{
13257 ins_encode( JccShort( cop, labl) ); 13242 Label* L = $labl$$label;
13243 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13244 %}
13258 ins_pipe( pipe_jcc ); 13245 ins_pipe( pipe_jcc );
13259 ins_short_branch(1); 13246 ins_short_branch(1);
13260 %} 13247 %}
13261 13248
13262 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13249 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13265 effect(USE labl); 13252 effect(USE labl);
13266 13253
13267 ins_cost(300); 13254 ins_cost(300);
13268 format %{ "J$cop,s $labl\t# Loop end" %} 13255 format %{ "J$cop,s $labl\t# Loop end" %}
13269 size(2); 13256 size(2);
13270 opcode(0x70); 13257 ins_encode %{
13271 ins_encode( JccShort( cop, labl) ); 13258 Label* L = $labl$$label;
13259 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13260 %}
13272 ins_pipe( pipe_jcc ); 13261 ins_pipe( pipe_jcc );
13273 ins_short_branch(1); 13262 ins_short_branch(1);
13274 %} 13263 %}
13275 13264
13276 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13265 // Jump Direct Conditional - Label defines a relative address from Jcc+1
13279 effect(USE labl); 13268 effect(USE labl);
13280 13269
13281 ins_cost(300); 13270 ins_cost(300);
13282 format %{ "J$cop,us $labl\t# Loop end" %} 13271 format %{ "J$cop,us $labl\t# Loop end" %}
13283 size(2); 13272 size(2);
13284 opcode(0x70); 13273 ins_encode %{
13285 ins_encode( JccShort( cop, labl) ); 13274 Label* L = $labl$$label;
13275 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13276 %}
13286 ins_pipe( pipe_jcc ); 13277 ins_pipe( pipe_jcc );
13287 ins_short_branch(1); 13278 ins_short_branch(1);
13288 %} 13279 %}
13289 13280
13290 instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13281 instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
13292 effect(USE labl); 13283 effect(USE labl);
13293 13284
13294 ins_cost(300); 13285 ins_cost(300);
13295 format %{ "J$cop,us $labl\t# Loop end" %} 13286 format %{ "J$cop,us $labl\t# Loop end" %}
13296 size(2); 13287 size(2);
13297 opcode(0x70); 13288 ins_encode %{
13298 ins_encode( JccShort( cop, labl) ); 13289 Label* L = $labl$$label;
13290 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13291 %}
13299 ins_pipe( pipe_jcc ); 13292 ins_pipe( pipe_jcc );
13300 ins_short_branch(1); 13293 ins_short_branch(1);
13301 %} 13294 %}
13302 13295
13303 // Jump Direct Conditional - using unsigned comparison 13296 // Jump Direct Conditional - using unsigned comparison
13306 effect(USE labl); 13299 effect(USE labl);
13307 13300
13308 ins_cost(300); 13301 ins_cost(300);
13309 format %{ "J$cop,us $labl" %} 13302 format %{ "J$cop,us $labl" %}
13310 size(2); 13303 size(2);
13311 opcode(0x70); 13304 ins_encode %{
13312 ins_encode( JccShort( cop, labl) ); 13305 Label* L = $labl$$label;
13306 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13307 %}
13313 ins_pipe( pipe_jcc ); 13308 ins_pipe( pipe_jcc );
13314 ins_short_branch(1); 13309 ins_short_branch(1);
13315 %} 13310 %}
13316 13311
13317 instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13312 instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
13319 effect(USE labl); 13314 effect(USE labl);
13320 13315
13321 ins_cost(300); 13316 ins_cost(300);
13322 format %{ "J$cop,us $labl" %} 13317 format %{ "J$cop,us $labl" %}
13323 size(2); 13318 size(2);
13324 opcode(0x70); 13319 ins_encode %{
13325 ins_encode( JccShort( cop, labl) ); 13320 Label* L = $labl$$label;
13321 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
13322 %}
13326 ins_pipe( pipe_jcc ); 13323 ins_pipe( pipe_jcc );
13327 ins_short_branch(1); 13324 ins_short_branch(1);
13328 %} 13325 %}
13329 13326
13330 instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 13327 instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
13341 $$emit$$"J$cop,u,s $labl\n\t" 13338 $$emit$$"J$cop,u,s $labl\n\t"
13342 $$emit$$"done:" 13339 $$emit$$"done:"
13343 } 13340 }
13344 %} 13341 %}
13345 size(4); 13342 size(4);
13346 opcode(0x70);
13347 ins_encode %{ 13343 ins_encode %{
13348 Label* l = $labl$$label; 13344 Label* l = $labl$$label;
13349 emit_cc(cbuf, $primary, Assembler::parity);
13350 int parity_disp = -1;
13351 if ($cop$$cmpcode == Assembler::notEqual) { 13345 if ($cop$$cmpcode == Assembler::notEqual) {
13352 parity_disp = l->loc_pos() - (cbuf.insts_size() + 1); 13346 __ jccb(Assembler::parity, *l);
13347 __ jccb(Assembler::notEqual, *l);
13353 } else if ($cop$$cmpcode == Assembler::equal) { 13348 } else if ($cop$$cmpcode == Assembler::equal) {
13354 parity_disp = 2; 13349 Label done;
13350 __ jccb(Assembler::parity, done);
13351 __ jccb(Assembler::equal, *l);
13352 __ bind(done);
13355 } else { 13353 } else {
13356 ShouldNotReachHere(); 13354 ShouldNotReachHere();
13357 } 13355 }
13358 emit_d8(cbuf, parity_disp);
13359 emit_cc(cbuf, $primary, $cop$$cmpcode);
13360 int disp = l->loc_pos() - (cbuf.insts_size() + 1);
13361 emit_d8(cbuf, disp);
13362 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
13363 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
13364 %} 13356 %}
13365 ins_pipe(pipe_jcc); 13357 ins_pipe(pipe_jcc);
13366 ins_short_branch(1); 13358 ins_short_branch(1);
13367 %} 13359 %}
13368 13360

mercurial