[llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp SparcV8InstrFormats.td SparcV8InstrInfo.td SparcV8RegisterInfo.td
Chris Lattner
lattner at cs.uiuc.edu
Sat Dec 17 17:20:46 PST 2005
Changes in directory llvm/lib/Target/SparcV8:
SparcV8ISelDAGToDAG.cpp updated: 1.10 -> 1.11
SparcV8InstrFormats.td updated: 1.13 -> 1.14
SparcV8InstrInfo.td updated: 1.71 -> 1.72
SparcV8RegisterInfo.td updated: 1.24 -> 1.25
---
Log message:
Add initial conditional branch support. This doesn't actually work yet due
to a bug in the scheduler.
---
Diffs of the changes: (+160 -46)
SparcV8ISelDAGToDAG.cpp | 83 +++++++++++++++++++++++++++++++----
SparcV8InstrFormats.td | 4 +
SparcV8InstrInfo.td | 111 +++++++++++++++++++++++++++++++++---------------
SparcV8RegisterInfo.td | 8 +++
4 files changed, 160 insertions(+), 46 deletions(-)
Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.10 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.11
--- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.10 Sat Dec 17 16:55:57 2005
+++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Sat Dec 17 19:20:35 2005
@@ -27,11 +27,21 @@
// 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 @@
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::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 @@
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 @@
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));
Index: llvm/lib/Target/SparcV8/SparcV8InstrFormats.td
diff -u llvm/lib/Target/SparcV8/SparcV8InstrFormats.td:1.13 llvm/lib/Target/SparcV8/SparcV8InstrFormats.td:1.14
--- llvm/lib/Target/SparcV8/SparcV8InstrFormats.td:1.13 Sat Dec 17 17:05:35 2005
+++ llvm/lib/Target/SparcV8/SparcV8InstrFormats.td Sat Dec 17 19:20:35 2005
@@ -33,12 +33,14 @@
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;
Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.71 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.72
--- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.71 Sat Dec 17 17:52:08 2005
+++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Sat Dec 17 19:20:35 2005
@@ -68,6 +68,19 @@
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 @@
// 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 @@
// 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
Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.24 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.25
--- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.24 Sat Dec 17 16:22:53 2005
+++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td Sat Dec 17 19:20:35 2005
@@ -71,6 +71,14 @@
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.
//
More information about the llvm-commits
mailing list