Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.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 |
---|---|
1964 | 1964 |
1965 // Is this branch offset short enough that a short branch can be used? | 1965 // Is this branch offset short enough that a short branch can be used? |
1966 // | 1966 // |
1967 // NOTE: If the platform does not provide any short branch variants, then | 1967 // NOTE: If the platform does not provide any short branch variants, then |
1968 // this method should return false for offset 0. | 1968 // this method should return false for offset 0. |
1969 bool Matcher::is_short_branch_offset(int rule, int offset) { | 1969 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { |
1970 // The passed offset is relative to address of the branch. | |
1971 // On 86 a branch displacement is calculated relative to address | |
1972 // of a next instruction. | |
1973 offset -= br_size; | |
1974 | |
1970 // the short version of jmpConUCF2 contains multiple branches, | 1975 // the short version of jmpConUCF2 contains multiple branches, |
1971 // making the reach slightly less | 1976 // making the reach slightly less |
1972 if (rule == jmpConUCF2_rule) | 1977 if (rule == jmpConUCF2_rule) |
1973 return (-126 <= offset && offset <= 125); | 1978 return (-126 <= offset && offset <= 125); |
1974 return (-128 <= offset && offset <= 127); | 1979 return (-128 <= offset && offset <= 127); |
2424 // 32-bit immediate | 2429 // 32-bit immediate |
2425 $$$emit32$imm$$constant; | 2430 $$$emit32$imm$$constant; |
2426 } | 2431 } |
2427 %} | 2432 %} |
2428 | 2433 |
2429 enc_class Lbl(label labl) | |
2430 %{ | |
2431 // GOTO | |
2432 Label* l = $labl$$label; | |
2433 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size() + 4))); | |
2434 %} | |
2435 | |
2436 enc_class LblShort(label labl) | |
2437 %{ | |
2438 // GOTO | |
2439 Label* l = $labl$$label; | |
2440 int disp = l->loc_pos() - (cbuf.insts_size() + 1); | |
2441 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); | |
2442 emit_d8(cbuf, disp); | |
2443 %} | |
2444 | |
2445 enc_class opc2_reg(rRegI dst) | 2434 enc_class opc2_reg(rRegI dst) |
2446 %{ | 2435 %{ |
2447 // BSWAP | 2436 // BSWAP |
2448 emit_cc(cbuf, $secondary, $dst$$reg); | 2437 emit_cc(cbuf, $secondary, $dst$$reg); |
2449 %} | 2438 %} |
2456 | 2445 |
2457 enc_class reg_opc(rRegI div) | 2446 enc_class reg_opc(rRegI div) |
2458 %{ | 2447 %{ |
2459 // INC, DEC, IDIV, IMOD, JMP indirect, ... | 2448 // INC, DEC, IDIV, IMOD, JMP indirect, ... |
2460 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); | 2449 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); |
2461 %} | |
2462 | |
2463 enc_class Jcc(cmpOp cop, label labl) | |
2464 %{ | |
2465 // JCC | |
2466 Label* l = $labl$$label; | |
2467 $$$emit8$primary; | |
2468 emit_cc(cbuf, $secondary, $cop$$cmpcode); | |
2469 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size() + 4))); | |
2470 %} | |
2471 | |
2472 enc_class JccShort (cmpOp cop, label labl) | |
2473 %{ | |
2474 // JCC | |
2475 Label *l = $labl$$label; | |
2476 emit_cc(cbuf, $primary, $cop$$cmpcode); | |
2477 int disp = l->loc_pos() - (cbuf.insts_size() + 1); | |
2478 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); | |
2479 emit_d8(cbuf, disp); | |
2480 %} | 2450 %} |
2481 | 2451 |
2482 enc_class enc_cmov(cmpOp cop) | 2452 enc_class enc_cmov(cmpOp cop) |
2483 %{ | 2453 %{ |
2484 // CMOV | 2454 // CMOV |
12009 effect(USE labl); | 11979 effect(USE labl); |
12010 | 11980 |
12011 ins_cost(300); | 11981 ins_cost(300); |
12012 format %{ "jmp $labl" %} | 11982 format %{ "jmp $labl" %} |
12013 size(5); | 11983 size(5); |
12014 opcode(0xE9); | 11984 ins_encode %{ |
12015 ins_encode(OpcP, Lbl(labl)); | 11985 Label* L = $labl$$label; |
11986 __ jmp(*L, false); // Always long jump | |
11987 %} | |
12016 ins_pipe(pipe_jmp); | 11988 ins_pipe(pipe_jmp); |
12017 %} | 11989 %} |
12018 | 11990 |
12019 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 11991 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12020 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) | 11992 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) |
12023 effect(USE labl); | 11995 effect(USE labl); |
12024 | 11996 |
12025 ins_cost(300); | 11997 ins_cost(300); |
12026 format %{ "j$cop $labl" %} | 11998 format %{ "j$cop $labl" %} |
12027 size(6); | 11999 size(6); |
12028 opcode(0x0F, 0x80); | 12000 ins_encode %{ |
12029 ins_encode(Jcc(cop, labl)); | 12001 Label* L = $labl$$label; |
12002 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12003 %} | |
12030 ins_pipe(pipe_jcc); | 12004 ins_pipe(pipe_jcc); |
12031 %} | 12005 %} |
12032 | 12006 |
12033 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 12007 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12034 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) | 12008 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) |
12037 effect(USE labl); | 12011 effect(USE labl); |
12038 | 12012 |
12039 ins_cost(300); | 12013 ins_cost(300); |
12040 format %{ "j$cop $labl\t# loop end" %} | 12014 format %{ "j$cop $labl\t# loop end" %} |
12041 size(6); | 12015 size(6); |
12042 opcode(0x0F, 0x80); | 12016 ins_encode %{ |
12043 ins_encode(Jcc(cop, labl)); | 12017 Label* L = $labl$$label; |
12018 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12019 %} | |
12044 ins_pipe(pipe_jcc); | 12020 ins_pipe(pipe_jcc); |
12045 %} | 12021 %} |
12046 | 12022 |
12047 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 12023 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12048 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ | 12024 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
12050 effect(USE labl); | 12026 effect(USE labl); |
12051 | 12027 |
12052 ins_cost(300); | 12028 ins_cost(300); |
12053 format %{ "j$cop,u $labl\t# loop end" %} | 12029 format %{ "j$cop,u $labl\t# loop end" %} |
12054 size(6); | 12030 size(6); |
12055 opcode(0x0F, 0x80); | 12031 ins_encode %{ |
12056 ins_encode(Jcc(cop, labl)); | 12032 Label* L = $labl$$label; |
12033 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12034 %} | |
12057 ins_pipe(pipe_jcc); | 12035 ins_pipe(pipe_jcc); |
12058 %} | 12036 %} |
12059 | 12037 |
12060 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ | 12038 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
12061 match(CountedLoopEnd cop cmp); | 12039 match(CountedLoopEnd cop cmp); |
12062 effect(USE labl); | 12040 effect(USE labl); |
12063 | 12041 |
12064 ins_cost(200); | 12042 ins_cost(200); |
12065 format %{ "j$cop,u $labl\t# loop end" %} | 12043 format %{ "j$cop,u $labl\t# loop end" %} |
12066 size(6); | 12044 size(6); |
12067 opcode(0x0F, 0x80); | 12045 ins_encode %{ |
12068 ins_encode(Jcc(cop, labl)); | 12046 Label* L = $labl$$label; |
12047 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12048 %} | |
12069 ins_pipe(pipe_jcc); | 12049 ins_pipe(pipe_jcc); |
12070 %} | 12050 %} |
12071 | 12051 |
12072 // Jump Direct Conditional - using unsigned comparison | 12052 // Jump Direct Conditional - using unsigned comparison |
12073 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ | 12053 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ |
12075 effect(USE labl); | 12055 effect(USE labl); |
12076 | 12056 |
12077 ins_cost(300); | 12057 ins_cost(300); |
12078 format %{ "j$cop,u $labl" %} | 12058 format %{ "j$cop,u $labl" %} |
12079 size(6); | 12059 size(6); |
12080 opcode(0x0F, 0x80); | 12060 ins_encode %{ |
12081 ins_encode(Jcc(cop, labl)); | 12061 Label* L = $labl$$label; |
12062 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12063 %} | |
12082 ins_pipe(pipe_jcc); | 12064 ins_pipe(pipe_jcc); |
12083 %} | 12065 %} |
12084 | 12066 |
12085 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ | 12067 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
12086 match(If cop cmp); | 12068 match(If cop cmp); |
12087 effect(USE labl); | 12069 effect(USE labl); |
12088 | 12070 |
12089 ins_cost(200); | 12071 ins_cost(200); |
12090 format %{ "j$cop,u $labl" %} | 12072 format %{ "j$cop,u $labl" %} |
12091 size(6); | 12073 size(6); |
12092 opcode(0x0F, 0x80); | 12074 ins_encode %{ |
12093 ins_encode(Jcc(cop, labl)); | 12075 Label* L = $labl$$label; |
12076 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump | |
12077 %} | |
12094 ins_pipe(pipe_jcc); | 12078 ins_pipe(pipe_jcc); |
12095 %} | 12079 %} |
12096 | 12080 |
12097 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ | 12081 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ |
12098 match(If cop cmp); | 12082 match(If cop cmp); |
12107 $$emit$$"jp,u done\n\t" | 12091 $$emit$$"jp,u done\n\t" |
12108 $$emit$$"j$cop,u $labl\n\t" | 12092 $$emit$$"j$cop,u $labl\n\t" |
12109 $$emit$$"done:" | 12093 $$emit$$"done:" |
12110 } | 12094 } |
12111 %} | 12095 %} |
12112 size(12); | |
12113 opcode(0x0F, 0x80); | |
12114 ins_encode %{ | 12096 ins_encode %{ |
12115 Label* l = $labl$$label; | 12097 Label* l = $labl$$label; |
12116 $$$emit8$primary; | |
12117 emit_cc(cbuf, $secondary, Assembler::parity); | |
12118 int parity_disp = -1; | |
12119 if ($cop$$cmpcode == Assembler::notEqual) { | 12098 if ($cop$$cmpcode == Assembler::notEqual) { |
12120 // the two jumps 6 bytes apart so the jump distances are too | 12099 __ jcc(Assembler::parity, *l, false); |
12121 parity_disp = l->loc_pos() - (cbuf.insts_size() + 4); | 12100 __ jcc(Assembler::notEqual, *l, false); |
12122 } else if ($cop$$cmpcode == Assembler::equal) { | 12101 } else if ($cop$$cmpcode == Assembler::equal) { |
12123 parity_disp = 6; | 12102 Label done; |
12103 __ jccb(Assembler::parity, done); | |
12104 __ jcc(Assembler::equal, *l, false); | |
12105 __ bind(done); | |
12124 } else { | 12106 } else { |
12125 ShouldNotReachHere(); | 12107 ShouldNotReachHere(); |
12126 } | 12108 } |
12127 emit_d32(cbuf, parity_disp); | |
12128 $$$emit8$primary; | |
12129 emit_cc(cbuf, $secondary, $cop$$cmpcode); | |
12130 int disp = l->loc_pos() - (cbuf.insts_size() + 4); | |
12131 emit_d32(cbuf, disp); | |
12132 %} | 12109 %} |
12133 ins_pipe(pipe_jcc); | 12110 ins_pipe(pipe_jcc); |
12134 %} | 12111 %} |
12135 | 12112 |
12136 // ============================================================================ | 12113 // ============================================================================ |
12202 effect(USE labl); | 12179 effect(USE labl); |
12203 | 12180 |
12204 ins_cost(300); | 12181 ins_cost(300); |
12205 format %{ "jmp,s $labl" %} | 12182 format %{ "jmp,s $labl" %} |
12206 size(2); | 12183 size(2); |
12207 opcode(0xEB); | 12184 ins_encode %{ |
12208 ins_encode(OpcP, LblShort(labl)); | 12185 Label* L = $labl$$label; |
12186 __ jmpb(*L); | |
12187 %} | |
12209 ins_pipe(pipe_jmp); | 12188 ins_pipe(pipe_jmp); |
12210 ins_short_branch(1); | 12189 ins_short_branch(1); |
12211 %} | 12190 %} |
12212 | 12191 |
12213 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 12192 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12216 effect(USE labl); | 12195 effect(USE labl); |
12217 | 12196 |
12218 ins_cost(300); | 12197 ins_cost(300); |
12219 format %{ "j$cop,s $labl" %} | 12198 format %{ "j$cop,s $labl" %} |
12220 size(2); | 12199 size(2); |
12221 opcode(0x70); | 12200 ins_encode %{ |
12222 ins_encode(JccShort(cop, labl)); | 12201 Label* L = $labl$$label; |
12202 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12203 %} | |
12223 ins_pipe(pipe_jcc); | 12204 ins_pipe(pipe_jcc); |
12224 ins_short_branch(1); | 12205 ins_short_branch(1); |
12225 %} | 12206 %} |
12226 | 12207 |
12227 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 12208 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12230 effect(USE labl); | 12211 effect(USE labl); |
12231 | 12212 |
12232 ins_cost(300); | 12213 ins_cost(300); |
12233 format %{ "j$cop,s $labl\t# loop end" %} | 12214 format %{ "j$cop,s $labl\t# loop end" %} |
12234 size(2); | 12215 size(2); |
12235 opcode(0x70); | 12216 ins_encode %{ |
12236 ins_encode(JccShort(cop, labl)); | 12217 Label* L = $labl$$label; |
12218 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12219 %} | |
12237 ins_pipe(pipe_jcc); | 12220 ins_pipe(pipe_jcc); |
12238 ins_short_branch(1); | 12221 ins_short_branch(1); |
12239 %} | 12222 %} |
12240 | 12223 |
12241 // Jump Direct Conditional - Label defines a relative address from Jcc+1 | 12224 // Jump Direct Conditional - Label defines a relative address from Jcc+1 |
12244 effect(USE labl); | 12227 effect(USE labl); |
12245 | 12228 |
12246 ins_cost(300); | 12229 ins_cost(300); |
12247 format %{ "j$cop,us $labl\t# loop end" %} | 12230 format %{ "j$cop,us $labl\t# loop end" %} |
12248 size(2); | 12231 size(2); |
12249 opcode(0x70); | 12232 ins_encode %{ |
12250 ins_encode(JccShort(cop, labl)); | 12233 Label* L = $labl$$label; |
12234 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12235 %} | |
12251 ins_pipe(pipe_jcc); | 12236 ins_pipe(pipe_jcc); |
12252 ins_short_branch(1); | 12237 ins_short_branch(1); |
12253 %} | 12238 %} |
12254 | 12239 |
12255 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ | 12240 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
12257 effect(USE labl); | 12242 effect(USE labl); |
12258 | 12243 |
12259 ins_cost(300); | 12244 ins_cost(300); |
12260 format %{ "j$cop,us $labl\t# loop end" %} | 12245 format %{ "j$cop,us $labl\t# loop end" %} |
12261 size(2); | 12246 size(2); |
12262 opcode(0x70); | 12247 ins_encode %{ |
12263 ins_encode(JccShort(cop, labl)); | 12248 Label* L = $labl$$label; |
12249 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12250 %} | |
12264 ins_pipe(pipe_jcc); | 12251 ins_pipe(pipe_jcc); |
12265 ins_short_branch(1); | 12252 ins_short_branch(1); |
12266 %} | 12253 %} |
12267 | 12254 |
12268 // Jump Direct Conditional - using unsigned comparison | 12255 // Jump Direct Conditional - using unsigned comparison |
12271 effect(USE labl); | 12258 effect(USE labl); |
12272 | 12259 |
12273 ins_cost(300); | 12260 ins_cost(300); |
12274 format %{ "j$cop,us $labl" %} | 12261 format %{ "j$cop,us $labl" %} |
12275 size(2); | 12262 size(2); |
12276 opcode(0x70); | 12263 ins_encode %{ |
12277 ins_encode(JccShort(cop, labl)); | 12264 Label* L = $labl$$label; |
12265 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12266 %} | |
12278 ins_pipe(pipe_jcc); | 12267 ins_pipe(pipe_jcc); |
12279 ins_short_branch(1); | 12268 ins_short_branch(1); |
12280 %} | 12269 %} |
12281 | 12270 |
12282 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ | 12271 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ |
12284 effect(USE labl); | 12273 effect(USE labl); |
12285 | 12274 |
12286 ins_cost(300); | 12275 ins_cost(300); |
12287 format %{ "j$cop,us $labl" %} | 12276 format %{ "j$cop,us $labl" %} |
12288 size(2); | 12277 size(2); |
12289 opcode(0x70); | 12278 ins_encode %{ |
12290 ins_encode(JccShort(cop, labl)); | 12279 Label* L = $labl$$label; |
12280 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); | |
12281 %} | |
12291 ins_pipe(pipe_jcc); | 12282 ins_pipe(pipe_jcc); |
12292 ins_short_branch(1); | 12283 ins_short_branch(1); |
12293 %} | 12284 %} |
12294 | 12285 |
12295 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ | 12286 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ |
12306 $$emit$$"j$cop,u,s $labl\n\t" | 12297 $$emit$$"j$cop,u,s $labl\n\t" |
12307 $$emit$$"done:" | 12298 $$emit$$"done:" |
12308 } | 12299 } |
12309 %} | 12300 %} |
12310 size(4); | 12301 size(4); |
12311 opcode(0x70); | |
12312 ins_encode %{ | 12302 ins_encode %{ |
12313 Label* l = $labl$$label; | 12303 Label* l = $labl$$label; |
12314 emit_cc(cbuf, $primary, Assembler::parity); | |
12315 int parity_disp = -1; | |
12316 if ($cop$$cmpcode == Assembler::notEqual) { | 12304 if ($cop$$cmpcode == Assembler::notEqual) { |
12317 parity_disp = l->loc_pos() - (cbuf.insts_size() + 1); | 12305 __ jccb(Assembler::parity, *l); |
12306 __ jccb(Assembler::notEqual, *l); | |
12318 } else if ($cop$$cmpcode == Assembler::equal) { | 12307 } else if ($cop$$cmpcode == Assembler::equal) { |
12319 parity_disp = 2; | 12308 Label done; |
12309 __ jccb(Assembler::parity, done); | |
12310 __ jccb(Assembler::equal, *l); | |
12311 __ bind(done); | |
12320 } else { | 12312 } else { |
12321 ShouldNotReachHere(); | 12313 ShouldNotReachHere(); |
12322 } | 12314 } |
12323 emit_d8(cbuf, parity_disp); | |
12324 emit_cc(cbuf, $primary, $cop$$cmpcode); | |
12325 int disp = l->loc_pos() - (cbuf.insts_size() + 1); | |
12326 emit_d8(cbuf, disp); | |
12327 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); | |
12328 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); | |
12329 %} | 12315 %} |
12330 ins_pipe(pipe_jcc); | 12316 ins_pipe(pipe_jcc); |
12331 ins_short_branch(1); | 12317 ins_short_branch(1); |
12332 %} | 12318 %} |
12333 | 12319 |