comparison src/cpu/x86/vm/x86_32.ad @ 647:bd441136a5ce

Merge
author kvn
date Thu, 19 Mar 2009 09:13:24 -0700
parents 7bb995fbd3c0 c517646eef23
children d0994e5bebce
comparison
equal deleted inserted replaced
640:ba50942c8138 647:bd441136a5ce
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"