3162 emit_opcode(cbuf, 0x0F); 3163 emit_opcode(cbuf, 0x9C); 3164 emit_rm(cbuf, 0x3, 0x0, dstenc); 3165 %} 3166 3167 enc_class setNZ_reg(rRegI dst) 3168 %{ 3169 int dstenc = $dst$$reg; 3170 if (dstenc >= 8) { 3171 emit_opcode(cbuf, Assembler::REX_B); 3172 dstenc -= 8; 3173 } else if (dstenc >= 4) { 3174 emit_opcode(cbuf, Assembler::REX); 3175 } 3176 // SETNZ $dst 3177 emit_opcode(cbuf, 0x0F); 3178 emit_opcode(cbuf, 0x95); 3179 emit_rm(cbuf, 0x3, 0x0, dstenc); 3180 %} 3181 3182 enc_class enc_cmpLTP(no_rcx_RegI p, no_rcx_RegI q, no_rcx_RegI y, 3183 rcx_RegI tmp) 3184 %{ 3185 // cadd_cmpLT 3186 3187 int tmpReg = $tmp$$reg; 3188 3189 int penc = $p$$reg; 3190 int qenc = $q$$reg; 3191 int yenc = $y$$reg; 3192 3193 // subl $p,$q 3194 if (penc < 8) { 3195 if (qenc >= 8) { 3196 emit_opcode(cbuf, Assembler::REX_B); 3197 } 3198 } else { 3199 if (qenc < 8) { 3200 emit_opcode(cbuf, Assembler::REX_R); 3201 } else { 3202 emit_opcode(cbuf, Assembler::REX_RB); 3203 } 3204 } 3205 emit_opcode(cbuf, 0x2B); 3206 emit_rm(cbuf, 0x3, penc & 7, qenc & 7); 3207 3208 // sbbl $tmp, $tmp 3209 emit_opcode(cbuf, 0x1B); 3210 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 3211 3212 // andl $tmp, $y 3213 if (yenc >= 8) { 3214 emit_opcode(cbuf, Assembler::REX_B); 3215 } 3216 emit_opcode(cbuf, 0x23); 3217 emit_rm(cbuf, 0x3, tmpReg, yenc & 7); 3218 3219 // addl $p,$tmp 3220 if (penc >= 8) { 3221 emit_opcode(cbuf, Assembler::REX_R); 3222 } 3223 emit_opcode(cbuf, 0x03); 3224 emit_rm(cbuf, 0x3, penc & 7, tmpReg); 3225 %} 3226 3227 // Compare the lonogs and set -1, 0, or 1 into dst 3228 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 3229 %{ 3230 int src1enc = $src1$$reg; 3231 int src2enc = $src2$$reg; 3232 int dstenc = $dst$$reg; 3233 3234 // cmpq $src1, $src2 3235 if (src1enc < 8) { 3236 if (src2enc < 8) { 3237 emit_opcode(cbuf, Assembler::REX_W); 3238 } else { 3239 emit_opcode(cbuf, Assembler::REX_WB); 3240 } 3241 } else { 3242 if (src2enc < 8) { 3243 emit_opcode(cbuf, Assembler::REX_WR); 3244 } else { 3245 emit_opcode(cbuf, Assembler::REX_WRB); 3246 } 10189 setLT_reg(dst), 10190 REX_reg_breg(dst, dst), // movzbl 10191 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10192 neg_reg(dst)); 10193 ins_pipe(pipe_slow); 10194 %} 10195 10196 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10197 %{ 10198 match(Set dst (CmpLTMask dst zero)); 10199 effect(KILL cr); 10200 10201 ins_cost(100); // XXX 10202 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10203 opcode(0xC1, 0x7); /* C1 /7 ib */ 10204 ins_encode(reg_opc_imm(dst, 0x1F)); 10205 ins_pipe(ialu_reg); 10206 %} 10207 10208 10209 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, 10210 rRegI tmp, 10211 rFlagsReg cr) 10212 %{ 10213 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10214 effect(TEMP tmp, KILL cr); 10215 10216 ins_cost(400); // XXX 10217 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 10218 "sbbl $tmp, $tmp\n\t" 10219 "andl $tmp, $y\n\t" 10220 "addl $p, $tmp" %} 10221 ins_encode(enc_cmpLTP(p, q, y, tmp)); 10222 ins_pipe(pipe_cmplt); 10223 %} 10224 10225 /* If I enable this, I encourage spilling in the inner loop of compress. 10226 instruct cadd_cmpLTMask_mem( rRegI p, rRegI q, memory y, rRegI tmp, rFlagsReg cr ) 10227 %{ 10228 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q))); 10229 effect( TEMP tmp, KILL cr ); 10230 ins_cost(400); 10231 10232 format %{ "SUB $p,$q\n\t" 10233 "SBB RCX,RCX\n\t" 10234 "AND RCX,$y\n\t" 10235 "ADD $p,RCX" %} 10236 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) ); 10237 %} 10238 */ 10239 10240 //---------- FP Instructions------------------------------------------------ 10241 10242 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10243 %{ 10244 match(Set cr (CmpF src1 src2)); 10245 10246 ins_cost(145); 10247 format %{ "ucomiss $src1, $src2\n\t" 10248 "jnp,s exit\n\t" 10249 "pushfq\t# saw NaN, set CF\n\t" 10250 "andq [rsp], #0xffffff2b\n\t" 10251 "popfq\n" 10252 "exit: nop\t# avoid branch to branch" %} 10253 opcode(0x0F, 0x2E); 10254 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10255 cmpfp_fixup); 10256 ins_pipe(pipe_slow); 10257 %} 10258 10259 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ | 3162 emit_opcode(cbuf, 0x0F); 3163 emit_opcode(cbuf, 0x9C); 3164 emit_rm(cbuf, 0x3, 0x0, dstenc); 3165 %} 3166 3167 enc_class setNZ_reg(rRegI dst) 3168 %{ 3169 int dstenc = $dst$$reg; 3170 if (dstenc >= 8) { 3171 emit_opcode(cbuf, Assembler::REX_B); 3172 dstenc -= 8; 3173 } else if (dstenc >= 4) { 3174 emit_opcode(cbuf, Assembler::REX); 3175 } 3176 // SETNZ $dst 3177 emit_opcode(cbuf, 0x0F); 3178 emit_opcode(cbuf, 0x95); 3179 emit_rm(cbuf, 0x3, 0x0, dstenc); 3180 %} 3181 3182 3183 // Compare the lonogs and set -1, 0, or 1 into dst 3184 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 3185 %{ 3186 int src1enc = $src1$$reg; 3187 int src2enc = $src2$$reg; 3188 int dstenc = $dst$$reg; 3189 3190 // cmpq $src1, $src2 3191 if (src1enc < 8) { 3192 if (src2enc < 8) { 3193 emit_opcode(cbuf, Assembler::REX_W); 3194 } else { 3195 emit_opcode(cbuf, Assembler::REX_WB); 3196 } 3197 } else { 3198 if (src2enc < 8) { 3199 emit_opcode(cbuf, Assembler::REX_WR); 3200 } else { 3201 emit_opcode(cbuf, Assembler::REX_WRB); 3202 } 10145 setLT_reg(dst), 10146 REX_reg_breg(dst, dst), // movzbl 10147 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10148 neg_reg(dst)); 10149 ins_pipe(pipe_slow); 10150 %} 10151 10152 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10153 %{ 10154 match(Set dst (CmpLTMask dst zero)); 10155 effect(KILL cr); 10156 10157 ins_cost(100); // XXX 10158 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10159 opcode(0xC1, 0x7); /* C1 /7 ib */ 10160 ins_encode(reg_opc_imm(dst, 0x1F)); 10161 ins_pipe(ialu_reg); 10162 %} 10163 10164 10165 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 10166 %{ 10167 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10168 effect(TEMP tmp, KILL cr); 10169 10170 ins_cost(400); // XXX 10171 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 10172 "sbbl $tmp, $tmp\n\t" 10173 "andl $tmp, $y\n\t" 10174 "addl $p, $tmp" %} 10175 ins_encode %{ 10176 Register Rp = $p$$Register; 10177 Register Rq = $q$$Register; 10178 Register Ry = $y$$Register; 10179 Register Rt = $tmp$$Register; 10180 __ subl(Rp, Rq); 10181 __ sbbl(Rt, Rt); 10182 __ andl(Rt, Ry); 10183 __ addl(Rp, Rt); 10184 %} 10185 ins_pipe(pipe_cmplt); 10186 %} 10187 10188 //---------- FP Instructions------------------------------------------------ 10189 10190 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10191 %{ 10192 match(Set cr (CmpF src1 src2)); 10193 10194 ins_cost(145); 10195 format %{ "ucomiss $src1, $src2\n\t" 10196 "jnp,s exit\n\t" 10197 "pushfq\t# saw NaN, set CF\n\t" 10198 "andq [rsp], #0xffffff2b\n\t" 10199 "popfq\n" 10200 "exit: nop\t# avoid branch to branch" %} 10201 opcode(0x0F, 0x2E); 10202 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10203 cmpfp_fixup); 10204 ins_pipe(pipe_slow); 10205 %} 10206 10207 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ |