Add initial conditional branch support. This doesn't actually work yet due

to a bug in the scheduler.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-12-18 01:20:35 +00:00
parent a5282d8df2
commit 4d55aca87a
8 changed files with 320 additions and 92 deletions

View File

@ -27,11 +27,21 @@ using namespace llvm;
// TargetLowering Implementation
//===----------------------------------------------------------------------===//
namespace V8ISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
CMPICC, // Compare two GPR operands, set icc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRFCC, // Branch to dest on fcc condition
};
}
namespace {
class SparcV8TargetLowering : public TargetLowering {
public:
SparcV8TargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
virtual std::vector<SDOperand>
LowerArguments(Function &F, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
@ -70,6 +80,22 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
setOperationAction(ISD::UREM, MVT::i32, Expand);
setOperationAction(ISD::SREM, MVT::i32, Expand);
// Sparc has no select or setcc: expand to SELECT_CC.
setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::SELECT, MVT::f32, Expand);
setOperationAction(ISD::SELECT, MVT::f64, Expand);
setOperationAction(ISD::SETCC, MVT::i32, Expand);
setOperationAction(ISD::SETCC, MVT::f32, Expand);
setOperationAction(ISD::SETCC, MVT::f64, Expand);
// Sparc doesn't have BRCOND either, it has BR_CC.
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
computeRegisterProperties();
}
@ -171,26 +197,52 @@ SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
}
}
SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG) {
SDOperand SparcV8TargetLowering::
LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV,
SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
std::pair<SDOperand,SDOperand>
SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG) {
std::pair<SDOperand,SDOperand> SparcV8TargetLowering::
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
std::pair<SDOperand, SDOperand>
SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
SDOperand SparcV8TargetLowering::
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Should not custom lower this!");
case ISD::BR_CC: {
SDOperand Chain = Op.getOperand(0);
SDOperand CC = Op.getOperand(1);
SDOperand LHS = Op.getOperand(2);
SDOperand RHS = Op.getOperand(3);
SDOperand Dest = Op.getOperand(4);
// Get the condition flag.
if (LHS.getValueType() == MVT::i32) {
SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
} else {
SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
}
}
}
}
//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//
@ -273,8 +325,8 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
SDNode *N = Op.Val;
if (N->getOpcode() >= ISD::BUILTIN_OP_END/* &&
N->getOpcode() < V8ISD::FIRST_NUMBER*/)
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
N->getOpcode() < V8ISD::FIRST_NUMBER)
return Op; // Already selected.
// If this has already been converted, use it.
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
@ -282,6 +334,15 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
switch (N->getOpcode()) {
default: break;
case ISD::BasicBlock: return CodeGenMap[Op] = Op;
case V8ISD::CMPICC: {
// FIXME: Handle compare with immediate.
SDOperand LHS = Select(N->getOperand(0));
SDOperand RHS = Select(N->getOperand(1));
SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
LHS, RHS);
return CodeGenMap[Op] = Result.getValue(1);
}
case ISD::ADD_PARTS: {
SDOperand LHSL = Select(N->getOperand(0));
SDOperand LHSH = Select(N->getOperand(1));

View File

@ -33,12 +33,14 @@ class F2_1<bits<3> op2Val, dag ops, string asmstr, list<dag> pattern> : F2 {
let Inst{29-25} = rd;
}
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr> : F2 {
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr,
list<dag> pattern> : F2 {
bits<4> cond;
bit annul = 0; // currently unused
dag OperandList = ops;
let AsmString = asmstr;
let Pattern = pattern;
let cond = condVal;
let op2 = op2Val;

View File

@ -68,6 +68,19 @@ def MEMri : Operand<i32> {
let MIOperandInfo = (ops IntRegs, i32imm);
}
def SDTV8cmpicc :
SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
def SDTV8cmpfcc :
SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
def SDTV8brcc :
SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTV8cmpicc>;
def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc>;
def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>;
def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@ -389,53 +402,81 @@ def RESTOREri : F3_2<2, 0b111101,
// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
// conditional branch class:
class BranchV8<bits<4> cc, dag ops, string asmstr>
: F2_2<cc, 0b010, ops, asmstr> {
class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
: F2_2<cc, 0b010, ops, asmstr, pattern> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
let isBarrier = 1 in
def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">;
def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">;
def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">;
def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">;
def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">;
def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">;
def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">;
def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">;
def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">;
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">;
def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">;
def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">;
def BA : BranchV8<0b1000, (ops IntRegs:$dst),
"ba $dst", []>;
def BN : BranchV8<0b0000, (ops IntRegs:$dst),
"bn $dst", []>;
def BNE : BranchV8<0b1001, (ops IntRegs:$dst),
"bne $dst",
[(V8bricc IntRegs:$dst, SETNE, ICC)]>;
def BE : BranchV8<0b0001, (ops IntRegs:$dst),
"be $dst",
[(V8bricc IntRegs:$dst, SETEQ, ICC)]>;
def BG : BranchV8<0b1010, (ops IntRegs:$dst),
"bg $dst", []>;
def BLE : BranchV8<0b0010, (ops IntRegs:$dst),
"ble $dst", []>;
def BGE : BranchV8<0b1011, (ops IntRegs:$dst),
"bge $dst", []>;
def BL : BranchV8<0b0011, (ops IntRegs:$dst),
"bl $dst", []>;
def BGU : BranchV8<0b1100, (ops IntRegs:$dst),
"bgu $dst", []>;
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst),
"bleu $dst", []>;
def BCC : BranchV8<0b1101, (ops IntRegs:$dst),
"bcc $dst", []>;
def BCS : BranchV8<0b0101, (ops IntRegs:$dst),
"bcs $dst", []>;
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
// floating-point conditional branch class:
class FPBranchV8<bits<4> cc, dag ops, string asmstr>
: F2_2<cc, 0b110, ops, asmstr> {
class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
: F2_2<cc, 0b110, ops, asmstr, pattern> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">;
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">;
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">;
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">;
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">;
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">;
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">;
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">;
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">;
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">;
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">;
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">;
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">;
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">;
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">;
def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst), "fbo $dst">;
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst),
"fbn $dst", []>;
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst),
"fbu $dst", []>;
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst),
"fbg $dst", []>;
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst),
"fbug $dst", []>;
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst),
"fbl $dst", []>;
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst),
"fbul $dst", []>;
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst),
"fblg $dst", []>;
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst),
"fbne $dst", []>;
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst),
"fbe $dst", []>;
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst),
"fbue $dst", []>;
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst),
"fbge $dst", []>;
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst),
"fbuge $dst", []>;
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst),
"fble $dst", []>;
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst),
"fbule $dst", []>;
def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst),
"fbo $dst", []>;
@ -576,10 +617,12 @@ def FDIVD : F3_3<2, 0b110100, 0b001001110,
// is modelled with a forced noop after the instruction.
def FCMPS : F3_3<2, 0b110101, 0b001010001,
(ops FPRegs:$src1, FPRegs:$src2),
"fcmps $src1, $src2\n\tnop", []>;
"fcmps $src1, $src2\n\tnop",
[(set FCC, (V8cmpfcc FPRegs:$src1, FPRegs:$src2))]>;
def FCMPD : F3_3<2, 0b110101, 0b001010010,
(ops DFPRegs:$src1, DFPRegs:$src2),
"fcmpd $src1, $src2\n\tnop", []>;
"fcmpd $src1, $src2\n\tnop",
[(set FCC, (V8cmpfcc DFPRegs:$src1, DFPRegs:$src2))]>;
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns

