src/cpu/x86/vm/x86_64.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7063628 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/x86_64.ad

Print this page




2411       // 32-bit immediate
2412       emit_opcode(cbuf, $primary);
2413     }
2414     // Emit r/m byte with secondary opcode, after primary opcode.
2415     emit_rm(cbuf, 0x3, $secondary, dstenc);
2416   %}
2417 
2418   enc_class Con8or32(immI imm)
2419   %{
2420     // Check for 8-bit immediate, and set sign extend bit in opcode
2421     if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2422       $$$emit8$imm$$constant;
2423     } else {
2424       // 32-bit immediate
2425       $$$emit32$imm$$constant;
2426     }
2427   %}
2428 
2429   enc_class Lbl(label labl)
2430   %{
2431     // JMP, CALL
2432     Label* l = $labl$$label;
2433     emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
2434   %}
2435 
2436   enc_class LblShort(label labl)
2437   %{
2438     // JMP, CALL
2439     Label* l = $labl$$label;
2440     int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
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)
2446   %{
2447     // BSWAP
2448     emit_cc(cbuf, $secondary, $dst$$reg);
2449   %}
2450 
2451   enc_class opc3_reg(rRegI dst)
2452   %{
2453     // BSWAP
2454     emit_cc(cbuf, $tertiary, $dst$$reg);
2455   %}
2456 
2457   enc_class reg_opc(rRegI div)
2458   %{
2459     // INC, DEC, IDIV, IMOD, JMP indirect, ...
2460     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 ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
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 ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
2478     assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
2479     emit_d8(cbuf, disp);
2480   %}
2481 
2482   enc_class enc_cmov(cmpOp cop)
2483   %{
2484     // CMOV
2485     $$$emit8$primary;
2486     emit_cc(cbuf, $secondary, $cop$$cmpcode);
2487   %}
2488 
2489   enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src)
2490   %{
2491     // Invert sense of branch from sense of cmov
2492     emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2493     emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8)
2494                   ? (UseXmmRegToRegMoveAll ? 3 : 4)
2495                   : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX
2496     // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src)
2497     if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3);


12114   ins_cost(200);
12115   format %{ $$template
12116     if ($cop$$cmpcode == Assembler::notEqual) {
12117       $$emit$$"jp,u   $labl\n\t"
12118       $$emit$$"j$cop,u   $labl"
12119     } else {
12120       $$emit$$"jp,u   done\n\t"
12121       $$emit$$"j$cop,u   $labl\n\t"
12122       $$emit$$"done:"
12123     }
12124   %}
12125   size(12);
12126   opcode(0x0F, 0x80);
12127   ins_encode %{
12128     Label* l = $labl$$label;
12129     $$$emit8$primary;
12130     emit_cc(cbuf, $secondary, Assembler::parity);
12131     int parity_disp = -1;
12132     if ($cop$$cmpcode == Assembler::notEqual) {
12133        // the two jumps 6 bytes apart so the jump distances are too
12134        parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
12135     } else if ($cop$$cmpcode == Assembler::equal) {
12136        parity_disp = 6;
12137     } else {
12138        ShouldNotReachHere();
12139     }
12140     emit_d32(cbuf, parity_disp);
12141     $$$emit8$primary;
12142     emit_cc(cbuf, $secondary, $cop$$cmpcode);
12143     int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
12144     emit_d32(cbuf, disp);
12145   %}
12146   ins_pipe(pipe_jcc);
12147   ins_pc_relative(1);
12148 %}
12149 
12150 // ============================================================================
12151 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
12152 // superklass array for an instance of the superklass.  Set a hidden
12153 // internal cache on a hit (cache is checked with exposed code in
12154 // gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
12155 // encoding ALSO sets flags.
12156 
12157 instruct partialSubtypeCheck(rdi_RegP result,
12158                              rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12159                              rFlagsReg cr)
12160 %{
12161   match(Set result (PartialSubtypeCheck sub super));
12162   effect(KILL rcx, KILL cr);
12163 


12318   effect(USE labl);
12319 
12320   ins_cost(300);
12321   format %{ $$template
12322     if ($cop$$cmpcode == Assembler::notEqual) {
12323       $$emit$$"jp,u,s   $labl\n\t"
12324       $$emit$$"j$cop,u,s   $labl"
12325     } else {
12326       $$emit$$"jp,u,s   done\n\t"
12327       $$emit$$"j$cop,u,s  $labl\n\t"
12328       $$emit$$"done:"
12329     }
12330   %}
12331   size(4);
12332   opcode(0x70);
12333   ins_encode %{
12334     Label* l = $labl$$label;
12335     emit_cc(cbuf, $primary, Assembler::parity);
12336     int parity_disp = -1;
12337     if ($cop$$cmpcode == Assembler::notEqual) {
12338       parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
12339     } else if ($cop$$cmpcode == Assembler::equal) {
12340       parity_disp = 2;
12341     } else {
12342       ShouldNotReachHere();
12343     }
12344     emit_d8(cbuf, parity_disp);
12345     emit_cc(cbuf, $primary, $cop$$cmpcode);
12346     int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
12347     emit_d8(cbuf, disp);
12348     assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
12349     assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
12350   %}
12351   ins_pipe(pipe_jcc);
12352   ins_pc_relative(1);
12353   ins_short_branch(1);
12354 %}
12355 
12356 // ============================================================================
12357 // inlined locking and unlocking
12358 
12359 instruct cmpFastLock(rFlagsReg cr,
12360                      rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
12361 %{
12362   match(Set cr (FastLock object box));
12363   effect(TEMP tmp, TEMP scr);
12364 
12365   ins_cost(300);
12366   format %{ "fastlock $object,$box,$tmp,$scr" %}




2411       // 32-bit immediate
2412       emit_opcode(cbuf, $primary);
2413     }
2414     // Emit r/m byte with secondary opcode, after primary opcode.
2415     emit_rm(cbuf, 0x3, $secondary, dstenc);
2416   %}
2417 
2418   enc_class Con8or32(immI imm)
2419   %{
2420     // Check for 8-bit immediate, and set sign extend bit in opcode
2421     if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2422       $$$emit8$imm$$constant;
2423     } else {
2424       // 32-bit immediate
2425       $$$emit32$imm$$constant;
2426     }
2427   %}
2428 
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)
2446   %{
2447     // BSWAP
2448     emit_cc(cbuf, $secondary, $dst$$reg);
2449   %}
2450 
2451   enc_class opc3_reg(rRegI dst)
2452   %{
2453     // BSWAP
2454     emit_cc(cbuf, $tertiary, $dst$$reg);
2455   %}
2456 
2457   enc_class reg_opc(rRegI div)
2458   %{
2459     // INC, DEC, IDIV, IMOD, JMP indirect, ...
2460     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   %}
2481 
2482   enc_class enc_cmov(cmpOp cop)
2483   %{
2484     // CMOV
2485     $$$emit8$primary;
2486     emit_cc(cbuf, $secondary, $cop$$cmpcode);
2487   %}
2488 
2489   enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src)
2490   %{
2491     // Invert sense of branch from sense of cmov
2492     emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1);
2493     emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8)
2494                   ? (UseXmmRegToRegMoveAll ? 3 : 4)
2495                   : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX
2496     // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src)
2497     if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3);


