llvm.org GIT mirror llvm / 54a1117
Add X86 ANDN instruction. Including instruction selection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141947 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 8 years ago
8 changed file(s) with 83 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
1070110701 case X86ISD::OR: return "X86ISD::OR";
1070210702 case X86ISD::XOR: return "X86ISD::XOR";
1070310703 case X86ISD::AND: return "X86ISD::AND";
10704 case X86ISD::ANDN: return "X86ISD::ANDN";
1070410705 case X86ISD::MUL_IMM: return "X86ISD::MUL_IMM";
1070510706 case X86ISD::PTEST: return "X86ISD::PTEST";
1070610707 case X86ISD::TESTP: return "X86ISD::TESTP";
1329413295 if (R.getNode())
1329513296 return R;
1329613297
13298 EVT VT = N->getValueType(0);
13299
13300 // Create ANDN instructions
13301 if (Subtarget->hasBMI() && (VT == MVT::i32 || VT == MVT::i64)) {
13302 SDValue N0 = N->getOperand(0);
13303 SDValue N1 = N->getOperand(1);
13304 DebugLoc DL = N->getDebugLoc();
13305
13306 // Check LHS for not
13307 if (N0.getOpcode() == ISD::XOR && isAllOnes(N0.getOperand(1)))
13308 return DAG.getNode(X86ISD::ANDN, DL, VT, N0.getOperand(0), N1);
13309 // Check RHS for not
13310 if (N1.getOpcode() == ISD::XOR && isAllOnes(N1.getOperand(1)))
13311 return DAG.getNode(X86ISD::ANDN, DL, VT, N1.getOperand(0), N0);
13312
13313 return SDValue();
13314 }
13315
1329713316 // Want to form ANDNP nodes:
1329813317 // 1) In the hopes of then easily combining them with OR and AND nodes
1329913318 // to form PBLEND/PSIGN.
1330013319 // 2) To match ANDN packed intrinsics
13301 EVT VT = N->getValueType(0);
1330213320 if (VT != MVT::v2i64 && VT != MVT::v4i64)
1330313321 return SDValue();
1330413322
226226 // ADD, SUB, SMUL, etc. - Arithmetic operations with FLAGS results.
227227 ADD, SUB, ADC, SBB, SMUL,
228228 INC, DEC, OR, XOR, AND,
229
230 ANDN, // ANDN - Bitwise AND NOT with FLAGS results.
229231
230232 UMUL, // LOW, HI, FLAGS = umul LHS, RHS
231233
11501150 let isPseudo = 1 in
11511151 def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
11521152 "", []>;
1153 }
1154
1153 }
1154
1155 //===----------------------------------------------------------------------===//
1156 // ANDN Instruction
1157 //
1158 multiclass bmi_andn
1159 PatFrag ld_frag> {
1160 def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1161 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1162 [(set RC:$dst, EFLAGS, (X86andn_flag RC:$src1, RC:$src2))]>;
1163 def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1164 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1165 [(set RC:$dst, EFLAGS,
1166 (X86andn_flag RC:$src1, (ld_frag addr:$src2)))]>;
1167 }
1168
1169 let Predicates = [HasBMI], Defs = [EFLAGS] in {
1170 defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8, VEX_4V;
1171 defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8, VEX_4V, VEX_W;
1172 }
223223 [SDNPCommutative]>;
224224 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
225225 [SDNPCommutative]>;
226 def X86andn_flag : SDNode<"X86ISD::ANDN", SDTBinaryArithWithFlags>;
226227
227228 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
228229
3535
3636 declare i8 @llvm.cttz.i8(i8) nounwind readnone
3737
38 define i32 @andn32(i32 %x, i32 %y) nounwind readnone {
39 %tmp1 = xor i32 %x, -1
40 %tmp2 = and i32 %y, %tmp1
41 ret i32 %tmp2
42 ; CHECK: andn32:
43 ; CHECK: andnl
44 }
45
46 define i64 @andn64(i64 %x, i64 %y) nounwind readnone {
47 %tmp1 = xor i64 %x, -1
48 %tmp2 = and i64 %tmp1, %y
49 ret i64 %tmp2
50 ; CHECK: andn64:
51 ; CHECK: andnq
52 }
505505
506506 # CHECK: tzcntq %rax, %rax
507507 0xf3 0x48 0x0f 0xbc 0xc0
508
509 # CHECK: andnl %ecx, %r15d, %eax
510 0xc4 0xe2 0x00 0xf2 0xc1
511
512 # CHECK: andnq %rax, %r15, %rax
513 0xc4 0xe2 0x80 0xf2 0xc0
514
515 # CHECK: andnl (%rax), %r15d, %eax
516 0xc4 0xe2 0x00 0xf2 0x00
517
518 # CHECK: andnq (%rax), %r15, %rax
519 0xc4 0xe2 0x80 0xf2 0x00
482482
483483 # CHECK: tzcntw %ax, %ax
484484 0x66 0xf3 0x0f 0xbc 0xc0
485
486 # CHECK: andnl %ecx, %edi, %eax
487 0xc4 0xe2 0x00 0xf2 0xc1
488
489 # CHECK: andnl (%eax), %edi, %eax
490 0xc4 0xe2 0x00 0xf2 0x00
491
492 # CHECK: andnl %ecx, %edi, %eax
493 0xc4 0xe2 0x80 0xf2 0xc1
494
495 # CHECK: andnl (%eax), %edi, %eax
496 0xc4 0xe2 0x80 0xf2 0x00
11411141 OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString
11421142 (const std::string &s,
11431143 bool hasOpSizePrefix) {
1144 ENCODING("GR32", ENCODING_VVVV)
1145 ENCODING("GR64", ENCODING_VVVV)
11441146 ENCODING("FR32", ENCODING_VVVV)
11451147 ENCODING("FR64", ENCODING_VVVV)
11461148 ENCODING("VR128", ENCODING_VVVV)