aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/MSP430
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:12:23 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-05-03 13:12:23 +0000
commit8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9 (patch)
tree152e3fb01cadc9e040298fffba1ec792278ddb08 /lib/Target/MSP430
parented1a51af376b9027db60ff060e0a2572493df07b (diff)
downloadexternal_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.zip
external_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.tar.gz
external_llvm-8b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9.tar.bz2
Lower select with custom inserted and make condjumps generic
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70744 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/MSP430')
-rw-r--r--lib/Target/MSP430/MSP430AsmPrinter.cpp28
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp118
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h9
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.h3
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td46
5 files changed, 168 insertions, 36 deletions
diff --git a/lib/Target/MSP430/MSP430AsmPrinter.cpp b/lib/Target/MSP430/MSP430AsmPrinter.cpp
index 8fc5de6..039ccce 100644
--- a/lib/Target/MSP430/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/MSP430AsmPrinter.cpp
@@ -51,6 +51,7 @@ namespace {
const char* Modifier = 0);
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
const char* Modifier = 0);
+ void printCCOperand(const MachineInstr *MI, int OpNum);
bool printInstruction(const MachineInstr *MI); // autogenerated.
void printMachineInstruction(const MachineInstr * MI);
bool runOnMachineFunction(MachineFunction &F);
@@ -182,3 +183,30 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
assert(0 && "Unsupported memory operand");
}
+void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
+ unsigned CC = MI->getOperand(OpNum).getImm();
+
+ switch (CC) {
+ default:
+ assert(0 && "Unsupported CC code");
+ break;
+ case MSP430::COND_E:
+ O << 'e';
+ break;
+ case MSP430::COND_NE:
+ O << "ne";
+ break;
+ case MSP430::COND_HS:
+ O << "hs";
+ break;
+ case MSP430::COND_LO:
+ O << "lo";
+ break;
+ case MSP430::COND_GE:
+ O << "ge";
+ break;
+ case MSP430::COND_L:
+ O << 'l';
+ break;
+ }
+}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 2354c83..5e67265 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -58,7 +58,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
setBooleanContents(ZeroOrOneBooleanContent);
setSchedulingPreference(SchedulingForLatency);
- setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
+ setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
@@ -67,13 +67,16 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
// We don't have any truncstores
setTruncStoreAction(MVT::i16, MVT::i8, Expand);
- setOperationAction(ISD::SRA, MVT::i16, Custom);
- setOperationAction(ISD::RET, MVT::Other, Custom);
- setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
- setOperationAction(ISD::BR_CC, MVT::Other, Expand);
- setOperationAction(ISD::BRCOND, MVT::Other, Custom);
- setOperationAction(ISD::SETCC, MVT::i8 , Custom);
- setOperationAction(ISD::SETCC, MVT::i16 , Custom);
+ setOperationAction(ISD::SRA, MVT::i16, Custom);
+ setOperationAction(ISD::RET, MVT::Other, Custom);
+ setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
+ setOperationAction(ISD::BR_CC, MVT::Other, Expand);
+ setOperationAction(ISD::BRCOND, MVT::Other, Custom);
+ setOperationAction(ISD::SETCC, MVT::i8, Custom);
+ setOperationAction(ISD::SETCC, MVT::i16, Custom);
+ setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
+ setOperationAction(ISD::SELECT, MVT::i8, Custom);
+ setOperationAction(ISD::SELECT, MVT::i16, Custom);
}
SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
@@ -85,6 +88,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
+ case ISD::SELECT: return LowerSELECT(Op, DAG);
default:
assert(0 && "unimplemented operand");
return SDValue();
@@ -517,6 +521,40 @@ SDValue MSP430TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
Chain, Dest, CC, Cond);
}
+SDValue MSP430TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
+ SDValue Cond = Op.getOperand(0);
+ SDValue TrueV = Op.getOperand(1);
+ SDValue FalseV = Op.getOperand(2);
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue CC;
+
+ // Lower condition if not lowered yet
+ if (Cond.getOpcode() == ISD::SETCC)
+ Cond = LowerSETCC(Cond, DAG);
+
+ // If condition flag is set by a MSP430ISD::CMP, then use it as the condition
+ // setting operand in place of the MSP430ISD::SETCC.
+ if (Cond.getOpcode() == MSP430ISD::SETCC) {
+ CC = Cond.getOperand(0);
+ Cond = Cond.getOperand(1);
+ TrueV = Cond.getOperand(0);
+ FalseV = Cond.getOperand(1);
+ } else {
+ CC = DAG.getConstant(MSP430::COND_NE, MVT::i16);
+ Cond = DAG.getNode(MSP430ISD::CMP, dl, MVT::i16,
+ Cond, DAG.getConstant(0, MVT::i16));
+ }
+
+ SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
+ SmallVector<SDValue, 4> Ops;
+ Ops.push_back(TrueV);
+ Ops.push_back(FalseV);
+ Ops.push_back(CC);
+ Ops.push_back(Cond);
+
+ return DAG.getNode(MSP430ISD::SELECT, dl, VTs, &Ops[0], Ops.size());
+}
+
const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return NULL;
@@ -527,5 +565,69 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
case MSP430ISD::BRCOND: return "MSP430ISD::BRCOND";
case MSP430ISD::CMP: return "MSP430ISD::CMP";
case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
+ case MSP430ISD::SELECT: return "MSP430ISD::SELECT";
}
}
+
+//===----------------------------------------------------------------------===//
+// Other Lowering Code
+//===----------------------------------------------------------------------===//
+
+MachineBasicBlock*
+MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *BB) const {
+ const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
+ DebugLoc dl = MI->getDebugLoc();
+ assert((MI->getOpcode() == MSP430::Select16) &&
+ "Unexpected instr type to insert");
+
+ // To "insert" a SELECT instruction, we actually have to insert the diamond
+ // control-flow pattern. The incoming instruction knows the destination vreg
+ // to set, the condition code register to branch on, the true/false values to
+ // select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction::iterator I = BB;
+ ++I;
+
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // cmpTY ccX, r1, r2
+ // jCC copy1MBB
+ // fallthrough --> copy0MBB
+ MachineBasicBlock *thisMBB = BB;
+ MachineFunction *F = BB->getParent();
+ MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ BuildMI(BB, dl, TII.get(MSP430::JCC))
+ .addMBB(copy1MBB)
+ .addImm(MI->getOperand(3).getImm());
+ F->insert(I, copy0MBB);
+ F->insert(I, copy1MBB);
+ // Update machine-CFG edges by transferring all successors of the current
+ // block to the new block which will contain the Phi node for the select.
+ copy1MBB->transferSuccessors(BB);
+ // Next, add the true and fallthrough blocks as its successors.
+ BB->addSuccessor(copy0MBB);
+ BB->addSuccessor(copy1MBB);
+
+ // copy0MBB:
+ // %FalseValue = ...
+ // # fallthrough to copy1MBB
+ BB = copy0MBB;
+
+ // Update machine-CFG edges
+ BB->addSuccessor(copy1MBB);
+
+ // copy1MBB:
+ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+ // ...
+ BB = copy1MBB;
+ BuildMI(BB, dl, TII.get(MSP430::PHI),
+ MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
+ .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
+
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
+ return BB;
+}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index c0ababd..f14af1d 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -49,7 +49,11 @@ namespace llvm {
/// is the block to branch if condition is true, operand 2 is the
/// condition code, and operand 3 is the flag operand produced by a CMP
/// instruction.
- BRCOND
+ BRCOND,
+
+ /// SELECT. Operand 0 and operand 1 are selection variable, operand 3 is
+ /// condition code and operand 4 is flag operand.
+ SELECT
};
}
@@ -77,6 +81,7 @@ namespace llvm {
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG);
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG,
unsigned CC);
@@ -84,6 +89,8 @@ namespace llvm {
CallSDNode *TheCall,
unsigned CallingConv, SelectionDAG &DAG);
+ MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *BB) const;
private:
const MSP430Subtarget &Subtarget;
diff --git a/lib/Target/MSP430/MSP430InstrInfo.h b/lib/Target/MSP430/MSP430InstrInfo.h
index 0803e2d..59133d9 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.h
+++ b/lib/Target/MSP430/MSP430InstrInfo.h
@@ -22,8 +22,7 @@ namespace llvm {
class MSP430TargetMachine;
namespace MSP430 {
- // MSP430 specific condition code. These correspond to MSP430_*_COND in
- // MSP430InstrInfo.td. They must be kept in synch.
+ // MSP430 specific condition code.
enum CondCode {
COND_E = 0, // aka COND_Z
COND_NE = 1, // aka COND_NZ
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 83a236e..5799121 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -31,6 +31,8 @@ def SDT_MSP430SetCC : SDTypeProfile<1, 2, [SDTCisVT<0, i8>,
def SDT_MSP430Cmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
def SDT_MSP430BrCond : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>,
SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
+def SDT_MSP430Select : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
+ SDTCisVT<3, i8>, SDTCisVT<4, i16>]>;
//===----------------------------------------------------------------------===//
// MSP430 Specific Node Definitions.
@@ -52,6 +54,7 @@ def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
def MSP430setcc : SDNode<"MSP430ISD::SETCC", SDT_MSP430SetCC>;
def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp>;
def MSP430brcond : SDNode<"MSP430ISD::BRCOND", SDT_MSP430BrCond, [SDNPHasChain]>;
+def MSP430select : SDNode<"MSP430ISD::SELECT", SDT_MSP430Select>;
//===----------------------------------------------------------------------===//
// MSP430 Operand Definitions.
@@ -71,6 +74,11 @@ def memdst : Operand<i16> {
// Branch targets have OtherVT type.
def brtarget : Operand<OtherVT>;
+// Operand for printing out a condition code.
+def cc : Operand<i8> {
+ let PrintMethod = "printCCOperand";
+}
+
//===----------------------------------------------------------------------===//
// MSP430 Complex Pattern Definitions.
//===----------------------------------------------------------------------===//
@@ -82,15 +90,6 @@ def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
-// MSP430 specific condition code. These correspond to CondCode in
-// MSP430InstrInfo.h. They must be kept in synch.
-def MSP430_COND_E : PatLeaf<(i8 0)>; // aka COND_Z
-def MSP430_COND_NE : PatLeaf<(i8 1)>; // aka COND_NZ
-def MSP430_COND_HS : PatLeaf<(i8 2)>; // aka COND_C
-def MSP430_COND_LO : PatLeaf<(i8 3)>; // aka COND_NC
-def MSP430_COND_GE : PatLeaf<(i8 4)>;
-def MSP430_COND_L : PatLeaf<(i8 5)>;
-
//===----------------------------------------------------------------------===//
// Instruction list..
@@ -108,6 +107,12 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
[(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
}
+let usesCustomDAGSchedInserter = 1 in {
+ def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
+ "# Select16 PSEUDO",
+ [(set GR16:$dst,
+ (MSP430select GR16:$src1, GR16:$src2, imm:$cc, SRW))]>;
+}
let neverHasSideEffects = 1 in
def NOP : Pseudo<(outs), (ins), "nop", []>;
@@ -123,18 +128,9 @@ let isReturn = 1, isTerminator = 1 in {
// Conditional branches
let isBranch = 1, isTerminator = 1, Uses = [SRW] in {
-def JE : Pseudo<(outs), (ins brtarget:$dst), "je\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_E, SRW)]>;
-def JNE : Pseudo<(outs), (ins brtarget:$dst), "jne\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_NE, SRW)]>;
-def JHS : Pseudo<(outs), (ins brtarget:$dst), "jhs\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_HS, SRW)]>;
-def JLO : Pseudo<(outs), (ins brtarget:$dst), "jlo\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_LO, SRW)]>;
-def JGE : Pseudo<(outs), (ins brtarget:$dst), "jge\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_GE, SRW)]>;
-def JL : Pseudo<(outs), (ins brtarget:$dst), "jl\t$dst",
- [(MSP430brcond bb:$dst, MSP430_COND_L, SRW)]>;
+def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
+ "j$cc $dst",
+ [(MSP430brcond bb:$dst, imm:$cc, SRW)]>;
} // Uses = [SRW]
//===----------------------------------------------------------------------===//
@@ -656,17 +652,17 @@ def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
// Integer comparisons
let Defs = [SRW] in {
def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "cmp.b\t{$src2, $src1|$src1, $src2}",
+ "cmp.b\t{$src1, $src2}",
[(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "cmp.w\t{$src2, $src1|$src1, $src2}",
+ "cmp.w\t{$src1, $src2}",
[(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
- "cmp.b\t{$src2, $src1|$src1, $src2}",
+ "cmp.b\t{$src1, $src2}",
[(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
- "cmp.w\t{$src2, $src1|$src1, $src2}",
+ "cmp.w\t{$src1, $src2}",
[(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),