1.1 --- a/src/cpu/x86/vm/x86_32.ad Fri Apr 12 20:37:18 2013 -0400 1.2 +++ b/src/cpu/x86/vm/x86_32.ad Fri Apr 12 19:14:47 2013 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 // 1.5 -// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 +// Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 // 1.9 // This code is free software; you can redistribute it and/or modify it 1.10 @@ -2317,30 +2317,6 @@ 1.11 emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 1.12 %} 1.13 1.14 - enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT 1.15 - int tmpReg = $tmp$$reg; 1.16 - 1.17 - // SUB $p,$q 1.18 - emit_opcode(cbuf,0x2B); 1.19 - emit_rm(cbuf, 0x3, $p$$reg, $q$$reg); 1.20 - // SBB $tmp,$tmp 1.21 - emit_opcode(cbuf,0x1B); 1.22 - emit_rm(cbuf, 0x3, tmpReg, tmpReg); 1.23 - // AND $tmp,$y 1.24 - cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 1.25 - emit_opcode(cbuf,0x23); 1.26 - int reg_encoding = tmpReg; 1.27 - int base = $mem$$base; 1.28 - int index = $mem$$index; 1.29 - int scale = $mem$$scale; 1.30 - int displace = $mem$$disp; 1.31 - relocInfo::relocType disp_reloc = $mem->disp_reloc(); 1.32 - encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 1.33 - // ADD $p,$tmp 1.34 - emit_opcode(cbuf,0x03); 1.35 - emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 1.36 - %} 1.37 - 1.38 enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{ 1.39 // TEST shift,32 1.40 emit_opcode(cbuf,0xF7); 1.41 @@ -8922,9 +8898,9 @@ 1.42 %} 1.43 %} 1.44 1.45 -instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{ 1.46 +instruct cmpLTMask(eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr) %{ 1.47 match(Set dst (CmpLTMask p q)); 1.48 - effect( KILL cr ); 1.49 + effect(KILL cr); 1.50 ins_cost(400); 1.51 1.52 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination 1.53 @@ -8932,50 +8908,83 @@ 1.54 "CMP $p,$q\n\t" 1.55 "SETlt $dst\n\t" 1.56 "NEG $dst" %} 1.57 - ins_encode( OpcRegReg(0x33,dst,dst), 1.58 - OpcRegReg(0x3B,p,q), 1.59 - setLT_reg(dst), neg_reg(dst) ); 1.60 - ins_pipe( pipe_slow ); 1.61 -%} 1.62 - 1.63 -instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{ 1.64 + ins_encode %{ 1.65 + Register Rp = $p$$Register; 1.66 + Register Rq = $q$$Register; 1.67 + Register Rd = $dst$$Register; 1.68 + Label done; 1.69 + __ xorl(Rd, Rd); 1.70 + __ cmpl(Rp, Rq); 1.71 + __ setb(Assembler::less, Rd); 1.72 + __ negl(Rd); 1.73 + %} 1.74 + 1.75 + ins_pipe(pipe_slow); 1.76 +%} 1.77 + 1.78 +instruct cmpLTMask0(rRegI dst, immI0 zero, eFlagsReg cr) %{ 1.79 match(Set dst (CmpLTMask dst zero)); 1.80 - effect( DEF dst, KILL cr ); 1.81 + effect(DEF dst, KILL cr); 1.82 ins_cost(100); 1.83 1.84 - format %{ "SAR $dst,31" %} 1.85 - opcode(0xC1, 0x7); /* C1 /7 ib */ 1.86 - ins_encode( RegOpcImm( dst, 0x1F ) ); 1.87 - ins_pipe( ialu_reg ); 1.88 -%} 1.89 - 1.90 - 1.91 -instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{ 1.92 + format %{ "SAR $dst,31\t# cmpLTMask0" %} 1.93 + ins_encode %{ 1.94 + __ sarl($dst$$Register, 31); 1.95 + %} 1.96 + ins_pipe(ialu_reg); 1.97 +%} 1.98 + 1.99 +/* better to save a register than avoid a branch */ 1.100 +instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{ 1.101 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 1.102 - effect( KILL tmp, KILL cr ); 1.103 + effect(KILL cr); 1.104 ins_cost(400); 1.105 - // annoyingly, $tmp has no edges so you cant ask for it in 1.106 - // any format or encoding 1.107 - format %{ "SUB $p,$q\n\t" 1.108 - "SBB ECX,ECX\n\t" 1.109 - "AND ECX,$y\n\t" 1.110 - "ADD $p,ECX" %} 1.111 - ins_encode( enc_cmpLTP(p,q,y,tmp) ); 1.112 - ins_pipe( pipe_cmplt ); 1.113 + format %{ "SUB $p,$q\t# cadd_cmpLTMask\n\t" 1.114 + "JGE done\n\t" 1.115 + "ADD $p,$y\n" 1.116 + "done: " %} 1.117 + ins_encode %{ 1.118 + Register Rp = $p$$Register; 1.119 + Register Rq = $q$$Register; 1.120 + Register Ry = $y$$Register; 1.121 + Label done; 1.122 + __ subl(Rp, Rq); 1.123 + __ jccb(Assembler::greaterEqual, done); 1.124 + __ addl(Rp, Ry); 1.125 + __ bind(done); 1.126 + %} 1.127 + 1.128 + ins_pipe(pipe_cmplt); 1.129 +%} 1.130 + 1.131 +/* better to save a register than avoid a branch */ 1.132 +instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, eFlagsReg cr) %{ 1.133 + match(Set y (AndI (CmpLTMask p q) y)); 1.134 + effect(KILL cr); 1.135 + 1.136 + ins_cost(300); 1.137 + 1.138 + format %{ "CMPL $p, $q\t# and_cmpLTMask\n\t" 1.139 + "JLT done\n\t" 1.140 + "XORL $y, $y\n" 1.141 + "done: " %} 1.142 + ins_encode %{ 1.143 + Register Rp = $p$$Register; 1.144 + Register Rq = $q$$Register; 1.145 + Register Ry = $y$$Register; 1.146 + Label done; 1.147 + __ cmpl(Rp, Rq); 1.148 + __ jccb(Assembler::less, done); 1.149 + __ xorl(Ry, Ry); 1.150 + __ bind(done); 1.151 + %} 1.152 + 1.153 + ins_pipe(pipe_cmplt); 1.154 %} 1.155 1.156 /* If I enable this, I encourage spilling in the inner loop of compress. 1.157 -instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{ 1.158 +instruct cadd_cmpLTMask_mem(ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr) %{ 1.159 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q))); 1.160 - effect( USE_KILL tmp, KILL cr ); 1.161 - ins_cost(400); 1.162 - 1.163 - format %{ "SUB $p,$q\n\t" 1.164 - "SBB ECX,ECX\n\t" 1.165 - "AND ECX,$y\n\t" 1.166 - "ADD $p,ECX" %} 1.167 - ins_encode( enc_cmpLTP_mem(p,q,y,tmp) ); 1.168 -%} 1.169 */ 1.170 1.171 //----------Long Instructions------------------------------------------------