src/cpu/x86/vm/x86_32.ad

changeset 1082
bd441136a5ce
parent 1063
7bb995fbd3c0
parent 1079
c517646eef23
child 1106
d0994e5bebce
     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"

mercurial