mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Add 64-bit compare + branch for SPARC v9.
The same compare instruction is used for 32-bit and 64-bit compares. It sets two different sets of flags: icc and xcc. This patch adds a conditional branch instruction using the xcc flags for 64-bit compares. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2d8f62017d
commit
8534e9998c
@ -824,6 +824,10 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::BR_CC, MVT::i64, Custom);
|
||||
}
|
||||
|
||||
// FIXME: There are instructions available for ATOMIC_FENCE
|
||||
// on SparcV8 and later.
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
|
||||
@ -893,6 +897,7 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case SPISD::CMPICC: return "SPISD::CMPICC";
|
||||
case SPISD::CMPFCC: return "SPISD::CMPFCC";
|
||||
case SPISD::BRICC: return "SPISD::BRICC";
|
||||
case SPISD::BRXCC: return "SPISD::BRXCC";
|
||||
case SPISD::BRFCC: return "SPISD::BRFCC";
|
||||
case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
|
||||
case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
|
||||
@ -1029,12 +1034,13 @@ static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
// Get the condition flag.
|
||||
SDValue CompareFlag;
|
||||
if (LHS.getValueType() == MVT::i32) {
|
||||
EVT VTs[] = { MVT::i32, MVT::Glue };
|
||||
if (LHS.getValueType().isInteger()) {
|
||||
EVT VTs[] = { LHS.getValueType(), MVT::Glue };
|
||||
SDValue Ops[2] = { LHS, RHS };
|
||||
CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
|
||||
if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
|
||||
Opc = SPISD::BRICC;
|
||||
// 32-bit compares use the icc flags, 64-bit uses the xcc flags.
|
||||
Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC;
|
||||
} else {
|
||||
CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
|
||||
if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
|
||||
|
@ -24,9 +24,10 @@ namespace llvm {
|
||||
namespace SPISD {
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
CMPICC, // Compare two GPR operands, set icc.
|
||||
CMPICC, // Compare two GPR operands, set icc+xcc.
|
||||
CMPFCC, // Compare two FP operands, set fcc.
|
||||
BRICC, // Branch to dest on icc condition
|
||||
BRXCC, // Branch to dest on xcc condition (64-bit only).
|
||||
BRFCC, // Branch to dest on fcc condition
|
||||
SELECT_ICC, // Select between two values using the current ICC flags.
|
||||
SELECT_FCC, // Select between two values using the current FCC flags.
|
||||
|
@ -161,6 +161,8 @@ def : Pat<(sube i64:$a, i64:$b), (SUBXrr $a, $b)>;
|
||||
def : Pat<(addc i64:$a, i64:$b), (ADDCCrr $a, $b)>;
|
||||
def : Pat<(subc i64:$a, i64:$b), (SUBCCrr $a, $b)>;
|
||||
|
||||
def : Pat<(SPcmpicc i64:$a, i64:$b), (SUBCCrr $a, $b)>;
|
||||
|
||||
// Register-immediate instructions.
|
||||
|
||||
def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>;
|
||||
@ -170,6 +172,8 @@ def : Pat<(xor i64:$a, (i64 simm13:$b)), (XORri $a, (as_i32imm $b))>;
|
||||
def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;
|
||||
def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
|
||||
|
||||
def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (SUBCCri $a, (as_i32imm $b))>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
||||
|
||||
|
||||
@ -239,3 +243,20 @@ def : Pat<(truncstorei32 i64:$src, ADDRrr:$addr), (STrr ADDRrr:$addr, $src)>;
|
||||
def : Pat<(truncstorei32 i64:$src, ADDRri:$addr), (STri ADDRri:$addr, $src)>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 64-bit Conditionals.
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Flag-setting instructions like subcc and addcc set both icc and xcc flags.
|
||||
// The icc flags correspond to the 32-bit result, and the xcc are for the
|
||||
// full 64-bit result.
|
||||
//
|
||||
// We reuse CMPICC SDNodes for compares, but use new BRXCC branch nodes for
|
||||
// 64-bit compares. See LowerBR_CC.
|
||||
|
||||
let Uses = [ICC] in
|
||||
def BPXCC : BranchSP<0, (ins brtarget:$dst, CCOp:$cc),
|
||||
"bp$cc %xcc, $dst",
|
||||
[(SPbrxcc bb:$dst, imm:$cc)]>;
|
||||
|
@ -104,6 +104,7 @@ SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
|
||||
def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutGlue]>;
|
||||
def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;
|
||||
def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
|
||||
def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
|
||||
def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
|
||||
|
||||
def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>;
|
||||
|
@ -43,7 +43,7 @@ class Rd<bits<5> num, string n, list<Register> subregs> : SparcReg<n> {
|
||||
}
|
||||
|
||||
// Control Registers
|
||||
def ICC : SparcCtrlReg<"ICC">;
|
||||
def ICC : SparcCtrlReg<"ICC">; // This represents icc and xcc in 64-bit code.
|
||||
def FCC : SparcCtrlReg<"FCC">;
|
||||
|
||||
// Y register
|
||||
|
34
test/CodeGen/SPARC/64cond.ll
Normal file
34
test/CodeGen/SPARC/64cond.ll
Normal file
@ -0,0 +1,34 @@
|
||||
; RUN: llc < %s -march=sparcv9 | FileCheck %s
|
||||
; Testing 64-bit conditionals.
|
||||
|
||||
; CHECK: cmpri
|
||||
; CHECK: subcc %i1, 1
|
||||
; CHECK: bpe %xcc,
|
||||
define void @cmpri(i64* %p, i64 %x) {
|
||||
entry:
|
||||
%tobool = icmp eq i64 %x, 1
|
||||
br i1 %tobool, label %if.end, label %if.then
|
||||
|
||||
if.then:
|
||||
store i64 %x, i64* %p, align 8
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: cmprr
|
||||
; CHECK: subcc %i1, %i2
|
||||
; CHECK: bpgu %xcc,
|
||||
define void @cmprr(i64* %p, i64 %x, i64 %y) {
|
||||
entry:
|
||||
%tobool = icmp ugt i64 %x, %y
|
||||
br i1 %tobool, label %if.end, label %if.then
|
||||
|
||||
if.then:
|
||||
store i64 %x, i64* %p, align 8
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user