1481 // encoding scheme (opcode, rm, sib, immediate), and call them from C++ |
1481 // encoding scheme (opcode, rm, sib, immediate), and call them from C++ |
1482 // code in the enc_class source block. Emit functions will live in the |
1482 // code in the enc_class source block. Emit functions will live in the |
1483 // main source block for now. In future, we can generalize this by |
1483 // main source block for now. In future, we can generalize this by |
1484 // adding a syntax that specifies the sizes of fields in an order, |
1484 // adding a syntax that specifies the sizes of fields in an order, |
1485 // so that the adlc can build the emit functions automagically |
1485 // so that the adlc can build the emit functions automagically |
1486 enc_class OpcP %{ // Emit opcode |
1486 |
1487 emit_opcode(cbuf,$primary); |
1487 // Emit primary opcode |
1488 %} |
1488 enc_class OpcP %{ |
1489 |
1489 emit_opcode(cbuf, $primary); |
1490 enc_class OpcS %{ // Emit opcode |
1490 %} |
1491 emit_opcode(cbuf,$secondary); |
1491 |
1492 %} |
1492 // Emit secondary opcode |
1493 |
1493 enc_class OpcS %{ |
1494 enc_class Opcode(immI d8 ) %{ // Emit opcode |
1494 emit_opcode(cbuf, $secondary); |
1495 emit_opcode(cbuf,$d8$$constant); |
1495 %} |
|
1496 |
|
1497 // Emit opcode directly |
|
1498 enc_class Opcode(immI d8) %{ |
|
1499 emit_opcode(cbuf, $d8$$constant); |
1496 %} |
1500 %} |
1497 |
1501 |
1498 enc_class SizePrefix %{ |
1502 enc_class SizePrefix %{ |
1499 emit_opcode(cbuf,0x66); |
1503 emit_opcode(cbuf,0x66); |
1500 %} |
1504 %} |
1686 enc_class enc_PartialSubtypeCheck( ) %{ |
1690 enc_class enc_PartialSubtypeCheck( ) %{ |
1687 Register Redi = as_Register(EDI_enc); // result register |
1691 Register Redi = as_Register(EDI_enc); // result register |
1688 Register Reax = as_Register(EAX_enc); // super class |
1692 Register Reax = as_Register(EAX_enc); // super class |
1689 Register Recx = as_Register(ECX_enc); // killed |
1693 Register Recx = as_Register(ECX_enc); // killed |
1690 Register Resi = as_Register(ESI_enc); // sub class |
1694 Register Resi = as_Register(ESI_enc); // sub class |
1691 Label hit, miss; |
1695 Label miss; |
1692 |
1696 |
1693 MacroAssembler _masm(&cbuf); |
1697 MacroAssembler _masm(&cbuf); |
1694 // Compare super with sub directly, since super is not in its own SSA. |
1698 __ check_klass_subtype_slow_path(Resi, Reax, Recx, Redi, |
1695 // The compiler used to emit this test, but we fold it in here, |
1699 NULL, &miss, |
1696 // to allow platform-specific tweaking on sparc. |
1700 /*set_cond_codes:*/ true); |
1697 __ cmpptr(Reax, Resi); |
1701 if ($primary) { |
1698 __ jcc(Assembler::equal, hit); |
1702 __ xorptr(Redi, Redi); |
1699 #ifndef PRODUCT |
1703 } |
1700 __ incrementl(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); |
|
1701 #endif //PRODUCT |
|
1702 __ movptr(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); |
|
1703 __ movl(Recx,Address(Redi,arrayOopDesc::length_offset_in_bytes())); |
|
1704 __ addptr(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
|
1705 __ repne_scan(); |
|
1706 __ jcc(Assembler::notEqual, miss); |
|
1707 __ movptr(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); |
|
1708 __ bind(hit); |
|
1709 if( $primary ) |
|
1710 __ xorptr(Redi,Redi); |
|
1711 __ bind(miss); |
1704 __ bind(miss); |
1712 %} |
1705 %} |
1713 |
1706 |
1714 enc_class FFree_Float_Stack_All %{ // Free_Float_Stack_All |
1707 enc_class FFree_Float_Stack_All %{ // Free_Float_Stack_All |
1715 MacroAssembler masm(&cbuf); |
1708 MacroAssembler masm(&cbuf); |
6385 ins_encode( bswap_long_bytes(dst) ); |
6378 ins_encode( bswap_long_bytes(dst) ); |
6386 ins_pipe( ialu_reg_reg); |
6379 ins_pipe( ialu_reg_reg); |
6387 %} |
6380 %} |
6388 |
6381 |
6389 |
6382 |
|
6383 //---------- Population Count Instructions ------------------------------------- |
|
6384 |
|
6385 instruct popCountI(eRegI dst, eRegI src) %{ |
|
6386 predicate(UsePopCountInstruction); |
|
6387 match(Set dst (PopCountI src)); |
|
6388 |
|
6389 format %{ "POPCNT $dst, $src" %} |
|
6390 ins_encode %{ |
|
6391 __ popcntl($dst$$Register, $src$$Register); |
|
6392 %} |
|
6393 ins_pipe(ialu_reg); |
|
6394 %} |
|
6395 |
|
6396 instruct popCountI_mem(eRegI dst, memory mem) %{ |
|
6397 predicate(UsePopCountInstruction); |
|
6398 match(Set dst (PopCountI (LoadI mem))); |
|
6399 |
|
6400 format %{ "POPCNT $dst, $mem" %} |
|
6401 ins_encode %{ |
|
6402 __ popcntl($dst$$Register, $mem$$Address); |
|
6403 %} |
|
6404 ins_pipe(ialu_reg); |
|
6405 %} |
|
6406 |
|
6407 // Note: Long.bitCount(long) returns an int. |
|
6408 instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ |
|
6409 predicate(UsePopCountInstruction); |
|
6410 match(Set dst (PopCountL src)); |
|
6411 effect(KILL cr, TEMP tmp, TEMP dst); |
|
6412 |
|
6413 format %{ "POPCNT $dst, $src.lo\n\t" |
|
6414 "POPCNT $tmp, $src.hi\n\t" |
|
6415 "ADD $dst, $tmp" %} |
|
6416 ins_encode %{ |
|
6417 __ popcntl($dst$$Register, $src$$Register); |
|
6418 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); |
|
6419 __ addl($dst$$Register, $tmp$$Register); |
|
6420 %} |
|
6421 ins_pipe(ialu_reg); |
|
6422 %} |
|
6423 |
|
6424 // Note: Long.bitCount(long) returns an int. |
|
6425 instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{ |
|
6426 predicate(UsePopCountInstruction); |
|
6427 match(Set dst (PopCountL (LoadL mem))); |
|
6428 effect(KILL cr, TEMP tmp, TEMP dst); |
|
6429 |
|
6430 format %{ "POPCNT $dst, $mem\n\t" |
|
6431 "POPCNT $tmp, $mem+4\n\t" |
|
6432 "ADD $dst, $tmp" %} |
|
6433 ins_encode %{ |
|
6434 //__ popcntl($dst$$Register, $mem$$Address$$first); |
|
6435 //__ popcntl($tmp$$Register, $mem$$Address$$second); |
|
6436 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false)); |
|
6437 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false)); |
|
6438 __ addl($dst$$Register, $tmp$$Register); |
|
6439 %} |
|
6440 ins_pipe(ialu_reg); |
|
6441 %} |
|
6442 |
|
6443 |
6390 //----------Load/Store/Move Instructions--------------------------------------- |
6444 //----------Load/Store/Move Instructions--------------------------------------- |
6391 //----------Load Instructions-------------------------------------------------- |
6445 //----------Load Instructions-------------------------------------------------- |
6392 // Load Byte (8bit signed) |
6446 // Load Byte (8bit signed) |
6393 instruct loadB(xRegI dst, memory mem) %{ |
6447 instruct loadB(xRegI dst, memory mem) %{ |
6394 match(Set dst (LoadB mem)); |
6448 match(Set dst (LoadB mem)); |
12499 instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ |
12553 instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ |
12500 match(Set result (PartialSubtypeCheck sub super)); |
12554 match(Set result (PartialSubtypeCheck sub super)); |
12501 effect( KILL rcx, KILL cr ); |
12555 effect( KILL rcx, KILL cr ); |
12502 |
12556 |
12503 ins_cost(1100); // slightly larger than the next version |
12557 ins_cost(1100); // slightly larger than the next version |
12504 format %{ "CMPL EAX,ESI\n\t" |
12558 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" |
12505 "JEQ,s hit\n\t" |
|
12506 "MOV EDI,[$sub+Klass::secondary_supers]\n\t" |
|
12507 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" |
12559 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" |
12508 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" |
12560 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" |
12509 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" |
12561 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" |
12510 "JNE,s miss\t\t# Missed: EDI not-zero\n\t" |
12562 "JNE,s miss\t\t# Missed: EDI not-zero\n\t" |
12511 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t" |
12563 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t" |
12512 "hit:\n\t" |
|
12513 "XOR $result,$result\t\t Hit: EDI zero\n\t" |
12564 "XOR $result,$result\t\t Hit: EDI zero\n\t" |
12514 "miss:\t" %} |
12565 "miss:\t" %} |
12515 |
12566 |
12516 opcode(0x1); // Force a XOR of EDI |
12567 opcode(0x1); // Force a XOR of EDI |
12517 ins_encode( enc_PartialSubtypeCheck() ); |
12568 ins_encode( enc_PartialSubtypeCheck() ); |
12521 instruct partialSubtypeCheck_vs_Zero( eFlagsReg cr, eSIRegP sub, eAXRegP super, eCXRegI rcx, eDIRegP result, immP0 zero ) %{ |
12572 instruct partialSubtypeCheck_vs_Zero( eFlagsReg cr, eSIRegP sub, eAXRegP super, eCXRegI rcx, eDIRegP result, immP0 zero ) %{ |
12522 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
12573 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); |
12523 effect( KILL rcx, KILL result ); |
12574 effect( KILL rcx, KILL result ); |
12524 |
12575 |
12525 ins_cost(1000); |
12576 ins_cost(1000); |
12526 format %{ "CMPL EAX,ESI\n\t" |
12577 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" |
12527 "JEQ,s miss\t# Actually a hit; we are done.\n\t" |
|
12528 "MOV EDI,[$sub+Klass::secondary_supers]\n\t" |
|
12529 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" |
12578 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" |
12530 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" |
12579 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" |
12531 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" |
12580 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" |
12532 "JNE,s miss\t\t# Missed: flags NZ\n\t" |
12581 "JNE,s miss\t\t# Missed: flags NZ\n\t" |
12533 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache, flags Z\n\t" |
12582 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache, flags Z\n\t" |