12114   ins_cost(200);
12115   format %{ $$template
12116     if ($cop$$cmpcode == Assembler::notEqual) {
12117       $$emit$$"jp,u   $labl\n\t"
12118       $$emit$$"j$cop,u   $labl"
12119     } else {
12120       $$emit$$"jp,u   done\n\t"
12121       $$emit$$"j$cop,u   $labl\n\t"
12122       $$emit$$"done:"
12123     }
12124   %}
12125   size(12);
12126   opcode(0x0F, 0x80);
12127   ins_encode %{
12128     Label* l = $labl$$label;
12129     $$$emit8$primary;
12130     emit_cc(cbuf, $secondary, Assembler::parity);
12131     int parity_disp = -1;
12132     if ($cop$$cmpcode == Assembler::notEqual) {
12133        // the two jumps 6 bytes apart so the jump distances are too
12134        parity_disp = l->loc_pos() - (cbuf.insts_size() + 4);
12135     } else if ($cop$$cmpcode == Assembler::equal) {
12136        parity_disp = 6;
12137     } else {
12138        ShouldNotReachHere();
12139     }
12140     emit_d32(cbuf, parity_disp);
12141     $$$emit8$primary;
12142     emit_cc(cbuf, $secondary, $cop$$cmpcode);
12143     int disp = l->loc_pos() - (cbuf.insts_size() + 4);
12144     emit_d32(cbuf, disp);
12145   %}
12146   ins_pipe(pipe_jcc);
12147   ins_pc_relative(1);
12148 %}
12149 
12150 // ============================================================================
12151 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
12152 // superklass array for an instance of the superklass.  Set a hidden
12153 // internal cache on a hit (cache is checked with exposed code in
12154 // gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
12155 // encoding ALSO sets flags.
12156 
12157 instruct partialSubtypeCheck(rdi_RegP result,
12158                              rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
12159                              rFlagsReg cr)
12160 %{
12161   match(Set result (PartialSubtypeCheck sub super));
12162   effect(KILL rcx, KILL cr);
12163 


12318   effect(USE labl);
12319 
12320   ins_cost(300);
12321   format %{ $$template
12322     if ($cop$$cmpcode == Assembler::notEqual) {
12323       $$emit$$"jp,u,s   $labl\n\t"
12324       $$emit$$"j$cop,u,s   $labl"
12325     } else {
12326       $$emit$$"jp,u,s   done\n\t"
12327       $$emit$$"j$cop,u,s  $labl\n\t"
12328       $$emit$$"done:"
12329     }
12330   %}
12331   size(4);
12332   opcode(0x70);
12333   ins_encode %{
12334     Label* l = $labl$$label;
12335     emit_cc(cbuf, $primary, Assembler::parity);
12336     int parity_disp = -1;
12337     if ($cop$$cmpcode == Assembler::notEqual) {
12338       parity_disp = l->loc_pos() - (cbuf.insts_size() + 1);
12339     } else if ($cop$$cmpcode == Assembler::equal) {
12340       parity_disp = 2;
12341     } else {
12342       ShouldNotReachHere();
12343     }
12344     emit_d8(cbuf, parity_disp);
12345     emit_cc(cbuf, $primary, $cop$$cmpcode);
12346     int disp = l->loc_pos() - (cbuf.insts_size() + 1);
12347     emit_d8(cbuf, disp);
12348     assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
12349     assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
12350   %}
12351   ins_pipe(pipe_jcc);
12352   ins_pc_relative(1);
12353   ins_short_branch(1);
12354 %}
12355 
12356 // ============================================================================
12357 // inlined locking and unlocking
12358 
12359 instruct cmpFastLock(rFlagsReg cr,
12360                      rRegP object, rRegP box, rax_RegI tmp, rRegP scr)
12361 %{
12362   match(Set cr (FastLock object box));
12363   effect(TEMP tmp, TEMP scr);
12364 
12365   ins_cost(300);
12366   format %{ "fastlock $object,$box,$tmp,$scr" %}


src/cpu/x86/vm/x86_64.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File