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 assert(l != NULL, "need Label"); 2434 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0); 2435 %} 2436 2437 enc_class LblShort(label labl) 2438 %{ 2439 // GOTO 2440 Label* l = $labl$$label; 2441 assert(l != NULL, "need Label"); 2442 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 2443 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2444 emit_d8(cbuf, disp); 2445 %} 2446 2447 enc_class opc2_reg(rRegI dst) 2448 %{ 2449 // BSWAP 2450 emit_cc(cbuf, $secondary, $dst$$reg); 2451 %} 2452 2453 enc_class opc3_reg(rRegI dst) 2454 %{ 2455 // BSWAP 2456 emit_cc(cbuf, $tertiary, $dst$$reg); 2457 %} 2458 2459 enc_class reg_opc(rRegI div) 2460 %{ 2461 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2462 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2463 %} 2464 2465 enc_class Jcc(cmpOp cop, label labl) 2466 %{ 2467 // JCC 2468 Label* l = $labl$$label; 2469 assert(l != NULL, "need Label"); 2470 $$$emit8$primary; 2471 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2472 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0); 2473 %} 2474 2475 enc_class JccShort (cmpOp cop, label labl) 2476 %{ 2477 // JCC 2478 Label *l = $labl$$label; 2479 assert(l != NULL, "need Label"); 2480 emit_cc(cbuf, $primary, $cop$$cmpcode); 2481 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 2482 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2483 emit_d8(cbuf, disp); 2484 %} 2485 2486 enc_class enc_cmov(cmpOp cop) 2487 %{ 2488 // CMOV 2489 $$$emit8$primary; 2490 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2491 %} 2492 2493 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src) 2494 %{ 2495 // Invert sense of branch from sense of cmov 2496 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2497 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8) 2498 ? (UseXmmRegToRegMoveAll ? 3 : 4) 2499 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX 2500 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src) 2501 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3); 12119 format %{ $$template 12120 if ($cop$$cmpcode == Assembler::notEqual) { 12121 $$emit$$"jp,u $labl\n\t" 12122 $$emit$$"j$cop,u $labl" 12123 } else { 12124 $$emit$$"jp,u done\n\t" 12125 $$emit$$"j$cop,u $labl\n\t" 12126 $$emit$$"done:" 12127 } 12128 %} 12129 size(12); 12130 opcode(0x0F, 0x80); 12131 ins_encode %{ 12132 Label* l = $labl$$label; 12133 assert(l != NULL, "need Label"); 12134 $$$emit8$primary; 12135 emit_cc(cbuf, $secondary, Assembler::parity); 12136 int parity_disp = -1; 12137 if ($cop$$cmpcode == Assembler::notEqual) { 12138 // the two jumps 6 bytes apart so the jump distances are too 12139 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 12140 } else if ($cop$$cmpcode == Assembler::equal) { 12141 parity_disp = 6; 12142 } else { 12143 ShouldNotReachHere(); 12144 } 12145 emit_d32(cbuf, parity_disp); 12146 $$$emit8$primary; 12147 emit_cc(cbuf, $secondary, $cop$$cmpcode); 12148 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 12149 emit_d32(cbuf, disp); 12150 %} 12151 ins_pipe(pipe_jcc); 12152 ins_pc_relative(1); 12153 %} 12154 12155 // ============================================================================ 12156 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12157 // superklass array for an instance of the superklass. Set a hidden 12158 // internal cache on a hit (cache is checked with exposed code in 12159 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12160 // encoding ALSO sets flags. 12161 12162 instruct partialSubtypeCheck(rdi_RegP result, 12163 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12164 rFlagsReg cr) 12165 %{ 12166 match(Set result (PartialSubtypeCheck sub super)); 12167 effect(KILL rcx, KILL cr); 12168 12324 12325 ins_cost(300); 12326 format %{ $$template 12327 if ($cop$$cmpcode == Assembler::notEqual) { 12328 $$emit$$"jp,u,s $labl\n\t" 12329 $$emit$$"j$cop,u,s $labl" 12330 } else { 12331 $$emit$$"jp,u,s done\n\t" 12332 $$emit$$"j$cop,u,s $labl\n\t" 12333 $$emit$$"done:" 12334 } 12335 %} 12336 size(4); 12337 opcode(0x70); 12338 ins_encode %{ 12339 Label* l = $labl$$label; 12340 assert(l != NULL, "need Label"); 12341 emit_cc(cbuf, $primary, Assembler::parity); 12342 int parity_disp = -1; 12343 if ($cop$$cmpcode == Assembler::notEqual) { 12344 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 12345 } else if ($cop$$cmpcode == Assembler::equal) { 12346 parity_disp = 2; 12347 } else { 12348 ShouldNotReachHere(); 12349 } 12350 emit_d8(cbuf, parity_disp); 12351 emit_cc(cbuf, $primary, $cop$$cmpcode); 12352 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 12353 emit_d8(cbuf, disp); 12354 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 12355 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 12356 %} 12357 ins_pipe(pipe_jcc); 12358 ins_pc_relative(1); 12359 ins_short_branch(1); 12360 %} 12361 12362 // ============================================================================ 12363 // inlined locking and unlocking 12364 12365 instruct cmpFastLock(rFlagsReg cr, 12366 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 12367 %{ 12368 match(Set cr (FastLock object box)); 12369 effect(TEMP tmp, TEMP scr); 12370 12371 ins_cost(300); 12372 format %{ "fastlock $object,$box,$tmp,$scr" %} | 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 assert(l != NULL, "need Label"); 2468 $$$emit8$primary; 2469 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2470 emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size() + 4))); 2471 %} 2472 2473 enc_class JccShort (cmpOp cop, label labl) 2474 %{ 2475 // JCC 2476 Label *l = $labl$$label; 2477 assert(l != NULL, "need Label"); 2478 emit_cc(cbuf, $primary, $cop$$cmpcode); 2479 int disp = l->loc_pos() - (cbuf.insts_size() + 1); 2480 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2481 emit_d8(cbuf, disp); 2482 %} 2483 2484 enc_class enc_cmov(cmpOp cop) 2485 %{ 2486 // CMOV 2487 $$$emit8$primary; 2488 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2489 %} 2490 2491 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src) 2492 %{ 2493 // Invert sense of branch from sense of cmov 2494 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2495 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8) 2496 ? (UseXmmRegToRegMoveAll ? 3 : 4) 2497 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX 2498 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src) 2499 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3); 12117 format %{ $$template 12118 if ($cop$$cmpcode == Assembler::notEqual) { 12119 $$emit$$"jp,u $labl\n\t" 12120 $$emit$$"j$cop,u $labl" 12121 } else { 12122 $$emit$$"jp,u done\n\t" 12123 $$emit$$"j$cop,u $labl\n\t" 12124 $$emit$$"done:" 12125 } 12126 %} 12127 size(12); 12128 opcode(0x0F, 0x80); 12129 ins_encode %{ 12130 Label* l = $labl$$label; 12131 assert(l != NULL, "need Label"); 12132 $$$emit8$primary; 12133 emit_cc(cbuf, $secondary, Assembler::parity); 12134 int parity_disp = -1; 12135 if ($cop$$cmpcode == Assembler::notEqual) { 12136 // the two jumps 6 bytes apart so the jump distances are too 12137 parity_disp = l->loc_pos() - (cbuf.insts_size() + 4); 12138 } else if ($cop$$cmpcode == Assembler::equal) { 12139 parity_disp = 6; 12140 } else { 12141 ShouldNotReachHere(); 12142 } 12143 emit_d32(cbuf, parity_disp); 12144 $$$emit8$primary; 12145 emit_cc(cbuf, $secondary, $cop$$cmpcode); 12146 int disp = l->loc_pos() - (cbuf.insts_size() + 4); 12147 emit_d32(cbuf, disp); 12148 %} 12149 ins_pipe(pipe_jcc); 12150 ins_pc_relative(1); 12151 %} 12152 12153 // ============================================================================ 12154 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12155 // superklass array for an instance of the superklass. Set a hidden 12156 // internal cache on a hit (cache is checked with exposed code in 12157 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12158 // encoding ALSO sets flags. 12159 12160 instruct partialSubtypeCheck(rdi_RegP result, 12161 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12162 rFlagsReg cr) 12163 %{ 12164 match(Set result (PartialSubtypeCheck sub super)); 12165 effect(KILL rcx, KILL cr); 12166 12322 12323 ins_cost(300); 12324 format %{ $$template 12325 if ($cop$$cmpcode == Assembler::notEqual) { 12326 $$emit$$"jp,u,s $labl\n\t" 12327 $$emit$$"j$cop,u,s $labl" 12328 } else { 12329 $$emit$$"jp,u,s done\n\t" 12330 $$emit$$"j$cop,u,s $labl\n\t" 12331 $$emit$$"done:" 12332 } 12333 %} 12334 size(4); 12335 opcode(0x70); 12336 ins_encode %{ 12337 Label* l = $labl$$label; 12338 assert(l != NULL, "need Label"); 12339 emit_cc(cbuf, $primary, Assembler::parity); 12340 int parity_disp = -1; 12341 if ($cop$$cmpcode == Assembler::notEqual) { 12342 parity_disp = l->loc_pos() - (cbuf.insts_size() + 1); 12343 } else if ($cop$$cmpcode == Assembler::equal) { 12344 parity_disp = 2; 12345 } else { 12346 ShouldNotReachHere(); 12347 } 12348 emit_d8(cbuf, parity_disp); 12349 emit_cc(cbuf, $primary, $cop$$cmpcode); 12350 int disp = l->loc_pos() - (cbuf.insts_size() + 1); 12351 emit_d8(cbuf, disp); 12352 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 12353 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 12354 %} 12355 ins_pipe(pipe_jcc); 12356 ins_pc_relative(1); 12357 ins_short_branch(1); 12358 %} 12359 12360 // ============================================================================ 12361 // inlined locking and unlocking 12362 12363 instruct cmpFastLock(rFlagsReg cr, 12364 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 12365 %{ 12366 match(Set cr (FastLock object box)); 12367 effect(TEMP tmp, TEMP scr); 12368 12369 ins_cost(300); 12370 format %{ "fastlock $object,$box,$tmp,$scr" %} |