Mercurial > hg > truffle
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" |