View File

@ -71,6 +71,14 @@ def D10 : Rd<20, "F20", [F20, F21]>; def D11 : Rd<22, "F22", [F22, F23]>;
def D12 : Rd<24, "F24", [F24, F25]>; def D13 : Rd<26, "F26", [F26, F27]>;
def D14 : Rd<28, "F28", [F28, F29]>; def D15 : Rd<30, "F30", [F30, F31]>;
/// Integer and FP Condition codes.
let Namespace = "V8" in {
def ICC : Register<"ICC">;
def FCC : Register<"FCC">;
}
def FLAGS_REGS : RegisterClass<"V8", [FlagVT], 32, [ICC, FCC]> {
let Size = 32;
}
// Register classes.
//

View File

@ -27,11 +27,21 @@ using namespace llvm;
// TargetLowering Implementation
//===----------------------------------------------------------------------===//
namespace V8ISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
CMPICC, // Compare two GPR operands, set icc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRFCC, // Branch to dest on fcc condition
};
}
namespace {
class SparcV8TargetLowering : public TargetLowering {
public:
SparcV8TargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
virtual std::vector<SDOperand>
LowerArguments(Function &F, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
@ -70,6 +80,22 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
setOperationAction(ISD::UREM, MVT::i32, Expand);
setOperationAction(ISD::SREM, MVT::i32, Expand);
// Sparc has no select or setcc: expand to SELECT_CC.
setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::SELECT, MVT::f32, Expand);
setOperationAction(ISD::SELECT, MVT::f64, Expand);
setOperationAction(ISD::SETCC, MVT::i32, Expand);
setOperationAction(ISD::SETCC, MVT::f32, Expand);
setOperationAction(ISD::SETCC, MVT::f64, Expand);
// Sparc doesn't have BRCOND either, it has BR_CC.
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
computeRegisterProperties();
}
@ -171,26 +197,52 @@ SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
}
}
SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
Value *VAListV, SelectionDAG &DAG) {
SDOperand SparcV8TargetLowering::
LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV,
SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
std::pair<SDOperand,SDOperand>
SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG) {
std::pair<SDOperand,SDOperand> SparcV8TargetLowering::
LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
const Type *ArgTy, SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
std::pair<SDOperand, SDOperand>
SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
assert(0 && "Unimp");
abort();
}
SDOperand SparcV8TargetLowering::
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Should not custom lower this!");
case ISD::BR_CC: {
SDOperand Chain = Op.getOperand(0);
SDOperand CC = Op.getOperand(1);
SDOperand LHS = Op.getOperand(2);
SDOperand RHS = Op.getOperand(3);
SDOperand Dest = Op.getOperand(4);
// Get the condition flag.
if (LHS.getValueType() == MVT::i32) {
SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
} else {
SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
}
}
}
}
//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//
@ -273,8 +325,8 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
SDNode *N = Op.Val;
if (N->getOpcode() >= ISD::BUILTIN_OP_END/* &&
N->getOpcode() < V8ISD::FIRST_NUMBER*/)
if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
N->getOpcode() < V8ISD::FIRST_NUMBER)
return Op; // Already selected.
// If this has already been converted, use it.
std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
@ -282,6 +334,15 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
switch (N->getOpcode()) {
default: break;
case ISD::BasicBlock: return CodeGenMap[Op] = Op;
case V8ISD::CMPICC: {
// FIXME: Handle compare with immediate.
SDOperand LHS = Select(N->getOperand(0));
SDOperand RHS = Select(N->getOperand(1));
SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
LHS, RHS);
return CodeGenMap[Op] = Result.getValue(1);
}
case ISD::ADD_PARTS: {
SDOperand LHSL = Select(N->getOperand(0));
SDOperand LHSH = Select(N->getOperand(1));

View File

@ -33,12 +33,14 @@ class F2_1<bits<3> op2Val, dag ops, string asmstr, list<dag> pattern> : F2 {
let Inst{29-25} = rd;
}
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr> : F2 {
class F2_2<bits<4> condVal, bits<3> op2Val, dag ops, string asmstr,
list<dag> pattern> : F2 {
bits<4> cond;
bit annul = 0; // currently unused
dag OperandList = ops;
let AsmString = asmstr;
let Pattern = pattern;
let cond = condVal;
let op2 = op2Val;

View File

@ -68,6 +68,19 @@ def MEMri : Operand<i32> {
let MIOperandInfo = (ops IntRegs, i32imm);
}
def SDTV8cmpicc :
SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
def SDTV8cmpfcc :
SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>;
def SDTV8brcc :
SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTV8cmpicc>;
def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc>;
def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>;
def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@ -389,53 +402,81 @@ def RESTOREri : F3_2<2, 0b111101,
// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
// conditional branch class:
class BranchV8<bits<4> cc, dag ops, string asmstr>
: F2_2<cc, 0b010, ops, asmstr> {
class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
: F2_2<cc, 0b010, ops, asmstr, pattern> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
let isBarrier = 1 in
def BA : BranchV8<0b1000, (ops IntRegs:$dst), "ba $dst">;
def BN : BranchV8<0b0000, (ops IntRegs:$dst), "bn $dst">;
def BNE : BranchV8<0b1001, (ops IntRegs:$dst), "bne $dst">;
def BE : BranchV8<0b0001, (ops IntRegs:$dst), "be $dst">;
def BG : BranchV8<0b1010, (ops IntRegs:$dst), "bg $dst">;
def BLE : BranchV8<0b0010, (ops IntRegs:$dst), "ble $dst">;
def BGE : BranchV8<0b1011, (ops IntRegs:$dst), "bge $dst">;
def BL : BranchV8<0b0011, (ops IntRegs:$dst), "bl $dst">;
def BGU : BranchV8<0b1100, (ops IntRegs:$dst), "bgu $dst">;
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst), "bleu $dst">;
def BCC : BranchV8<0b1101, (ops IntRegs:$dst), "bcc $dst">;
def BCS : BranchV8<0b0101, (ops IntRegs:$dst), "bcs $dst">;
def BA : BranchV8<0b1000, (ops IntRegs:$dst),
"ba $dst", []>;
def BN : BranchV8<0b0000, (ops IntRegs:$dst),
"bn $dst", []>;
def BNE : BranchV8<0b1001, (ops IntRegs:$dst),
"bne $dst",
[(V8bricc IntRegs:$dst, SETNE, ICC)]>;
def BE : BranchV8<0b0001, (ops IntRegs:$dst),
"be $dst",
[(V8bricc IntRegs:$dst, SETEQ, ICC)]>;
def BG : BranchV8<0b1010, (ops IntRegs:$dst),
"bg $dst", []>;
def BLE : BranchV8<0b0010, (ops IntRegs:$dst),
"ble $dst", []>;
def BGE : BranchV8<0b1011, (ops IntRegs:$dst),
"bge $dst", []>;
def BL : BranchV8<0b0011, (ops IntRegs:$dst),
"bl $dst", []>;
def BGU : BranchV8<0b1100, (ops IntRegs:$dst),
"bgu $dst", []>;
def BLEU : BranchV8<0b0100, (ops IntRegs:$dst),
"bleu $dst", []>;
def BCC : BranchV8<0b1101, (ops IntRegs:$dst),
"bcc $dst", []>;
def BCS : BranchV8<0b0101, (ops IntRegs:$dst),
"bcs $dst", []>;
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
// floating-point conditional branch class:
class FPBranchV8<bits<4> cc, dag ops, string asmstr>
: F2_2<cc, 0b110, ops, asmstr> {
class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
: F2_2<cc, 0b110, ops, asmstr, pattern> {
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
}
def FBA : FPBranchV8<0b1000, (ops IntRegs:$dst), "fba $dst">;
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst), "fbn $dst">;
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst), "fbu $dst">;
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst), "fbg $dst">;
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst), "fbug $dst">;
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst), "fbl $dst">;
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst), "fbul $dst">;
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst), "fblg $dst">;
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst), "fbne $dst">;
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst), "fbe $dst">;
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst), "fbue $dst">;
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst), "fbge $dst">;
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst), "fbuge $dst">;
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst), "fble $dst">;
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst), "fbule $dst">;
def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst), "fbo $dst">;
def FBN : FPBranchV8<0b0000, (ops IntRegs:$dst),
"fbn $dst", []>;
def FBU : FPBranchV8<0b0111, (ops IntRegs:$dst),
"fbu $dst", []>;
def FBG : FPBranchV8<0b0110, (ops IntRegs:$dst),
"fbg $dst", []>;
def FBUG : FPBranchV8<0b0101, (ops IntRegs:$dst),
"fbug $dst", []>;
def FBL : FPBranchV8<0b0100, (ops IntRegs:$dst),
"fbl $dst", []>;
def FBUL : FPBranchV8<0b0011, (ops IntRegs:$dst),
"fbul $dst", []>;
def FBLG : FPBranchV8<0b0010, (ops IntRegs:$dst),
"fblg $dst", []>;
def FBNE : FPBranchV8<0b0001, (ops IntRegs:$dst),
"fbne $dst", []>;
def FBE : FPBranchV8<0b1001, (ops IntRegs:$dst),
"fbe $dst", []>;
def FBUE : FPBranchV8<0b1010, (ops IntRegs:$dst),
"fbue $dst", []>;
def FBGE : FPBranchV8<0b1011, (ops IntRegs:$dst),
"fbge $dst", []>;
def FBUGE: FPBranchV8<0b1100, (ops IntRegs:$dst),
"fbuge $dst", []>;
def FBLE : FPBranchV8<0b1101, (ops IntRegs:$dst),
"fble $dst", []>;
def FBULE: FPBranchV8<0b1110, (ops IntRegs:$dst),
"fbule $dst", []>;
def FBO : FPBranchV8<0b1111, (ops IntRegs:$dst),
"fbo $dst", []>;
@ -576,10 +617,12 @@ def FDIVD : F3_3<2, 0b110100, 0b001001110,
// is modelled with a forced noop after the instruction.
def FCMPS : F3_3<2, 0b110101, 0b001010001,
(ops FPRegs:$src1, FPRegs:$src2),
"fcmps $src1, $src2\n\tnop", []>;
"fcmps $src1, $src2\n\tnop",
[(set FCC, (V8cmpfcc FPRegs:$src1, FPRegs:$src2))]>;
def FCMPD : F3_3<2, 0b110101, 0b001010010,
(ops DFPRegs:$src1, DFPRegs:$src2),
"fcmpd $src1, $src2\n\tnop", []>;
"fcmpd $src1, $src2\n\tnop",
[(set FCC, (V8cmpfcc DFPRegs:$src1, DFPRegs:$src2))]>;
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns

View File

@ -71,6 +71,14 @@ def D10 : Rd<20, "F20", [F20, F21]>; def D11 : Rd<22, "F22", [F22, F23]>;
def D12 : Rd<24, "F24", [F24, F25]>; def D13 : Rd<26, "F26", [F26, F27]>;
def D14 : Rd<28, "F28", [F28, F29]>; def D15 : Rd<30, "F30", [F30, F31]>;
/// Integer and FP Condition codes.
let Namespace = "V8" in {
def ICC : Register<"ICC">;
def FCC : Register<"FCC">;
}
def FLAGS_REGS : RegisterClass<"V8", [FlagVT], 32, [ICC, FCC]> {
let Size = 32;
}
// Register classes.
//