src/cpu/x86/vm/x86_32.ad

changeset 1063
7bb995fbd3c0
parent 1014
0fbdb4381b99
parent 1059
337400e7a5dd
child 1082
bd441136a5ce
     1.1 --- a/src/cpu/x86/vm/x86_32.ad	Mon Mar 09 13:34:00 2009 -0700
     1.2 +++ b/src/cpu/x86/vm/x86_32.ad	Thu Mar 12 18:16:36 2009 -0700
     1.3 @@ -130,7 +130,7 @@
     1.4  // allocation.  Highest priority is first.  A useful heuristic is to
     1.5  // give registers a low priority when they are required by machine
     1.6  // instructions, like EAX and EDX.  Registers which are used as
     1.7 -// pairs must fall on an even boundry (witness the FPR#L's in this list).
     1.8 +// pairs must fall on an even boundary (witness the FPR#L's in this list).
     1.9  // For the Intel integer registers, the equivalent Long pairs are
    1.10  // EDX:EAX, EBX:ECX, and EDI:EBP.
    1.11  alloc_class chunk0( ECX,   EBX,   EBP,   EDI,   EAX,   EDX,   ESI, ESP,
    1.12 @@ -3126,14 +3126,12 @@
    1.13  
    1.14    enc_class movq_ld(regXD dst, memory mem) %{
    1.15      MacroAssembler _masm(&cbuf);
    1.16 -    Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
    1.17 -    __ movq(as_XMMRegister($dst$$reg), madr);
    1.18 +    __ movq($dst$$XMMRegister, $mem$$Address);
    1.19    %}
    1.20  
    1.21    enc_class movq_st(memory mem, regXD src) %{
    1.22      MacroAssembler _masm(&cbuf);
    1.23 -    Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
    1.24 -    __ movq(madr, as_XMMRegister($src$$reg));
    1.25 +    __ movq($mem$$Address, $src$$XMMRegister);
    1.26    %}
    1.27  
    1.28    enc_class pshufd_8x8(regX dst, regX src) %{
    1.29 @@ -3751,8 +3749,8 @@
    1.30      masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
    1.31  
    1.32      // Load first characters
    1.33 -    masm.load_unsigned_word(rcx, Address(rbx, 0));
    1.34 -    masm.load_unsigned_word(rdi, Address(rax, 0));
    1.35 +    masm.load_unsigned_short(rcx, Address(rbx, 0));
    1.36 +    masm.load_unsigned_short(rdi, Address(rax, 0));
    1.37  
    1.38      // Compare first characters
    1.39      masm.subl(rcx, rdi);
    1.40 @@ -3782,8 +3780,8 @@
    1.41  
    1.42      // Compare the rest of the characters
    1.43      masm.bind(WHILE_HEAD_LABEL);
    1.44 -    masm.load_unsigned_word(rcx, Address(rbx, rsi, Address::times_2, 0));
    1.45 -    masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0));
    1.46 +    masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
    1.47 +    masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
    1.48      masm.subl(rcx, rdi);
    1.49      masm.jcc(Assembler::notZero, POP_LABEL);
    1.50      masm.incrementl(rsi);
    1.51 @@ -3840,8 +3838,8 @@
    1.52      masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
    1.53  
    1.54      // Compare 2-byte "tail" at end of arrays
    1.55 -    masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
    1.56 -    masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
    1.57 +    masm.load_unsigned_short(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
    1.58 +    masm.load_unsigned_short(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
    1.59      masm.cmpl(tmp1Reg, tmp2Reg);
    1.60      masm.jcc(Assembler::notEqual, FALSE_LABEL);
    1.61      masm.testl(resultReg, resultReg);
    1.62 @@ -5857,7 +5855,7 @@
    1.63  
    1.64  //----------OPERAND CLASSES----------------------------------------------------
    1.65  // Operand Classes are groups of operands that are used as to simplify
    1.66 -// instruction definitions by not requiring the AD writer to specify seperate
    1.67 +// instruction definitions by not requiring the AD writer to specify separate
    1.68  // instructions for every form of operand when the instruction accepts
    1.69  // multiple operand types with the same basic encoding and format.  The classic
    1.70  // case of this is memory operands.
    1.71 @@ -6396,21 +6394,94 @@
    1.72    match(Set dst (LoadB mem));
    1.73  
    1.74    ins_cost(125);
    1.75 -  format %{ "MOVSX8 $dst,$mem" %}
    1.76 -  opcode(0xBE, 0x0F);
    1.77 -  ins_encode( OpcS, OpcP, RegMem(dst,mem));
    1.78 -  ins_pipe( ialu_reg_mem );
    1.79 -%}
    1.80 -
    1.81 -// Load Byte (8bit UNsigned)
    1.82 -instruct loadUB(xRegI dst, memory mem, immI_255 bytemask) %{
    1.83 -  match(Set dst (AndI (LoadB mem) bytemask));
    1.84 +  format %{ "MOVSX8 $dst,$mem\t# byte" %}
    1.85 +
    1.86 +  ins_encode %{
    1.87 +    __ movsbl($dst$$Register, $mem$$Address);
    1.88 +  %}
    1.89 +
    1.90 +  ins_pipe(ialu_reg_mem);
    1.91 +%}
    1.92 +
    1.93 +// Load Byte (8bit signed) into Long Register
    1.94 +instruct loadB2L(eRegL dst, memory mem) %{
    1.95 +  match(Set dst (ConvI2L (LoadB mem)));
    1.96 +
    1.97 +  ins_cost(375);
    1.98 +  format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t"
    1.99 +            "MOV    $dst.hi,$dst.lo\n\t"
   1.100 +            "SAR    $dst.hi,7" %}
   1.101 +
   1.102 +  ins_encode %{
   1.103 +    __ movsbl($dst$$Register, $mem$$Address);
   1.104 +    __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
   1.105 +    __ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended.
   1.106 +  %}
   1.107 +
   1.108 +  ins_pipe(ialu_reg_mem);
   1.109 +%}
   1.110 +
   1.111 +// Load Unsigned Byte (8bit UNsigned)
   1.112 +instruct loadUB(xRegI dst, memory mem) %{
   1.113 +  match(Set dst (LoadUB mem));
   1.114  
   1.115    ins_cost(125);
   1.116 -  format %{ "MOVZX8 $dst,$mem" %}
   1.117 -  opcode(0xB6, 0x0F);
   1.118 -  ins_encode( OpcS, OpcP, RegMem(dst,mem));
   1.119 -  ins_pipe( ialu_reg_mem );
   1.120 +  format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %}
   1.121 +
   1.122 +  ins_encode %{
   1.123 +    __ movzbl($dst$$Register, $mem$$Address);
   1.124 +  %}
   1.125 +
   1.126 +  ins_pipe(ialu_reg_mem);
   1.127 +%}
   1.128 +
   1.129 +// Load Unsigned Byte (8 bit UNsigned) into Long Register
   1.130 +instruct loadUB2L(eRegL dst, memory mem)
   1.131 +%{
   1.132 +  match(Set dst (ConvI2L (LoadUB mem)));
   1.133 +
   1.134 +  ins_cost(250);
   1.135 +  format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t"
   1.136 +            "XOR    $dst.hi,$dst.hi" %}
   1.137 +
   1.138 +  ins_encode %{
   1.139 +    __ movzbl($dst$$Register, $mem$$Address);
   1.140 +    __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
   1.141 +  %}
   1.142 +
   1.143 +  ins_pipe(ialu_reg_mem);
   1.144 +%}
   1.145 +
   1.146 +// Load Short (16bit signed)
   1.147 +instruct loadS(eRegI dst, memory mem) %{
   1.148 +  match(Set dst (LoadS mem));
   1.149 +
   1.150 +  ins_cost(125);
   1.151 +  format %{ "MOVSX  $dst,$mem\t# short" %}
   1.152 +
   1.153 +  ins_encode %{
   1.154 +    __ movswl($dst$$Register, $mem$$Address);
   1.155 +  %}
   1.156 +
   1.157 +  ins_pipe(ialu_reg_mem);
   1.158 +%}
   1.159 +
   1.160 +// Load Short (16bit signed) into Long Register
   1.161 +instruct loadS2L(eRegL dst, memory mem) %{
   1.162 +  match(Set dst (ConvI2L (LoadS mem)));
   1.163 +
   1.164 +  ins_cost(375);
   1.165 +  format %{ "MOVSX  $dst.lo,$mem\t# short -> long\n\t"
   1.166 +            "MOV    $dst.hi,$dst.lo\n\t"
   1.167 +            "SAR    $dst.hi,15" %}
   1.168 +
   1.169 +  ins_encode %{
   1.170 +    __ movswl($dst$$Register, $mem$$Address);
   1.171 +    __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
   1.172 +    __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
   1.173 +  %}
   1.174 +
   1.175 +  ins_pipe(ialu_reg_mem);
   1.176  %}
   1.177  
   1.178  // Load Unsigned Short/Char (16bit unsigned)
   1.179 @@ -6418,10 +6489,30 @@
   1.180    match(Set dst (LoadUS mem));
   1.181  
   1.182    ins_cost(125);
   1.183 -  format %{ "MOVZX  $dst,$mem" %}
   1.184 -  opcode(0xB7, 0x0F);
   1.185 -  ins_encode( OpcS, OpcP, RegMem(dst,mem));
   1.186 -  ins_pipe( ialu_reg_mem );
   1.187 +  format %{ "MOVZX  $dst,$mem\t# ushort/char -> int" %}
   1.188 +
   1.189 +  ins_encode %{
   1.190 +    __ movzwl($dst$$Register, $mem$$Address);
   1.191 +  %}
   1.192 +
   1.193 +  ins_pipe(ialu_reg_mem);
   1.194 +%}
   1.195 +
   1.196 +// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
   1.197 +instruct loadUS2L(eRegL dst, memory mem)
   1.198 +%{
   1.199 +  match(Set dst (ConvI2L (LoadUS mem)));
   1.200 +
   1.201 +  ins_cost(250);
   1.202 +  format %{ "MOVZX  $dst.lo,$mem\t# ushort/char -> long\n\t"
   1.203 +            "XOR    $dst.hi,$dst.hi" %}
   1.204 +
   1.205 +  ins_encode %{
   1.206 +    __ movzwl($dst$$Register, $mem$$Address);
   1.207 +    __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
   1.208 +  %}
   1.209 +
   1.210 +  ins_pipe(ialu_reg_mem);
   1.211  %}
   1.212  
   1.213  // Load Integer
   1.214 @@ -6429,10 +6520,47 @@
   1.215    match(Set dst (LoadI mem));
   1.216  
   1.217    ins_cost(125);
   1.218 -  format %{ "MOV    $dst,$mem" %}
   1.219 -  opcode(0x8B);
   1.220 -  ins_encode( OpcP, RegMem(dst,mem));
   1.221 -  ins_pipe( ialu_reg_mem );
   1.222 +  format %{ "MOV    $dst,$mem\t# int" %}
   1.223 +
   1.224 +  ins_encode %{
   1.225 +    __ movl($dst$$Register, $mem$$Address);
   1.226 +  %}
   1.227 +
   1.228 +  ins_pipe(ialu_reg_mem);
   1.229 +%}
   1.230 +
   1.231 +// Load Integer into Long Register
   1.232 +instruct loadI2L(eRegL dst, memory mem) %{
   1.233 +  match(Set dst (ConvI2L (LoadI mem)));
   1.234 +
   1.235 +  ins_cost(375);
   1.236 +  format %{ "MOV    $dst.lo,$mem\t# int -> long\n\t"
   1.237 +            "MOV    $dst.hi,$dst.lo\n\t"
   1.238 +            "SAR    $dst.hi,31" %}
   1.239 +
   1.240 +  ins_encode %{
   1.241 +    __ movl($dst$$Register, $mem$$Address);
   1.242 +    __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
   1.243 +    __ sarl(HIGH_FROM_LOW($dst$$Register), 31);
   1.244 +  %}
   1.245 +
   1.246 +  ins_pipe(ialu_reg_mem);
   1.247 +%}
   1.248 +
   1.249 +// Load Unsigned Integer into Long Register
   1.250 +instruct loadUI2L(eRegL dst, memory mem) %{
   1.251 +  match(Set dst (LoadUI2L mem));
   1.252 +
   1.253 +  ins_cost(250);
   1.254 +  format %{ "MOV    $dst.lo,$mem\t# uint -> long\n\t"
   1.255 +            "XOR    $dst.hi,$dst.hi" %}
   1.256 +
   1.257 +  ins_encode %{
   1.258 +    __ movl($dst$$Register, $mem$$Address);
   1.259 +    __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register));
   1.260 +  %}
   1.261 +
   1.262 +  ins_pipe(ialu_reg_mem);
   1.263  %}
   1.264  
   1.265  // Load Long.  Cannot clobber address while loading, so restrict address
   1.266 @@ -6442,11 +6570,17 @@
   1.267    match(Set dst (LoadL mem));
   1.268  
   1.269    ins_cost(250);
   1.270 -  format %{ "MOV    $dst.lo,$mem\n\t"
   1.271 +  format %{ "MOV    $dst.lo,$mem\t# long\n\t"
   1.272              "MOV    $dst.hi,$mem+4" %}
   1.273 -  opcode(0x8B, 0x8B);
   1.274 -  ins_encode( OpcP, RegMem(dst,mem), OpcS, RegMem_Hi(dst,mem));
   1.275 -  ins_pipe( ialu_reg_long_mem );
   1.276 +
   1.277 +  ins_encode %{
   1.278 +    Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false);
   1.279 +    Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false);
   1.280 +    __ movl($dst$$Register, Amemlo);
   1.281 +    __ movl(HIGH_FROM_LOW($dst$$Register), Amemhi);
   1.282 +  %}
   1.283 +
   1.284 +  ins_pipe(ialu_reg_long_mem);
   1.285  %}
   1.286  
   1.287  // Volatile Load Long.  Must be atomic, so do 64-bit FILD
   1.288 @@ -6521,17 +6655,6 @@
   1.289    ins_pipe( ialu_reg_mem );
   1.290  %}
   1.291  
   1.292 -// Load Short (16bit signed)
   1.293 -instruct loadS(eRegI dst, memory mem) %{
   1.294 -  match(Set dst (LoadS mem));
   1.295 -
   1.296 -  ins_cost(125);
   1.297 -  format %{ "MOVSX  $dst,$mem" %}
   1.298 -  opcode(0xBF, 0x0F);
   1.299 -  ins_encode( OpcS, OpcP, RegMem(dst,mem));
   1.300 -  ins_pipe( ialu_reg_mem );
   1.301 -%}
   1.302 -
   1.303  // Load Double
   1.304  instruct loadD(regD dst, memory mem) %{
   1.305    predicate(UseSSE<=1);
   1.306 @@ -7957,7 +8080,7 @@
   1.307      __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
   1.308      if( os::is_MP() )
   1.309        __ lock();
   1.310 -    __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
   1.311 +    __ cmpxchg8($mem$$Address);
   1.312      __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
   1.313    %}
   1.314    ins_pipe( pipe_cmpxchg );
   1.315 @@ -11467,6 +11590,7 @@
   1.316  instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
   1.317    match(Set dst (ConvI2L src));
   1.318    effect(KILL cr);
   1.319 +  ins_cost(375);
   1.320    format %{ "MOV    $dst.lo,$src\n\t"
   1.321              "MOV    $dst.hi,$src\n\t"
   1.322              "SAR    $dst.hi,31" %}
   1.323 @@ -11478,6 +11602,7 @@
   1.324  instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
   1.325    match(Set dst (AndL (ConvI2L src) mask) );
   1.326    effect( KILL flags );
   1.327 +  ins_cost(250);
   1.328    format %{ "MOV    $dst.lo,$src\n\t"
   1.329              "XOR    $dst.hi,$dst.hi" %}
   1.330    opcode(0x33); // XOR
   1.331 @@ -11489,6 +11614,7 @@
   1.332  instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
   1.333    match(Set dst (AndL src mask) );
   1.334    effect( KILL flags );
   1.335 +  ins_cost(250);
   1.336    format %{ "MOV    $dst.lo,$src.lo\n\t"
   1.337              "XOR    $dst.hi,$dst.hi\n\t" %}
   1.338    opcode(0x33); // XOR
   1.339 @@ -13220,7 +13346,7 @@
   1.340  // These must follow all instruction definitions as they use the names
   1.341  // defined in the instructions definitions.
   1.342  //
   1.343 -// peepmatch ( root_instr_name [preceeding_instruction]* );
   1.344 +// peepmatch ( root_instr_name [preceding_instruction]* );
   1.345  //
   1.346  // peepconstraint %{
   1.347  // (instruction_number.operand_name relational_op instruction_number.operand_name

mercurial