[llvm] r353307 - [InlineAsm][X86] Add backend support for X86 flag output parameters.
Nirav Dave via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 6 07:26:29 PST 2019
Author: niravd
Date: Wed Feb 6 07:26:29 2019
New Revision: 353307
URL: http://llvm.org/viewvc/llvm-project?rev=353307&view=rev
Log:
[InlineAsm][X86] Add backend support for X86 flag output parameters.
Allow custom handling of inline assembly output parameters and add X86
flag parameter support.
Added:
llvm/trunk/test/CodeGen/X86/inline-asm-flag-output.ll
Modified:
llvm/trunk/include/llvm/CodeGen/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
Modified: llvm/trunk/include/llvm/CodeGen/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLowering.h?rev=353307&r1=353306&r2=353307&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLowering.h Wed Feb 6 07:26:29 2019
@@ -3658,6 +3658,12 @@ public:
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
+ // Lower custom output constraints. If invalid, return SDValue().
+ virtual SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue *Flag,
+ SDLoc DL,
+ const AsmOperandInfo &OpInfo,
+ SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Div utility functions
//
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=353307&r1=353306&r2=353307&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Feb 6 07:26:29 2019
@@ -7688,11 +7688,9 @@ void SelectionDAGBuilder::visitInlineAsm
switch (OpInfo.Type) {
case InlineAsm::isOutput:
- if (OpInfo.ConstraintType != TargetLowering::C_RegisterClass &&
- OpInfo.ConstraintType != TargetLowering::C_Register) {
- // Memory output, or 'other' output (e.g. 'X' constraint).
- assert(OpInfo.isIndirect && "Memory output must be indirect operand");
-
+ if (OpInfo.ConstraintType == TargetLowering::C_Memory ||
+ (OpInfo.ConstraintType == TargetLowering::C_Other &&
+ OpInfo.isIndirect)) {
unsigned ConstraintID =
TLI.getInlineAsmMemConstraint(OpInfo.ConstraintCode);
assert(ConstraintID != InlineAsm::Constraint_Unknown &&
@@ -7705,12 +7703,13 @@ void SelectionDAGBuilder::visitInlineAsm
MVT::i32));
AsmNodeOperands.push_back(OpInfo.CallOperand);
break;
- } else if (OpInfo.ConstraintType == TargetLowering::C_Register ||
+ } else if ((OpInfo.ConstraintType == TargetLowering::C_Other &&
+ !OpInfo.isIndirect) ||
+ OpInfo.ConstraintType == TargetLowering::C_Register ||
OpInfo.ConstraintType == TargetLowering::C_RegisterClass) {
- // Otherwise, this is a register or register class output.
-
- // Copy the output from the appropriate register. Find a register that
- // we can use.
+ // Otherwise, this outputs to a register (directly for C_Register /
+ // C_RegisterClass, and a target-defined fashion for C_Other). Find a
+ // register that we can use.
if (OpInfo.AssignedRegs.Regs.empty()) {
emitInlineAsmError(
CS, "couldn't allocate output register for constraint '" +
@@ -7941,13 +7940,16 @@ void SelectionDAGBuilder::visitInlineAsm
DAG, FuncInfo, getCurSDLoc(), Chain, &Flag, CS.getInstruction());
break;
case TargetLowering::C_Other:
+ Val = TLI.LowerAsmOutputForConstraint(Chain, &Flag, getCurSDLoc(),
+ OpInfo, DAG);
+ break;
case TargetLowering::C_Memory:
break; // Already handled.
case TargetLowering::C_Unknown:
assert(false && "Unexpected unknown constraint");
}
- // Indirect output are manifest as stores. Record output chains.
+ // Indirect output manifest as stores. Record output chains.
if (OpInfo.isIndirect) {
const Value *Ptr = OpInfo.CallOperandVal;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=353307&r1=353306&r2=353307&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Wed Feb 6 07:26:29 2019
@@ -3231,6 +3231,12 @@ const char *TargetLowering::LowerXConstr
return nullptr;
}
+SDValue TargetLowering::LowerAsmOutputForConstraint(
+ SDValue &Chain, SDValue *Flag, SDLoc DL, const AsmOperandInfo &OpInfo,
+ SelectionDAG &DAG) const {
+ return SDValue();
+}
+
/// Lower the specified operand into the Ops vector.
/// If it is invalid, don't add anything to Ops.
void TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=353307&r1=353306&r2=353307&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 6 07:26:29 2019
@@ -42494,6 +42494,40 @@ bool X86TargetLowering::ExpandInlineAsm(
return false;
}
+static X86::CondCode parseConstraintCode(llvm::StringRef Constraint) {
+ X86::CondCode Cond = StringSwitch<X86::CondCode>(Constraint)
+ .Case("{@cca}", X86::COND_A)
+ .Case("{@ccae}", X86::COND_AE)
+ .Case("{@ccb}", X86::COND_B)
+ .Case("{@ccbe}", X86::COND_BE)
+ .Case("{@ccc}", X86::COND_B)
+ .Case("{@cce}", X86::COND_E)
+ .Case("{@ccz}", X86::COND_NE)
+ .Case("{@ccg}", X86::COND_G)
+ .Case("{@ccge}", X86::COND_GE)
+ .Case("{@ccl}", X86::COND_L)
+ .Case("{@ccle}", X86::COND_LE)
+ .Case("{@ccna}", X86::COND_BE)
+ .Case("{@ccnae}", X86::COND_B)
+ .Case("{@ccnb}", X86::COND_AE)
+ .Case("{@ccnbe}", X86::COND_A)
+ .Case("{@ccnc}", X86::COND_AE)
+ .Case("{@ccne}", X86::COND_NE)
+ .Case("{@ccnz}", X86::COND_NE)
+ .Case("{@ccng}", X86::COND_LE)
+ .Case("{@ccnge}", X86::COND_L)
+ .Case("{@ccnl}", X86::COND_GE)
+ .Case("{@ccnle}", X86::COND_G)
+ .Case("{@ccno}", X86::COND_NO)
+ .Case("{@ccnp}", X86::COND_P)
+ .Case("{@ccns}", X86::COND_NS)
+ .Case("{@cco}", X86::COND_O)
+ .Case("{@ccp}", X86::COND_P)
+ .Case("{@ccs}", X86::COND_S)
+ .Default(X86::COND_INVALID);
+ return Cond;
+}
+
/// Given a constraint letter, return the type of constraint for this target.
X86TargetLowering::ConstraintType
X86TargetLowering::getConstraintType(StringRef Constraint) const {
@@ -42554,7 +42588,8 @@ X86TargetLowering::getConstraintType(Str
return C_RegisterClass;
}
}
- }
+ } else if (parseConstraintCode(Constraint) != X86::COND_INVALID)
+ return C_Other;
return TargetLowering::getConstraintType(Constraint);
}
@@ -42725,6 +42760,33 @@ LowerXConstraint(EVT ConstraintVT) const
return TargetLowering::LowerXConstraint(ConstraintVT);
}
+// Lower @cc targets via setcc.
+SDValue X86TargetLowering::LowerAsmOutputForConstraint(
+ SDValue &Chain, SDValue *Flag, SDLoc DL, const AsmOperandInfo &OpInfo,
+ SelectionDAG &DAG) const {
+ X86::CondCode Cond = parseConstraintCode(OpInfo.ConstraintCode);
+ if (Cond == X86::COND_INVALID)
+ return SDValue();
+ // Check that return type is valid.
+ if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
+ OpInfo.ConstraintVT.getSizeInBits() < 8)
+ report_fatal_error("Flag output operand is of invalid type");
+
+ // Get EFLAGS register. Only update chain when copyfrom is glued.
+ SDValue EFlags;
+ if (Flag) {
+ EFlags = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32, *Flag);
+ Chain = EFlags.getValue(1);
+ } else
+ EFlags = DAG.getCopyFromReg(Chain, DL, X86::EFLAGS, MVT::i32);
+ // Extract CC code.
+ SDValue CC = getSETCC(Cond, EFlags, DL, DAG);
+ // Extend to 32-bits
+ SDValue Result = DAG.getNode(ISD::ZERO_EXTEND, DL, OpInfo.ConstraintVT, CC);
+
+ return Result;
+}
+
/// Lower the specified operand into the Ops vector.
/// If it is invalid, don't add anything to Ops.
void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
@@ -43081,6 +43143,9 @@ X86TargetLowering::getRegForInlineAsmCon
}
}
+ if (parseConstraintCode(Constraint) != X86::COND_INVALID)
+ return std::make_pair(0U, &X86::GR32RegClass);
+
// Use the default implementation in TargetLowering to convert the register
// constraint into a member of a register class.
std::pair<unsigned, const TargetRegisterClass*> Res;
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=353307&r1=353306&r2=353307&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Feb 6 07:26:29 2019
@@ -923,6 +923,11 @@ namespace llvm {
return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
}
+ /// Handle Lowering flag assembly outputs.
+ SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue *Flag, SDLoc DL,
+ const AsmOperandInfo &Constraint,
+ SelectionDAG &DAG) const override;
+
/// Given a physical register constraint
/// (e.g. {edx}), return the register number and the register class for the
/// register. This should only be used for C_Register constraints. On
Added: llvm/trunk/test/CodeGen/X86/inline-asm-flag-output.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/inline-asm-flag-output.ll?rev=353307&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/inline-asm-flag-output.ll (added)
+++ llvm/trunk/test/CodeGen/X86/inline-asm-flag-output.ll Wed Feb 6 07:26:29 2019
@@ -0,0 +1,954 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-- -no-integrated-as | FileCheck %s -check-prefix=X32
+; RUN: llc < %s -mtriple=x86_64-- -no-integrated-as | FileCheck %s -check-prefix=X64
+
+define i32 @test_cca(i64 %nr, i64* %addr) {
+; X32-LABEL: test_cca:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setbe %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_cca:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setbe %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@cca},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccae(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccae:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setb %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccae:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setb %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccb(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccb:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setae %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccb:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setae %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccbe(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccbe:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: seta %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccbe:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: seta %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccc(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccc:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setae %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccc:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setae %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_cce(i64 %nr, i64* %addr) {
+; X32-LABEL: test_cce:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setne %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_cce:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setne %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@cce},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccz(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccz:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: sete %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccz:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: sete %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccg(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccg:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setle %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccg:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setle %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccg},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccge(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccge:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setl %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccge:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setl %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccl(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccl:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setge %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccl:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setge %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccle(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccle:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setg %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccle:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setg %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccna(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccna:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: seta %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccna:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: seta %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccna},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnae(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnae:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setae %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnae:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setae %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnb(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnb:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setb %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnb:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setb %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnbe(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnbe:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setbe %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnbe:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setbe %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnc(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnc:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setb %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnc:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setb %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccne(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccne:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: sete %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccne:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: sete %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccne},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnz(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnz:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: sete %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnz:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: sete %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccng(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccng:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setg %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccng:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setg %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccng},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnge(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnge:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setge %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnge:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setge %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnl(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnl:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setl %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnl:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setl %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnle(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnle:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setle %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnle:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setle %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccno(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccno:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: seto %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccno:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: seto %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccno},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccnp(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccnp:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setnp %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccnp:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setnp %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccnp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccns(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccns:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: sets %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccns:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: sets %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccns},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_cco(i64 %nr, i64* %addr) {
+; X32-LABEL: test_cco:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setno %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_cco:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setno %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@cco},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccp(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccp:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setnp %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccp:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setnp %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
+
+
+define i32 @test_ccs(i64 %nr, i64* %addr) {
+; X32-LABEL: test_ccs:
+; X32: # %bb.0: # %entry
+; X32-NEXT: pushl %esi
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .cfi_offset %esi, -8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: #APP
+; X32-NEXT: cmp %ecx,(%esi)
+; X32-NEXT: #NO_APP
+; X32-NEXT: setns %al
+; X32-NEXT: popl %esi
+; X32-NEXT: .cfi_def_cfa_offset 4
+; X32-NEXT: retl
+;
+; X64-LABEL: test_ccs:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: #APP
+; X64-NEXT: cmp %rdi,(%rsi)
+; X64-NEXT: #NO_APP
+; X64-NEXT: setns %al
+; X64-NEXT: retq
+entry:
+ %cc = tail call i32 asm "cmp $2,$1", "={@ccs},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr) nounwind
+ %tobool = icmp eq i32 %cc, 0
+ %rv = zext i1 %tobool to i32
+ ret i32 %rv
+}
More information about the llvm-commits
mailing list