diff options
Diffstat (limited to 'llvm/lib')
19 files changed, 1120 insertions, 1092 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index da56d97c4bc..2edab0b1373 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -139,6 +139,13 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine, break; } break; + case ELF::EM_MSP430: + switch (Type) { +#include "llvm/BinaryFormat/ELFRelocs/MSP430.def" + default: + break; + } + break; default: break; } diff --git a/llvm/lib/Target/MSP430/CMakeLists.txt b/llvm/lib/Target/MSP430/CMakeLists.txt index 3facfd526a5..2a0848fb308 100644 --- a/llvm/lib/Target/MSP430/CMakeLists.txt +++ b/llvm/lib/Target/MSP430/CMakeLists.txt @@ -1,9 +1,12 @@ set(LLVM_TARGET_DEFINITIONS MSP430.td) +tablegen(LLVM MSP430GenAsmMatcher.inc -gen-asm-matcher) tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer) tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv) tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel) +tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info) +tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info) tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget) @@ -26,3 +29,5 @@ add_llvm_target(MSP430CodeGen add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) add_subdirectory(TargetInfo) +add_subdirectory(AsmParser) +add_subdirectory(Disassembler) diff --git a/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.cpp b/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.cpp index be6d1a84a37..4d62547bc65 100644 --- a/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.cpp +++ b/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.cpp @@ -16,28 +16,34 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; #define DEBUG_TYPE "asm-printer" - // Include the auto-generated portion of the assembly writer. +#define PRINT_ALIAS_INSTR #include "MSP430GenAsmWriter.inc" void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { - printInstruction(MI, O); + if (!printAliasInstr(MI, O)) + printInstruction(MI, O); printAnnotation(O, Annot); } void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); - if (Op.isImm()) - O << Op.getImm(); - else { + if (Op.isImm()) { + int64_t Imm = Op.getImm() * 2 + 2; + O << "$"; + if (Imm >= 0) + O << '+'; + O << Imm; + } else { assert(Op.isExpr() && "unknown pcrel immediate operand"); Op.getExpr()->print(O, &MAI); } @@ -72,7 +78,7 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo, // vs // mov.w glb(r1), r2 // Otherwise (!) msp430-as will silently miscompile the output :( - if (!Base.getReg()) + if (Base.getReg() == MSP430::SR) O << '&'; if (Disp.isExpr()) @@ -83,10 +89,23 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo, } // Print register base field - if (Base.getReg()) + if ((Base.getReg() != MSP430::SR) && + (Base.getReg() != MSP430::PC)) O << '(' << getRegisterName(Base.getReg()) << ')'; } +void MSP430InstPrinter::printIndRegOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Base = MI->getOperand(OpNo); + O << "@" << getRegisterName(Base.getReg()); +} + +void MSP430InstPrinter::printPostIndRegOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Base = MI->getOperand(OpNo); + O << "@" << getRegisterName(Base.getReg()) << "+"; +} + void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { unsigned CC = MI->getOperand(OpNo).getImm(); @@ -112,5 +131,8 @@ void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo, case MSP430CC::COND_L: O << 'l'; break; + case MSP430CC::COND_N: + O << 'n'; + break; } } diff --git a/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h b/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h index 72afec18bec..cd02c4fa645 100644 --- a/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h +++ b/llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h @@ -28,13 +28,20 @@ namespace llvm { // Autogenerated by tblgen. void printInstruction(const MCInst *MI, raw_ostream &O); + bool printAliasInstr(const MCInst *MI, raw_ostream &O); + void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, + unsigned PrintMethodIdx, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); +private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, const char *Modifier = nullptr); void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, const char *Modifier = nullptr); + void printIndRegOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPostIndRegOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O); void printCCOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); }; diff --git a/llvm/lib/Target/MSP430/LLVMBuild.txt b/llvm/lib/Target/MSP430/LLVMBuild.txt index 51d9702ac56..0cbd1851777 100644 --- a/llvm/lib/Target/MSP430/LLVMBuild.txt +++ b/llvm/lib/Target/MSP430/LLVMBuild.txt @@ -16,13 +16,15 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = InstPrinter MCTargetDesc TargetInfo +subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo [component_0] type = TargetGroup name = MSP430 parent = Target +has_asmparser = 1 has_asmprinter = 1 +has_disassembler = 1 [component_1] type = Library diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/MSP430/MCTargetDesc/CMakeLists.txt index 0f3ebd30392..a2f468779f5 100644 --- a/llvm/lib/Target/MSP430/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/MSP430/MCTargetDesc/CMakeLists.txt @@ -1,4 +1,8 @@ add_llvm_library(LLVMMSP430Desc - MSP430MCTargetDesc.cpp + MSP430AsmBackend.cpp + MSP430ELFObjectWriter.cpp + MSP430ELFStreamer.cpp MSP430MCAsmInfo.cpp + MSP430MCCodeEmitter.cpp + MSP430MCTargetDesc.cpp ) diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp index 8c715500f38..b21145d3904 100644 --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp @@ -58,22 +58,15 @@ static MCInstPrinter *createMSP430MCInstPrinter(const Triple &T, } extern "C" void LLVMInitializeMSP430TargetMC() { - // Register the MC asm info. - RegisterMCAsmInfo<MSP430MCAsmInfo> X(getTheMSP430Target()); + Target &T = getTheMSP430Target(); - // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(getTheMSP430Target(), - createMSP430MCInstrInfo); - - // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(getTheMSP430Target(), - createMSP430MCRegisterInfo); - - // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(getTheMSP430Target(), - createMSP430MCSubtargetInfo); - - // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(getTheMSP430Target(), - createMSP430MCInstPrinter); + RegisterMCAsmInfo<MSP430MCAsmInfo> X(T); + TargetRegistry::RegisterMCInstrInfo(T, createMSP430MCInstrInfo); + TargetRegistry::RegisterMCRegInfo(T, createMSP430MCRegisterInfo); + TargetRegistry::RegisterMCSubtargetInfo(T, createMSP430MCSubtargetInfo); + TargetRegistry::RegisterMCInstPrinter(T, createMSP430MCInstPrinter); + TargetRegistry::RegisterMCCodeEmitter(T, createMSP430MCCodeEmitter); + TargetRegistry::RegisterMCAsmBackend(T, createMSP430MCAsmBackend); + TargetRegistry::RegisterObjectTargetStreamer( + T, createMSP430ObjectTargetStreamer); } diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.h b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.h index b901c5f0979..e484c79c9ee 100644 --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.h +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.h @@ -15,12 +15,39 @@ #define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430MCTARGETDESC_H #include "llvm/Support/DataTypes.h" +#include <memory> namespace llvm { class Target; +class MCAsmBackend; +class MCCodeEmitter; +class MCInstrInfo; +class MCSubtargetInfo; +class MCRegisterInfo; +class MCContext; +class MCTargetOptions; +class MCObjectTargetWriter; +class MCStreamer; +class MCTargetStreamer; Target &getTheMSP430Target(); +/// Creates a machine code emitter for MSP430. +MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx); + +MCAsmBackend *createMSP430MCAsmBackend(const Target &T, + const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options); + +MCTargetStreamer * +createMSP430ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI); + +std::unique_ptr<MCObjectTargetWriter> +createMSP430ELFObjectWriter(uint8_t OSABI); + } // End llvm namespace // Defines symbolic names for MSP430 registers. diff --git a/llvm/lib/Target/MSP430/MSP430.h b/llvm/lib/Target/MSP430/MSP430.h index 796f2523312..7a5314a1084 100644 --- a/llvm/lib/Target/MSP430/MSP430.h +++ b/llvm/lib/Target/MSP430/MSP430.h @@ -27,6 +27,8 @@ namespace MSP430CC { COND_LO = 3, // aka COND_NC COND_GE = 4, COND_L = 5, + COND_N = 6, // jump if negative + COND_NONE, // unconditional COND_INVALID = -1 }; diff --git a/llvm/lib/Target/MSP430/MSP430.td b/llvm/lib/Target/MSP430/MSP430.td index 203864dd406..8fa99dc13dd 100644 --- a/llvm/lib/Target/MSP430/MSP430.td +++ b/llvm/lib/Target/MSP430/MSP430.td @@ -64,11 +64,29 @@ include "MSP430InstrInfo.td" def MSP430InstrInfo : InstrInfo; +//===---------------------------------------------------------------------===// +// Assembly Printers +//===---------------------------------------------------------------------===// + +def MSP430AsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; +} + +//===---------------------------------------------------------------------===// +// Assembly Parsers +//===---------------------------------------------------------------------===// + +def MSP430AsmParser : AsmParser { + let AllowDuplicateRegisterNames = 1; + let ShouldEmitMatchRegisterAltName = 1; +} + //===----------------------------------------------------------------------===// // Target Declaration //===----------------------------------------------------------------------===// def MSP430 : Target { let InstructionSet = MSP430InstrInfo; + let AssemblyParsers = [MSP430AsmParser]; } diff --git a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index b196c013902..7a1998ad355 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -98,6 +98,7 @@ namespace { MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) : SelectionDAGISel(TM, OptLevel) {} + private: StringRef getPassName() const override { return "MSP430 DAG->DAG Pattern Instruction Selection"; } @@ -112,8 +113,9 @@ namespace { // Include the pieces autogenerated from the target description. #include "MSP430GenDAGISel.inc" - private: + // Main method to transform nodes into machine nodes. void Select(SDNode *N) override; + bool tryIndexedLoad(SDNode *Op); bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8, unsigned Opc16); @@ -250,11 +252,9 @@ bool MSP430DAGToDAGISel::SelectAddr(SDValue N, if (MatchAddress(N, AM)) return false; - EVT VT = N.getValueType(); - if (AM.BaseType == MSP430ISelAddressMode::RegBase) { + if (AM.BaseType == MSP430ISelAddressMode::RegBase) if (!AM.Base.Reg.getNode()) - AM.Base.Reg = CurDAG->getRegister(0, VT); - } + AM.Base.Reg = CurDAG->getRegister(MSP430::SR, MVT::i16); Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? CurDAG->getTargetFrameIndex( @@ -336,10 +336,10 @@ bool MSP430DAGToDAGISel::tryIndexedLoad(SDNode *N) { unsigned Opcode = 0; switch (VT.SimpleTy) { case MVT::i8: - Opcode = MSP430::MOV8rm_POST; + Opcode = MSP430::MOV8rp; break; case MVT::i16: - Opcode = MSP430::MOV16rm_POST; + Opcode = MSP430::MOV16rp; break; default: return false; @@ -412,47 +412,47 @@ void MSP430DAGToDAGISel::Select(SDNode *Node) { break; case ISD::ADD: if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), - MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) + MSP430::ADD8rp, MSP430::ADD16rp)) return; else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), - MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) + MSP430::ADD8rp, MSP430::ADD16rp)) return; // Other cases are autogenerated. break; case ISD::SUB: if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), - MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) + MSP430::SUB8rp, MSP430::SUB16rp)) return; // Other cases are autogenerated. break; case ISD::AND: if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), - MSP430::AND8rm_POST, MSP430::AND16rm_POST)) + MSP430::AND8rp, MSP430::AND16rp)) return; else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), - MSP430::AND8rm_POST, MSP430::AND16rm_POST)) + MSP430::AND8rp, MSP430::AND16rp)) return; // Other cases are autogenerated. break; case ISD::OR: if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), - MSP430::OR8rm_POST, MSP430::OR16rm_POST)) + MSP430::BIS8rp, MSP430::BIS16rp)) return; else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), - MSP430::OR8rm_POST, MSP430::OR16rm_POST)) + MSP430::BIS8rp, MSP430::BIS16rp)) return; // Other cases are autogenerated. break; case ISD::XOR: if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), - MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) + MSP430::XOR8rp, MSP430::XOR16rp)) return; else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), - MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) + MSP430::XOR8rp, MSP430::XOR16rp)) return; // Other cases are autogenerated. diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index f5b2bda5d1e..ac93d7efc2b 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -940,18 +940,7 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op, // Expand non-constant shifts to loops: if (!isa<ConstantSDNode>(N->getOperand(1))) - switch (Opc) { - default: llvm_unreachable("Invalid shift opcode!"); - case ISD::SHL: - return DAG.getNode(MSP430ISD::SHL, dl, - VT, N->getOperand(0), N->getOperand(1)); - case ISD::SRA: - return DAG.getNode(MSP430ISD::SRA, dl, - VT, N->getOperand(0), N->getOperand(1)); - case ISD::SRL: - return DAG.getNode(MSP430ISD::SRL, dl, - VT, N->getOperand(0), N->getOperand(1)); - } + return Op; uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); @@ -963,7 +952,7 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op, if (Opc == ISD::SRL && ShiftAmount) { // Emit a special goodness here: // srl A, 1 => clrc; rrc A - Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); + Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim); ShiftAmount -= 1; } @@ -1342,15 +1331,14 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { case MSP430ISD::RRA: return "MSP430ISD::RRA"; case MSP430ISD::RLA: return "MSP430ISD::RLA"; case MSP430ISD::RRC: return "MSP430ISD::RRC"; + case MSP430ISD::RRCL: return "MSP430ISD::RRCL"; case MSP430ISD::CALL: return "MSP430ISD::CALL"; case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; case MSP430ISD::CMP: return "MSP430ISD::CMP"; case MSP430ISD::SETCC: return "MSP430ISD::SETCC"; case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; - case MSP430ISD::SHL: return "MSP430ISD::SHL"; - case MSP430ISD::SRA: return "MSP430ISD::SRA"; - case MSP430ISD::SRL: return "MSP430ISD::SRL"; + case MSP430ISD::DADD: return "MSP430ISD::DADD"; } return nullptr; } @@ -1397,33 +1385,49 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI, const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo(); unsigned Opc; + bool ClearCarry = false; const TargetRegisterClass * RC; switch (MI.getOpcode()) { default: llvm_unreachable("Invalid shift opcode!"); case MSP430::Shl8: - Opc = MSP430::SHL8r1; - RC = &MSP430::GR8RegClass; - break; + Opc = MSP430::ADD8rr; + RC = &MSP430::GR8RegClass; + break; case MSP430::Shl16: - Opc = MSP430::SHL16r1; - RC = &MSP430::GR16RegClass; - break; + Opc = MSP430::ADD16rr; + RC = &MSP430::GR16RegClass; + break; case MSP430::Sra8: - Opc = MSP430::SAR8r1; - RC = &MSP430::GR8RegClass; - break; + Opc = MSP430::RRA8r; + RC = &MSP430::GR8RegClass; + break; case MSP430::Sra16: - Opc = MSP430::SAR16r1; - RC = &MSP430::GR16RegClass; - break; + Opc = MSP430::RRA16r; + RC = &MSP430::GR16RegClass; + break; case MSP430::Srl8: - Opc = MSP430::SAR8r1c; - RC = &MSP430::GR8RegClass; - break; + ClearCarry = true; + Opc = MSP430::RRC8r; + RC = &MSP430::GR8RegClass; + break; case MSP430::Srl16: - Opc = MSP430::SAR16r1c; - RC = &MSP430::GR16RegClass; - break; + ClearCarry = true; + Opc = MSP430::RRC16r; + RC = &MSP430::GR16RegClass; + break; + case MSP430::Rrcl8: + case MSP430::Rrcl16: { + BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR) + .addReg(MSP430::SR).addImm(1); + unsigned SrcReg = MI.getOperand(1).getReg(); + unsigned DstReg = MI.getOperand(0).getReg(); + unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16 + ? MSP430::RRC16r : MSP430::RRC8r; + BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg) + .addReg(SrcReg); + MI.eraseFromParent(); // The pseudo instruction is gone now. + return BB; + } } const BasicBlock *LLVM_BB = BB->getBasicBlock(); @@ -1476,8 +1480,16 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI, BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) .addReg(ShiftAmtSrcReg).addMBB(BB) .addReg(ShiftAmtReg2).addMBB(LoopBB); - BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) - .addReg(ShiftReg); + if (ClearCarry) + BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR) + .addReg(MSP430::SR).addImm(1); + if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr) + BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) + .addReg(ShiftReg) + .addReg(ShiftReg); + else + BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) + .addReg(ShiftReg); BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) .addReg(ShiftAmtReg).addImm(1); BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) @@ -1499,9 +1511,10 @@ MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const { unsigned Opc = MI.getOpcode(); - if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || - Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || - Opc == MSP430::Srl8 || Opc == MSP430::Srl16) + if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || + Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || + Opc == MSP430::Srl8 || Opc == MSP430::Srl16 || + Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16) return EmitShiftInstr(MI, BB); const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo(); diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h index 842d03df32f..731bc140671 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h @@ -36,6 +36,9 @@ namespace llvm { /// Y = RRC X, rotate right via carry RRC, + /// Rotate right via carry, carry gets cleared beforehand by clrc + RRCL, + /// CALL - These operations represent an abstract call /// instruction, which includes a bunch of information. CALL, @@ -61,8 +64,9 @@ namespace llvm { /// is condition code and operand 4 is flag operand. SELECT_CC, - /// SHL, SRA, SRL - Non-constant shifts. - SHL, SRA, SRL + /// DADD - Decimal addition with carry + /// TODO Nothing generates a node of this type yet. + DADD, }; } diff --git a/llvm/lib/Target/MSP430/MSP430InstrFormats.td b/llvm/lib/Target/MSP430/MSP430InstrFormats.td index a9e87dad0cd..e2e4503db20 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrFormats.td +++ b/llvm/lib/Target/MSP430/MSP430InstrFormats.td @@ -11,201 +11,431 @@ // Describe MSP430 instructions format here // -// Format specifies the encoding used by the instruction. This is part of the -// ad-hoc solution used to emit machine instruction encodings by our machine -// code emitter. -class Format<bits<2> val> { - bits<2> Value = val; -} - -def PseudoFrm : Format<0>; -def SingleOpFrm : Format<1>; -def DoubleOpFrm : Format<2>; -def CondJumpFrm : Format<3>; - class SourceMode<bits<2> val> { bits<2> Value = val; } -def SrcReg : SourceMode<0>; -def SrcMem : SourceMode<1>; -def SrcIndReg : SourceMode<2>; -def SrcPostInc : SourceMode<3>; -def SrcImm : SourceMode<3>; +def SrcReg : SourceMode<0>; // r +def SrcMem : SourceMode<1>; // m +def SrcIndReg : SourceMode<2>; // n +def SrcPostInc : SourceMode<3>; // p +def SrcImm : SourceMode<3>; // i +// SrcCGImm : SourceMode< >; // c class DestMode<bit val> { bit Value = val; } -def DstReg : DestMode<0>; -def DstMem : DestMode<1>; - -class SizeVal<bits<3> val> { - bits<3> Value = val; -} - -def SizeUnknown : SizeVal<0>; // Unknown / unset size -def SizeSpecial : SizeVal<1>; // Special instruction, e.g. pseudo -def Size2Bytes : SizeVal<2>; -def Size4Bytes : SizeVal<3>; -def Size6Bytes : SizeVal<4>; +def DstReg : DestMode<0>; // r +def DstMem : DestMode<1>; // m // Generic MSP430 Format -class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f, - string asmstr> : Instruction { - field bits<16> Inst; +class MSP430Inst<dag outs, dag ins, int size, string asmstr> : Instruction { + field bits<48> Inst; + field bits<48> SoftFail = 0; let Namespace = "MSP430"; dag OutOperandList = outs; dag InOperandList = ins; - Format Form = f; - SizeVal Sz = sz; - - // Define how we want to layout our TargetSpecific information field... This - // should be kept up-to-date with the fields in the MSP430InstrInfo.h file. - let TSFlags{1-0} = Form.Value; - let TSFlags{4-2} = Sz.Value; - - let AsmString = asmstr; + let AsmString = asmstr; + let Size = size; } -// FIXME: Create different classes for different addressing modes. - // MSP430 Double Operand (Format I) Instructions -class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz, +class IForm<bits<4> opcode, DestMode ad, bit bw, SourceMode as, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> { + : MSP430Inst<outs, ins, size, asmstr> { let Pattern = pattern; - DestMode ad = dest; - SourceMode as = src; - - let Inst{12-15} = opcode; + bits<4> rs; + bits<4> rd; + + let Inst{15-12} = opcode; + let Inst{11-8} = rs; let Inst{7} = ad.Value; let Inst{6} = bw; - let Inst{4-5} = as.Value; + let Inst{5-4} = as.Value; + let Inst{3-0} = rd; } // 8 bit IForm instructions -class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz, +class IForm8<bits<4> opcode, DestMode dest, SourceMode src, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>; + : IForm<opcode, dest, 1, src, size, outs, ins, asmstr, pattern>; class I8rr<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstReg, SrcReg, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Alpha"; +} class I8ri<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstReg, SrcImm, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<16> imm; + let Inst{31-16} = imm; + let rs = 0b0000; +} + +class I8rc<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 2, asmstr> { + let DecoderNamespace = "Beta"; + let Pattern = pattern; + + bits<6> imm; + bits<4> rd; + + let Inst{15-12} = opcode; + let Inst{11-8} = imm{3-0}; + let Inst{7} = DstReg.Value; + let Inst{6} = 1; + let Inst{5-4} = imm{5-4}; + let Inst{3-0} = rd; +} class I8rm<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstReg, SrcMem, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<20> src; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; +} + +class I8rn<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm8<opcode, DstReg, SrcIndReg, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; +} + +class I8rp<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm8<opcode, DstReg, SrcPostInc, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; +} class I8mr<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstMem, SrcReg, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Alpha"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} class I8mi<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstMem, SrcImm, 6, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<16> imm; + bits<20> dst; + let rs = 0b0000; + let Inst{31-16} = imm; + let rd = dst{3-0}; + let Inst{47-32} = dst{19-4}; +} + +class I8mc<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 4, asmstr> { + let DecoderNamespace = "Beta"; + let Pattern = pattern; + + bits<6> imm; + bits<20> dst; + + let Inst{31-16} = dst{19-4}; + let Inst{15-12} = opcode; + let Inst{11-8} = imm{3-0}; + let Inst{7} = DstMem.Value; + let Inst{6} = 1; + let Inst{5-4} = imm{5-4}; + let Inst{3-0} = dst{3-0}; +} class I8mm<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm8<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>; + : IForm8<opcode, DstMem, SrcMem, 6, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<20> src; + bits<20> dst; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; + let rd = dst{3-0}; + let Inst{47-32} = dst{19-4}; +} + +class I8mn<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm8<opcode, DstMem, SrcIndReg, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} + +class I8mp<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm8<opcode, DstMem, SrcPostInc, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} // 16 bit IForm instructions -class IForm16<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz, +class IForm16<bits<4> opcode, DestMode dest, SourceMode src, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm<opcode, dest, 0, src, sz, outs, ins, asmstr, pattern>; + : IForm<opcode, dest, 0, src, size, outs, ins, asmstr, pattern>; class I16rr<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstReg, SrcReg, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Alpha"; +} class I16ri<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstReg, SrcImm, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<16> imm; + let Inst{31-16} = imm; + let rs = 0b0000; +} + +class I16rc<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 2, asmstr> { + let DecoderNamespace = "Beta"; + let Pattern = pattern; + + bits<6> imm; + bits<4> rd; + + let Inst{15-12} = opcode; + let Inst{11-8} = imm{3-0}; + let Inst{7} = DstReg.Value; + let Inst{6} = 0; + let Inst{5-4} = imm{5-4}; + let Inst{3-0} = rd; +} class I16rm<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstReg, SrcMem, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<20> src; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; +} + +class I16rn<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm16<opcode, DstReg, SrcIndReg, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; +} + +class I16rp<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm16<opcode, DstReg, SrcPostInc, 2, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; +} class I16mr<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstMem, SrcReg, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Alpha"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} class I16mi<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstMem, SrcImm, 6, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<16> imm; + bits<20> dst; + let Inst{31-16} = imm; + let rs = 0b0000; + let rd = dst{3-0}; + let Inst{47-32} = dst{19-4}; +} + +class I16mc<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 4, asmstr> { + let DecoderNamespace = "Beta"; + let Pattern = pattern; + + bits<6> imm; + bits<20> dst; + + let Inst{31-16} = dst{19-4}; + let Inst{15-12} = opcode; + let Inst{11-8} = imm{3-0}; + let Inst{7} = DstMem.Value; + let Inst{6} = 0; + let Inst{5-4} = imm{5-4}; + let Inst{3-0} = dst{3-0}; +} class I16mm<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IForm16<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>; + : IForm16<opcode, DstMem, SrcMem, 6, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Gamma"; + bits<20> src; + bits<20> dst; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; + let rd = dst{3-0}; + let Inst{47-32} = dst{19-4}; +} + +class I16mn<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm16<opcode, DstMem, SrcIndReg, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} + +class I16mp<bits<4> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IForm16<opcode, DstMem, SrcPostInc, 4, outs, ins, asmstr, pattern> { + let DecoderNamespace = "Delta"; + bits<20> dst; + let rd = dst{3-0}; + let Inst{31-16} = dst{19-4}; +} // MSP430 Single Operand (Format II) Instructions -class IIForm<bits<9> opcode, bit bw, SourceMode src, SizeVal sz, +class IIForm<bits<3> opcode, bit bw, SourceMode as, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : MSP430Inst<outs, ins, sz, SingleOpFrm, asmstr> { + : MSP430Inst<outs, ins, size, asmstr> { let Pattern = pattern; - - SourceMode as = src; - let Inst{7-15} = opcode; - let Inst{6} = bw; - let Inst{4-5} = as.Value; + bits<4> rs; + + let Inst{15-10} = 0b000100; + let Inst{9-7} = opcode; + let Inst{6} = bw; + let Inst{5-4} = as.Value; + let Inst{3-0} = rs; } // 8 bit IIForm instructions -class IIForm8<bits<9> opcode, SourceMode src, SizeVal sz, +class IIForm8<bits<3> opcode, SourceMode src, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm<opcode, 1, src, sz, outs, ins, asmstr, pattern>; + : IIForm<opcode, 1, src, size, outs, ins, asmstr, pattern>; + +class II8r<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IIForm8<opcode, SrcReg, 2, outs, ins, asmstr, pattern>; -class II8r<bits<9> opcode, +class II8m<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm8<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>; + : IIForm8<opcode, SrcMem, 4, outs, ins, asmstr, pattern> { + bits<20> src; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; +} -class II8m<bits<9> opcode, +class II8i<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm8<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>; + : IIForm8<opcode, SrcImm, 4, outs, ins, asmstr, pattern> { + bits<16> imm; + let rs = 0b0000; + let Inst{31-16} = imm; +} -class II8i<bits<9> opcode, +class II8c<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm8<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>; + : MSP430Inst<outs, ins, 2, asmstr> { + let Pattern = pattern; + + bits<6> imm; + + let Inst{15-10} = 0b000100; + let Inst{9-7} = opcode; + let Inst{6} = 1; + let Inst{5-0} = imm; +} + +class II8n<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IIForm8<opcode, SrcIndReg, 2, outs, ins, asmstr, pattern>; + +class II8p<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IIForm8<opcode, SrcPostInc, 2, outs, ins, asmstr, pattern>; // 16 bit IIForm instructions -class IIForm16<bits<9> opcode, SourceMode src, SizeVal sz, +class IIForm16<bits<3> opcode, SourceMode src, int size, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm<opcode, 0, src, sz, outs, ins, asmstr, pattern>; + : IIForm<opcode, 0, src, size, outs, ins, asmstr, pattern>; -class II16r<bits<9> opcode, +class II16r<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm16<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>; + : IIForm16<opcode, SrcReg, 2, outs, ins, asmstr, pattern>; -class II16m<bits<9> opcode, +class II16m<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm16<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>; + : IIForm16<opcode, SrcMem, 4, outs, ins, asmstr, pattern> { + bits<20> src; + let rs = src{3-0}; + let Inst{31-16} = src{19-4}; +} -class II16i<bits<9> opcode, +class II16i<bits<3> opcode, dag outs, dag ins, string asmstr, list<dag> pattern> - : IIForm16<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>; + : IIForm16<opcode, SrcImm, 4, outs, ins, asmstr, pattern> { + bits<16> imm; + let rs = 0b0000; + let Inst{31-16} = imm; +} + +class II16c<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 2, asmstr> { + let Pattern = pattern; + + bits<6> imm; + + let Inst{15-10} = 0b000100; + let Inst{9-7} = opcode; + let Inst{6} = 0; + let Inst{5-0} = imm; +} + +class II16n<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IIForm16<opcode, SrcIndReg, 2, outs, ins, asmstr, pattern>; + +class II16p<bits<3> opcode, + dag outs, dag ins, string asmstr, list<dag> pattern> + : IIForm16<opcode, SrcPostInc, 2, outs, ins, asmstr, pattern>; // MSP430 Conditional Jumps Instructions -class CJForm<bits<3> opcode, bits<3> cond, - dag outs, dag ins, string asmstr, list<dag> pattern> - : MSP430Inst<outs, ins, Size2Bytes, CondJumpFrm, asmstr> { +class CJForm<dag outs, dag ins, string asmstr, list<dag> pattern> + : MSP430Inst<outs, ins, 2, asmstr> { let Pattern = pattern; - let Inst{13-15} = opcode; - let Inst{10-12} = cond; + bits<3> cond; + bits<10> dst; + + let Inst{15-13} = 0b001; + let Inst{12-10} = cond; + let Inst{9-0} = dst; } // Pseudo instructions class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> - : MSP430Inst<outs, ins, SizeSpecial, PseudoFrm, asmstr> { + : MSP430Inst<outs, ins, 0, asmstr> { let Pattern = pattern; - let Inst{15-0} = 0; } diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp b/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp index dd1b30a3e47..c136933a51b 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp @@ -301,35 +301,20 @@ unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB, unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { const MCInstrDesc &Desc = MI.getDesc(); - switch (Desc.TSFlags & MSP430II::SizeMask) { - default: - switch (Desc.getOpcode()) { - default: llvm_unreachable("Unknown instruction size!"); - case TargetOpcode::CFI_INSTRUCTION: - case TargetOpcode::EH_LABEL: - case TargetOpcode::IMPLICIT_DEF: - case TargetOpcode::KILL: - case TargetOpcode::DBG_VALUE: - return 0; - case TargetOpcode::INLINEASM: { - const MachineFunction *MF = MI.getParent()->getParent(); - const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); - return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), - *MF->getTarget().getMCAsmInfo()); - } - } - case MSP430II::SizeSpecial: - switch (MI.getOpcode()) { - default: llvm_unreachable("Unknown instruction size!"); - case MSP430::SAR8r1c: - case MSP430::SAR16r1c: - return 4; - } - case MSP430II::Size2Bytes: - return 2; - case MSP430II::Size4Bytes: - return 4; - case MSP430II::Size6Bytes: - return 6; + switch (Desc.getOpcode()) { + case TargetOpcode::CFI_INSTRUCTION: + case TargetOpcode::EH_LABEL: + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: + case TargetOpcode::DBG_VALUE: + return 0; + case TargetOpcode::INLINEASM: { + const MachineFunction *MF = MI.getParent()->getParent(); + const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); + return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), + *MF->getTarget().getMCAsmInfo()); } + } + + return Desc.getSize(); } diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.h b/llvm/lib/Target/MSP430/MSP430InstrInfo.h index 45357f54c9c..fee3bea9b8d 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.h +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.h @@ -24,22 +24,6 @@ namespace llvm { class MSP430Subtarget; -/// MSP430II - This namespace holds all of the target specific flags that -/// instruction info tracks. -/// -namespace MSP430II { - enum { - SizeShift = 2, - SizeMask = 7 << SizeShift, - - SizeUnknown = 0 << SizeShift, - SizeSpecial = 1 << SizeShift, - Size2Bytes = 2 << SizeShift, - Size4Bytes = 3 << SizeShift, - Size6Bytes = 4 << SizeShift - }; -} - class MSP430InstrInfo : public MSP430GenInstrInfo { const MSP430RegisterInfo RI; virtual void anchor(); diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.td b/llvm/lib/Target/MSP430/MSP430InstrInfo.td index cec43040f60..3ed17374a2d 100644 --- a/llvm/lib/Target/MSP430/MSP430InstrInfo.td +++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.td @@ -34,8 +34,9 @@ def SDT_MSP430BrCC : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>; -def SDT_MSP430Shift : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, - SDTCisI8<2>]>; +def SDT_MSP430DAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, + SDTCisSameAs<0, 2>, + SDTCisInt<0>]>; //===----------------------------------------------------------------------===// // MSP430 Specific Node Definitions. @@ -48,6 +49,7 @@ def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone, def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>; def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>; def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>; +def MSP430rrcl : SDNode<"MSP430ISD::RRCL", SDTIntUnaryOp, []>; def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call, [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; @@ -63,33 +65,88 @@ def MSP430brcc : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInGlue]>; def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInGlue]>; -def MSP430shl : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>; -def MSP430sra : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>; -def MSP430srl : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>; +def MSP430dadd : SDNode<"MSP430ISD::DADD", SDT_MSP430DAdd, []>; //===----------------------------------------------------------------------===// // MSP430 Operand Definitions. //===----------------------------------------------------------------------===// +def MemAsmOperand : AsmOperandClass { + let Name = "Mem"; +} + // Address operands def memsrc : Operand<i16> { let PrintMethod = "printSrcMemOperand"; let MIOperandInfo = (ops GR16, i16imm); + let ParserMatchClass = MemAsmOperand; + let EncoderMethod = "getMemOpValue"; + let DecoderMethod = "DecodeMemOperand"; } def memdst : Operand<i16> { let PrintMethod = "printSrcMemOperand"; let MIOperandInfo = (ops GR16, i16imm); + let ParserMatchClass = MemAsmOperand; + let EncoderMethod = "getMemOpValue"; + let DecoderMethod = "DecodeMemOperand"; +} + +def IndRegAsmOperand : AsmOperandClass { + let Name = "IndReg"; + let RenderMethod = "addRegOperands"; +} + +def indreg : Operand<i16> { + let PrintMethod = "printIndRegOperand"; + let MIOperandInfo = (ops GR16); + let ParserMatchClass = IndRegAsmOperand; + let DecoderMethod = "DecodeGR16RegisterClass"; +} + +def PostIndRegAsmOperand : AsmOperandClass { + let Name = "PostIndReg"; + let RenderMethod = "addRegOperands"; +} + +def postreg : Operand<i16> { + let PrintMethod = "printPostIndRegOperand"; + let MIOperandInfo = (ops GR16); + let ParserMatchClass = PostIndRegAsmOperand; + let DecoderMethod = "DecodeGR16RegisterClass"; } // Short jump targets have OtherVT type and are printed as pcrel imm values. def jmptarget : Operand<OtherVT> { let PrintMethod = "printPCRelImmOperand"; + let EncoderMethod = "getPCRelImmOpValue"; } // Operand for printing out a condition code. def cc : Operand<i8> { let PrintMethod = "printCCOperand"; + let EncoderMethod = "getCCOpValue"; +} + +def CGImmAsmOperand : AsmOperandClass { + let Name = "CGImm"; + let RenderMethod = "addImmOperands"; +} + +def cg8imm : Operand<i8>, + ImmLeaf<i8, [{return Imm == 0 || Imm == 1 || Imm == 2 || + Imm == 4 || Imm == 8 || Imm == -1;}]> { + let ParserMatchClass = CGImmAsmOperand; + let EncoderMethod = "getCGImmOpValue"; + let DecoderMethod = "DecodeCGImm"; +} + +def cg16imm : Operand<i16>, + ImmLeaf<i16, [{return Imm == 0 || Imm == 1 || Imm == 2 || + Imm == 4 || Imm == 8 || Imm == -1;}]> { + let ParserMatchClass = CGImmAsmOperand; + let EncoderMethod = "getCGImmOpValue"; + let DecoderMethod = "DecodeCGImm"; } //===----------------------------------------------------------------------===// @@ -102,6 +159,7 @@ def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>; // Pattern Fragments def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>; +def bic : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, (not node:$rhs))>; def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ return N->hasOneUse(); }]>; @@ -113,21 +171,21 @@ def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ // pointer before prolog-epilog rewriting occurs. // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become // sub / add which can clobber SR. -let Defs = [SP, SR], Uses = [SP] in { +let isCodeGenOnly = 1, Defs = [SP, SR], Uses = [SP] in { def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2), - "#ADJCALLSTACKDOWN", + "#ADJCALLSTACKDOWN $amt1 $amt2", [(MSP430callseq_start timm:$amt1, timm:$amt2)]>; def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2), - "#ADJCALLSTACKUP", + "#ADJCALLSTACKUP $amt1 $amt2", [(MSP430callseq_end timm:$amt1, timm:$amt2)]>; } -let Defs = [SR], Uses = [SP] in { +let isCodeGenOnly = 1, Defs = [SR], Uses = [SP] in { def ADDframe : Pseudo<(outs GR16:$dst), (ins i16imm:$base, i16imm:$offset), "# ADDframe PSEUDO", []>; } -let usesCustomInserter = 1 in { +let isCodeGenOnly = 1, usesCustomInserter = 1 in { let Uses = [SR] in { def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$src2, i8imm:$cc), "# Select8 PSEUDO", @@ -141,38 +199,45 @@ let usesCustomInserter = 1 in { let Defs = [SR] in { def Shl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), "# Shl8 PSEUDO", - [(set GR8:$dst, (MSP430shl GR8:$src, GR8:$cnt))]>; + [(set GR8:$dst, (shl GR8:$src, GR8:$cnt))]>; def Shl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), "# Shl16 PSEUDO", - [(set GR16:$dst, (MSP430shl GR16:$src, GR8:$cnt))]>; + [(set GR16:$dst, (shl GR16:$src, GR8:$cnt))]>; def Sra8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), "# Sra8 PSEUDO", - [(set GR8:$dst, (MSP430sra GR8:$src, GR8:$cnt))]>; + [(set GR8:$dst, (sra GR8:$src, GR8:$cnt))]>; def Sra16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), "# Sra16 PSEUDO", - [(set GR16:$dst, (MSP430sra GR16:$src, GR8:$cnt))]>; + [(set GR16:$dst, (sra GR16:$src, GR8:$cnt))]>; def Srl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt), "# Srl8 PSEUDO", - [(set GR8:$dst, (MSP430srl GR8:$src, GR8:$cnt))]>; + [(set GR8:$dst, (srl GR8:$src, GR8:$cnt))]>; def Srl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt), "# Srl16 PSEUDO", - [(set GR16:$dst, (MSP430srl GR16:$src, GR8:$cnt))]>; - + [(set GR16:$dst, (srl GR16:$src, GR8:$cnt))]>; + def Rrcl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src), "", + [(set GR8:$dst, (MSP430rrcl GR8:$src))]>; + def Rrcl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src), "", + [(set GR16:$dst, (MSP430rrcl GR16:$src))]>; } } -let hasSideEffects = 0 in -def NOP : Pseudo<(outs), (ins), "nop", []>; - //===----------------------------------------------------------------------===// // Control Flow Instructions... // // FIXME: Provide proper encoding! let isReturn = 1, isTerminator = 1, isBarrier = 1 in { - def RET : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs), (ins), "ret", [(MSP430retflag)]>; - def RETI : II16r<0x0, (outs), (ins), "reti", [(MSP430retiflag)]>; + def RET : IForm16<0b0100, DstReg, SrcPostInc, 2, + (outs), (ins), "ret", [(MSP430retflag)]> { + let DecoderNamespace = "Delta"; + let rs = 1; + let rd = 0; + } + def RETI : IIForm16<0b110, SrcReg, 2, + (outs), (ins), "reti", [(MSP430retiflag)]> { + let rs = 0; + } } let isBranch = 1, isTerminator = 1 in { @@ -182,64 +247,69 @@ let isBranch = 1, isTerminator = 1 in { // Direct branch let isBarrier = 1 in { // Short branch - def JMP : CJForm<0, 0, (outs), (ins jmptarget:$dst), + def JMP : CJForm<(outs), (ins jmptarget:$dst), "jmp\t$dst", - [(br bb:$dst)]>; - let isIndirectBranch = 1 in { + [(br bb:$dst)]> { + let cond = 0b111; + } + let isIndirectBranch = 1, rd = 0 in { // Long branches - def Bi : I16ri<0, (outs), (ins i16imm:$brdst), - "br\t$brdst", - [(brind tblockaddress:$brdst)]>; - def Br : I16rr<0, (outs), (ins GR16:$brdst), - "br\t$brdst", - [(brind GR16:$brdst)]>; - def Bm : I16rm<0, (outs), (ins memsrc:$brdst), - "br\t$brdst", - [(brind (load addr:$brdst))]>; + def Bi : I16ri<0b0100, (outs), (ins i16imm:$imm), + "br\t$imm", + [(brind tblockaddress:$imm)]>; + def Br : I16rr<0b0100, (outs), (ins GR16:$rs), + "br\t$rs", + [(brind GR16:$rs)]>; + def Bm : I16rm<0b0100, (outs), (ins memsrc:$src), + "br\t$src", + [(brind (load addr:$src))]>; } } // Conditional branches let Uses = [SR] in - def JCC : CJForm<0, 0, - (outs), (ins jmptarget:$dst, cc:$cc), - "j$cc\t$dst", - [(MSP430brcc bb:$dst, imm:$cc)]>; + def JCC : CJForm<(outs), (ins jmptarget:$dst, cc:$cond), + "j$cond\t$dst", + [(MSP430brcc bb:$dst, imm:$cond)]>; } // isBranch, isTerminator //===----------------------------------------------------------------------===// // Call Instructions... // -let isCall = 1 in - // All calls clobber the non-callee saved registers. SPW is marked as - // a use to prevent stack-pointer assignments that appear immediately - // before calls from potentially appearing dead. Uses for argument - // registers are added manually. - let Defs = [R11, R12, R13, R14, R15, SR], - Uses = [SP] in { - def CALLi : II16i<0x0, - (outs), (ins i16imm:$dst), - "call\t$dst", [(MSP430call imm:$dst)]>; - def CALLr : II16r<0x0, - (outs), (ins GR16:$dst), - "call\t$dst", [(MSP430call GR16:$dst)]>; - def CALLm : II16m<0x0, - (outs), (ins memsrc:$dst), - "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>; - } - +// All calls clobber the non-callee saved registers. SPW is marked as +// a use to prevent stack-pointer assignments that appear immediately +// before calls from potentially appearing dead. Uses for argument +// registers are added manually. +let isCall = 1, + Defs = [R11, R12, R13, R14, R15, SR], + Uses = [SP] in { + def CALLi : II16i<0b101, + (outs), (ins i16imm:$imm), + "call\t$imm", [(MSP430call imm:$imm)]>; + def CALLr : II16r<0b101, + (outs), (ins GR16:$rs), + "call\t$rs", [(MSP430call GR16:$rs)]>; + def CALLm : II16m<0b101, + (outs), (ins memsrc:$src), + "call\t$src", [(MSP430call (load addr:$src))]>; +} //===----------------------------------------------------------------------===// // Miscellaneous Instructions... // -let Defs = [SP], Uses = [SP], hasSideEffects=0 in { +let Defs = [SP], Uses = [SP], hasSideEffects = 0 in { let mayLoad = 1 in -def POP16r : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$reg), (ins), "pop.w\t$reg", []>; +def POP16r : IForm16<0b0100, DstReg, SrcPostInc, 2, + (outs GR16:$rd), (ins), "pop\t$rd", []> { + let DecoderNamespace = "Delta"; + let rs = 1; +} let mayStore = 1 in -def PUSH16r : II16r<0x0, - (outs), (ins GR16:$reg), "push.w\t$reg",[]>; +def PUSH8r : II8r<0b100, (outs), (ins GR8:$rs), "push.b\t$rs", []>; +def PUSH16r : II16r<0b100, (outs), (ins GR16:$rs), "push\t$rs", []>; +def PUSH16c : II16c<0b100, (outs), (ins cg16imm:$imm), "push\t$imm", []>; +def PUSH16i : II16i<0b100, (outs), (ins i16imm:$imm), "push\t$imm", []>; } //===----------------------------------------------------------------------===// @@ -247,55 +317,73 @@ def PUSH16r : II16r<0x0, // FIXME: Provide proper encoding! let hasSideEffects = 0 in { -def MOV8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src), - "mov.b\t{$src, $dst}", +def MOV8rr : I8rr<0b0100, + (outs GR8:$rd), (ins GR8:$rs), + "mov.b\t{$rs, $rd}", []>; -def MOV16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src), - "mov.w\t{$src, $dst}", +def MOV16rr : I16rr<0b0100, + (outs GR16:$rd), (ins GR16:$rs), + "mov\t{$rs, $rd}", []>; } // FIXME: Provide proper encoding! let isReMaterializable = 1, isAsCheapAsAMove = 1 in { -def MOV8ri : I8ri<0x0, - (outs GR8:$dst), (ins i8imm:$src), - "mov.b\t{$src, $dst}", - [(set GR8:$dst, imm:$src)]>; -def MOV16ri : I16ri<0x0, - (outs GR16:$dst), (ins i16imm:$src), - "mov.w\t{$src, $dst}", - [(set GR16:$dst, imm:$src)]>; +def MOV8rc : I8rc<0b0100, + (outs GR8:$rd), (ins cg8imm:$imm), + "mov.b\t$imm, $rd", + [(set GR8:$rd, cg8imm:$imm)]>; +def MOV16rc : I16rc<0b0100, + (outs GR16:$rd), (ins cg16imm:$imm), + "mov\t$imm, $rd", + [(set GR16:$rd, cg16imm:$imm)]>; +def MOV8ri : I8ri<0b0100, + (outs GR8:$rd), (ins i8imm:$imm), + "mov.b\t{$imm, $rd}", + [(set GR8:$rd, imm:$imm)]>; +def MOV16ri : I16ri<0b0100, + (outs GR16:$rd), (ins i16imm:$imm), + "mov\t{$imm, $rd}", + [(set GR16:$rd, imm:$imm)]>; } let canFoldAsLoad = 1, isReMaterializable = 1 in { -def MOV8rm : I8rm<0x0, - (outs GR8:$dst), (ins memsrc:$src), - "mov.b\t{$src, $dst}", - [(set GR8:$dst, (load addr:$src))]>; -def MOV16rm : I16rm<0x0, - (outs GR16:$dst), (ins memsrc:$src), - "mov.w\t{$src, $dst}", - [(set GR16:$dst, (load addr:$src))]>; -} - -def MOVZX16rr8 : I8rr<0x0, - (outs GR16:$dst), (ins GR8:$src), - "mov.b\t{$src, $dst}", - [(set GR16:$dst, (zext GR8:$src))]>; -def MOVZX16rm8 : I8rm<0x0, - (outs GR16:$dst), (ins memsrc:$src), - "mov.b\t{$src, $dst}", - [(set GR16:$dst, (zextloadi16i8 addr:$src))]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in { -def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base), - "mov.b\t{@$base+, $dst}", []>; -def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), (ins GR16:$base), - "mov.w\t{@$base+, $dst}", []>; +def MOV8rm : I8rm<0b0100, + (outs GR8:$rd), (ins memsrc:$src), + "mov.b\t{$src, $rd}", + [(set GR8:$rd, (load addr:$src))]>; +def MOV16rm : I16rm<0b0100, + (outs GR16:$rd), (ins memsrc:$src), + "mov\t{$src, $rd}", + [(set GR16:$rd, (load addr:$src))]>; +def MOV8rn : I8rn<0b0100, + (outs GR8:$rd), (ins indreg:$rs), + "mov.b\t{$rs, $rd}", + [(set GR8:$rd, (load addr:$rs))]>; +def MOV16rn : I16rn<0b0100, + (outs GR16:$rd), (ins indreg:$rs), + "mov\t{$rs, $rd}", + [(set GR16:$rd, (load addr:$rs))]>; +} + +let isCodeGenOnly = 1 in { +def MOVZX16rr8 : I8rr<0b0100, + (outs GR16:$rd), (ins GR8:$rs), + "mov.b\t{$rs, $rd}", + [(set GR16:$rd, (zext GR8:$rs))]>; +def MOVZX16rm8 : I8rm<0b0100, + (outs GR16:$rd), (ins memsrc:$src), + "mov.b\t{$src, $rd}", + [(set GR16:$rd, (zextloadi16i8 addr:$src))]>; +} + +let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$rs = $wb" in { +def MOV8rp : I8rp<0b0100, + (outs GR8:$rd, GR16:$wb), (ins postreg:$rs), + "mov.b\t{$rs, $rd}", []>; +def MOV16rp : I16rp<0b0100, + (outs GR16:$rd, GR16:$wb), (ins postreg:$rs), + "mov\t{$rs, $rd}", []>; } // Any instruction that defines a 8-bit result leaves the high half of the @@ -313,821 +401,450 @@ def def8 : PatLeaf<(i8 GR8:$src), [{ def : Pat<(i16 (zext def8:$src)), (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>; -def MOV8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "mov.b\t{$src, $dst}", - [(store (i8 imm:$src), addr:$dst)]>; -def MOV16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "mov.w\t{$src, $dst}", - [(store (i16 imm:$src), addr:$dst)]>; - -def MOV8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "mov.b\t{$src, $dst}", - [(store GR8:$src, addr:$dst)]>; -def MOV16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "mov.w\t{$src, $dst}", - [(store GR16:$src, addr:$dst)]>; - -def MOV8mm : I8mm<0x0, +def MOV8mc : I8mc<0b0100, + (outs), (ins memdst:$dst, cg8imm:$imm), + "mov.b\t{$imm, $dst}", + [(store (i8 cg8imm:$imm), addr:$dst)]>; +def MOV16mc : I16mc<0b0100, + (outs), (ins memdst:$dst, cg16imm:$imm), + "mov\t{$imm, $dst}", + [(store (i16 cg16imm:$imm), addr:$dst)]>; + +def MOV8mi : I8mi<0b0100, + (outs), (ins memdst:$dst, i8imm:$imm), + "mov.b\t{$imm, $dst}", + [(store (i8 imm:$imm), addr:$dst)]>; +def MOV16mi : I16mi<0b0100, + (outs), (ins memdst:$dst, i16imm:$imm), + "mov\t{$imm, $dst}", + [(store (i16 imm:$imm), addr:$dst)]>; + +def MOV8mr : I8mr<0b0100, + (outs), (ins memdst:$dst, GR8:$rs), + "mov.b\t{$rs, $dst}", + [(store GR8:$rs, addr:$dst)]>; +def MOV16mr : I16mr<0b0100, + (outs), (ins memdst:$dst, GR16:$rs), + "mov\t{$rs, $dst}", + [(store GR16:$rs, addr:$dst)]>; + +def MOV8mm : I8mm<0b0100, (outs), (ins memdst:$dst, memsrc:$src), "mov.b\t{$src, $dst}", [(store (i8 (load addr:$src)), addr:$dst)]>; -def MOV16mm : I16mm<0x0, +def MOV16mm : I16mm<0b0100, (outs), (ins memdst:$dst, memsrc:$src), - "mov.w\t{$src, $dst}", + "mov\t{$src, $dst}", [(store (i16 (load addr:$src)), addr:$dst)]>; //===----------------------------------------------------------------------===// // Arithmetic Instructions -let Constraints = "$src = $dst" in { - -let Defs = [SR] in { - -let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y - -def ADD8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "add.b\t{$src2, $dst}", - [(set GR8:$dst, (add GR8:$src, GR8:$src2)), - (implicit SR)]>; -def ADD16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "add.w\t{$src2, $dst}", - [(set GR16:$dst, (add GR16:$src, GR16:$src2)), - (implicit SR)]>; -} - -def ADD8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "add.b\t{$src2, $dst}", - [(set GR8:$dst, (add GR8:$src, (load addr:$src2))), - (implicit SR)]>; -def ADD16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "add.w\t{$src2, $dst}", - [(set GR16:$dst, (add GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, -Constraints = "$base = $base_wb, $src = $dst" in { -def ADD8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), - (ins GR8:$src, GR16:$base), - "add.b\t{@$base+, $dst}", []>; -def ADD16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), - (ins GR16:$src, GR16:$base), - "add.w\t{@$base+, $dst}", []>; -} - - -def ADD8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "add.b\t{$src2, $dst}", - [(set GR8:$dst, (add GR8:$src, imm:$src2)), - (implicit SR)]>; -def ADD16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "add.w\t{$src2, $dst}", - [(set GR16:$dst, (add GR16:$src, imm:$src2)), - (implicit SR)]>; - -let Constraints = "" in { -def ADD8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "add.b\t{$src, $dst}", - [(store (add (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def ADD16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "add.w\t{$src, $dst}", - [(store (add (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; - -def ADD8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "add.b\t{$src, $dst}", - [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def ADD16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "add.w\t{$src, $dst}", - [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; - -def ADD8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "add.b\t{$src, $dst}", - [(store (add (load addr:$dst), - (i8 (load addr:$src))), addr:$dst), - (implicit SR)]>; -def ADD16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "add.w\t{$src, $dst}", - [(store (add (load addr:$dst), - (i16 (load addr:$src))), addr:$dst), - (implicit SR)]>; -} - -let Uses = [SR] in { - -let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y -def ADC8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "addc.b\t{$src2, $dst}", - [(set GR8:$dst, (adde GR8:$src, GR8:$src2)), - (implicit SR)]>; -def ADC16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "addc.w\t{$src2, $dst}", - [(set GR16:$dst, (adde GR16:$src, GR16:$src2)), - (implicit SR)]>; -} // isCommutable - -def ADC8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "addc.b\t{$src2, $dst}", - [(set GR8:$dst, (adde GR8:$src, imm:$src2)), - (implicit SR)]>; -def ADC16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "addc.w\t{$src2, $dst}", - [(set GR16:$dst, (adde GR16:$src, imm:$src2)), - (implicit SR)]>; - -def ADC8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "addc.b\t{$src2, $dst}", - [(set GR8:$dst, (adde GR8:$src, (load addr:$src2))), - (implicit SR)]>; -def ADC16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "addc.w\t{$src2, $dst}", - [(set GR16:$dst, (adde GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let Constraints = "" in { -def ADC8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "addc.b\t{$src, $dst}", - [(store (adde (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def ADC16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "addc.w\t{$src, $dst}", - [(store (adde (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; - -def ADC8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "addc.b\t{$src, $dst}", - [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def ADC16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "addc.w\t{$src, $dst}", - [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; - -def ADC8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "addc.b\t{$src, $dst}", - [(store (adde (load addr:$dst), - (i8 (load addr:$src))), addr:$dst), - (implicit SR)]>; -def ADC16mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "addc.w\t{$src, $dst}", - [(store (adde (load addr:$dst), - (i16 (load addr:$src))), addr:$dst), - (implicit SR)]>; -} - -} // Uses = [SR] - -let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y -def AND8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "and.b\t{$src2, $dst}", - [(set GR8:$dst, (and GR8:$src, GR8:$src2)), - (implicit SR)]>; -def AND16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "and.w\t{$src2, $dst}", - [(set GR16:$dst, (and GR16:$src, GR16:$src2)), - (implicit SR)]>; -} - -def AND8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "and.b\t{$src2, $dst}", - [(set GR8:$dst, (and GR8:$src, imm:$src2)), +multiclass Arith<bits<4> opcode, string asmstring, SDNode node, + bit commutes, list<Register> uses> { + let Defs = [SR], Uses = uses in { + let Constraints = "$src2 = $rd" in { + let isCommutable = commutes in { + def 8rr : I8rr<opcode, (outs GR8:$rd), (ins GR8:$src2, GR8:$rs), + !strconcat(asmstring, ".b\t$rs, $rd"), + [(set GR8:$rd, (node GR8:$src2, GR8:$rs)), + (implicit SR)]>; + def 16rr : I16rr<opcode, (outs GR16:$rd), (ins GR16:$src2, GR16:$rs), + !strconcat(asmstring, "\t$rs, $rd"), + [(set GR16:$rd, (node GR16:$src2, GR16:$rs)), (implicit SR)]>; -def AND16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "and.w\t{$src2, $dst}", - [(set GR16:$dst, (and GR16:$src, imm:$src2)), - (implicit SR)]>; - -def AND8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "and.b\t{$src2, $dst}", - [(set GR8:$dst, (and GR8:$src, (load addr:$src2))), - (implicit SR)]>; -def AND16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "and.w\t{$src2, $dst}", - [(set GR16:$dst, (and GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, -Constraints = "$base = $base_wb, $src = $dst" in { -def AND8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), - (ins GR8:$src, GR16:$base), - "and.b\t{@$base+, $dst}", []>; -def AND16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), - (ins GR16:$src, GR16:$base), - "and.w\t{@$base+, $dst}", []>; -} - -let Constraints = "" in { -def AND8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "and.b\t{$src, $dst}", - [(store (and (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def AND16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "and.w\t{$src, $dst}", - [(store (and (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; - -def AND8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "and.b\t{$src, $dst}", - [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def AND16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "and.w\t{$src, $dst}", - [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; - -def AND8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "and.b\t{$src, $dst}", - [(store (and (load addr:$dst), - (i8 (load addr:$src))), addr:$dst), - (implicit SR)]>; -def AND16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "and.w\t{$src, $dst}", - [(store (and (load addr:$dst), + } + def 8rm : I8rm<opcode, (outs GR8:$rd), (ins GR8:$src2, memsrc:$src), + !strconcat(asmstring, ".b\t$src, $rd"), + [(set GR8:$rd, (node GR8:$src2, (load addr:$src))), + (implicit SR)]>; + def 16rm : I16rm<opcode, (outs GR16:$rd), (ins GR16:$src2, memsrc:$src), + !strconcat(asmstring, "\t$src, $rd"), + [(set GR16:$rd, (node GR16:$src2, (load addr:$src))), + (implicit SR)]>; + def 8rn : I8rn<opcode, (outs GR8:$rd), (ins GR8:$src2, indreg:$rs), + !strconcat(asmstring, ".b\t$rs, $rd"), []>; + def 16rn : I16rn<opcode, (outs GR16:$rd), (ins GR16:$src2, indreg:$rs), + !strconcat(asmstring, "\t$rs, $rd"), []>; + let mayLoad = 1, + hasExtraDefRegAllocReq = 1, + Constraints = "$rs = $wb, $src2 = $rd" in { + def 8rp : I8rp<opcode, (outs GR8:$rd, GR16:$wb), (ins GR8:$src2, postreg:$rs), + !strconcat(asmstring, ".b\t$rs, $rd"), []>; + def 16rp : I16rp<opcode, (outs GR16:$rd, GR16:$wb), (ins GR16:$src2, postreg:$rs), + !strconcat(asmstring, "\t$rs, $rd"), []>; + } + def 8rc : I8rc<opcode, (outs GR8:$rd), (ins GR8:$src2, cg8imm:$imm), + !strconcat(asmstring, ".b\t$imm, $rd"), + [(set GR8:$rd, (node GR8:$src2, cg8imm:$imm)), + (implicit SR)]>; + def 16rc : I16rc<opcode, (outs GR16:$rd), (ins GR16:$src2, cg16imm:$imm), + !strconcat(asmstring, "\t$imm, $rd"), + [(set GR16:$rd, (node GR16:$src2, cg16imm:$imm)), + (implicit SR)]>; + def 8ri : I8ri<opcode, (outs GR8:$rd), (ins GR8:$src2, i8imm:$imm), + !strconcat(asmstring, ".b\t$imm, $rd"), + [(set GR8:$rd, (node GR8:$src2, imm:$imm)), + (implicit SR)]>; + def 16ri : I16ri<opcode, (outs GR16:$rd), (ins GR16:$src2, i16imm:$imm), + !strconcat(asmstring, "\t$imm, $rd"), + [(set GR16:$rd, (node GR16:$src2, imm:$imm)), + (implicit SR)]>; + } + def 8mr : I8mr<opcode, (outs), (ins memdst:$dst, GR8:$rs), + !strconcat(asmstring, ".b\t$rs, $dst"), + [(store (node (load addr:$dst), GR8:$rs), addr:$dst), + (implicit SR)]>; + def 16mr : I16mr<opcode, (outs), (ins memdst:$dst, GR16:$rs), + !strconcat(asmstring, "\t$rs, $dst"), + [(store (node (load addr:$dst), GR16:$rs), addr:$dst), + (implicit SR)]>; + def 8mc : I8mc<opcode, (outs), (ins memdst:$dst, cg8imm:$imm), + !strconcat(asmstring, ".b\t$imm, $dst"), + [(store (node (load addr:$dst), (i8 cg8imm:$imm)), addr:$dst), + (implicit SR)]>; + def 16mc : I16mc<opcode, (outs), (ins memdst:$dst, cg16imm:$imm), + !strconcat(asmstring, "\t$imm, $dst"), + [(store (node (load addr:$dst), (i16 cg16imm:$imm)), addr:$dst), + (implicit SR)]>; + def 8mi : I8mi<opcode, (outs), (ins memdst:$dst, i8imm:$imm), + !strconcat(asmstring, ".b\t$imm, $dst"), + [(store (node (load addr:$dst), (i8 imm:$imm)), addr:$dst), + (implicit SR)]>; + def 16mi : I16mi<opcode, (outs), (ins memdst:$dst, i16imm:$imm), + !strconcat(asmstring, "\t$imm, $dst"), + [(store (node (load addr:$dst), (i16 imm:$imm)), addr:$dst), + (implicit SR)]>; + def 8mm : I8mm<opcode, (outs), (ins memdst:$dst, memsrc:$src), + !strconcat(asmstring, ".b\t$src, $dst"), + [(store (node (load addr:$dst), + (i8 (load addr:$src))), addr:$dst), + (implicit SR)]>; + def 16mm : I16mm<opcode, (outs), (ins memdst:$dst, memsrc:$src), + !strconcat(asmstring, "\t$src, $dst"), + [(store (node (load addr:$dst), (i16 (load addr:$src))), addr:$dst), - (implicit SR)]>; -} - -let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y -def OR8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "bis.b\t{$src2, $dst}", - [(set GR8:$dst, (or GR8:$src, GR8:$src2))]>; -def OR16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "bis.w\t{$src2, $dst}", - [(set GR16:$dst, (or GR16:$src, GR16:$src2))]>; -} - -def OR8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "bis.b\t{$src2, $dst}", - [(set GR8:$dst, (or GR8:$src, imm:$src2))]>; -def OR16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "bis.w\t{$src2, $dst}", - [(set GR16:$dst, (or GR16:$src, imm:$src2))]>; - -def OR8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "bis.b\t{$src2, $dst}", - [(set GR8:$dst, (or GR8:$src, (load addr:$src2)))]>; -def OR16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "bis.w\t{$src2, $dst}", - [(set GR16:$dst, (or GR16:$src, (load addr:$src2)))]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, -Constraints = "$base = $base_wb, $src = $dst" in { -def OR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), - (ins GR8:$src, GR16:$base), - "bis.b\t{@$base+, $dst}", []>; -def OR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), - (ins GR16:$src, GR16:$base), - "bis.w\t{@$base+, $dst}", []>; -} - -let Constraints = "" in { -def OR8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "bis.b\t{$src, $dst}", - [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>; -def OR16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "bis.w\t{$src, $dst}", - [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>; - -def OR8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "bis.b\t{$src, $dst}", - [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>; -def OR16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "bis.w\t{$src, $dst}", - [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>; - -def OR8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "bis.b\t{$src, $dst}", - [(store (or (i8 (load addr:$dst)), - (i8 (load addr:$src))), addr:$dst)]>; -def OR16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "bis.w\t{$src, $dst}", - [(store (or (i16 (load addr:$dst)), - (i16 (load addr:$src))), addr:$dst)]>; -} - -// bic does not modify condition codes -def BIC8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "bic.b\t{$src2, $dst}", - [(set GR8:$dst, (and GR8:$src, (not GR8:$src2)))]>; -def BIC16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "bic.w\t{$src2, $dst}", - [(set GR16:$dst, (and GR16:$src, (not GR16:$src2)))]>; - -def BIC8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "bic.b\t{$src2, $dst}", - [(set GR8:$dst, (and GR8:$src, (not (i8 (load addr:$src2)))))]>; -def BIC16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "bic.w\t{$src2, $dst}", - [(set GR16:$dst, (and GR16:$src, (not (i16 (load addr:$src2)))))]>; - -let Constraints = "" in { -def BIC8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "bic.b\t{$src, $dst}", - [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>; -def BIC16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "bic.w\t{$src, $dst}", - [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>; - -def BIC8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "bic.b\t{$src, $dst}", - [(store (and (load addr:$dst), - (not (i8 (load addr:$src)))), addr:$dst)]>; -def BIC16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "bic.w\t{$src, $dst}", - [(store (and (load addr:$dst), - (not (i16 (load addr:$src)))), addr:$dst)]>; -} - -let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y -def XOR8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "xor.b\t{$src2, $dst}", - [(set GR8:$dst, (xor GR8:$src, GR8:$src2)), - (implicit SR)]>; -def XOR16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "xor.w\t{$src2, $dst}", - [(set GR16:$dst, (xor GR16:$src, GR16:$src2)), - (implicit SR)]>; -} - -def XOR8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "xor.b\t{$src2, $dst}", - [(set GR8:$dst, (xor GR8:$src, imm:$src2)), - (implicit SR)]>; -def XOR16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "xor.w\t{$src2, $dst}", - [(set GR16:$dst, (xor GR16:$src, imm:$src2)), - (implicit SR)]>; - -def XOR8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "xor.b\t{$src2, $dst}", - [(set GR8:$dst, (xor GR8:$src, (load addr:$src2))), - (implicit SR)]>; -def XOR16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "xor.w\t{$src2, $dst}", - [(set GR16:$dst, (xor GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, -Constraints = "$base = $base_wb, $src = $dst" in { -def XOR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), - (ins GR8:$src, GR16:$base), - "xor.b\t{@$base+, $dst}", []>; -def XOR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), - (ins GR16:$src, GR16:$base), - "xor.w\t{@$base+, $dst}", []>; -} - -let Constraints = "" in { -def XOR8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "xor.b\t{$src, $dst}", - [(store (xor (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def XOR16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "xor.w\t{$src, $dst}", - [(store (xor (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; - -def XOR8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "xor.b\t{$src, $dst}", - [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def XOR16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "xor.w\t{$src, $dst}", - [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; - -def XOR8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "xor.b\t{$src, $dst}", - [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst), (implicit SR)]>; -def XOR16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "xor.w\t{$src, $dst}", - [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst), - (implicit SR)]>; -} - - -def SUB8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "sub.b\t{$src2, $dst}", - [(set GR8:$dst, (sub GR8:$src, GR8:$src2)), - (implicit SR)]>; -def SUB16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "sub.w\t{$src2, $dst}", - [(set GR16:$dst, (sub GR16:$src, GR16:$src2)), - (implicit SR)]>; - -def SUB8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "sub.b\t{$src2, $dst}", - [(set GR8:$dst, (sub GR8:$src, imm:$src2)), - (implicit SR)]>; -def SUB16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "sub.w\t{$src2, $dst}", - [(set GR16:$dst, (sub GR16:$src, imm:$src2)), - (implicit SR)]>; - -def SUB8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "sub.b\t{$src2, $dst}", - [(set GR8:$dst, (sub GR8:$src, (load addr:$src2))), - (implicit SR)]>; -def SUB16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "sub.w\t{$src2, $dst}", - [(set GR16:$dst, (sub GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let mayLoad = 1, hasExtraDefRegAllocReq = 1, -Constraints = "$base = $base_wb, $src = $dst" in { -def SUB8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR8:$dst, GR16:$base_wb), - (ins GR8:$src, GR16:$base), - "sub.b\t{@$base+, $dst}", []>; -def SUB16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes, - (outs GR16:$dst, GR16:$base_wb), - (ins GR16:$src, GR16:$base), - "sub.w\t{@$base+, $dst}", []>; + def 8mn : I8mn<opcode, (outs), (ins memdst:$dst, indreg:$rs), + !strconcat(asmstring, ".b\t$rs, $dst"), []>; + def 16mn : I16mn<opcode, (outs), (ins memdst:$dst, indreg:$rs), + !strconcat(asmstring, "\t$rs, $dst"), []>; + def 8mp : I8mp<opcode, (outs), (ins memdst:$dst, postreg:$rs), + !strconcat(asmstring, ".b\t$rs, $dst"), []>; + def 16mp : I16mp<opcode, (outs), (ins memdst:$dst, postreg:$rs), + !strconcat(asmstring, "\t$rs, $dst"), []>; + } } -let Constraints = "" in { -def SUB8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "sub.b\t{$src, $dst}", - [(store (sub (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def SUB16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "sub.w\t{$src, $dst}", - [(store (sub (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; +defm ADD : Arith<0b0101, "add", add, 1, []>; +defm ADDC : Arith<0b0110, "addc", adde, 1, [SR]>; +defm AND : Arith<0b1111, "and", and, 1, []>; +defm BIS : Arith<0b1101, "bis", or, 1, []>; +defm BIC : Arith<0b1100, "bic", bic, 0, []>; +defm XOR : Arith<0b1110, "xor", xor, 1, []>; +defm SUB : Arith<0b1000, "sub", sub, 0, []>; +defm SUBC : Arith<0b0111, "subc", sube, 0, [SR]>; +defm DADD : Arith<0b1010, "dadd", MSP430dadd, 1, [SR]>; + +def ADC8r : InstAlias<"adc.b\t$dst", (ADDC8rc GR8:$dst, 0)>; +def ADC16r : InstAlias<"adc\t$dst", (ADDC16rc GR16:$dst, 0)>; +def ADC8m : InstAlias<"adc.b\t$dst", (ADDC8mc memdst:$dst, 0)>; +def ADC16m : InstAlias<"adc\t$dst", (ADDC16mc memdst:$dst, 0)>; + +def DADC8r : InstAlias<"dadc.b\t$dst", (DADD8rc GR8:$dst, 0)>; +def DADC16r : InstAlias<"dadc\t$dst", (DADD16rc GR16:$dst, 0)>; +def DADC8m : InstAlias<"dadc.b\t$dst", (DADD8mc memdst:$dst, 0)>; +def DADC16m : InstAlias<"dadc\t$dst", (DADD16mc memdst:$dst, 0)>; + +def DEC8r : InstAlias<"dec.b\t$dst", (SUB8rc GR8:$dst, 1)>; +def DEC16r : InstAlias<"dec\t$dst", (SUB16rc GR16:$dst, 1)>; +def DEC8m : InstAlias<"dec.b\t$dst", (SUB8mc memdst:$dst, 1)>; +def DEC16m : InstAlias<"dec\t$dst", (SUB16mc memdst:$dst, 1)>; + +def DECD8r : InstAlias<"decd.b\t$dst", (SUB8rc GR8:$dst, 2)>; +def DECD16r : InstAlias<"decd\t$dst", (SUB16rc GR16:$dst, 2)>; +def DECD8m : InstAlias<"decd.b\t$dst", (SUB8mc memdst:$dst, 2)>; +def DECD16m : InstAlias<"decd\t$dst", (SUB16mc memdst:$dst, 2)>; + +def INC8r : InstAlias<"inc.b\t$dst", (ADD8rc GR8:$dst, 1)>; +def INC16r : InstAlias<"inc\t$dst", (ADD16rc GR16:$dst, 1)>; +def INC8m : InstAlias<"inc.b\t$dst", (ADD8mc memdst:$dst, 1)>; +def INC16m : InstAlias<"inc\t$dst", (ADD16mc memdst:$dst, 1)>; + +def INCD8r : InstAlias<"incd.b\t$dst", (ADD8rc GR8:$dst, 2)>; +def INCD16r : InstAlias<"incd\t$dst", (ADD16rc GR16:$dst, 2)>; +def INCD8m : InstAlias<"incd.b\t$dst", (ADD8mc memdst:$dst, 2)>; +def INCD16m : InstAlias<"incd\t$dst", (ADD16mc memdst:$dst, 2)>; + +def SBC8r : InstAlias<"sbc.b\t$dst", (SUBC8rc GR8:$dst, 0)>; +def SBC16r : InstAlias<"sbc\t$dst", (SUBC16rc GR16:$dst, 0)>; +def SBC8m : InstAlias<"sbc.b\t$dst", (SUBC8mc memdst:$dst, 0)>; +def SBC16m : InstAlias<"sbc\t$dst", (SUBC16mc memdst:$dst, 0)>; + +def INV8r : InstAlias<"inv.b\t$dst", (XOR8rc GR8:$dst, -1)>; +def INV16r : InstAlias<"inv\t$dst", (XOR16rc GR16:$dst, -1)>; +def INV8m : InstAlias<"inv.b\t$dst", (XOR8mc memdst:$dst, -1)>; +def INV16m : InstAlias<"inv\t$dst", (XOR16mc memdst:$dst, -1)>; + +// printAliasInstr() doesn't check $dst operands are actually equal +// for RLA and RLC aliases below, so disable printing aliases. + +def RLA8r : InstAlias<"rla.b\t$dst", (ADD8rr GR8:$dst, GR8:$dst), 0>; +def RLA16r : InstAlias<"rla\t$dst", (ADD16rr GR16:$dst, GR16:$dst), 0>; +def RLA8m : InstAlias<"rla.b\t$dst", (ADD8mm memdst:$dst, memdst:$dst), 0>; +def RLA16m : InstAlias<"rla\t$dst", (ADD16mm memdst:$dst, memdst:$dst), 0>; + +def RLC8r : InstAlias<"rlc.b\t$dst", (ADDC8rr GR8:$dst, GR8:$dst), 0>; +def RLC16r : InstAlias<"rlc\t$dst", (ADDC16rr GR16:$dst, GR16:$dst), 0>; +def RLC8m : InstAlias<"rlc.b\t$dst", (ADDC8mm memdst:$dst, memdst:$dst), 0>; +def RLC16m : InstAlias<"rlc\t$dst", (ADDC16mm memdst:$dst, memdst:$dst), 0>; + +def DINT : InstAlias<"dint", (BIC16rc SR, 8)>; +def EINT : InstAlias<"eint", (BIS16rc SR, 8)>; + +def NOP : InstAlias<"nop", (MOV16rc CG, 0)>; + +def CLR8r : InstAlias<"clr.b\t$dst", (MOV8rc GR8:$dst, 0)>; +def CLR16r : InstAlias<"clr\t$dst", (MOV16rc GR16:$dst, 0)>; +def CLR8m : InstAlias<"clr.b\t$dst", (MOV8mc memdst:$dst, 0)>; +def CLR16m : InstAlias<"clr\t$dst", (MOV16mc memdst:$dst, 0)>; + +def CLRC : InstAlias<"clrc", (BIC16rc SR, 1)>; +def CLRN : InstAlias<"clrn", (BIC16rc SR, 4)>; +def CLRZ : InstAlias<"clrz", (BIC16rc SR, 2)>; +def SETC : InstAlias<"setc", (BIS16rc SR, 1)>; +def SETN : InstAlias<"setn", (BIS16rc SR, 4)>; +def SETZ : InstAlias<"setz", (BIS16rc SR, 2)>; + +def : Pat<(MSP430rla GR8:$dst), (ADD8rr $dst, $dst)>; +def : Pat<(MSP430rla GR16:$dst), (ADD16rr $dst, $dst)>; + +let Constraints = "$rs = $rd" in { -def SUB8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "sub.b\t{$src, $dst}", - [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def SUB16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "sub.w\t{$src, $dst}", - [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; +let Defs = [SR] in { -def SUB8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "sub.b\t{$src, $dst}", - [(store (sub (load addr:$dst), - (i8 (load addr:$src))), addr:$dst), +// FIXME: memory variant! +def RRA8r : II8r<0b010, + (outs GR8:$rd), (ins GR8:$rs), + "rra.b\t$rd", + [(set GR8:$rd, (MSP430rra GR8:$rs)), (implicit SR)]>; -def SUB16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "sub.w\t{$src, $dst}", - [(store (sub (load addr:$dst), - (i16 (load addr:$src))), addr:$dst), +def RRA16r : II16r<0b010, + (outs GR16:$rd), (ins GR16:$rs), + "rra\t$rd", + [(set GR16:$rd, (MSP430rra GR16:$rs)), (implicit SR)]>; -} let Uses = [SR] in { -def SBC8rr : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src, GR8:$src2), - "subc.b\t{$src2, $dst}", - [(set GR8:$dst, (sube GR8:$src, GR8:$src2)), - (implicit SR)]>; -def SBC16rr : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src, GR16:$src2), - "subc.w\t{$src2, $dst}", - [(set GR16:$dst, (sube GR16:$src, GR16:$src2)), - (implicit SR)]>; - -def SBC8ri : I8ri<0x0, - (outs GR8:$dst), (ins GR8:$src, i8imm:$src2), - "subc.b\t{$src2, $dst}", - [(set GR8:$dst, (sube GR8:$src, imm:$src2)), +def RRC8r : II8r<0b000, + (outs GR8:$rd), (ins GR8:$rs), + "rrc.b\t$rd", + [(set GR8:$rd, (MSP430rrc GR8:$rs)), (implicit SR)]>; -def SBC16ri : I16ri<0x0, - (outs GR16:$dst), (ins GR16:$src, i16imm:$src2), - "subc.w\t{$src2, $dst}", - [(set GR16:$dst, (sube GR16:$src, imm:$src2)), - (implicit SR)]>; - -def SBC8rm : I8rm<0x0, - (outs GR8:$dst), (ins GR8:$src, memsrc:$src2), - "subc.b\t{$src2, $dst}", - [(set GR8:$dst, (sube GR8:$src, (load addr:$src2))), +def RRC16r : II16r<0b000, + (outs GR16:$rd), (ins GR16:$rs), + "rrc\t$rd", + [(set GR16:$rd, (MSP430rrc GR16:$rs)), (implicit SR)]>; -def SBC16rm : I16rm<0x0, - (outs GR16:$dst), (ins GR16:$src, memsrc:$src2), - "subc.w\t{$src2, $dst}", - [(set GR16:$dst, (sube GR16:$src, (load addr:$src2))), - (implicit SR)]>; - -let Constraints = "" in { -def SBC8mr : I8mr<0x0, - (outs), (ins memdst:$dst, GR8:$src), - "subc.b\t{$src, $dst}", - [(store (sube (load addr:$dst), GR8:$src), addr:$dst), - (implicit SR)]>; -def SBC16mr : I16mr<0x0, - (outs), (ins memdst:$dst, GR16:$src), - "subc.w\t{$src, $dst}", - [(store (sube (load addr:$dst), GR16:$src), addr:$dst), - (implicit SR)]>; - -def SBC8mi : I8mi<0x0, - (outs), (ins memdst:$dst, i8imm:$src), - "subc.b\t{$src, $dst}", - [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SR)]>; -def SBC16mi : I16mi<0x0, - (outs), (ins memdst:$dst, i16imm:$src), - "subc.w\t{$src, $dst}", - [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SR)]>; - -def SBC8mm : I8mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "subc.b\t{$src, $dst}", - [(store (sube (load addr:$dst), - (i8 (load addr:$src))), addr:$dst), - (implicit SR)]>; -def SBC16mm : I16mm<0x0, - (outs), (ins memdst:$dst, memsrc:$src), - "subc.w\t{$src, $dst}", - [(store (sube (load addr:$dst), - (i16 (load addr:$src))), addr:$dst), - (implicit SR)]>; } -} // Uses = [SR] - -// FIXME: memory variant! -def SAR8r1 : II8r<0x0, - (outs GR8:$dst), (ins GR8:$src), - "rra.b\t$dst", - [(set GR8:$dst, (MSP430rra GR8:$src)), - (implicit SR)]>; -def SAR16r1 : II16r<0x0, - (outs GR16:$dst), (ins GR16:$src), - "rra.w\t$dst", - [(set GR16:$dst, (MSP430rra GR16:$src)), - (implicit SR)]>; - -def SHL8r1 : I8rr<0x0, - (outs GR8:$dst), (ins GR8:$src), - "rla.b\t$dst", - [(set GR8:$dst, (MSP430rla GR8:$src)), - (implicit SR)]>; -def SHL16r1 : I16rr<0x0, - (outs GR16:$dst), (ins GR16:$src), - "rla.w\t$dst", - [(set GR16:$dst, (MSP430rla GR16:$src)), - (implicit SR)]>; - -def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src), - "clrc\n\t" - "rrc.b\t$dst", - [(set GR8:$dst, (MSP430rrc GR8:$src)), - (implicit SR)]>; -def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src), - "clrc\n\t" - "rrc.w\t$dst", - [(set GR16:$dst, (MSP430rrc GR16:$src)), - (implicit SR)]>; - // FIXME: Memory sext's ? -def SEXT16r : II16r<0x0, - (outs GR16:$dst), (ins GR16:$src), - "sxt\t$dst", - [(set GR16:$dst, (sext_inreg GR16:$src, i8)), +def SEXT16r : II16r<0b011, + (outs GR16:$rd), (ins GR16:$rs), + "sxt\t$rd", + [(set GR16:$rd, (sext_inreg GR16:$rs, i8)), (implicit SR)]>; } // Defs = [SR] -def ZEXT16r : I8rr<0x0, - (outs GR16:$dst), (ins GR16:$src), - "mov.b\t{$src, $dst}", - [(set GR16:$dst, (zext (trunc GR16:$src)))]>; +let isCodeGenOnly = 1 in +def ZEXT16r : I8rr<0b0100, + (outs GR16:$rd), (ins GR16:$rs), + "mov.b\t{$rs, $rd}", + [(set GR16:$rd, (zext (trunc GR16:$rs)))]>; // FIXME: Memory bitswaps? -def SWPB16r : II16r<0x0, - (outs GR16:$dst), (ins GR16:$src), - "swpb\t$dst", - [(set GR16:$dst, (bswap GR16:$src))]>; +def SWPB16r : II16r<0b001, + (outs GR16:$rd), (ins GR16:$rs), + "swpb\t$rd", + [(set GR16:$rd, (bswap GR16:$rs))]>; } // Constraints = "$src = $dst" // Integer comparisons let Defs = [SR] in { -def CMP8rr : I8rr<0x0, - (outs), (ins GR8:$src, GR8:$src2), - "cmp.b\t{$src2, $src}", - [(MSP430cmp GR8:$src, GR8:$src2), (implicit SR)]>; -def CMP16rr : I16rr<0x0, - (outs), (ins GR16:$src, GR16:$src2), - "cmp.w\t{$src2, $src}", - [(MSP430cmp GR16:$src, GR16:$src2), (implicit SR)]>; - -def CMP8ri : I8ri<0x0, - (outs), (ins GR8:$src, i8imm:$src2), - "cmp.b\t{$src2, $src}", - [(MSP430cmp GR8:$src, imm:$src2), (implicit SR)]>; -def CMP16ri : I16ri<0x0, - (outs), (ins GR16:$src, i16imm:$src2), - "cmp.w\t{$src2, $src}", - [(MSP430cmp GR16:$src, imm:$src2), (implicit SR)]>; - -def CMP8mi : I8mi<0x0, - (outs), (ins memsrc:$src, i8imm:$src2), - "cmp.b\t{$src2, $src}", - [(MSP430cmp (load addr:$src), - (i8 imm:$src2)), (implicit SR)]>; -def CMP16mi : I16mi<0x0, - (outs), (ins memsrc:$src, i16imm:$src2), - "cmp.w\t{$src2, $src}", - [(MSP430cmp (load addr:$src), - (i16 imm:$src2)), (implicit SR)]>; - -def CMP8rm : I8rm<0x0, - (outs), (ins GR8:$src, memsrc:$src2), - "cmp.b\t{$src2, $src}", - [(MSP430cmp GR8:$src, (load addr:$src2)), - (implicit SR)]>; -def CMP16rm : I16rm<0x0, - (outs), (ins GR16:$src, memsrc:$src2), - "cmp.w\t{$src2, $src}", - [(MSP430cmp GR16:$src, (load addr:$src2)), - (implicit SR)]>; - -def CMP8mr : I8mr<0x0, - (outs), (ins memsrc:$src, GR8:$src2), - "cmp.b\t{$src2, $src}", - [(MSP430cmp (load addr:$src), GR8:$src2), - (implicit SR)]>; -def CMP16mr : I16mr<0x0, - (outs), (ins memsrc:$src, GR16:$src2), - "cmp.w\t{$src2, $src}", - [(MSP430cmp (load addr:$src), GR16:$src2), +def CMP8rr : I8rr<0b1001, + (outs), (ins GR8:$rd, GR8:$rs), + "cmp.b\t$rs, $rd", + [(MSP430cmp GR8:$rd, GR8:$rs), (implicit SR)]>; +def CMP16rr : I16rr<0b1001, + (outs), (ins GR16:$rd, GR16:$rs), + "cmp\t$rs, $rd", + [(MSP430cmp GR16:$rd, GR16:$rs), (implicit SR)]>; + +def CMP8rc : I8rc<0b1001, + (outs), (ins GR8:$rd, cg8imm:$imm), + "cmp.b\t$imm, $rd", + [(MSP430cmp GR8:$rd, cg8imm:$imm), (implicit SR)]>; +def CMP16rc : I16rc<0b1001, + (outs), (ins GR16:$rd, cg16imm:$imm), + "cmp\t$imm, $rd", + [(MSP430cmp GR16:$rd, cg16imm:$imm), (implicit SR)]>; + +def CMP8ri : I8ri<0b1001, + (outs), (ins GR8:$rd, i8imm:$imm), + "cmp.b\t$imm, $rd", + [(MSP430cmp GR8:$rd, imm:$imm), (implicit SR)]>; +def CMP16ri : I16ri<0b1001, + (outs), (ins GR16:$rd, i16imm:$imm), + "cmp\t$imm, $rd", + [(MSP430cmp GR16:$rd, imm:$imm), (implicit SR)]>; + +def CMP8mc : I8mc<0b1001, + (outs), (ins memsrc:$dst, cg8imm:$imm), + "cmp.b\t$imm, $dst", + [(MSP430cmp (load addr:$dst), (i8 cg8imm:$imm)), + (implicit SR)]>; +def CMP16mc : I16mc<0b1001, + (outs), (ins memsrc:$dst, cg16imm:$imm), + "cmp\t$imm, $dst", + [(MSP430cmp (load addr:$dst), (i16 cg16imm:$imm)), + (implicit SR)]>; + +def CMP8mi : I8mi<0b1001, + (outs), (ins memsrc:$dst, i8imm:$imm), + "cmp.b\t$imm, $dst", + [(MSP430cmp (load addr:$dst), + (i8 imm:$imm)), (implicit SR)]>; +def CMP16mi : I16mi<0b1001, + (outs), (ins memsrc:$dst, i16imm:$imm), + "cmp\t$imm, $dst", + [(MSP430cmp (load addr:$dst), + (i16 imm:$imm)), (implicit SR)]>; + +def CMP8rm : I8rm<0b1001, + (outs), (ins GR8:$rd, memsrc:$src), + "cmp.b\t$src, $rd", + [(MSP430cmp GR8:$rd, (load addr:$src)), + (implicit SR)]>; +def CMP16rm : I16rm<0b1001, + (outs), (ins GR16:$rd, memsrc:$src), + "cmp\t$src, $rd", + [(MSP430cmp GR16:$rd, (load addr:$src)), + (implicit SR)]>; + +def CMP8mr : I8mr<0b1001, + (outs), (ins memsrc:$dst, GR8:$rs), + "cmp.b\t$rs, $dst", + [(MSP430cmp (load addr:$dst), GR8:$rs), + (implicit SR)]>; +def CMP16mr : I16mr<0b1001, + (outs), (ins memsrc:$dst, GR16:$rs), + "cmp\t$rs, $dst", + [(MSP430cmp (load addr:$dst), GR16:$rs), (implicit SR)]>; - // BIT TESTS, just sets condition codes // Note that the C condition is set differently than when using CMP. let isCommutable = 1 in { -def BIT8rr : I8rr<0x0, - (outs), (ins GR8:$src, GR8:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su GR8:$src, GR8:$src2), 0), +def BIT8rr : I8rr<0b1011, + (outs), (ins GR8:$rd, GR8:$rs), + "bit.b\t$rs, $rd", + [(MSP430cmp (and_su GR8:$rd, GR8:$rs), 0), (implicit SR)]>; -def BIT16rr : I16rr<0x0, - (outs), (ins GR16:$src, GR16:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su GR16:$src, GR16:$src2), 0), +def BIT16rr : I16rr<0b1011, + (outs), (ins GR16:$rd, GR16:$rs), + "bit\t$rs, $rd", + [(MSP430cmp (and_su GR16:$rd, GR16:$rs), 0), (implicit SR)]>; } -def BIT8ri : I8ri<0x0, - (outs), (ins GR8:$src, i8imm:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su GR8:$src, imm:$src2), 0), +def BIT8rc : I8rc<0b1011, + (outs), (ins GR8:$rd, cg8imm:$imm), + "bit.b\t$imm, $rd", + [(MSP430cmp (and_su GR8:$rd, cg8imm:$imm), 0), + (implicit SR)]>; +def BIT16rc : I16rc<0b1011, + (outs), (ins GR16:$rd, cg16imm:$imm), + "bit\t$imm, $rd", + [(MSP430cmp (and_su GR16:$rd, cg16imm:$imm), 0), + (implicit SR)]>; + +def BIT8ri : I8ri<0b1011, + (outs), (ins GR8:$rd, i8imm:$imm), + "bit.b\t$imm, $rd", + [(MSP430cmp (and_su GR8:$rd, imm:$imm), 0), (implicit SR)]>; -def BIT16ri : I16ri<0x0, - (outs), (ins GR16:$src, i16imm:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su GR16:$src, imm:$src2), 0), +def BIT16ri : I16ri<0b1011, + (outs), (ins GR16:$rd, i16imm:$imm), + "bit\t$imm, $rd", + [(MSP430cmp (and_su GR16:$rd, imm:$imm), 0), (implicit SR)]>; -def BIT8rm : I8rm<0x0, - (outs), (ins GR8:$src, memdst:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su GR8:$src, (load addr:$src2)), 0), +def BIT8rm : I8rm<0b1011, + (outs), (ins GR8:$rd, memdst:$src), + "bit.b\t$src, $rd", + [(MSP430cmp (and_su GR8:$rd, (load addr:$src)), 0), (implicit SR)]>; -def BIT16rm : I16rm<0x0, - (outs), (ins GR16:$src, memdst:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su GR16:$src, (load addr:$src2)), 0), +def BIT16rm : I16rm<0b1011, + (outs), (ins GR16:$rd, memdst:$src), + "bit\t$src, $rd", + [(MSP430cmp (and_su GR16:$rd, (load addr:$src)), 0), (implicit SR)]>; -def BIT8mr : I8mr<0x0, - (outs), (ins memsrc:$src, GR8:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su (load addr:$src), GR8:$src2), 0), +def BIT8mr : I8mr<0b1011, + (outs), (ins memsrc:$dst, GR8:$rs), + "bit.b\t$rs, $dst", + [(MSP430cmp (and_su (load addr:$dst), GR8:$rs), 0), (implicit SR)]>; -def BIT16mr : I16mr<0x0, - (outs), (ins memsrc:$src, GR16:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su (load addr:$src), GR16:$src2), 0), +def BIT16mr : I16mr<0b1011, + (outs), (ins memsrc:$dst, GR16:$rs), + "bit\t$rs, $dst", + [(MSP430cmp (and_su (load addr:$dst), GR16:$rs), 0), + (implicit SR)]>; + +def BIT8mc : I8mc<0b1011, + (outs), (ins memsrc:$dst, cg8imm:$imm), + "bit.b\t$imm, $dst", + [(MSP430cmp (and_su (load addr:$dst), (i8 cg8imm:$imm)), 0), + (implicit SR)]>; +def BIT16mc : I16mc<0b1011, + (outs), (ins memsrc:$dst, i16imm:$imm), + "bit\t$imm, $dst", + [(MSP430cmp (and_su (load addr:$dst), (i16 cg16imm:$imm)), 0), (implicit SR)]>; -def BIT8mi : I8mi<0x0, - (outs), (ins memsrc:$src, i8imm:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su (load addr:$src), (i8 imm:$src2)), 0), +def BIT8mi : I8mi<0b1011, + (outs), (ins memsrc:$dst, i8imm:$imm), + "bit.b\t$imm, $dst", + [(MSP430cmp (and_su (load addr:$dst), (i8 imm:$imm)), 0), (implicit SR)]>; -def BIT16mi : I16mi<0x0, - (outs), (ins memsrc:$src, i16imm:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su (load addr:$src), (i16 imm:$src2)), 0), +def BIT16mi : I16mi<0b1011, + (outs), (ins memsrc:$dst, i16imm:$imm), + "bit\t$imm, $dst", + [(MSP430cmp (and_su (load addr:$dst), (i16 imm:$imm)), 0), (implicit SR)]>; -def BIT8mm : I8mm<0x0, - (outs), (ins memsrc:$src, memsrc:$src2), - "bit.b\t{$src2, $src}", - [(MSP430cmp (and_su (i8 (load addr:$src)), - (load addr:$src2)), +def BIT8mm : I8mm<0b1011, + (outs), (ins memsrc:$dst, memsrc:$src), + "bit.b\t$src, $dst", + [(MSP430cmp (and_su (i8 (load addr:$dst)), + (load addr:$src)), 0), (implicit SR)]>; -def BIT16mm : I16mm<0x0, - (outs), (ins memsrc:$src, memsrc:$src2), - "bit.w\t{$src2, $src}", - [(MSP430cmp (and_su (i16 (load addr:$src)), - (load addr:$src2)), +def BIT16mm : I16mm<0b1011, + (outs), (ins memsrc:$dst, memsrc:$src), + "bit\t$src, $dst", + [(MSP430cmp (and_su (i16 (load addr:$dst)), + (load addr:$src)), 0), (implicit SR)]>; } // Defs = [SR] +def TST8r : InstAlias<"tst.b\t$dst", (CMP8rc GR8:$dst, 0)>; +def TST16r : InstAlias<"tst\t$dst", (CMP16rc GR16:$dst, 0)>; +def TST8m : InstAlias<"tst.b\t$dst", (CMP8mc memdst:$dst, 0)>; +def TST16m : InstAlias<"tst\t$dst", (CMP16mc memdst:$dst, 0)>; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns diff --git a/llvm/lib/Target/MSP430/MSP430MCInstLower.cpp b/llvm/lib/Target/MSP430/MSP430MCInstLower.cpp index e7716382b22..860c0006f78 100644 --- a/llvm/lib/Target/MSP430/MSP430MCInstLower.cpp +++ b/llvm/lib/Target/MSP430/MSP430MCInstLower.cpp @@ -110,6 +110,9 @@ LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { return MCOperand::createExpr(Expr); } +#define GET_REGINFO_ENUM +#include "MSP430GenRegisterInfo.inc" + void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { OutMI.setOpcode(MI->getOpcode()); diff --git a/llvm/lib/Target/MSP430/MSP430RegisterInfo.td b/llvm/lib/Target/MSP430/MSP430RegisterInfo.td index b5a6ed0f0a5..1e86bdf34a0 100644 --- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.td +++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.td @@ -11,26 +11,31 @@ // Declarations that describe the MSP430 register file //===----------------------------------------------------------------------===// -class MSP430Reg<bits<4> num, string n> : Register<n> { +class MSP430Reg<bits<4> num, string n, list<string> alt = []> : Register<n> { field bits<4> Num = num; let Namespace = "MSP430"; + let HWEncoding{3-0} = num; + let AltNames = alt; } -class MSP430RegWithSubregs<bits<4> num, string n, list<Register> subregs> +class MSP430RegWithSubregs<bits<4> num, string n, list<Register> subregs, + list<string> alt = []> : RegisterWithSubRegs<n, subregs> { field bits<4> Num = num; let Namespace = "MSP430"; + let HWEncoding{3-0} = num; + let AltNames = alt; } //===----------------------------------------------------------------------===// // Registers //===----------------------------------------------------------------------===// -def PCB : MSP430Reg<0, "r0">; -def SPB : MSP430Reg<1, "r1">; -def SRB : MSP430Reg<2, "r2">; -def CGB : MSP430Reg<3, "r3">; -def FPB : MSP430Reg<4, "r4">; +def PCB : MSP430Reg<0, "r0", ["pc"]>; +def SPB : MSP430Reg<1, "r1", ["sp"]>; +def SRB : MSP430Reg<2, "r2", ["sr"]>; +def CGB : MSP430Reg<3, "r3", ["cg"]>; +def FPB : MSP430Reg<4, "r4", ["fp"]>; def R5B : MSP430Reg<5, "r5">; def R6B : MSP430Reg<6, "r6">; def R7B : MSP430Reg<7, "r7">; @@ -46,11 +51,11 @@ def R15B : MSP430Reg<15, "r15">; def subreg_8bit : SubRegIndex<8> { let Namespace = "MSP430"; } let SubRegIndices = [subreg_8bit] in { -def PC : MSP430RegWithSubregs<0, "r0", [PCB]>; -def SP : MSP430RegWithSubregs<1, "r1", [SPB]>; -def SR : MSP430RegWithSubregs<2, "r2", [SRB]>; -def CG : MSP430RegWithSubregs<3, "r3", [CGB]>; -def FP : MSP430RegWithSubregs<4, "r4", [FPB]>; +def PC : MSP430RegWithSubregs<0, "r0", [PCB], ["pc"]>; +def SP : MSP430RegWithSubregs<1, "r1", [SPB], ["sp"]>; +def SR : MSP430RegWithSubregs<2, "r2", [SRB], ["sr"]>; +def CG : MSP430RegWithSubregs<3, "r3", [CGB], ["cg"]>; +def FP : MSP430RegWithSubregs<4, "r4", [FPB], ["fp"]>; def R5 : MSP430RegWithSubregs<5, "r5", [R5B]>; def R6 : MSP430RegWithSubregs<6, "r6", [R6B]>; def R7 : MSP430RegWithSubregs<7, "r7", [R7B]>; |