From 9a0d88efde47beedbe5569ff4435f636a1b6058d Mon Sep 17 00:00:00 2001 From: Christopher Lamb Date: Thu, 26 Jul 2007 07:48:21 +0000 Subject: [PATCH] Add target independent MachineInstr's to represent subreg insert/extract in MBB's. PR1350 llvm-svn: 40518 --- include/llvm/Target/TargetInstrInfo.h | 4 +++- lib/Target/Target.td | 12 +++++++++++ utils/TableGen/CodeEmitterGen.cpp | 12 ++++++++--- utils/TableGen/CodeGenTarget.cpp | 16 +++++++++++++- utils/TableGen/DAGISelEmitter.cpp | 31 ++++++++++++++++++++++++++- utils/TableGen/InstrInfoEmitter.cpp | 4 +++- 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 25fb79f068a..7accaf5789f 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -177,7 +177,9 @@ public: enum { PHI = 0, INLINEASM = 1, - LABEL = 2 + LABEL = 2, + EXTRACT_SUBREG = 3, + INSERT_SUBREG = 4 }; unsigned getNumOpcodes() const { return NumOpcodes; } diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 1583a93a988..84f62273d51 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -321,6 +321,18 @@ def LABEL : Instruction { let Namespace = "TargetInstrInfo"; let hasCtrlDep = 1; } +def EXTRACT_SUBREG : Instruction { + let OutOperandList = (ops variable_ops); + let InOperandList = (ops variable_ops); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; +} +def INSERT_SUBREG : Instruction { + let OutOperandList = (ops variable_ops); + let InOperandList = (ops variable_ops); + let AsmString = ""; + let Namespace = "TargetInstrInfo"; +} //===----------------------------------------------------------------------===// // AsmWriter - This class can be implemented by targets that need to customize diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index 300a1009a73..77907acae3e 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -26,7 +26,9 @@ void CodeEmitterGen::reverseBits(std::vector &Insts) { Record *R = *I; if (R->getName() == "PHI" || R->getName() == "INLINEASM" || - R->getName() == "LABEL") continue; + R->getName() == "LABEL" || + R->getName() == "EXTRACT_SUBREG" || + R->getName() == "INSERT_SUBREG") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); @@ -97,7 +99,9 @@ void CodeEmitterGen::run(std::ostream &o) { if (R->getName() == "PHI" || R->getName() == "INLINEASM" || - R->getName() == "LABEL") { + R->getName() == "LABEL" || + R->getName() == "EXTRACT_SUBREG" || + R->getName() == "INSERT_SUBREG") { o << " 0U"; continue; } @@ -127,7 +131,9 @@ void CodeEmitterGen::run(std::ostream &o) { if (InstName == "PHI" || InstName == "INLINEASM" || - InstName == "LABEL") continue; + InstName == "LABEL"|| + InstName == "EXTRACT_SUBREG" || + InstName == "INSERT_SUBREG") continue; BitsInit *BI = R->getValueAsBitsInit("Inst"); const std::vector &Vals = R->getValues(); diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 7952ca79aa8..21136c46456 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -275,14 +275,28 @@ getInstructionsByEnumValue(std::vector if (I == Instructions.end()) throw "Could not find 'LABEL' instruction!"; const CodeGenInstruction *LABEL = &I->second; + I = getInstructions().find("EXTRACT_SUBREG"); + if (I == Instructions.end()) + throw "Could not find 'EXTRACT_SUBREG' instruction!"; + const CodeGenInstruction *EXTRACT_SUBREG = &I->second; + + I = getInstructions().find("INSERT_SUBREG"); + if (I == Instructions.end()) + throw "Could not find 'INSERT_SUBREG' instruction!"; + const CodeGenInstruction *INSERT_SUBREG = &I->second; + // Print out the rest of the instructions now. NumberedInstructions.push_back(PHI); NumberedInstructions.push_back(INLINEASM); NumberedInstructions.push_back(LABEL); + NumberedInstructions.push_back(EXTRACT_SUBREG); + NumberedInstructions.push_back(INSERT_SUBREG); for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) if (&II->second != PHI && &II->second != INLINEASM && - &II->second != LABEL) + &II->second != LABEL && + &II->second != EXTRACT_SUBREG && + &II->second != INSERT_SUBREG) NumberedInstructions.push_back(&II->second); } diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 36677bb127b..b5b2ba1469a 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -3729,6 +3729,33 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " MVT::Other, Tmp, Chain);\n" << "}\n\n"; + OS << "SDNode *Select_EXTRACT_SUBREG(const SDOperand &N) {\n" + << " SDOperand N0 = N.getOperand(0);\n" + << " SDOperand N1 = N.getOperand(1);\n" + << " unsigned C = cast(N1)->getValue();\n" + << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" + << " AddToISelQueue(N0);\n" + << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" + << " N.getValueType(), N0, Tmp);\n" + << "}\n\n"; + + OS << "SDNode *Select_INSERT_SUBREG(const SDOperand &N) {\n" + << " SDOperand N0 = N.getOperand(0);\n" + << " SDOperand N1 = N.getOperand(1);\n" + << " SDOperand N2 = N.getOperand(2);\n" + << " unsigned C = cast(N2)->getValue();\n" + << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" + << " AddToISelQueue(N1);\n" + << " if (N0.getOpcode() == ISD::UNDEF) {\n" + << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" + << " N.getValueType(), N1, Tmp);\n" + << " } else {\n" + << " AddToISelQueue(N0);\n" + << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" + << " N.getValueType(), N0, N1, Tmp);\n" + << " }\n" + << "}\n\n"; + OS << "// The main instruction selector code.\n" << "SDNode *SelectCode(SDOperand N) {\n" << " if (N.getOpcode() >= ISD::BUILTIN_OP_END &&\n" @@ -3766,7 +3793,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " return NULL;\n" << " }\n" << " case ISD::INLINEASM: return Select_INLINEASM(N);\n" - << " case ISD::LABEL: return Select_LABEL(N);\n"; + << " case ISD::LABEL: return Select_LABEL(N);\n" + << " case ISD::EXTRACT_SUBREG: return Select_EXTRACT_SUBREG(N);\n" + << " case ISD::INSERT_SUBREG: return Select_INSERT_SUBREG(N);\n"; // Loop over all of the case statements, emiting a call to each method we diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index da2308e9e42..9a5dd2bda71 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -325,7 +325,9 @@ void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, // This isn't an error if this is a builtin instruction. if (R->getName() != "PHI" && R->getName() != "INLINEASM" && - R->getName() != "LABEL") + R->getName() != "LABEL" && + R->getName() != "EXTRACT_SUBREG" && + R->getName() != "INSERT_SUBREG") throw R->getName() + " doesn't have a field named '" + Val->getValue() + "'!"; return;