mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-22 03:58:16 +00:00
[x86] Broadwell: ADOX/ADCX. Added _addcarryx_u{32|64} intrinsics to LLVM.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216162 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3a34f5e115
commit
10dacc4b52
@ -2758,6 +2758,18 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
def int_x86_rdseed_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ADX
|
||||
|
||||
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
def int_x86_addcarryx_u32: GCCBuiltin<"__builtin_ia32_addcarryx_u32">,
|
||||
Intrinsic<[llvm_i8_ty], [llvm_i8_ty, llvm_i32_ty, llvm_i32_ty,
|
||||
llvm_ptr_ty], [IntrReadWriteArgMem]>;
|
||||
def int_x86_addcarryx_u64: GCCBuiltin<"__builtin_ia32_addcarryx_u64">,
|
||||
Intrinsic<[llvm_i8_ty], [llvm_i8_ty, llvm_i64_ty, llvm_i64_ty,
|
||||
llvm_ptr_ty], [IntrReadWriteArgMem]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// RTM intrinsics. Transactional Memory support.
|
||||
|
||||
|
@ -15355,7 +15355,7 @@ static SDValue LowerREADCYCLECOUNTER(SDValue Op, const X86Subtarget *Subtarget,
|
||||
}
|
||||
|
||||
enum IntrinsicType {
|
||||
GATHER, SCATTER, PREFETCH, RDSEED, RDRAND, RDPMC, RDTSC, XTEST
|
||||
GATHER, SCATTER, PREFETCH, RDSEED, RDRAND, RDPMC, RDTSC, XTEST, ADX
|
||||
};
|
||||
|
||||
struct IntrinsicData {
|
||||
@ -15451,6 +15451,10 @@ static void InitIntinsicsMap() {
|
||||
IntrinsicData(RDTSC, X86ISD::RDTSCP_DAG, 0)));
|
||||
IntrMap.insert(std::make_pair(Intrinsic::x86_rdpmc,
|
||||
IntrinsicData(RDPMC, X86ISD::RDPMC_DAG, 0)));
|
||||
IntrMap.insert(std::make_pair(Intrinsic::x86_addcarryx_u32,
|
||||
IntrinsicData(ADX, X86ISD::ADC, 0)));
|
||||
IntrMap.insert(std::make_pair(Intrinsic::x86_addcarryx_u64,
|
||||
IntrinsicData(ADX, X86ISD::ADC, 0)));
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
@ -15543,6 +15547,25 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget *Subtarget,
|
||||
return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(),
|
||||
Ret, SDValue(InTrans.getNode(), 1));
|
||||
}
|
||||
// ADC/ADCX
|
||||
case ADX: {
|
||||
SmallVector<SDValue, 2> Results;
|
||||
SDVTList CFVTs = DAG.getVTList(Op->getValueType(0), MVT::Other);
|
||||
SDVTList VTs = DAG.getVTList(Op.getOperand(3)->getValueType(0), MVT::Other);
|
||||
SDValue GenCF = DAG.getNode(X86ISD::ADD, dl, CFVTs, Op.getOperand(2),
|
||||
DAG.getConstant(-1, MVT::i8));
|
||||
SDValue Res = DAG.getNode(Intr.Opc0, dl, VTs, Op.getOperand(3),
|
||||
Op.getOperand(4), GenCF.getValue(1));
|
||||
SDValue Store = DAG.getStore(Op.getOperand(0), dl, Res.getValue(0),
|
||||
Op.getOperand(5), MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
SDValue SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
|
||||
DAG.getConstant(X86::COND_B, MVT::i8),
|
||||
Res.getValue(1));
|
||||
Results.push_back(SetCC);
|
||||
Results.push_back(Store);
|
||||
return DAG.getMergeValues(Results, dl);
|
||||
}
|
||||
}
|
||||
llvm_unreachable("Unknown Intrinsic Type");
|
||||
}
|
||||
|
@ -1355,49 +1355,57 @@ let Predicates = [HasBMI2] in {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ADCX Instruction
|
||||
//
|
||||
let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
|
||||
let hasSideEffects = 0, Defs = [EFLAGS], Uses = [EFLAGS],
|
||||
Constraints = "$src0 = $dst", AddedComplexity = 10 in {
|
||||
let SchedRW = [WriteALU] in {
|
||||
def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
|
||||
"adcx{l}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_NONMEM>, T8PD;
|
||||
|
||||
def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
|
||||
"adcx{q}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_NONMEM>, T8PD, Requires<[In64BitMode]>;
|
||||
def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
|
||||
(ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, EFLAGS,
|
||||
(X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
|
||||
IIC_BIN_CARRY_NONMEM>, T8PD, Requires<[HasADX]>;
|
||||
def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
|
||||
(ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, EFLAGS,
|
||||
(X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
|
||||
IIC_BIN_CARRY_NONMEM>, T8PD, Requires<[HasADX, In64BitMode]>;
|
||||
} // SchedRW
|
||||
|
||||
let mayLoad = 1, SchedRW = [WriteALULd] in {
|
||||
def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
|
||||
"adcx{l}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_MEM>, T8PD;
|
||||
def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
|
||||
(ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, EFLAGS,
|
||||
(X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
|
||||
IIC_BIN_CARRY_MEM>, T8PD, Requires<[HasADX]>;
|
||||
|
||||
def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
|
||||
"adcx{q}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_MEM>, T8PD, Requires<[In64BitMode]>;
|
||||
def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
|
||||
(ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, EFLAGS,
|
||||
(X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
|
||||
IIC_BIN_CARRY_MEM>, T8PD, Requires<[HasADX, In64BitMode]>;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ADOX Instruction
|
||||
//
|
||||
let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
|
||||
let hasSideEffects = 0, Defs = [EFLAGS], Uses = [EFLAGS] in {
|
||||
let SchedRW = [WriteALU] in {
|
||||
def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
|
||||
"adox{l}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_NONMEM>, T8XS;
|
||||
[], IIC_BIN_NONMEM>, T8XS, Requires<[HasADX]>;
|
||||
|
||||
def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
|
||||
"adox{q}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_NONMEM>, T8XS, Requires<[In64BitMode]>;
|
||||
[], IIC_BIN_NONMEM>, T8XS, Requires<[HasADX, In64BitMode]>;
|
||||
} // SchedRW
|
||||
|
||||
let mayLoad = 1, SchedRW = [WriteALULd] in {
|
||||
def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
|
||||
"adox{l}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_MEM>, T8XS;
|
||||
[], IIC_BIN_MEM>, T8XS, Requires<[HasADX]>;
|
||||
|
||||
def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
|
||||
"adox{q}\t{$src, $dst|$dst, $src}",
|
||||
[], IIC_BIN_MEM>, T8XS, Requires<[In64BitMode]>;
|
||||
[], IIC_BIN_MEM>, T8XS, Requires<[HasADX, In64BitMode]>;
|
||||
}
|
||||
}
|
||||
|
26
test/CodeGen/X86/adx-intrinsics.ll
Normal file
26
test/CodeGen/X86/adx-intrinsics.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=broadwell --show-mc-encoding| FileCheck %s --check-prefix=ADX --check-prefix=CHECK
|
||||
|
||||
declare i8 @llvm.x86.addcarryx.u32(i8, i32, i32, i8*)
|
||||
|
||||
define i8 @test_addcarryx_u32(i8 %c, i32 %a, i32 %b, i8* %ptr) {
|
||||
; CHECK-LABEL: test_addcarryx_u32
|
||||
; CHECK: addb
|
||||
; ADX: adcxl
|
||||
; CHECK: setb
|
||||
; CHECK: retq
|
||||
%ret = tail call i8 @llvm.x86.addcarryx.u32(i8 %c, i32 %a, i32 %b, i8* %ptr)
|
||||
ret i8 %ret;
|
||||
}
|
||||
|
||||
declare i8 @llvm.x86.addcarryx.u64(i8, i64, i64, i8*)
|
||||
|
||||
define i8 @test_addcarryx_u64(i8 %c, i64 %a, i64 %b, i8* %ptr) {
|
||||
; CHECK-LABEL: test_addcarryx_u64
|
||||
; CHECK: addb
|
||||
; ADX: adcxq
|
||||
; CHECK: setb
|
||||
; CHECK: retq
|
||||
%ret = tail call i8 @llvm.x86.addcarryx.u64(i8 %c, i64 %a, i64 %b, i8* %ptr)
|
||||
ret i8 %ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user