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