Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/x86_32.ad @ 3851:95134e034042
7063629: use cbcond in C2 generated code on T4
Summary: Use new short branch instruction in C2 generated code.
Reviewed-by: never
author | kvn |
---|---|
date | Thu, 11 Aug 2011 12:08:11 -0700 |
parents | f1c12354c3f7 |
children | 1af104d6cf99 |
comparison
equal
deleted
inserted
replaced
3850:6987871cfb9b | 3851: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 |