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