1.1 --- a/src/cpu/x86/vm/x86_32.ad Wed Mar 18 11:37:48 2009 -0400 1.2 +++ b/src/cpu/x86/vm/x86_32.ad Thu Mar 19 09:13:24 2009 -0700 1.3 @@ -1483,16 +1483,20 @@ 1.4 // main source block for now. In future, we can generalize this by 1.5 // adding a syntax that specifies the sizes of fields in an order, 1.6 // so that the adlc can build the emit functions automagically 1.7 - enc_class OpcP %{ // Emit opcode 1.8 - emit_opcode(cbuf,$primary); 1.9 - %} 1.10 - 1.11 - enc_class OpcS %{ // Emit opcode 1.12 - emit_opcode(cbuf,$secondary); 1.13 - %} 1.14 - 1.15 - enc_class Opcode(immI d8 ) %{ // Emit opcode 1.16 - emit_opcode(cbuf,$d8$$constant); 1.17 + 1.18 + // Emit primary opcode 1.19 + enc_class OpcP %{ 1.20 + emit_opcode(cbuf, $primary); 1.21 + %} 1.22 + 1.23 + // Emit secondary opcode 1.24 + enc_class OpcS %{ 1.25 + emit_opcode(cbuf, $secondary); 1.26 + %} 1.27 + 1.28 + // Emit opcode directly 1.29 + enc_class Opcode(immI d8) %{ 1.30 + emit_opcode(cbuf, $d8$$constant); 1.31 %} 1.32 1.33 enc_class SizePrefix %{ 1.34 @@ -1688,26 +1692,15 @@ 1.35 Register Reax = as_Register(EAX_enc); // super class 1.36 Register Recx = as_Register(ECX_enc); // killed 1.37 Register Resi = as_Register(ESI_enc); // sub class 1.38 - Label hit, miss; 1.39 + Label miss; 1.40 1.41 MacroAssembler _masm(&cbuf); 1.42 - // Compare super with sub directly, since super is not in its own SSA. 1.43 - // The compiler used to emit this test, but we fold it in here, 1.44 - // to allow platform-specific tweaking on sparc. 1.45 - __ cmpptr(Reax, Resi); 1.46 - __ jcc(Assembler::equal, hit); 1.47 -#ifndef PRODUCT 1.48 - __ incrementl(ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); 1.49 -#endif //PRODUCT 1.50 - __ movptr(Redi,Address(Resi,sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())); 1.51 - __ movl(Recx,Address(Redi,arrayOopDesc::length_offset_in_bytes())); 1.52 - __ addptr(Redi,arrayOopDesc::base_offset_in_bytes(T_OBJECT)); 1.53 - __ repne_scan(); 1.54 - __ jcc(Assembler::notEqual, miss); 1.55 - __ movptr(Address(Resi,sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()),Reax); 1.56 - __ bind(hit); 1.57 - if( $primary ) 1.58 - __ xorptr(Redi,Redi); 1.59 + __ check_klass_subtype_slow_path(Resi, Reax, Recx, Redi, 1.60 + NULL, &miss, 1.61 + /*set_cond_codes:*/ true); 1.62 + if ($primary) { 1.63 + __ xorptr(Redi, Redi); 1.64 + } 1.65 __ bind(miss); 1.66 %} 1.67 1.68 @@ -6387,6 +6380,67 @@ 1.69 %} 1.70 1.71 1.72 +//---------- Population Count Instructions ------------------------------------- 1.73 + 1.74 +instruct popCountI(eRegI dst, eRegI src) %{ 1.75 + predicate(UsePopCountInstruction); 1.76 + match(Set dst (PopCountI src)); 1.77 + 1.78 + format %{ "POPCNT $dst, $src" %} 1.79 + ins_encode %{ 1.80 + __ popcntl($dst$$Register, $src$$Register); 1.81 + %} 1.82 + ins_pipe(ialu_reg); 1.83 +%} 1.84 + 1.85 +instruct popCountI_mem(eRegI dst, memory mem) %{ 1.86 + predicate(UsePopCountInstruction); 1.87 + match(Set dst (PopCountI (LoadI mem))); 1.88 + 1.89 + format %{ "POPCNT $dst, $mem" %} 1.90 + ins_encode %{ 1.91 + __ popcntl($dst$$Register, $mem$$Address); 1.92 + %} 1.93 + ins_pipe(ialu_reg); 1.94 +%} 1.95 + 1.96 +// Note: Long.bitCount(long) returns an int. 1.97 +instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 1.98 + predicate(UsePopCountInstruction); 1.99 + match(Set dst (PopCountL src)); 1.100 + effect(KILL cr, TEMP tmp, TEMP dst); 1.101 + 1.102 + format %{ "POPCNT $dst, $src.lo\n\t" 1.103 + "POPCNT $tmp, $src.hi\n\t" 1.104 + "ADD $dst, $tmp" %} 1.105 + ins_encode %{ 1.106 + __ popcntl($dst$$Register, $src$$Register); 1.107 + __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 1.108 + __ addl($dst$$Register, $tmp$$Register); 1.109 + %} 1.110 + ins_pipe(ialu_reg); 1.111 +%} 1.112 + 1.113 +// Note: Long.bitCount(long) returns an int. 1.114 +instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{ 1.115 + predicate(UsePopCountInstruction); 1.116 + match(Set dst (PopCountL (LoadL mem))); 1.117 + effect(KILL cr, TEMP tmp, TEMP dst); 1.118 + 1.119 + format %{ "POPCNT $dst, $mem\n\t" 1.120 + "POPCNT $tmp, $mem+4\n\t" 1.121 + "ADD $dst, $tmp" %} 1.122 + ins_encode %{ 1.123 + //__ popcntl($dst$$Register, $mem$$Address$$first); 1.124 + //__ popcntl($tmp$$Register, $mem$$Address$$second); 1.125 + __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false)); 1.126 + __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false)); 1.127 + __ addl($dst$$Register, $tmp$$Register); 1.128 + %} 1.129 + ins_pipe(ialu_reg); 1.130 +%} 1.131 + 1.132 + 1.133 //----------Load/Store/Move Instructions--------------------------------------- 1.134 //----------Load Instructions-------------------------------------------------- 1.135 // Load Byte (8bit signed) 1.136 @@ -12501,15 +12555,12 @@ 1.137 effect( KILL rcx, KILL cr ); 1.138 1.139 ins_cost(1100); // slightly larger than the next version 1.140 - format %{ "CMPL EAX,ESI\n\t" 1.141 - "JEQ,s hit\n\t" 1.142 - "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 1.143 + format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 1.144 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 1.145 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 1.146 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 1.147 "JNE,s miss\t\t# Missed: EDI not-zero\n\t" 1.148 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t" 1.149 - "hit:\n\t" 1.150 "XOR $result,$result\t\t Hit: EDI zero\n\t" 1.151 "miss:\t" %} 1.152 1.153 @@ -12523,9 +12574,7 @@ 1.154 effect( KILL rcx, KILL result ); 1.155 1.156 ins_cost(1000); 1.157 - format %{ "CMPL EAX,ESI\n\t" 1.158 - "JEQ,s miss\t# Actually a hit; we are done.\n\t" 1.159 - "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 1.160 + format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 1.161 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 1.162 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 1.163 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t"