diff options
73 files changed, 3328 insertions, 1309 deletions
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index a42186bc270..ebbf830a60e 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -729,6 +729,38 @@ enum {  #include "ELFRelocs/BPF.def"  }; +// MSP430 specific e_flags +enum : unsigned { +  EF_MSP430_MACH_MSP430x11 = 11, +  EF_MSP430_MACH_MSP430x11x1 = 110, +  EF_MSP430_MACH_MSP430x12 = 12, +  EF_MSP430_MACH_MSP430x13 = 13, +  EF_MSP430_MACH_MSP430x14 = 14, +  EF_MSP430_MACH_MSP430x15 = 15, +  EF_MSP430_MACH_MSP430x16 = 16, +  EF_MSP430_MACH_MSP430x20 = 20, +  EF_MSP430_MACH_MSP430x22 = 22, +  EF_MSP430_MACH_MSP430x23 = 23, +  EF_MSP430_MACH_MSP430x24 = 24, +  EF_MSP430_MACH_MSP430x26 = 26, +  EF_MSP430_MACH_MSP430x31 = 31, +  EF_MSP430_MACH_MSP430x32 = 32, +  EF_MSP430_MACH_MSP430x33 = 33, +  EF_MSP430_MACH_MSP430x41 = 41, +  EF_MSP430_MACH_MSP430x42 = 42, +  EF_MSP430_MACH_MSP430x43 = 43, +  EF_MSP430_MACH_MSP430x44 = 44, +  EF_MSP430_MACH_MSP430X = 45, +  EF_MSP430_MACH_MSP430x46 = 46, +  EF_MSP430_MACH_MSP430x47 = 47, +  EF_MSP430_MACH_MSP430x54 = 54, +}; + +// ELF Relocation types for MSP430 +enum { +#include "ELFRelocs/MSP430.def" +}; +  #undef ELF_RELOC  // Section header. @@ -833,6 +865,8 @@ enum : unsigned {    SHT_MIPS_DWARF = 0x7000001e,          // DWARF debugging section.    SHT_MIPS_ABIFLAGS = 0x7000002a,       // ABI information. +  SHT_MSP430_ATTRIBUTES = 0x70000003U, +    SHT_HIPROC = 0x7fffffff,              // Highest processor arch-specific type.    SHT_LOUSER = 0x80000000,              // Lowest type reserved for applications.    SHT_HIUSER = 0xffffffff               // Highest type reserved for applications. diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/MSP430.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/MSP430.def new file mode 100644 index 00000000000..96990abf2db --- /dev/null +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/MSP430.def @@ -0,0 +1,16 @@ + +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_MSP430_NONE,               0) +ELF_RELOC(R_MSP430_32,                 1) +ELF_RELOC(R_MSP430_10_PCREL,           2) +ELF_RELOC(R_MSP430_16,                 3) +ELF_RELOC(R_MSP430_16_PCREL,           4) +ELF_RELOC(R_MSP430_16_BYTE,            5) +ELF_RELOC(R_MSP430_16_PCREL_BYTE,      6) +ELF_RELOC(R_MSP430_2X_PCREL,           7) +ELF_RELOC(R_MSP430_RL_PCREL,           8) +ELF_RELOC(R_MSP430_8,                  9) +ELF_RELOC(R_MSP430_SYM_DIFF,           10) diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 54907cbca4c..dff08607839 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -1021,6 +1021,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {        return "ELF32-lanai";      case ELF::EM_MIPS:        return "ELF32-mips"; +    case ELF::EM_MSP430: +      return "ELF32-msp430";      case ELF::EM_PPC:        return "ELF32-ppc";      case ELF::EM_RISCV: @@ -1091,6 +1093,8 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {      default:        report_fatal_error("Invalid ELFCLASS!");      } +  case ELF::EM_MSP430: +    return Triple::msp430;    case ELF::EM_PPC:      return Triple::ppc;    case ELF::EM_PPC64: diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap index 138eb06078d..c918eff2b97 100644 --- a/llvm/include/llvm/module.modulemap +++ b/llvm/include/llvm/module.modulemap @@ -52,6 +52,7 @@ module LLVM_BinaryFormat {      textual header "BinaryFormat/ELFRelocs/i386.def"      textual header "BinaryFormat/ELFRelocs/Lanai.def"      textual header "BinaryFormat/ELFRelocs/Mips.def" +    textual header "BinaryFormat/ELFRelocs/MSP430.def"      textual header "BinaryFormat/ELFRelocs/PowerPC64.def"      textual header "BinaryFormat/ELFRelocs/PowerPC.def"      textual header "BinaryFormat/ELFRelocs/RISCV.def" 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/AsmParser/CMakeLists.txt b/llvm/lib/Target/MSP430/AsmParser/CMakeLists.txt new file mode 100644 index 00000000000..bb484898afa --- /dev/null +++ b/llvm/lib/Target/MSP430/AsmParser/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMMSP430AsmParser +  MSP430AsmParser.cpp +) diff --git a/llvm/lib/Target/MSP430/AsmParser/LLVMBuild.txt b/llvm/lib/Target/MSP430/AsmParser/LLVMBuild.txt new file mode 100644 index 00000000000..58f67c07db1 --- /dev/null +++ b/llvm/lib/Target/MSP430/AsmParser/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- lib/Target/MSP430/AsmParser/LLVMBuild.txt ----------------*- Conf -*--===; +; +;                     The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +;   http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = MSP430AsmParser +parent = MSP430 +required_libraries = MC MCParser MSP430Desc MSP430Info Support +add_to_library_groups = MSP430 diff --git a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp new file mode 100644 index 00000000000..3f7d1860e9a --- /dev/null +++ b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp @@ -0,0 +1,562 @@ +//===- MSP430AsmParser.cpp - Parse MSP430 assembly to MCInst instructions -===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MSP430.h" +#include "MSP430RegisterInfo.h" +#include "MCTargetDesc/MSP430MCTargetDesc.h" + +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCParser/MCTargetAsmParser.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/TargetRegistry.h" + +#define DEBUG_TYPE "msp430-asm-parser" + +namespace llvm { + +/// Parses MSP430 assembly from a stream. +class MSP430AsmParser : public MCTargetAsmParser { +  const MCSubtargetInfo &STI; +  MCAsmParser &Parser; +  const MCRegisterInfo *MRI; + +  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, +                               OperandVector &Operands, MCStreamer &Out, +                               uint64_t &ErrorInfo, +                               bool MatchingInlineAsm) override; + +  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; + +  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, +                        SMLoc NameLoc, OperandVector &Operands) override; + +  bool ParseDirective(AsmToken DirectiveID) override; + +  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, +                                      unsigned Kind) override; + +  bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name, +                           SMLoc NameLoc, OperandVector &Operands); + +  bool ParseOperand(OperandVector &Operands); + +  bool ParseLiteralValues(unsigned Size, SMLoc L); + +  MCAsmParser &getParser() const { return Parser; } +  MCAsmLexer &getLexer() const { return Parser.getLexer(); } + +  /// @name Auto-generated Matcher Functions +  /// { + +#define GET_ASSEMBLER_HEADER +#include "MSP430GenAsmMatcher.inc" + +  /// } + +public: +  MSP430AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, +                  const MCInstrInfo &MII, const MCTargetOptions &Options) +      : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { +    MCAsmParserExtension::Initialize(Parser); +    MRI = getContext().getRegisterInfo(); + +    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); +  } +}; + +/// A parsed MSP430 assembly operand. +class MSP430Operand : public MCParsedAsmOperand { +  typedef MCParsedAsmOperand Base; + +  enum KindTy { +    k_Imm, +    k_Reg, +    k_Tok, +    k_Mem, +    k_IndReg, +    k_PostIndReg +  } Kind; + +  struct Memory { +    unsigned Reg; +    const MCExpr *Offset; +  }; +  union { +    const MCExpr *Imm; +    unsigned      Reg; +    StringRef     Tok; +    Memory        Mem; +  }; + +  SMLoc Start, End; + +public: +  MSP430Operand(StringRef Tok, SMLoc const &S) +      : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {} +  MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E) +      : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {} +  MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E) +      : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {} +  MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E) +      : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {} + +  void addRegOperands(MCInst &Inst, unsigned N) const { +    assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) && +        "Unexpected operand kind"); +    assert(N == 1 && "Invalid number of operands!"); + +    Inst.addOperand(MCOperand::createReg(Reg)); +  } + +  void addExprOperand(MCInst &Inst, const MCExpr *Expr) const { +    // Add as immediate when possible +    if (!Expr) +      Inst.addOperand(MCOperand::createImm(0)); +    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) +      Inst.addOperand(MCOperand::createImm(CE->getValue())); +    else +      Inst.addOperand(MCOperand::createExpr(Expr)); +  } + +  void addImmOperands(MCInst &Inst, unsigned N) const { +    assert(Kind == k_Imm && "Unexpected operand kind"); +    assert(N == 1 && "Invalid number of operands!"); + +    addExprOperand(Inst, Imm); +  } + +  void addMemOperands(MCInst &Inst, unsigned N) const { +    assert(Kind == k_Mem && "Unexpected operand kind"); +    assert(N == 2 && "Invalid number of operands"); + +    Inst.addOperand(MCOperand::createReg(Mem.Reg)); +    addExprOperand(Inst, Mem.Offset); +  } + +  bool isReg() const        { return Kind == k_Reg; } +  bool isImm() const        { return Kind == k_Imm; } +  bool isToken() const      { return Kind == k_Tok; } +  bool isMem() const        { return Kind == k_Mem; } +  bool isIndReg() const     { return Kind == k_IndReg; } +  bool isPostIndReg() const { return Kind == k_PostIndReg; } + +  bool isCGImm() const { +    if (Kind != k_Imm) +      return false; + +    int64_t Val; +    if (!Imm->evaluateAsAbsolute(Val)) +      return false; +     +    if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1) +      return true; + +    return false; +  } + +  StringRef getToken() const { +    assert(Kind == k_Tok && "Invalid access!"); +    return Tok; +  } + +  unsigned getReg() const { +    assert(Kind == k_Reg && "Invalid access!"); +    return Reg; +  } + +  void setReg(unsigned RegNo) { +    assert(Kind == k_Reg && "Invalid access!"); +    Reg = RegNo; +  } + +  static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) { +    return make_unique<MSP430Operand>(Str, S); +  } + +  static std::unique_ptr<MSP430Operand> CreateReg(unsigned RegNum, SMLoc S, +                                                  SMLoc E) { +    return make_unique<MSP430Operand>(k_Reg, RegNum, S, E); +  } + +  static std::unique_ptr<MSP430Operand> CreateImm(const MCExpr *Val, SMLoc S, +                                                  SMLoc E) { +    return make_unique<MSP430Operand>(Val, S, E); +  } + +  static std::unique_ptr<MSP430Operand> CreateMem(unsigned RegNum, +                                                  const MCExpr *Val, +                                                  SMLoc S, SMLoc E) { +    return make_unique<MSP430Operand>(RegNum, Val, S, E); +  } + +  static std::unique_ptr<MSP430Operand> CreateIndReg(unsigned RegNum, SMLoc S, +                                                  SMLoc E) { +    return make_unique<MSP430Operand>(k_IndReg, RegNum, S, E); +  } + +  static std::unique_ptr<MSP430Operand> CreatePostIndReg(unsigned RegNum, SMLoc S, +                                                  SMLoc E) { +    return make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E); +  } + +  SMLoc getStartLoc() const { return Start; } +  SMLoc getEndLoc() const { return End; } + +  virtual void print(raw_ostream &O) const { +    switch (Kind) { +    case k_Tok: +      O << "Token " << Tok; +      break; +    case k_Reg: +      O << "Register " << Reg; +      break; +    case k_Imm: +      O << "Immediate " << *Imm; +      break; +    case k_Mem: +      O << "Memory "; +      O << *Mem.Offset << "(" << Reg << ")"; +      break; +    case k_IndReg: +      O << "RegInd " << Reg; +      break; +    case k_PostIndReg: +      O << "PostInc " << Reg; +      break; +    } +  } +}; + +bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode, +                                              OperandVector &Operands, +                                              MCStreamer &Out, +                                              uint64_t &ErrorInfo, +                                              bool MatchingInlineAsm) { +  MCInst Inst; +  unsigned MatchResult = +      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); + +  switch (MatchResult) { +  case Match_Success: +    Inst.setLoc(Loc); +    Out.EmitInstruction(Inst, STI); +    return false; +  case Match_MnemonicFail: +    return Error(Loc, "invalid instruction mnemonic"); +  case Match_InvalidOperand: { +    SMLoc ErrorLoc = Loc; +    if (ErrorInfo != ~0U) { +      if (ErrorInfo >= Operands.size()) +        return Error(ErrorLoc, "too few operands for instruction"); + +      ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc(); +      if (ErrorLoc == SMLoc()) +        ErrorLoc = Loc; +    } +    return Error(ErrorLoc, "invalid operand for instruction"); +  } +  default: +    return true; +  } +} + +// Auto-generated by TableGen +static unsigned MatchRegisterName(StringRef Name); +static unsigned MatchRegisterAltName(StringRef Name); + +bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, +                                    SMLoc &EndLoc) { +  if (getLexer().getKind() == AsmToken::Identifier) { +    auto Name = getLexer().getTok().getIdentifier().lower(); +    RegNo = MatchRegisterName(Name); +    if (RegNo == MSP430::NoRegister) { +      RegNo = MatchRegisterAltName(Name); +      if (RegNo == MSP430::NoRegister) +        return true; +    } + +    AsmToken const &T = getParser().getTok(); +    StartLoc = T.getLoc(); +    EndLoc = T.getEndLoc(); +    getLexer().Lex(); // eat register token + +    return false; +  } + +  return Error(StartLoc, "invalid register name"); +} + +bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info, +                                          StringRef Name, SMLoc NameLoc, +                                          OperandVector &Operands) { +  if (!Name.startswith_lower("j")) +    return true; + +  auto CC = Name.drop_front().lower(); +  unsigned CondCode; +  if (CC == "ne" || CC == "nz") +    CondCode = MSP430CC::COND_NE; +  else if (CC == "eq" || CC == "z") +    CondCode = MSP430CC::COND_E; +  else if (CC == "lo" || CC == "nc") +    CondCode = MSP430CC::COND_LO; +  else if (CC == "hs" || CC == "c") +    CondCode = MSP430CC::COND_HS; +  else if (CC == "n") +    CondCode = MSP430CC::COND_N; +  else if (CC == "ge") +    CondCode = MSP430CC::COND_GE; +  else if (CC == "l") +    CondCode = MSP430CC::COND_L; +  else if (CC == "mp") +    CondCode = MSP430CC::COND_NONE; +  else +    return Error(NameLoc, "unknown instruction"); + +  if (CondCode == (unsigned)MSP430CC::COND_NONE) +    Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc)); +  else { +    Operands.push_back(MSP430Operand::CreateToken("j", NameLoc)); +    const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext()); +    Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc())); +  } + +  // Skip optional '$' sign. +  if (getLexer().getKind() == AsmToken::Dollar) +    getLexer().Lex(); // Eat '$' + +  const MCExpr *Val; +  SMLoc ExprLoc = getLexer().getLoc(); +  if (getParser().parseExpression(Val)) +    return Error(ExprLoc, "expected expression operand"); + +  int64_t Res; +  if (Val->evaluateAsAbsolute(Res)) +    if (Res < -512 || Res > 511) +      return Error(ExprLoc, "invalid jump offset"); + +  Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc, +    getLexer().getLoc())); + +  if (getLexer().isNot(AsmToken::EndOfStatement)) { +    SMLoc Loc = getLexer().getLoc(); +    getParser().eatToEndOfStatement(); +    return Error(Loc, "unexpected token"); +  } + +  getParser().Lex(); // Consume the EndOfStatement. +  return false; +} + +bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info, +                                       StringRef Name, SMLoc NameLoc, +                                       OperandVector &Operands) { +  // Drop .w suffix +  if (Name.endswith_lower(".w")) +    Name = Name.drop_back(2); + +  if (!parseJccInstruction(Info, Name, NameLoc, Operands)) +    return false; + +  // First operand is instruction mnemonic +  Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc)); + +  // If there are no more operands, then finish +  if (getLexer().is(AsmToken::EndOfStatement)) +    return false; + +  // Parse first operand +  if (ParseOperand(Operands)) +    return true; + +  // Parse second operand if any +  if (getLexer().is(AsmToken::Comma)) { +    getLexer().Lex(); // Eat ',' +    if (ParseOperand(Operands)) +      return true; +  } + +  if (getLexer().isNot(AsmToken::EndOfStatement)) { +    SMLoc Loc = getLexer().getLoc(); +    getParser().eatToEndOfStatement(); +    return Error(Loc, "unexpected token"); +  } + +  getParser().Lex(); // Consume the EndOfStatement. +  return false; +} + +bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) { +  StringRef IDVal = DirectiveID.getIdentifier(); +  if (IDVal.lower() == ".long") { +    ParseLiteralValues(4, DirectiveID.getLoc()); +  } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { +    ParseLiteralValues(2, DirectiveID.getLoc()); +  } else if (IDVal.lower() == ".byte") { +    ParseLiteralValues(1, DirectiveID.getLoc()); +  } +  return true; +} + +bool MSP430AsmParser::ParseOperand(OperandVector &Operands) { +  switch (getLexer().getKind()) { +    default: return true; +    case AsmToken::Identifier: { +      // try rN +      unsigned RegNo; +      SMLoc StartLoc, EndLoc; +      if (!ParseRegister(RegNo, StartLoc, EndLoc)) { +        Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc)); +        return false; +      } +      LLVM_FALLTHROUGH; +    } +    case AsmToken::Integer: +    case AsmToken::Plus: +    case AsmToken::Minus: { +      SMLoc StartLoc = getParser().getTok().getLoc(); +      const MCExpr *Val; +      // Try constexpr[(rN)] +      if (!getParser().parseExpression(Val)) { +        unsigned RegNo = MSP430::PC; +        SMLoc EndLoc = getParser().getTok().getLoc(); +        // Try (rN) +        if (getLexer().getKind() == AsmToken::LParen) { +          getLexer().Lex(); // Eat '(' +          SMLoc RegStartLoc; +          if (ParseRegister(RegNo, RegStartLoc, EndLoc)) +            return true; +          if (getLexer().getKind() != AsmToken::RParen) +            return true; +          EndLoc = getParser().getTok().getEndLoc(); +          getLexer().Lex(); // Eat ')' +        } +        Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc, +          EndLoc)); +        return false; +      } +      return true; +    } +    case AsmToken::Amp: { +      // Try &constexpr +      SMLoc StartLoc = getParser().getTok().getLoc(); +      getLexer().Lex(); // Eat '&' +      const MCExpr *Val; +      if (!getParser().parseExpression(Val)) { +        SMLoc EndLoc = getParser().getTok().getLoc(); +        Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc, +          EndLoc)); +        return false; +      } +      return true; +    } +    case AsmToken::At: { +      // Try @rN[+] +      SMLoc StartLoc = getParser().getTok().getLoc(); +      getLexer().Lex(); // Eat '@' +      unsigned RegNo; +      SMLoc RegStartLoc, EndLoc; +      if (ParseRegister(RegNo, RegStartLoc, EndLoc)) +        return true; +      if (getLexer().getKind() == AsmToken::Plus) { +        Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc)); +        getLexer().Lex(); // Eat '+' +        return false; +      } +      Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc)); +      return false; +    } +    case AsmToken::Hash: +      // Try #constexpr +      SMLoc StartLoc = getParser().getTok().getLoc(); +      getLexer().Lex(); // Eat '#' +      const MCExpr *Val; +      if (!getParser().parseExpression(Val)) { +        SMLoc EndLoc = getParser().getTok().getLoc(); +        Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc)); +        return false; +      } +      return true; +  } +} + +bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) { +  auto parseOne = [&]() -> bool { +    const MCExpr *Value; +    if (getParser().parseExpression(Value)) +      return true; +    getParser().getStreamer().EmitValue(Value, Size, L); +    return false; +  }; +  return (parseMany(parseOne)); +} + +extern "C" void LLVMInitializeMSP430AsmParser() { +  RegisterMCAsmParser<MSP430AsmParser> X(getTheMSP430Target()); +} + +#define GET_REGISTER_MATCHER +#define GET_MATCHER_IMPLEMENTATION +#include "MSP430GenAsmMatcher.inc" + +static unsigned convertGR16ToGR8(unsigned Reg) { +  switch (Reg) { +  default: +    llvm_unreachable("Unknown GR16 register"); +  case MSP430::PC:  return MSP430::PCB; +  case MSP430::SP:  return MSP430::SPB; +  case MSP430::SR:  return MSP430::SRB; +  case MSP430::CG:  return MSP430::CGB; +  case MSP430::FP:  return MSP430::FPB; +  case MSP430::R5:  return MSP430::R5B; +  case MSP430::R6:  return MSP430::R6B; +  case MSP430::R7:  return MSP430::R7B; +  case MSP430::R8:  return MSP430::R8B; +  case MSP430::R9:  return MSP430::R9B; +  case MSP430::R10: return MSP430::R10B; +  case MSP430::R11: return MSP430::R11B; +  case MSP430::R12: return MSP430::R12B; +  case MSP430::R13: return MSP430::R13B; +  case MSP430::R14: return MSP430::R14B; +  case MSP430::R15: return MSP430::R15B; +  } +} + +unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, +                                                     unsigned Kind) { +  MSP430Operand &Op = static_cast<MSP430Operand &>(AsmOp); + +  if (!Op.isReg()) +    return Match_InvalidOperand; + +  unsigned Reg = Op.getReg(); +  bool isGR16 = +      MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg); + +  if (isGR16 && (Kind == MCK_GR8)) { +    Op.setReg(convertGR16ToGR8(Reg)); +    return Match_Success; +  } + +  return Match_InvalidOperand; +} + +} // end of namespace llvm 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/Disassembler/CMakeLists.txt b/llvm/lib/Target/MSP430/Disassembler/CMakeLists.txt new file mode 100644 index 00000000000..bc33b906772 --- /dev/null +++ b/llvm/lib/Target/MSP430/Disassembler/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMMSP430Disassembler +  MSP430Disassembler.cpp +  ) diff --git a/llvm/lib/Target/MSP430/Disassembler/LLVMBuild.txt b/llvm/lib/Target/MSP430/Disassembler/LLVMBuild.txt new file mode 100644 index 00000000000..8af9cd9c222 --- /dev/null +++ b/llvm/lib/Target/MSP430/Disassembler/LLVMBuild.txt @@ -0,0 +1,23 @@ +;====- lib/Target/MSP430/Disassembler/LLVMBuild.txt ------------*- Conf -*--===; +; +;                     The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +;   http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = MSP430Disassembler +parent = MSP430 +required_libraries = MCDisassembler MSP430Info Support +add_to_library_groups = MSP430 diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp new file mode 100644 index 00000000000..2a66b4ed7f2 --- /dev/null +++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp @@ -0,0 +1,375 @@ +//===-- MSP430Disassembler.cpp - Disassembler for MSP430 ------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the MSP430Disassembler class. +// +//===----------------------------------------------------------------------===// + +#include "MSP430.h" +#include "MCTargetDesc/MSP430MCTargetDesc.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCFixedLenDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +#define DEBUG_TYPE "msp430-disassembler" + +typedef MCDisassembler::DecodeStatus DecodeStatus; + +namespace { +class MSP430Disassembler : public MCDisassembler { +  DecodeStatus getInstructionI(MCInst &MI, uint64_t &Size, +                               ArrayRef<uint8_t> Bytes, uint64_t Address, +                               raw_ostream &VStream, +                               raw_ostream &CStream) const; + +  DecodeStatus getInstructionII(MCInst &MI, uint64_t &Size, +                                ArrayRef<uint8_t> Bytes, uint64_t Address, +                                raw_ostream &VStream, +                                raw_ostream &CStream) const; + +  DecodeStatus getInstructionCJ(MCInst &MI, uint64_t &Size, +                                ArrayRef<uint8_t> Bytes, uint64_t Address, +                                raw_ostream &VStream, +                                raw_ostream &CStream) const; + +public: +  MSP430Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx) +      : MCDisassembler(STI, Ctx) {} + +  DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, +                              ArrayRef<uint8_t> Bytes, uint64_t Address, +                              raw_ostream &VStream, +                              raw_ostream &CStream) const override; +}; +} // end anonymous namespace + +static MCDisassembler *createMSP430Disassembler(const Target &T, +                                                const MCSubtargetInfo &STI, +                                                MCContext &Ctx) { +  return new MSP430Disassembler(STI, Ctx); +} + +extern "C" void LLVMInitializeMSP430Disassembler() { +  TargetRegistry::RegisterMCDisassembler(getTheMSP430Target(), +                                         createMSP430Disassembler); +} + +static const unsigned GR8DecoderTable[] = { +  MSP430::PCB,  MSP430::SPB,  MSP430::SRB,  MSP430::CGB, +  MSP430::FPB,  MSP430::R5B,  MSP430::R6B,  MSP430::R7B, +  MSP430::R8B,  MSP430::R9B,  MSP430::R10B, MSP430::R11B, +  MSP430::R12B, MSP430::R13B, MSP430::R14B, MSP430::R15B +}; + +static DecodeStatus DecodeGR8RegisterClass(MCInst &MI, uint64_t RegNo, +                                           uint64_t Address, +                                           const void *Decoder) { +  if (RegNo > 15) +    return MCDisassembler::Fail; + +  unsigned Reg = GR8DecoderTable[RegNo]; +  MI.addOperand(MCOperand::createReg(Reg)); +  return MCDisassembler::Success; +} + +static const unsigned GR16DecoderTable[] = { +  MSP430::PC,  MSP430::SP,  MSP430::SR,  MSP430::CG, +  MSP430::FP,  MSP430::R5,  MSP430::R6,  MSP430::R7, +  MSP430::R8,  MSP430::R9,  MSP430::R10, MSP430::R11, +  MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15 +}; + +static DecodeStatus DecodeGR16RegisterClass(MCInst &MI, uint64_t RegNo, +                                            uint64_t Address, +                                            const void *Decoder) { +  if (RegNo > 15) +    return MCDisassembler::Fail; + +  unsigned Reg = GR16DecoderTable[RegNo]; +  MI.addOperand(MCOperand::createReg(Reg)); +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address, +                                const void *Decoder); + +static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits, +                                     uint64_t Address, +                                     const void *Decoder); + +#include "MSP430GenDisassemblerTables.inc" + +static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address, +                                const void *Decoder) { +  int64_t Imm; +  switch (Bits) { +  default: +    llvm_unreachable("Invalid immediate value"); +  case 0x22: Imm =  4; break; +  case 0x32: Imm =  8; break; +  case 0x03: Imm =  0; break; +  case 0x13: Imm =  1; break; +  case 0x23: Imm =  2; break; +  case 0x33: Imm = -1; break; +  } +  MI.addOperand(MCOperand::createImm(Imm)); +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits, +                                     uint64_t Address, +                                     const void *Decoder) { +  unsigned Reg = Bits & 15; +  unsigned Imm = Bits >> 4; + +  if (DecodeGR16RegisterClass(MI, Reg, Address, Decoder) != +      MCDisassembler::Success) +    return MCDisassembler::Fail; +   +  MI.addOperand(MCOperand::createImm((int16_t)Imm)); +  return MCDisassembler::Success; +} + +enum AddrMode { +  amInvalid = 0, +  amRegister, +  amIndexed, +  amIndirect, +  amIndirectPost, +  amSymbolic, +  amImmediate, +  amAbsolute, +  amConstant +}; + +static AddrMode DecodeSrcAddrMode(unsigned Rs, unsigned As) { +  switch (Rs) { +  case 0: +    if (As == 1) return amSymbolic; +    if (As == 2) return amInvalid; +    if (As == 3) return amImmediate; +    break; +  case 2: +    if (As == 1) return amAbsolute; +    if (As == 2) return amConstant; +    if (As == 3) return amConstant; +    break; +  case 3: +    return amConstant; +  default: +    break; +  } +  switch (As) { +  case 0: return amRegister; +  case 1: return amIndexed; +  case 2: return amIndirect; +  case 3: return amIndirectPost; +  default: +    llvm_unreachable("As out of range"); +  } +} + +static AddrMode DecodeSrcAddrModeI(unsigned Insn) { +  unsigned Rs = fieldFromInstruction(Insn, 8, 4); +  unsigned As = fieldFromInstruction(Insn, 4, 2); +  return DecodeSrcAddrMode(Rs, As); +} + +static AddrMode DecodeSrcAddrModeII(unsigned Insn) { +  unsigned Rs = fieldFromInstruction(Insn, 0, 4); +  unsigned As = fieldFromInstruction(Insn, 4, 2); +  return DecodeSrcAddrMode(Rs, As); +} + +static AddrMode DecodeDstAddrMode(unsigned Insn) { +  unsigned Rd = fieldFromInstruction(Insn, 0, 4); +  unsigned Ad = fieldFromInstruction(Insn, 7, 1); +  switch (Rd) { +  case 0: return Ad ? amSymbolic : amRegister; +  case 2: return Ad ? amAbsolute : amRegister; +  default: +    break; +  } +  return Ad ? amIndexed : amRegister; +} + +static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) { +  assert(0 < Words && Words < 4 && "Incorrect number of words"); +  switch (SrcAM) { +  default: +    llvm_unreachable("Invalid addressing mode"); +  case amRegister: +    assert(Words < 3 && "Incorrect number of words"); +    return Words == 2 ? DecoderTableAlpha32 : DecoderTableAlpha16; +  case amConstant: +    assert(Words < 3 && "Incorrect number of words"); +    return Words == 2 ? DecoderTableBeta32 : DecoderTableBeta16; +  case amIndexed: +  case amSymbolic: +  case amImmediate: +  case amAbsolute: +    assert(Words > 1 && "Incorrect number of words"); +    return Words == 2 ? DecoderTableGamma32 : DecoderTableGamma48; +  case amIndirect: +  case amIndirectPost: +    assert(Words < 3 && "Incorrect number of words"); +    return Words == 2 ? DecoderTableDelta32 : DecoderTableDelta16; +  } +} + +DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size, +                                                 ArrayRef<uint8_t> Bytes, +                                                 uint64_t Address, +                                                 raw_ostream &VStream, +                                                 raw_ostream &CStream) const { +  uint64_t Insn = support::endian::read16le(Bytes.data()); +  AddrMode SrcAM = DecodeSrcAddrModeI(Insn); +  AddrMode DstAM = DecodeDstAddrMode(Insn); +  if (SrcAM == amInvalid || DstAM == amInvalid) { +    Size = 2; // skip one word and let disassembler to try further +    return MCDisassembler::Fail; +  } + +  unsigned Words = 1; +  switch (SrcAM) { +  case amIndexed: +  case amSymbolic: +  case amImmediate: +  case amAbsolute: +    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16; +    ++Words; +    break; +  default: +    break; +  } +  switch (DstAM) { +  case amIndexed: +  case amSymbolic: +  case amAbsolute: +    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2) +        << (Words * 16); +    ++Words; +    break; +  default: +    break; +  } + +  DecodeStatus Result = decodeInstruction(getDecoderTable(SrcAM, Words), MI, +                                          Insn, Address, this, STI); +  if (Result != MCDisassembler::Fail) { +    Size = Words * 2; +    return Result; +  } + +  Size = 2; +  return DecodeStatus::Fail; +} + +DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size, +                                                  ArrayRef<uint8_t> Bytes, +                                                  uint64_t Address, +                                                  raw_ostream &VStream, +                                                  raw_ostream &CStream) const { +  uint64_t Insn = support::endian::read16le(Bytes.data()); +  AddrMode SrcAM = DecodeSrcAddrModeII(Insn); +  if (SrcAM == amInvalid) { +    Size = 2; // skip one word and let disassembler to try further +    return MCDisassembler::Fail; +  } + +  unsigned Words = 1; +  switch (SrcAM) { +  case amIndexed: +  case amSymbolic: +  case amImmediate: +  case amAbsolute: +    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16; +    ++Words; +    break; +  default: +    break; +  } + +  const uint8_t *DecoderTable = Words == 2 ? DecoderTable32 : DecoderTable16; +  DecodeStatus Result = decodeInstruction(DecoderTable, MI, Insn, Address, +                                          this, STI); +  if (Result != MCDisassembler::Fail) { +    Size = Words * 2; +    return Result; +  } + +  Size = 2; +  return DecodeStatus::Fail; +} + +static MSP430CC::CondCodes getCondCode(unsigned Cond) { +  switch (Cond) { +  case 0: return MSP430CC::COND_NE; +  case 1: return MSP430CC::COND_E; +  case 2: return MSP430CC::COND_LO; +  case 3: return MSP430CC::COND_HS; +  case 4: return MSP430CC::COND_N; +  case 5: return MSP430CC::COND_GE; +  case 6: return MSP430CC::COND_L; +  case 7: return MSP430CC::COND_NONE; +  default: +    llvm_unreachable("Cond out of range"); +  } +} + +DecodeStatus MSP430Disassembler::getInstructionCJ(MCInst &MI, uint64_t &Size, +                                                  ArrayRef<uint8_t> Bytes, +                                                  uint64_t Address, +                                                  raw_ostream &VStream, +                                                  raw_ostream &CStream) const { +  uint64_t Insn = support::endian::read16le(Bytes.data()); +  unsigned Cond = fieldFromInstruction(Insn, 10, 3); +  unsigned Offset = fieldFromInstruction(Insn, 0, 10); + +  MI.addOperand(MCOperand::createImm(SignExtend32(Offset, 10))); + +  if (Cond == 7) +    MI.setOpcode(MSP430::JMP); +  else { +    MI.setOpcode(MSP430::JCC); +    MI.addOperand(MCOperand::createImm(getCondCode(Cond))); +  } + +  Size = 2; +  return DecodeStatus::Success; +} + +DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size, +                                                ArrayRef<uint8_t> Bytes, +                                                uint64_t Address, +                                                raw_ostream &VStream, +                                                raw_ostream &CStream) const { +  if (Bytes.size() < 2) { +    Size = 0; +    return MCDisassembler::Fail; +  } + +  uint64_t Insn = support::endian::read16le(Bytes.data()); +  unsigned Opc = fieldFromInstruction(Insn, 13, 3); +  switch (Opc) { +  case 0: +    return getInstructionII(MI, Size, Bytes, Address, VStream, CStream); +  case 1: +    return getInstructionCJ(MI, Size, Bytes, Address, VStream, CStream); +  default: +    return getInstructionI(MI, Size, Bytes, Address, VStream, CStream); +  } +} 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/MSP430AsmBackend.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp new file mode 100644 index 00000000000..bd69a9d8d79 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430AsmBackend.cpp @@ -0,0 +1,178 @@ +//===-- MSP430AsmBackend.cpp - MSP430 Assembler Backend -------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/MSP430FixupKinds.h" +#include "MCTargetDesc/MSP430MCTargetDesc.h" +#include "llvm/ADT/APInt.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { +class MSP430AsmBackend : public MCAsmBackend { +  uint8_t OSABI; + +  uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, +                            MCContext &Ctx) const; + +public: +  MSP430AsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI) +      : MCAsmBackend(support::little), OSABI(OSABI) {} +  ~MSP430AsmBackend() override {} + +  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, +                  const MCValue &Target, MutableArrayRef<char> Data, +                  uint64_t Value, bool IsResolved, +                  const MCSubtargetInfo *STI) const override; + +  std::unique_ptr<MCObjectTargetWriter> +  createObjectTargetWriter() const override { +    return createMSP430ELFObjectWriter(OSABI); +  } + +  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, +                            const MCRelaxableFragment *DF, +                            const MCAsmLayout &Layout) const override { +    return false; +  } + +  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, +                                    uint64_t Value, +                                    const MCRelaxableFragment *DF, +                                    const MCAsmLayout &Layout, +                                    const bool WasForced) const override { +    return false; +  } + +  unsigned getNumFixupKinds() const override { +    return MSP430::NumTargetFixupKinds; +  } + +  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { +    const static MCFixupKindInfo Infos[MSP430::NumTargetFixupKinds] = { +      // This table must be in the same order of enum in MSP430FixupKinds.h. +      // +      // name            offset bits flags +      {"fixup_32",            0, 32, 0}, +      {"fixup_10_pcrel",      0, 10, MCFixupKindInfo::FKF_IsPCRel}, +      {"fixup_16",            0, 16, 0}, +      {"fixup_16_pcrel",      0, 16, MCFixupKindInfo::FKF_IsPCRel}, +      {"fixup_16_byte",       0, 16, 0}, +      {"fixup_16_pcrel_byte", 0, 16, MCFixupKindInfo::FKF_IsPCRel}, +      {"fixup_2x_pcrel",      0, 10, MCFixupKindInfo::FKF_IsPCRel}, +      {"fixup_rl_pcrel",      0, 16, MCFixupKindInfo::FKF_IsPCRel}, +      {"fixup_8",             0,  8, 0}, +      {"fixup_sym_diff",      0, 32, 0}, +    }; +    static_assert((array_lengthof(Infos)) == MSP430::NumTargetFixupKinds, +                  "Not all fixup kinds added to Infos array"); +   +    if (Kind < FirstTargetFixupKind) +      return MCAsmBackend::getFixupKindInfo(Kind); +   +    return Infos[Kind - FirstTargetFixupKind]; +  } + +  bool mayNeedRelaxation(const MCInst &Inst, +                         const MCSubtargetInfo &STI) const override { +    return false; +  } + +  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, +                        MCInst &Res) const override {} + +  bool writeNopData(raw_ostream &OS, uint64_t Count) const override; +}; + +uint64_t MSP430AsmBackend::adjustFixupValue(const MCFixup &Fixup, +                                            uint64_t Value, +                                            MCContext &Ctx) const { +  unsigned Kind = Fixup.getKind(); +  switch (Kind) { +  case MSP430::fixup_10_pcrel: { +    if (Value & 0x1) +      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned"); + +    // Offset is signed +    int16_t Offset = Value; +    // Jumps are in words +    Offset >>= 1; +    // PC points to the next instruction so decrement by one +    --Offset; + +    if (Offset < -512 || Offset > 511) +      Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); + +    // Mask 10 bits +    Offset &= 0x3ff; + +    return Offset; +  } +  default: +    return Value; +  } +} + +void MSP430AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, +                                  const MCValue &Target, +                                  MutableArrayRef<char> Data, +                                  uint64_t Value, bool IsResolved, +                                  const MCSubtargetInfo *STI) const { +  Value = adjustFixupValue(Fixup, Value, Asm.getContext()); +  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind()); +  if (!Value) +    return; // Doesn't change encoding. + +  // Shift the value into position. +  Value <<= Info.TargetOffset; + +  unsigned Offset = Fixup.getOffset(); +  unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8; + +  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!"); + +  // For each byte of the fragment that the fixup touches, mask in the +  // bits from the fixup value. +  for (unsigned i = 0; i != NumBytes; ++i) { +    Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff); +  } +} + +bool MSP430AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { +  if ((Count % 2) != 0) +    return false; + +  // The canonical nop on MSP430 is mov #0, r3 +  uint64_t NopCount = Count / 2; +  while (NopCount--) +    OS.write("\x03\x43", 2); + +  return true; +} + +} // end anonymous namespace + +MCAsmBackend *llvm::createMSP430MCAsmBackend(const Target &T, +                                             const MCSubtargetInfo &STI, +                                             const MCRegisterInfo &MRI, +                                             const MCTargetOptions &Options) { +  return new MSP430AsmBackend(STI, ELF::ELFOSABI_STANDALONE); +} diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFObjectWriter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFObjectWriter.cpp new file mode 100644 index 00000000000..30d077b5b58 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFObjectWriter.cpp @@ -0,0 +1,59 @@ +//===-- MSP430ELFObjectWriter.cpp - MSP430 ELF Writer ---------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/MSP430FixupKinds.h" +#include "MCTargetDesc/MSP430MCTargetDesc.h" + +#include "MCTargetDesc/MSP430MCTargetDesc.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCValue.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { +class MSP430ELFObjectWriter : public MCELFObjectTargetWriter { +public: +  MSP430ELFObjectWriter(uint8_t OSABI) +    : MCELFObjectTargetWriter(false, OSABI, ELF::EM_MSP430, +                              /*HasRelocationAddend*/ true) {} + +  ~MSP430ELFObjectWriter() override {} + +protected: +  unsigned getRelocType(MCContext &Ctx, const MCValue &Target, +                        const MCFixup &Fixup, bool IsPCRel) const override { +    // Translate fixup kind to ELF relocation type. +    switch ((unsigned)Fixup.getKind()) { +    case FK_Data_1:                   return ELF::R_MSP430_8; +    case FK_Data_2:                   return ELF::R_MSP430_16; +    case FK_Data_4:                   return ELF::R_MSP430_32; +    case MSP430::fixup_32:            return ELF::R_MSP430_32; +    case MSP430::fixup_10_pcrel:      return ELF::R_MSP430_10_PCREL; +    case MSP430::fixup_16:            return ELF::R_MSP430_16; +    case MSP430::fixup_16_pcrel:      return ELF::R_MSP430_16_PCREL; +    case MSP430::fixup_16_byte:       return ELF::R_MSP430_16_BYTE; +    case MSP430::fixup_16_pcrel_byte: return ELF::R_MSP430_16_PCREL_BYTE; +    case MSP430::fixup_2x_pcrel:      return ELF::R_MSP430_2X_PCREL; +    case MSP430::fixup_rl_pcrel:      return ELF::R_MSP430_RL_PCREL; +    case MSP430::fixup_8:             return ELF::R_MSP430_8; +    case MSP430::fixup_sym_diff:      return ELF::R_MSP430_SYM_DIFF; +    default: +      llvm_unreachable("Invalid fixup kind"); +    } +  } +}; +} // end of anonymous namespace + +std::unique_ptr<MCObjectTargetWriter> +llvm::createMSP430ELFObjectWriter(uint8_t OSABI) { +  return llvm::make_unique<MSP430ELFObjectWriter>(OSABI); +} diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp new file mode 100644 index 00000000000..9449cb27802 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp @@ -0,0 +1,81 @@ +//===-- MSP430ELFStreamer.cpp - MSP430 ELF Target Streamer Methods --------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides MSP430 specific target streamer methods. +// +//===----------------------------------------------------------------------===// + +#include "MSP430MCTargetDesc.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" + +using namespace llvm; + +namespace llvm { + +class MSP430TargetELFStreamer : public MCTargetStreamer { +public: +  MCELFStreamer &getStreamer(); +  MSP430TargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); +}; + +// This part is for ELF object output. +MSP430TargetELFStreamer::MSP430TargetELFStreamer(MCStreamer &S, +                                                 const MCSubtargetInfo &STI) +    : MCTargetStreamer(S) { +  MCAssembler &MCA = getStreamer().getAssembler(); +  unsigned EFlags = MCA.getELFHeaderEFlags(); +  MCA.setELFHeaderEFlags(EFlags); + +  // Emit build attributes section according to +  // MSP430 EABI (slaa534.pdf, part 13). +  MCSection *AttributeSection = getStreamer().getContext().getELFSection( +      ".MSP430.attributes", ELF::SHT_MSP430_ATTRIBUTES, 0); +  Streamer.SwitchSection(AttributeSection); + +  // Format version. +  Streamer.EmitIntValue(0x41, 1); +  // Subsection length. +  Streamer.EmitIntValue(22, 4); +  // Vendor name string, zero-terminated. +  Streamer.EmitBytes("mspabi"); +  Streamer.EmitIntValue(0, 1); + +  // Attribute vector scope tag. 1 stands for the entire file. +  Streamer.EmitIntValue(1, 1); +  // Attribute vector length. +  Streamer.EmitIntValue(11, 4); +  // OFBA_MSPABI_Tag_ISA(4) = 1, MSP430 +  Streamer.EmitIntValue(4, 1); +  Streamer.EmitIntValue(1, 1); +  // OFBA_MSPABI_Tag_Code_Model(6) = 1, Small +  Streamer.EmitIntValue(6, 1); +  Streamer.EmitIntValue(1, 1); +  // OFBA_MSPABI_Tag_Data_Model(8) = 1, Small +  Streamer.EmitIntValue(8, 1); +  Streamer.EmitIntValue(1, 1); +} + +MCELFStreamer &MSP430TargetELFStreamer::getStreamer() { +  return static_cast<MCELFStreamer &>(Streamer); +} + +MCTargetStreamer * +createMSP430ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { +  const Triple &TT = STI.getTargetTriple(); +  if (TT.isOSBinFormatELF()) +    return new MSP430TargetELFStreamer(S, STI); +  return nullptr; +} + +} // namespace llvm diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430FixupKinds.h b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430FixupKinds.h new file mode 100644 index 00000000000..1eb6a275942 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430FixupKinds.h @@ -0,0 +1,53 @@ +//===-- MSP430FixupKinds.h - MSP430 Specific Fixup Entries ------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430FIXUPKINDS_H +#define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430FIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +#undef MSP430 + +namespace llvm { +namespace MSP430 { + +// This table must be in the same order of +// MCFixupKindInfo Infos[MSP430::NumTargetFixupKinds] +// in MSP430AsmBackend.cpp. +// +enum Fixups { +  // A 32 bit absolute fixup. +  fixup_32 = FirstTargetFixupKind, +  // A 10 bit PC relative fixup. +  fixup_10_pcrel, +  // A 16 bit absolute fixup. +  fixup_16, +  // A 16 bit PC relative fixup. +  fixup_16_pcrel, +  // A 16 bit absolute fixup for byte operations. +  fixup_16_byte, +  // A 16 bit PC relative fixup for command address. +  fixup_16_pcrel_byte, +  // A 10 bit PC relative fixup for complicated polymorphs. +  fixup_2x_pcrel, +  // A 16 bit relaxable fixup. +  fixup_rl_pcrel, +  // A 8 bit absolute fixup. +  fixup_8, +  // A 32 bit symbol difference fixup. +  fixup_sym_diff, + +  // Marker +  LastTargetFixupKind, +  NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} // end namespace MSP430 +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp new file mode 100644 index 00000000000..ba9f7d7a9a5 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp @@ -0,0 +1,212 @@ +//===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the MSP430MCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "MSP430.h" +#include "MCTargetDesc/MSP430MCTargetDesc.h" +#include "MCTargetDesc/MSP430FixupKinds.h" + +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/EndianStream.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "mccodeemitter" + +namespace llvm { + +class MSP430MCCodeEmitter : public MCCodeEmitter { +  MCContext &Ctx; +  MCInstrInfo const &MCII; + +  // Offset keeps track of current word number being emitted +  // inside a particular instruction. +  mutable unsigned Offset; + +  /// TableGen'erated function for getting the binary encoding for an +  /// instruction. +  uint64_t getBinaryCodeForInstr(const MCInst &MI, +                                 SmallVectorImpl<MCFixup> &Fixups, +                                 const MCSubtargetInfo &STI) const; + +  /// Returns the binary encoding of operands. +  /// +  /// If an operand requires relocation, the relocation is recorded +  /// and zero is returned. +  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, +                             SmallVectorImpl<MCFixup> &Fixups, +                             const MCSubtargetInfo &STI) const; + +  unsigned getMemOpValue(const MCInst &MI, unsigned Op, +                         SmallVectorImpl<MCFixup> &Fixups, +                         const MCSubtargetInfo &STI) const; + +  unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op, +                              SmallVectorImpl<MCFixup> &Fixups, +                              const MCSubtargetInfo &STI) const; + +  unsigned getCGImmOpValue(const MCInst &MI, unsigned Op, +                           SmallVectorImpl<MCFixup> &Fixups, +                           const MCSubtargetInfo &STI) const; + +  unsigned getCCOpValue(const MCInst &MI, unsigned Op, +                        SmallVectorImpl<MCFixup> &Fixups, +                        const MCSubtargetInfo &STI) const; + +public: +  MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII) +      : Ctx(ctx), MCII(MCII) {} + +  void encodeInstruction(const MCInst &MI, raw_ostream &OS, +                         SmallVectorImpl<MCFixup> &Fixups, +                         const MCSubtargetInfo &STI) const override; +}; + +void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, +                                            SmallVectorImpl<MCFixup> &Fixups, +                                            const MCSubtargetInfo &STI) const { +  const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); +  // Get byte count of instruction. +  unsigned Size = Desc.getSize(); + +  // Initialize fixup offset +  Offset = 2; + +  uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI); +  const uint16_t *Words = reinterpret_cast<uint16_t const *>(&BinaryOpCode); +  size_t WordCount = Size / 2; + +  for (size_t i = 0; i < WordCount; ++i) { +    uint16_t Word = Words[i]; +    support::endian::write(OS, Word, support::little); +  } +} + +unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI, +                                                const MCOperand &MO, +                                                SmallVectorImpl<MCFixup> &Fixups, +                                                const MCSubtargetInfo &STI) const { +  if (MO.isReg()) +    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); + +  if (MO.isImm()) { +    Offset += 2; +    return MO.getImm(); +  } + +  assert(MO.isExpr() && "Expected expr operand"); +  Fixups.push_back(MCFixup::create(Offset, MO.getExpr(), +      static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc())); +  Offset += 2; +  return 0; +} + +unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op, +                                            SmallVectorImpl<MCFixup> &Fixups, +                                            const MCSubtargetInfo &STI) const { +  const MCOperand &MO1 = MI.getOperand(Op); +  assert(MO1.isReg() && "Register operand expected"); +  unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg()); + +  const MCOperand &MO2 = MI.getOperand(Op + 1); +  if (MO2.isImm()) { +    Offset += 2; +    return (MO2.getImm() << 4) | Reg; +  } + +  assert(MO2.isExpr() && "Expr operand expected"); +  MSP430::Fixups FixupKind; +  switch (Reg) { +  case 0: +    FixupKind = MSP430::fixup_16_pcrel_byte; +    break; +  case 2: +    FixupKind = MSP430::fixup_16_byte; +    break; +  default: +    FixupKind = MSP430::fixup_16_byte; +    break; +  } +  Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(), +    static_cast<MCFixupKind>(FixupKind), MI.getLoc())); +  Offset += 2; +  return Reg; +} + +unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op, +                                                 SmallVectorImpl<MCFixup> &Fixups, +                                                 const MCSubtargetInfo &STI) const { +  const MCOperand &MO = MI.getOperand(Op); +  if (MO.isImm()) +    return MO.getImm(); + +  assert(MO.isExpr() && "Expr operand expected"); +  Fixups.push_back(MCFixup::create(0, MO.getExpr(), +    static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc())); +  return 0; +} + +unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op, +                                              SmallVectorImpl<MCFixup> &Fixups, +                                              const MCSubtargetInfo &STI) const { +  const MCOperand &MO = MI.getOperand(Op); +  assert(MO.isImm() && "Expr operand expected"); +   +  int64_t Imm = MO.getImm(); +  switch (Imm) { +  default: +    llvm_unreachable("Invalid immediate value"); +  case 4:  return 0x22; +  case 8:  return 0x32; +  case 0:  return 0x03; +  case 1:  return 0x13; +  case 2:  return 0x23; +  case -1: return 0x33; +  } +} + +unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op, +                                           SmallVectorImpl<MCFixup> &Fixups, +                                           const MCSubtargetInfo &STI) const { +  const MCOperand &MO = MI.getOperand(Op); +  assert(MO.isImm() && "Immediate operand expected"); +  switch (MO.getImm()) { +  case MSP430CC::COND_NE: return 0; +  case MSP430CC::COND_E:  return 1; +  case MSP430CC::COND_LO: return 2; +  case MSP430CC::COND_HS: return 3; +  case MSP430CC::COND_N:  return 4; +  case MSP430CC::COND_GE: return 5; +  case MSP430CC::COND_L:  return 6; +  default: +    llvm_unreachable("Unknown condition code"); +  } +} + +MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII, +                                         const MCRegisterInfo &MRI, +                                         MCContext &Ctx) { +  return new MSP430MCCodeEmitter(Ctx, MCII); +} + +#include "MSP430GenMCCodeEmitter.inc" + +} // end of namespace llvm 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]>; diff --git a/llvm/test/CodeGen/MSP430/AddrMode-bis-rx.ll b/llvm/test/CodeGen/MSP430/AddrMode-bis-rx.ll index f4cb30f2d01..948b67eb66c 100644 --- a/llvm/test/CodeGen/MSP430/AddrMode-bis-rx.ll +++ b/llvm/test/CodeGen/MSP430/AddrMode-bis-rx.ll @@ -8,7 +8,7 @@ define i16 @am1(i16 %x, i16* %a) nounwind {  	ret i16 %2  }  ; CHECK-LABEL: am1: -; CHECK:		bis.w	0(r13), r12 +; CHECK:		bis	0(r13), r12  @foo = external global i16 @@ -18,7 +18,7 @@ define i16 @am2(i16 %x) nounwind {  	ret i16 %2  }  ; CHECK-LABEL: am2: -; CHECK:		bis.w	&foo, r12 +; CHECK:		bis	&foo, r12  @bar = internal constant [2 x i8] [ i8 32, i8 64 ] @@ -37,7 +37,7 @@ define i16 @am4(i16 %x) nounwind {  	ret i16 %2  }  ; CHECK-LABEL: am4: -; CHECK:		bis.w	&32, r12 +; CHECK:		bis	&32, r12  define i16 @am5(i16 %x, i16* %a) nounwind {  	%1 = getelementptr i16, i16* %a, i16 2 @@ -46,7 +46,7 @@ define i16 @am5(i16 %x, i16* %a) nounwind {  	ret i16 %3  }  ; CHECK-LABEL: am5: -; CHECK:		bis.w	4(r13), r12 +; CHECK:		bis	4(r13), r12  %S = type { i16, i16 }  @baz = common global %S zeroinitializer, align 1 @@ -57,7 +57,7 @@ define i16 @am6(i16 %x) nounwind {  	ret i16 %2  }  ; CHECK-LABEL: am6: -; CHECK:		bis.w	&baz+2, r12 +; CHECK:		bis	&baz+2, r12  %T = type { i16, [2 x i8] }  @duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] } diff --git a/llvm/test/CodeGen/MSP430/AddrMode-bis-xr.ll b/llvm/test/CodeGen/MSP430/AddrMode-bis-xr.ll index 1e150f38206..6d3a497386d 100644 --- a/llvm/test/CodeGen/MSP430/AddrMode-bis-xr.ll +++ b/llvm/test/CodeGen/MSP430/AddrMode-bis-xr.ll @@ -9,7 +9,7 @@ define void @am1(i16* %a, i16 %x) nounwind {  	ret void  }  ; CHECK-LABEL: am1: -; CHECK:		bis.w	r13, 0(r12) +; CHECK:		bis	r13, 0(r12)  @foo = external global i16 @@ -20,7 +20,7 @@ define void @am2(i16 %x) nounwind {  	ret void  }  ; CHECK-LABEL: am2: -; CHECK:		bis.w	r12, &foo +; CHECK:		bis	r12, &foo  @bar = external global [2 x i8] @@ -41,7 +41,7 @@ define void @am4(i16 %x) nounwind {  	ret void  }  ; CHECK-LABEL: am4: -; CHECK:		bis.w	r12, &32 +; CHECK:		bis	r12, &32  define void @am5(i16* %a, i16 %x) readonly {  	%1 = getelementptr inbounds i16, i16* %a, i16 2 @@ -51,7 +51,7 @@ define void @am5(i16* %a, i16 %x) readonly {  	ret void  }  ; CHECK-LABEL: am5: -; CHECK:		bis.w	r13, 4(r12) +; CHECK:		bis	r13, 4(r12)  %S = type { i16, i16 }  @baz = common global %S zeroinitializer @@ -63,7 +63,7 @@ define void @am6(i16 %x) nounwind {  	ret void  }  ; CHECK-LABEL: am6: -; CHECK:		bis.w	r12, &baz+2 +; CHECK:		bis	r12, &baz+2  %T = type { i16, [2 x i8] }  @duh = external global %T diff --git a/llvm/test/CodeGen/MSP430/AddrMode-mov-rx.ll b/llvm/test/CodeGen/MSP430/AddrMode-mov-rx.ll index 808aca0ea10..0605e8e86ce 100644 --- a/llvm/test/CodeGen/MSP430/AddrMode-mov-rx.ll +++ b/llvm/test/CodeGen/MSP430/AddrMode-mov-rx.ll @@ -7,7 +7,7 @@ define i16 @am1(i16* %a) nounwind {  	ret i16 %1  }  ; CHECK-LABEL: am1: -; CHECK:		mov.w	0(r12), r12 +; CHECK:		mov	0(r12), r12  @foo = external global i16 @@ -16,7 +16,7 @@ define i16 @am2() nounwind {  	ret i16 %1  }  ; CHECK-LABEL: am2: -; CHECK:		mov.w	&foo, r12 +; CHECK:		mov	&foo, r12  @bar = internal constant [2 x i8] [ i8 32, i8 64 ] @@ -33,7 +33,7 @@ define i16 @am4() nounwind {  	ret i16 %1  }  ; CHECK-LABEL: am4: -; CHECK:		mov.w	&32, r12 +; CHECK:		mov	&32, r12  define i16 @am5(i16* %a) nounwind {  	%1 = getelementptr i16, i16* %a, i16 2 @@ -41,7 +41,7 @@ define i16 @am5(i16* %a) nounwind {  	ret i16 %2  }  ; CHECK-LABEL: am5: -; CHECK:		mov.w	4(r12), r12 +; CHECK:		mov	4(r12), r12  %S = type { i16, i16 }  @baz = common global %S zeroinitializer, align 1 @@ -51,7 +51,7 @@ define i16 @am6() nounwind {  	ret i16 %1  }  ; CHECK-LABEL: am6: -; CHECK:		mov.w	&baz+2, r12 +; CHECK:		mov	&baz+2, r12  %T = type { i16, [2 x i8] }  @duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] } diff --git a/llvm/test/CodeGen/MSP430/AddrMode-mov-xr.ll b/llvm/test/CodeGen/MSP430/AddrMode-mov-xr.ll index c336289a60d..acc0b825711 100644 --- a/llvm/test/CodeGen/MSP430/AddrMode-mov-xr.ll +++ b/llvm/test/CodeGen/MSP430/AddrMode-mov-xr.ll @@ -7,7 +7,7 @@ define void @am1(i16* %a, i16 %b) nounwind {  	ret void  }  ; CHECK-LABEL: am1: -; CHECK:		mov.w	r13, 0(r12) +; CHECK:		mov	r13, 0(r12)  @foo = external global i16 @@ -16,7 +16,7 @@ define void @am2(i16 %a) nounwind {  	ret void  }  ; CHECK-LABEL: am2: -; CHECK:		mov.w	r12, &foo +; CHECK:		mov	r12, &foo  @bar = external global [2 x i8] @@ -33,7 +33,7 @@ define void @am4(i16 %a) nounwind {  	ret void  }  ; CHECK-LABEL: am4: -; CHECK:		mov.w	r12, &32 +; CHECK:		mov	r12, &32  define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {  	%1 = getelementptr inbounds i16, i16* %p, i16 2 @@ -41,7 +41,7 @@ define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {  	ret void  }  ; CHECK-LABEL: am5: -; CHECK:		mov.w	r13, 4(r12) +; CHECK:		mov	r13, 4(r12)  %S = type { i16, i16 }  @baz = common global %S zeroinitializer, align 1 @@ -51,7 +51,7 @@ define void @am6(i16 %a) nounwind {  	ret void  }  ; CHECK-LABEL: am6: -; CHECK:		mov.w	r12, &baz+2 +; CHECK:		mov	r12, &baz+2  %T = type { i16, [2 x i8] }  @duh = external global %T diff --git a/llvm/test/CodeGen/MSP430/Inst16mi.ll b/llvm/test/CodeGen/MSP430/Inst16mi.ll index 38c16f2ba23..bb99e28a1ba 100644 --- a/llvm/test/CodeGen/MSP430/Inst16mi.ll +++ b/llvm/test/CodeGen/MSP430/Inst16mi.ll @@ -6,14 +6,14 @@ target triple = "msp430-generic-generic"  define void @mov() nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.w	#2, &foo +; CHECK: mov	#2, &foo  	store i16 2, i16 * @foo  	ret void  }  define void @add() nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	#2, &foo +; CHECK: incd	&foo  	%1 = load i16, i16* @foo  	%2 = add i16 %1, 2  	store i16 %2, i16 * @foo @@ -22,7 +22,7 @@ define void @add() nounwind {  define void @and() nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	#2, &foo +; CHECK: and	#2, &foo  	%1 = load i16, i16* @foo  	%2 = and i16 %1, 2  	store i16 %2, i16 * @foo @@ -31,7 +31,7 @@ define void @and() nounwind {  define void @bis() nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	#2, &foo +; CHECK: bis	#2, &foo  	%1 = load i16, i16* @foo  	%2 = or i16 %1, 2  	store i16 %2, i16 * @foo @@ -40,7 +40,7 @@ define void @bis() nounwind {  define void @xor() nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	#2, &foo +; CHECK: xor	#2, &foo  	%1 = load i16, i16* @foo  	%2 = xor i16 %1, 2  	store i16 %2, i16 * @foo diff --git a/llvm/test/CodeGen/MSP430/Inst16mm.ll b/llvm/test/CodeGen/MSP430/Inst16mm.ll index 14a799b9171..21fab42fd59 100644 --- a/llvm/test/CodeGen/MSP430/Inst16mm.ll +++ b/llvm/test/CodeGen/MSP430/Inst16mm.ll @@ -6,7 +6,7 @@ target triple = "msp430-generic-generic"  define void @mov() nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.w	&bar, &foo +; CHECK: mov	&bar, &foo          %1 = load i16, i16* @bar          store i16 %1, i16* @foo          ret void @@ -14,7 +14,7 @@ define void @mov() nounwind {  define void @add() nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	&bar, &foo +; CHECK: add	&bar, &foo  	%1 = load i16, i16* @bar  	%2 = load i16, i16* @foo  	%3 = add i16 %2, %1 @@ -24,7 +24,7 @@ define void @add() nounwind {  define void @and() nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	&bar, &foo +; CHECK: and	&bar, &foo  	%1 = load i16, i16* @bar  	%2 = load i16, i16* @foo  	%3 = and i16 %2, %1 @@ -34,7 +34,7 @@ define void @and() nounwind {  define void @bis() nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	&bar, &foo +; CHECK: bis	&bar, &foo  	%1 = load i16, i16* @bar  	%2 = load i16, i16* @foo  	%3 = or i16 %2, %1 @@ -44,7 +44,7 @@ define void @bis() nounwind {  define void @xor() nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	&bar, &foo +; CHECK: xor	&bar, &foo  	%1 = load i16, i16* @bar  	%2 = load i16, i16* @foo  	%3 = xor i16 %2, %1 @@ -64,6 +64,6 @@ entry:   %0 = load i16, i16* %retval                          ; <i16> [#uses=1]   ret i16 %0  ; CHECK-LABEL: mov2: -; CHECK-DAG:	mov.w	2(r1), 6(r1) -; CHECK-DAG:	mov.w	0(r1), 4(r1) +; CHECK-DAG:	mov	2(r1), 6(r1) +; CHECK-DAG:	mov	0(r1), 4(r1)  } diff --git a/llvm/test/CodeGen/MSP430/Inst16mr.ll b/llvm/test/CodeGen/MSP430/Inst16mr.ll index 847c093f408..e3f23d9c562 100644 --- a/llvm/test/CodeGen/MSP430/Inst16mr.ll +++ b/llvm/test/CodeGen/MSP430/Inst16mr.ll @@ -5,14 +5,14 @@ target triple = "msp430-generic-generic"  define void @mov(i16 %a) nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.w	r12, &foo +; CHECK: mov	r12, &foo  	store i16 %a, i16* @foo  	ret void  }  define void @add(i16 %a) nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	r12, &foo +; CHECK: add	r12, &foo  	%1 = load i16, i16* @foo  	%2 = add i16 %a, %1  	store i16 %2, i16* @foo @@ -21,7 +21,7 @@ define void @add(i16 %a) nounwind {  define void @and(i16 %a) nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	r12, &foo +; CHECK: and	r12, &foo  	%1 = load i16, i16* @foo  	%2 = and i16 %a, %1  	store i16 %2, i16* @foo @@ -30,7 +30,7 @@ define void @and(i16 %a) nounwind {  define void @bis(i16 %a) nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	r12, &foo +; CHECK: bis	r12, &foo  	%1 = load i16, i16* @foo  	%2 = or i16 %a, %1  	store i16 %2, i16* @foo @@ -39,7 +39,7 @@ define void @bis(i16 %a) nounwind {  define void @bic(i16 zeroext %m) nounwind {  ; CHECK-LABEL: bic: -; CHECK: bic.w   r12, &foo +; CHECK: bic   r12, &foo          %1 = xor i16 %m, -1          %2 = load i16, i16* @foo          %3 = and i16 %2, %1 @@ -49,7 +49,7 @@ define void @bic(i16 zeroext %m) nounwind {  define void @xor(i16 %a) nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	r12, &foo +; CHECK: xor	r12, &foo  	%1 = load i16, i16* @foo  	%2 = xor i16 %a, %1  	store i16 %2, i16* @foo diff --git a/llvm/test/CodeGen/MSP430/Inst16ri.ll b/llvm/test/CodeGen/MSP430/Inst16ri.ll index 3a4bb6a93d9..58b2791194a 100644 --- a/llvm/test/CodeGen/MSP430/Inst16ri.ll +++ b/llvm/test/CodeGen/MSP430/Inst16ri.ll @@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"  define i16 @mov() nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.w	#1, r12 +; CHECK: mov	#1, r12  	ret i16 1  }  define i16 @add(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	#1, r12 +; CHECK: inc	r12  	%1 = add i16 %a, 1  	ret i16 %1  }  define i16 @and(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	#1, r12 +; CHECK: and	#1, r12  	%1 = and i16 %a, 1  	ret i16 %1  }  define i16 @bis(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	#1, r12 +; CHECK: bis	#1, r12  	%1 = or i16 %a, 1  	ret i16 %1  }  define i16 @xor(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	#1, r12 +; CHECK: xor	#1, r12  	%1 = xor i16 %a, 1  	ret i16 %1  } diff --git a/llvm/test/CodeGen/MSP430/Inst16rm.ll b/llvm/test/CodeGen/MSP430/Inst16rm.ll index 44b8f39d8fa..8a3cd0a46fb 100644 --- a/llvm/test/CodeGen/MSP430/Inst16rm.ll +++ b/llvm/test/CodeGen/MSP430/Inst16rm.ll @@ -5,7 +5,7 @@ target triple = "msp430-generic-generic"  define i16 @add(i16 %a) nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	&foo, r12 +; CHECK: add	&foo, r12  	%1 = load i16, i16* @foo  	%2 = add i16 %a, %1  	ret i16 %2 @@ -13,7 +13,7 @@ define i16 @add(i16 %a) nounwind {  define i16 @and(i16 %a) nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	&foo, r12 +; CHECK: and	&foo, r12  	%1 = load i16, i16* @foo  	%2 = and i16 %a, %1  	ret i16 %2 @@ -21,7 +21,7 @@ define i16 @and(i16 %a) nounwind {  define i16 @bis(i16 %a) nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	&foo, r12 +; CHECK: bis	&foo, r12  	%1 = load i16, i16* @foo  	%2 = or i16 %a, %1  	ret i16 %2 @@ -29,7 +29,7 @@ define i16 @bis(i16 %a) nounwind {  define i16  @bic(i16 %a) nounwind {  ; CHECK-LABEL: bic: -; CHECK: bic.w	&foo, r12 +; CHECK: bic	&foo, r12          %1 = load i16, i16* @foo          %2 = xor i16 %1, -1          %3 = and i16 %a, %2 @@ -38,7 +38,7 @@ define i16  @bic(i16 %a) nounwind {  define i16 @xor(i16 %a) nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	&foo, r12 +; CHECK: xor	&foo, r12  	%1 = load i16, i16* @foo  	%2 = xor i16 %a, %1  	ret i16 %2 diff --git a/llvm/test/CodeGen/MSP430/Inst16rr.ll b/llvm/test/CodeGen/MSP430/Inst16rr.ll index 75440ca2b40..124d42113a2 100644 --- a/llvm/test/CodeGen/MSP430/Inst16rr.ll +++ b/llvm/test/CodeGen/MSP430/Inst16rr.ll @@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"  define i16 @mov(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.w	r13, r12 +; CHECK: mov	r13, r12  	ret i16 %b  }  define i16 @add(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: add: -; CHECK: add.w	r13, r12 +; CHECK: add	r13, r12  	%1 = add i16 %a, %b  	ret i16 %1  }  define i16 @and(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	r13, r12 +; CHECK: and	r13, r12  	%1 = and i16 %a, %b  	ret i16 %1  }  define i16 @bis(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	r13, r12 +; CHECK: bis	r13, r12  	%1 = or i16 %a, %b  	ret i16 %1  }  define i16 @bic(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: bic: -; CHECK: bic.w	r13, r12 +; CHECK: bic	r13, r12          %1 = xor i16 %b, -1          %2 = and i16 %a, %1          ret i16 %2 @@ -39,7 +39,7 @@ define i16 @bic(i16 %a, i16 %b) nounwind {  define i16 @xor(i16 %a, i16 %b) nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	r13, r12 +; CHECK: xor	r13, r12  	%1 = xor i16 %a, %b  	ret i16 %1  } diff --git a/llvm/test/CodeGen/MSP430/Inst8mi.ll b/llvm/test/CodeGen/MSP430/Inst8mi.ll index ff22d7e1eb3..36eb3f91f84 100644 --- a/llvm/test/CodeGen/MSP430/Inst8mi.ll +++ b/llvm/test/CodeGen/MSP430/Inst8mi.ll @@ -12,7 +12,7 @@ define void @mov() nounwind {  define void @add() nounwind {  ; CHECK-LABEL: add: -; CHECK: add.b	#2, &foo +; CHECK: incd.b	&foo  	%1 = load i8, i8* @foo  	%2 = add i8 %1, 2  	store i8 %2, i8 * @foo diff --git a/llvm/test/CodeGen/MSP430/Inst8ri.ll b/llvm/test/CodeGen/MSP430/Inst8ri.ll index 0e50f17f2a5..ff3dee8bfb9 100644 --- a/llvm/test/CodeGen/MSP430/Inst8ri.ll +++ b/llvm/test/CodeGen/MSP430/Inst8ri.ll @@ -10,7 +10,7 @@ define i8 @mov() nounwind {  define i8 @add(i8 %a, i8 %b) nounwind {  ; CHECK-LABEL: add: -; CHECK: add.b	#1, r12 +; CHECK: inc.b	r12  	%1 = add i8 %a, 1  	ret i8 %1  } diff --git a/llvm/test/CodeGen/MSP430/Inst8rr.ll b/llvm/test/CodeGen/MSP430/Inst8rr.ll index f37bc32a28f..20c4fa5aacf 100644 --- a/llvm/test/CodeGen/MSP430/Inst8rr.ll +++ b/llvm/test/CodeGen/MSP430/Inst8rr.ll @@ -4,7 +4,7 @@ target triple = "msp430-generic-generic"  define i8 @mov(i8 %a, i8 %b) nounwind {  ; CHECK-LABEL: mov: -; CHECK: mov.{{[bw]}} r13, r12 +; CHECK: mov r13, r12  	ret i8 %b  } @@ -17,14 +17,14 @@ define i8 @add(i8 %a, i8 %b) nounwind {  define i8 @and(i8 %a, i8 %b) nounwind {  ; CHECK-LABEL: and: -; CHECK: and.w	r13, r12 +; CHECK: and	r13, r12  	%1 = and i8 %a, %b  	ret i8 %1  }  define i8 @bis(i8 %a, i8 %b) nounwind {  ; CHECK-LABEL: bis: -; CHECK: bis.w	r13, r12 +; CHECK: bis	r13, r12  	%1 = or i8 %a, %b  	ret i8 %1  } @@ -39,7 +39,7 @@ define i8 @bic(i8 %a, i8 %b) nounwind {  define i8 @xor(i8 %a, i8 %b) nounwind {  ; CHECK-LABEL: xor: -; CHECK: xor.w	r13, r12 +; CHECK: xor	r13, r12  	%1 = xor i8 %a, %b  	ret i8 %1  } diff --git a/llvm/test/CodeGen/MSP430/asm-clobbers.ll b/llvm/test/CodeGen/MSP430/asm-clobbers.ll index 216a3fe4018..0a0335057f1 100644 --- a/llvm/test/CodeGen/MSP430/asm-clobbers.ll +++ b/llvm/test/CodeGen/MSP430/asm-clobbers.ll @@ -6,8 +6,8 @@ target triple = "msp430---elf"  define void @test() {  entry:  ; CHECK-LABEL: test: -; CHECK: push.w r10 +; CHECK: push r10    call void asm sideeffect "", "~{r10}"() -; CHECK: pop.w r10 +; CHECK: pop r10    ret void  } diff --git a/llvm/test/CodeGen/MSP430/bit.ll b/llvm/test/CodeGen/MSP430/bit.ll index 172822fbb5f..a4b781243b4 100644 --- a/llvm/test/CodeGen/MSP430/bit.ll +++ b/llvm/test/CodeGen/MSP430/bit.ll @@ -93,7 +93,7 @@ define i16 @bitwrr(i16 %a, i16 %b) nounwind {  	ret i16 %t3  }  ; CHECK-LABEL: bitwrr: -; CHECK: bit.w	r13, r12 +; CHECK: bit	r13, r12  define i16 @bitwri(i16 %a) nounwind {  	%t1 = and i16 %a, 4080 @@ -102,7 +102,7 @@ define i16 @bitwri(i16 %a) nounwind {  	ret i16 %t3  }  ; CHECK-LABEL: bitwri: -; CHECK: bit.w	#4080, r12 +; CHECK: bit	#4080, r12  define i16 @bitwir(i16 %a) nounwind {  	%t1 = and i16 4080, %a @@ -111,7 +111,7 @@ define i16 @bitwir(i16 %a) nounwind {  	ret i16 %t3  }  ; CHECK-LABEL: bitwir: -; CHECK: bit.w	#4080, r12 +; CHECK: bit	#4080, r12  define i16 @bitwmi() nounwind {  	%t1 = load i16, i16* @foo16 @@ -121,7 +121,7 @@ define i16 @bitwmi() nounwind {  	ret i16 %t4  }  ; CHECK-LABEL: bitwmi: -; CHECK: bit.w	#4080, &foo16 +; CHECK: bit	#4080, &foo16  define i16 @bitwim() nounwind {  	%t1 = load i16, i16* @foo16 @@ -131,7 +131,7 @@ define i16 @bitwim() nounwind {  	ret i16 %t4  }  ; CHECK-LABEL: bitwim: -; CHECK: bit.w	#4080, &foo16 +; CHECK: bit	#4080, &foo16  define i16 @bitwrm(i16 %a) nounwind {  	%t1 = load i16, i16* @foo16 @@ -141,7 +141,7 @@ define i16 @bitwrm(i16 %a) nounwind {  	ret i16 %t4  }  ; CHECK-LABEL: bitwrm: -; CHECK: bit.w	&foo16, r12 +; CHECK: bit	&foo16, r12  define i16 @bitwmr(i16 %a) nounwind {  	%t1 = load i16, i16* @foo16 @@ -151,7 +151,7 @@ define i16 @bitwmr(i16 %a) nounwind {  	ret i16 %t4  }  ; CHECK-LABEL: bitwmr: -; CHECK: bit.w	r12, &foo16 +; CHECK: bit	r12, &foo16  define i16 @bitwmm() nounwind {  	%t1 = load i16, i16* @foo16 @@ -162,5 +162,5 @@ define i16 @bitwmm() nounwind {  	ret i16 %t5  }  ; CHECK-LABEL: bitwmm: -; CHECK: bit.w	&bar16, &foo16 +; CHECK: bit	&bar16, &foo16 diff --git a/llvm/test/CodeGen/MSP430/byval.ll b/llvm/test/CodeGen/MSP430/byval.ll index 401896b43c2..838e883d4be 100644 --- a/llvm/test/CodeGen/MSP430/byval.ll +++ b/llvm/test/CodeGen/MSP430/byval.ll @@ -9,7 +9,7 @@ target triple = "msp430---elf"  define i16 @callee(%struct.Foo* byval %f) nounwind {  entry:  ; CHECK-LABEL: callee: -; CHECK: mov.w 2(r1), r12 +; CHECK: mov 2(r1), r12    %0 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i32 0, i32 0    %1 = load i16, i16* %0, align 2    ret i16 %1 @@ -18,9 +18,9 @@ entry:  define void @caller() nounwind {  entry:  ; CHECK-LABEL: caller: -; CHECK: mov.w &foo+4, 4(r1) -; CHECK-NEXT: mov.w &foo+2, 2(r1) -; CHECK-NEXT: mov.w &foo, 0(r1) +; CHECK: mov &foo+4, 4(r1) +; CHECK-NEXT: mov &foo+2, 2(r1) +; CHECK-NEXT: mov &foo, 0(r1)    %call = call i16 @callee(%struct.Foo* byval @foo)    ret void  } diff --git a/llvm/test/CodeGen/MSP430/cc_args.ll b/llvm/test/CodeGen/MSP430/cc_args.ll index 70ac901f7e4..eb7e470a9b6 100644 --- a/llvm/test/CodeGen/MSP430/cc_args.ll +++ b/llvm/test/CodeGen/MSP430/cc_args.ll @@ -7,50 +7,50 @@ define void @test() #0 {  entry:  ; CHECK: test: -; CHECK: mov.w #1, r12 +; CHECK: mov #1, r12  ; CHECK: call #f_i16    call void @f_i16(i16 1) -; CHECK: mov.w #772, r12 -; CHECK: mov.w #258, r13 +; CHECK: mov #772, r12 +; CHECK: mov #258, r13  ; CHECK: call #f_i32    call void @f_i32(i32 16909060) -; CHECK: mov.w #1800, r12 -; CHECK: mov.w #1286, r13 -; CHECK: mov.w #772, r14 -; CHECK: mov.w #258, r15 +; CHECK: mov #1800, r12 +; CHECK: mov #1286, r13 +; CHECK: mov #772, r14 +; CHECK: mov #258, r15  ; CHECK: call #f_i64    call void @f_i64(i64 72623859790382856) -; CHECK: mov.w #772, r12 -; CHECK: mov.w #258, r13 -; CHECK: mov.w #1800, r14 -; CHECK: mov.w #1286, r15 +; CHECK: mov #772, r12 +; CHECK: mov #258, r13 +; CHECK: mov #1800, r14 +; CHECK: mov #1286, r15  ; CHECK: call #f_i32_i32    call void @f_i32_i32(i32 16909060, i32 84281096) -; CHECK: mov.w #1, r12 -; CHECK: mov.w #772, r13 -; CHECK: mov.w #258, r14 -; CHECK: mov.w #2, r15 +; CHECK: mov #1, r12 +; CHECK: mov #772, r13 +; CHECK: mov #258, r14 +; CHECK: mov #2, r15  ; CHECK: call #f_i16_i32_i16    call void @f_i16_i32_i16(i16 1, i32 16909060, i16 2) -; CHECK: mov.w #1286, 0(r1) -; CHECK: mov.w #1, r12 -; CHECK: mov.w #772, r13 -; CHECK: mov.w #258, r14 -; CHECK: mov.w #1800, r15 +; CHECK: mov #1286, 0(r1) +; CHECK: mov #1, r12 +; CHECK: mov #772, r13 +; CHECK: mov #258, r14 +; CHECK: mov #1800, r15  ; CHECK: call #f_i16_i32_i32    call void @f_i16_i32_i32(i16 1, i32 16909060, i32 84281096) -; CHECK: mov.w #258, 6(r1) -; CHECK: mov.w #772, 4(r1) -; CHECK: mov.w #1286, 2(r1) -; CHECK: mov.w #1800, 0(r1) -; CHECK: mov.w #1, r12 -; CHECK: mov.w #2, r13 +; CHECK: mov #258, 6(r1) +; CHECK: mov #772, 4(r1) +; CHECK: mov #1286, 2(r1) +; CHECK: mov #1800, 0(r1) +; CHECK: mov #1, r12 +; CHECK: mov #2, r13  ; CHECK: call #f_i16_i64_i16    call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2) @@ -63,75 +63,75 @@ entry:  define void @f_i16(i16 %a) #0 {  ; CHECK: f_i16: -; CHECK: mov.w r12, &g_i16 +; CHECK: mov r12, &g_i16    store volatile i16 %a, i16* @g_i16, align 2    ret void  }  define void @f_i32(i32 %a) #0 {  ; CHECK: f_i32: -; CHECK: mov.w r13, &g_i32+2 -; CHECK: mov.w r12, &g_i32 +; CHECK: mov r13, &g_i32+2 +; CHECK: mov r12, &g_i32    store volatile i32 %a, i32* @g_i32, align 2    ret void  }  define void @f_i64(i64 %a) #0 {  ; CHECK: f_i64: -; CHECK: mov.w r15, &g_i64+6 -; CHECK: mov.w r14, &g_i64+4 -; CHECK: mov.w r13, &g_i64+2 -; CHECK: mov.w r12, &g_i64 +; CHECK: mov r15, &g_i64+6 +; CHECK: mov r14, &g_i64+4 +; CHECK: mov r13, &g_i64+2 +; CHECK: mov r12, &g_i64    store volatile i64 %a, i64* @g_i64, align 2    ret void  }  define void @f_i32_i32(i32 %a, i32 %b) #0 {  ; CHECK: f_i32_i32: -; CHECK: mov.w r13, &g_i32+2 -; CHECK: mov.w r12, &g_i32 +; CHECK: mov r13, &g_i32+2 +; CHECK: mov r12, &g_i32    store volatile i32 %a, i32* @g_i32, align 2 -; CHECK: mov.w r15, &g_i32+2 -; CHECK: mov.w r14, &g_i32 +; CHECK: mov r15, &g_i32+2 +; CHECK: mov r14, &g_i32    store volatile i32 %b, i32* @g_i32, align 2    ret void  }  define void @f_i16_i32_i32(i16 %a, i32 %b, i32 %c) #0 {  ; CHECK: f_i16_i32_i32: -; CHECK: mov.w r12, &g_i16 +; CHECK: mov r12, &g_i16    store volatile i16 %a, i16* @g_i16, align 2 -; CHECK: mov.w r14, &g_i32+2 -; CHECK: mov.w r13, &g_i32 +; CHECK: mov r14, &g_i32+2 +; CHECK: mov r13, &g_i32    store volatile i32 %b, i32* @g_i32, align 2 -; CHECK: mov.w r15, &g_i32 -; CHECK: mov.w 4(r4), &g_i32+2 +; CHECK: mov r15, &g_i32 +; CHECK: mov 4(r4), &g_i32+2    store volatile i32 %c, i32* @g_i32, align 2    ret void  }  define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {  ; CHECK: f_i16_i32_i16: -; CHECK: mov.w r12, &g_i16 +; CHECK: mov r12, &g_i16    store volatile i16 %a, i16* @g_i16, align 2 -; CHECK: mov.w r14, &g_i32+2 -; CHECK: mov.w r13, &g_i32 +; CHECK: mov r14, &g_i32+2 +; CHECK: mov r13, &g_i32    store volatile i32 %b, i32* @g_i32, align 2 -; CHECK: mov.w r15, &g_i16 +; CHECK: mov r15, &g_i16    store volatile i16 %c, i16* @g_i16, align 2    ret void  }  define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {  ; CHECK: f_i16_i64_i16: -; CHECK: mov.w r12, &g_i16 +; CHECK: mov r12, &g_i16    store volatile i16 %a, i16* @g_i16, align 2 -;CHECK: mov.w 10(r4), &g_i64+6 -;CHECK: mov.w 8(r4), &g_i64+4 -;CHECK: mov.w 6(r4), &g_i64+2 -;CHECK: mov.w 4(r4), &g_i64 +;CHECK: mov 10(r4), &g_i64+6 +;CHECK: mov 8(r4), &g_i64+4 +;CHECK: mov 6(r4), &g_i64+2 +;CHECK: mov 4(r4), &g_i64    store volatile i64 %b, i64* @g_i64, align 2 -;CHECK: mov.w r13, &g_i16 +;CHECK: mov r13, &g_i16    store volatile i16 %c, i16* @g_i16, align 2    ret void  } diff --git a/llvm/test/CodeGen/MSP430/cc_ret.ll b/llvm/test/CodeGen/MSP430/cc_ret.ll index 937db6dbf3b..b4bb0554208 100644 --- a/llvm/test/CodeGen/MSP430/cc_ret.ll +++ b/llvm/test/CodeGen/MSP430/cc_ret.ll @@ -8,21 +8,21 @@ entry:  ; CHECK: test:  ; CHECK: call #f_i16 -; CHECK: mov.w r12, &g_i16 +; CHECK: mov r12, &g_i16    %0 = call i16 @f_i16()    store volatile i16 %0, i16* @g_i16  ; CHECK: call #f_i32 -; CHECK: mov.w r13, &g_i32+2 -; CHECK: mov.w r12, &g_i32 +; CHECK: mov r13, &g_i32+2 +; CHECK: mov r12, &g_i32    %1 = call i32 @f_i32()    store volatile i32 %1, i32* @g_i32  ; CHECK: call #f_i64 -; CHECK: mov.w r15, &g_i64+6 -; CHECK: mov.w r14, &g_i64+4 -; CHECK: mov.w r13, &g_i64+2 -; CHECK: mov.w r12, &g_i64 +; CHECK: mov r15, &g_i64+6 +; CHECK: mov r14, &g_i64+4 +; CHECK: mov r13, &g_i64+2 +; CHECK: mov r12, &g_i64    %2 = call i64 @f_i64()    store volatile i64 %2, i64* @g_i64 @@ -35,25 +35,25 @@ entry:  define i16 @f_i16() #0 {  ; CHECK: f_i16: -; CHECK: mov.w #1, r12 +; CHECK: mov #1, r12  ; CHECK: ret    ret i16 1  }  define i32 @f_i32() #0 {  ; CHECK: f_i32: -; CHECK: mov.w #772, r12 -; CHECK: mov.w #258, r13 +; CHECK: mov #772, r12 +; CHECK: mov #258, r13  ; CHECK: ret    ret i32 16909060  }  define i64 @f_i64() #0 {  ; CHECK: f_i64: -; CHECK: mov.w #1800, r12 -; CHECK: mov.w #1286, r13 -; CHECK: mov.w #772, r14 -; CHECK: mov.w #258, r15 +; CHECK: mov #1800, r12 +; CHECK: mov #1286, r13 +; CHECK: mov #772, r14 +; CHECK: mov #258, r15  ; CHECK: ret    ret i64 72623859790382856  } diff --git a/llvm/test/CodeGen/MSP430/fp.ll b/llvm/test/CodeGen/MSP430/fp.ll index 2559e23ae1f..87c4055829c 100644 --- a/llvm/test/CodeGen/MSP430/fp.ll +++ b/llvm/test/CodeGen/MSP430/fp.ll @@ -6,13 +6,13 @@ target triple = "msp430---elf"  define void @fp() nounwind {  entry:  ; CHECK-LABEL: fp: -; CHECK: push.w r4 -; CHECK: mov.w r1, r4 -; CHECK: sub.w #2, r1 +; CHECK: push r4 +; CHECK: mov r1, r4 +; CHECK: sub #2, r1    %i = alloca i16, align 2 -; CHECK: mov.w #0, -2(r4) +; CHECK: clr -2(r4)    store i16 0, i16* %i, align 2 -; CHECK: pop.w r4 +; CHECK: pop r4    ret void  } diff --git a/llvm/test/CodeGen/MSP430/jumptable.ll b/llvm/test/CodeGen/MSP430/jumptable.ll index 49f23166a0a..6121f7ebed6 100644 --- a/llvm/test/CodeGen/MSP430/jumptable.ll +++ b/llvm/test/CodeGen/MSP430/jumptable.ll @@ -7,15 +7,15 @@ target triple = "msp430---elf"  define i16 @test(i16 %i) #0 {  entry:  ; CHECK-LABEL: test: -; CHECK:      sub.w   #4, r1 -; CHECK-NEXT: mov.w   r12, 0(r1) -; CHECK-NEXT: cmp.w   #4, r12 +; CHECK:      sub   #4, r1 +; CHECK-NEXT: mov   r12, 0(r1) +; CHECK-NEXT: cmp   #4, r12  ; CHECK-NEXT: jhs     .LBB0_3    %retval = alloca i16, align 2    %i.addr = alloca i16, align 2    store i16 %i, i16* %i.addr, align 2    %0 = load i16, i16* %i.addr, align 2 -; CHECK:      rla.w r12 +; CHECK:      add   r12, r12  ; CHECK-NEXT: br .LJTI0_0(r12)    switch i16 %0, label %sw.default [      i16 0, label %sw.bb diff --git a/llvm/test/CodeGen/MSP430/memset.ll b/llvm/test/CodeGen/MSP430/memset.ll index 10b506c60d9..0f83b607820 100644 --- a/llvm/test/CodeGen/MSP430/memset.ll +++ b/llvm/test/CodeGen/MSP430/memset.ll @@ -9,9 +9,9 @@ define void @test() nounwind {  entry:  ; CHECK-LABEL: test:    %0 = load i8*, i8** @buf, align 2 -; CHECK: mov.w &buf, r12 -; CHECK-NEXT: mov.w #5, r13 -; CHECK-NEXT: mov.w #128, r14 +; CHECK: mov &buf, r12 +; CHECK-NEXT: mov #5, r13 +; CHECK-NEXT: mov #128, r14  ; CHECK-NEXT: call #memset    call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i1 false)    ret void diff --git a/llvm/test/CodeGen/MSP430/misched-msp430.ll b/llvm/test/CodeGen/MSP430/misched-msp430.ll index 3d18fa005a6..f44f10ccd3e 100644 --- a/llvm/test/CodeGen/MSP430/misched-msp430.ll +++ b/llvm/test/CodeGen/MSP430/misched-msp430.ll @@ -10,7 +10,7 @@ target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"  ; only verifies that the code generator ran successfully.  ;  ; CHECK-LABEL: @f -; CHECK: mov.w &y, &x +; CHECK: mov &y, &x  ; CHECK: ret  define void @f() {  entry: diff --git a/llvm/test/CodeGen/MSP430/postinc.ll b/llvm/test/CodeGen/MSP430/postinc.ll index 75a927f33fc..20ee8fb3c85 100644 --- a/llvm/test/CodeGen/MSP430/postinc.ll +++ b/llvm/test/CodeGen/MSP430/postinc.ll @@ -12,7 +12,7 @@ for.body:                                         ; preds = %for.body, %entry    %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]    %arrayidx = getelementptr i16, i16* %a, i16 %i.010   ; <i16*> [#uses=1]  ; CHECK-LABEL: add: -; CHECK: add.w @r{{[0-9]+}}+, r{{[0-9]+}} +; CHECK: add @r{{[0-9]+}}+, r{{[0-9]+}}    %tmp4 = load i16, i16* %arrayidx                     ; <i16> [#uses=1]    %add = add i16 %tmp4, %sum.09                   ; <i16> [#uses=2]    %inc = add i16 %i.010, 1                        ; <i16> [#uses=2] @@ -34,7 +34,7 @@ for.body:                                         ; preds = %for.body, %entry    %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]    %arrayidx = getelementptr i16, i16* %a, i16 %i.010   ; <i16*> [#uses=1]  ; CHECK-LABEL: sub: -; CHECK: sub.w @r{{[0-9]+}}+, r{{[0-9]+}} +; CHECK: sub @r{{[0-9]+}}+, r{{[0-9]+}}    %tmp4 = load i16, i16* %arrayidx                     ; <i16> [#uses=1]    %add = sub i16 %tmp4, %sum.09                   ; <i16> [#uses=2]    %inc = add i16 %i.010, 1                        ; <i16> [#uses=2] @@ -56,7 +56,7 @@ for.body:                                         ; preds = %for.body, %entry    %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]    %arrayidx = getelementptr i16, i16* %a, i16 %i.010   ; <i16*> [#uses=1]  ; CHECK-LABEL: or: -; CHECK: bis.w @r{{[0-9]+}}+, r{{[0-9]+}} +; CHECK: bis @r{{[0-9]+}}+, r{{[0-9]+}}    %tmp4 = load i16, i16* %arrayidx                     ; <i16> [#uses=1]    %add = or i16 %tmp4, %sum.09                   ; <i16> [#uses=2]    %inc = add i16 %i.010, 1                        ; <i16> [#uses=2] @@ -78,7 +78,7 @@ for.body:                                         ; preds = %for.body, %entry    %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]    %arrayidx = getelementptr i16, i16* %a, i16 %i.010   ; <i16*> [#uses=1]  ; CHECK-LABEL: xor: -; CHECK: xor.w @r{{[0-9]+}}+, r{{[0-9]+}} +; CHECK: xor @r{{[0-9]+}}+, r{{[0-9]+}}    %tmp4 = load i16, i16* %arrayidx                     ; <i16> [#uses=1]    %add = xor i16 %tmp4, %sum.09                   ; <i16> [#uses=2]    %inc = add i16 %i.010, 1                        ; <i16> [#uses=2] @@ -100,7 +100,7 @@ for.body:                                         ; preds = %for.body, %entry    %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]    %arrayidx = getelementptr i16, i16* %a, i16 %i.010   ; <i16*> [#uses=1]  ; CHECK-LABEL: and: -; CHECK: and.w @r{{[0-9]+}}+, r{{[0-9]+}} +; CHECK: and @r{{[0-9]+}}+, r{{[0-9]+}}    %tmp4 = load i16, i16* %arrayidx                     ; <i16> [#uses=1]    %add = and i16 %tmp4, %sum.09                   ; <i16> [#uses=2]    %inc = add i16 %i.010, 1                        ; <i16> [#uses=2] diff --git a/llvm/test/CodeGen/MSP430/select-use-sr.ll b/llvm/test/CodeGen/MSP430/select-use-sr.ll index 3f67fb85f79..159fc93db5a 100644 --- a/llvm/test/CodeGen/MSP430/select-use-sr.ll +++ b/llvm/test/CodeGen/MSP430/select-use-sr.ll @@ -6,8 +6,8 @@ target triple = "msp430"  ; Test that CMP instruction is not removed by MachineCSE.  ;  ; CHECK-LABEL: @f -; CHECK: cmp.w r15, r13 -; CHECK: cmp.w r15, r13 +; CHECK: cmp r15, r13 +; CHECK: cmp r15, r13  ; CHECK-NEXT: jeq .LBB0_2  define i16 @f(i16, i16, i16, i16) {  entry: diff --git a/llvm/test/CodeGen/MSP430/setcc.ll b/llvm/test/CodeGen/MSP430/setcc.ll index 6e2ec8ea3ea..52baf642903 100644 --- a/llvm/test/CodeGen/MSP430/setcc.ll +++ b/llvm/test/CodeGen/MSP430/setcc.ll @@ -9,10 +9,10 @@ define i16 @sccweqand(i16 %a, i16 %b) nounwind {  	ret i16 %t3  }  ; CHECK-LABEL: sccweqand: -; CHECK:	bit.w	r13, r12 -; CHECK:	mov.w	r2, r12 -; CHECK:	rra.w   r12 -; CHECK:	and.w	#1, r12 +; CHECK:	bit	r13, r12 +; CHECK:	mov	r2, r12 +; CHECK:	rra   r12 +; CHECK:	and	#1, r12  define i16 @sccwneand(i16 %a, i16 %b) nounwind {  	%t1 = and i16 %a, %b @@ -21,9 +21,9 @@ define i16 @sccwneand(i16 %a, i16 %b) nounwind {  	ret i16 %t3  }  ; CHECK-LABEL: sccwneand: -; CHECK: 	bit.w	r13, r12 -; CHECK:	mov.w	r2, r12 -; CHECK:	and.w	#1, r12 +; CHECK: 	bit	r13, r12 +; CHECK:	mov	r2, r12 +; CHECK:	and	#1, r12  define i16 @sccwne(i16 %a, i16 %b) nounwind {  	%t1 = icmp ne i16 %a, %b @@ -31,11 +31,11 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccwne: -; CHECK:	cmp.w	r13, r12 -; CHECK:	mov.w	r2, r13 -; CHECK:	rra.w	r13 -; CHECK:	mov.w	#1, r12 -; CHECK:	bic.w	r13, r12 +; CHECK:	cmp	r13, r12 +; CHECK:	mov	r2, r13 +; CHECK:	rra	r13 +; CHECK:	mov	#1, r12 +; CHECK:	bic	r13, r12  define i16 @sccweq(i16 %a, i16 %b) nounwind {  	%t1 = icmp eq i16 %a, %b @@ -43,10 +43,10 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccweq: -; CHECK:	cmp.w	r13, r12 -; CHECK:	mov.w	r2, r12 -; CHECK:	rra.w	r12 -; CHECK:	and.w	#1, r12 +; CHECK:	cmp	r13, r12 +; CHECK:	mov	r2, r12 +; CHECK:	rra	r12 +; CHECK:	and	#1, r12  define i16 @sccwugt(i16 %a, i16 %b) nounwind {  	%t1 = icmp ugt i16 %a, %b @@ -54,9 +54,9 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccwugt: -; CHECK:	cmp.w	r12, r13 -; CHECK:	mov.w	#1, r12 -; CHECK:	bic.w	r2, r12 +; CHECK:	cmp	r12, r13 +; CHECK:	mov	#1, r12 +; CHECK:	bic	r2, r12  define i16 @sccwuge(i16 %a, i16 %b) nounwind {  	%t1 = icmp uge i16 %a, %b @@ -64,9 +64,9 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccwuge: -; CHECK:	cmp.w	r13, r12 -; CHECK:	mov.w	r2, r12 -; CHECK:	and.w	#1, r12 +; CHECK:	cmp	r13, r12 +; CHECK:	mov	r2, r12 +; CHECK:	and	#1, r12  define i16 @sccwult(i16 %a, i16 %b) nounwind {  	%t1 = icmp ult i16 %a, %b @@ -74,9 +74,9 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccwult: -; CHECK:	cmp.w	r13, r12 -; CHECK:	mov.w	#1, r12 -; CHECK:	bic.w	r2, r12 +; CHECK:	cmp	r13, r12 +; CHECK:	mov	#1, r12 +; CHECK:	bic	r2, r12  define i16 @sccwule(i16 %a, i16 %b) nounwind {  	%t1 = icmp ule i16 %a, %b @@ -84,9 +84,9 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind {  	ret i16 %t2  }  ; CHECK-LABEL:sccwule: -; CHECK:	cmp.w	r12, r13 -; CHECK:	mov.w	r2, r12 -; CHECK:	and.w	#1, r12 +; CHECK:	cmp	r12, r13 +; CHECK:	mov	r2, r12 +; CHECK:	and	#1, r12  define i16 @sccwsgt(i16 %a, i16 %b) nounwind {  	%t1 = icmp sgt i16 %a, %b diff --git a/llvm/test/CodeGen/MSP430/shifts.ll b/llvm/test/CodeGen/MSP430/shifts.ll index 22ae59ef4b0..6d4050f42be 100644 --- a/llvm/test/CodeGen/MSP430/shifts.ll +++ b/llvm/test/CodeGen/MSP430/shifts.ll @@ -21,7 +21,7 @@ entry:  define zeroext i8 @shl8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {  entry:  ; CHECK: shl8 -; CHECK: rla.b +; CHECK: add.b    %shl = shl i8 %a, %cnt    ret i8 %shl  } @@ -29,7 +29,7 @@ entry:  define zeroext i16 @lshr16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {  entry:  ; CHECK-LABEL: lshr16: -; CHECK: rrc.w +; CHECK: rrc    %shr = lshr i16 %a, %cnt    ret i16 %shr  } @@ -37,7 +37,7 @@ entry:  define signext i16 @ashr16(i16 signext %a, i16 zeroext %cnt) nounwind readnone {  entry:  ; CHECK-LABEL: ashr16: -; CHECK: rra.w +; CHECK: rra    %shr = ashr i16 %a, %cnt    ret i16 %shr  } @@ -45,7 +45,7 @@ entry:  define zeroext i16 @shl16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {  entry:  ; CHECK-LABEL: shl16: -; CHECK: rla.w +; CHECK: add    %shl = shl i16 %a, %cnt    ret i16 %shl  } diff --git a/llvm/test/CodeGen/MSP430/struct-return.ll b/llvm/test/CodeGen/MSP430/struct-return.ll index c28bf06af43..a52ea1b702a 100644 --- a/llvm/test/CodeGen/MSP430/struct-return.ll +++ b/llvm/test/CodeGen/MSP430/struct-return.ll @@ -9,14 +9,14 @@ target triple = "msp430---elf"  define %s @fred() #0 {  ; CHECK-LABEL: fred: -; CHECK: mov.w	#2314, 14(r12) -; CHECK: mov.w	#2828, 12(r12) -; CHECK: mov.w	#3342, 10(r12) -; CHECK: mov.w	#3840, 8(r12) -; CHECK: mov.w	#258, 6(r12) -; CHECK: mov.w	#772, 4(r12) -; CHECK: mov.w	#1286, 2(r12) -; CHECK: mov.w	#1800, 0(r12) +; CHECK: mov	#2314, 14(r12) +; CHECK: mov	#2828, 12(r12) +; CHECK: mov	#3342, 10(r12) +; CHECK: mov	#3840, 8(r12) +; CHECK: mov	#258, 6(r12) +; CHECK: mov	#772, 4(r12) +; CHECK: mov	#1286, 2(r12) +; CHECK: mov	#1800, 0(r12)    ret %s {i64 72623859790382856, i64 651345242494996224}   } diff --git a/llvm/test/CodeGen/MSP430/struct_layout.ll b/llvm/test/CodeGen/MSP430/struct_layout.ll index 60ae9f09b4e..4c5a131acca 100644 --- a/llvm/test/CodeGen/MSP430/struct_layout.ll +++ b/llvm/test/CodeGen/MSP430/struct_layout.ll @@ -5,7 +5,7 @@ target triple = "msp430"  %struct.X = type { i8 }  ; CHECK-LABEL: @foo -; CHECK: sub.w   #4, r1 +; CHECK: sub   #4, r1  ; CHECK: mov.b   #1, 3(r1)  define void @foo() {    %1 = alloca %struct.X @@ -21,7 +21,7 @@ define void @foo() {  }  ; CHECK-LABEL: @bar -; CHECK: sub.w   #4, r1 +; CHECK: sub   #4, r1  ; CHECK: mov.b   #1, 3(r1)  define void @bar() {    %1 = alloca [3 x %struct.X] @@ -40,8 +40,8 @@ define void @bar() {  %struct.Y = type { i8, i16 }  ; CHECK-LABEL: @baz -; CHECK: sub.w   #8, r1 -; CHECK: mov.w   #2, 6(r1) +; CHECK: sub   #8, r1 +; CHECK: mov   #2, 6(r1)  define void @baz() {    %1 = alloca %struct.Y, align 2    %2 = alloca %struct.Y, align 2 diff --git a/llvm/test/CodeGen/MSP430/transient-stack-alignment.ll b/llvm/test/CodeGen/MSP430/transient-stack-alignment.ll index cca83509cf4..a2ddf8a0b08 100644 --- a/llvm/test/CodeGen/MSP430/transient-stack-alignment.ll +++ b/llvm/test/CodeGen/MSP430/transient-stack-alignment.ll @@ -5,11 +5,11 @@ target triple = "msp430---elf"  define void @test() #0 {  ; CHECK-LABEL: test: -; CHECK: sub.w #2, r1 +; CHECK: sub #2, r1    %1 = alloca i8, align 1 -; CHECK-NEXT: mov.b #0, 1(r1) +; CHECK-NEXT: clr.b 1(r1)    store i8 0, i8* %1, align 1 -; CHECK-NEXT: add.w #2, r1 +; CHECK-NEXT: add #2, r1  ; CHECK-NEXT: ret    ret void  } diff --git a/llvm/test/CodeGen/MSP430/vararg.ll b/llvm/test/CodeGen/MSP430/vararg.ll index 3501861f575..edb61d2221e 100644 --- a/llvm/test/CodeGen/MSP430/vararg.ll +++ b/llvm/test/CodeGen/MSP430/vararg.ll @@ -10,12 +10,12 @@ declare void @llvm.va_copy(i8*, i8*) nounwind  define void @va_start(i16 %a, ...) nounwind {  entry:  ; CHECK-LABEL: va_start: -; CHECK: sub.w #2, r1 +; CHECK: sub #2, r1    %vl = alloca i8*, align 2    %vl1 = bitcast i8** %vl to i8* -; CHECK-NEXT: mov.w r1, [[REG:r[0-9]+]] -; CHECK-NEXT: add.w #6, [[REG]] -; CHECK-NEXT: mov.w [[REG]], 0(r1) +; CHECK-NEXT: mov r1, [[REG:r[0-9]+]] +; CHECK-NEXT: add #6, [[REG]] +; CHECK-NEXT: mov [[REG]], 0(r1)    call void @llvm.va_start(i8* %vl1)    call void @llvm.va_end(i8* %vl1)    ret void @@ -26,11 +26,11 @@ entry:  ; CHECK-LABEL: va_arg:    %vl.addr = alloca i8*, align 2    store i8* %vl, i8** %vl.addr, align 2 -; CHECK: mov.w r12, [[REG:r[0-9]+]] -; CHECK-NEXT: add.w #2, [[REG]] -; CHECK-NEXT: mov.w [[REG]], 0(r1) +; CHECK: mov r12, [[REG:r[0-9]+]] +; CHECK-NEXT: incd [[REG]] +; CHECK-NEXT: mov [[REG]], 0(r1)    %0 = va_arg i8** %vl.addr, i16 -; CHECK-NEXT: mov.w 0(r12), r12 +; CHECK-NEXT: mov 0(r12), r12    ret i16 %0  } @@ -39,11 +39,11 @@ entry:  ; CHECK-LABEL: va_copy:    %vl.addr = alloca i8*, align 2    %vl2 = alloca i8*, align 2 -; CHECK-DAG: mov.w r12, 2(r1) +; CHECK-DAG: mov r12, 2(r1)    store i8* %vl, i8** %vl.addr, align 2    %0 = bitcast i8** %vl2 to i8*    %1 = bitcast i8** %vl.addr to i8* -; CHECK-DAG: mov.w r12, 0(r1) +; CHECK-DAG: mov r12, 0(r1)    call void @llvm.va_copy(i8* %0, i8* %1)    ret void  } diff --git a/llvm/test/MC/Disassembler/MSP430/lit.local.cfg b/llvm/test/MC/Disassembler/MSP430/lit.local.cfg new file mode 100644 index 00000000000..b1cf1fbd21d --- /dev/null +++ b/llvm/test/MC/Disassembler/MSP430/lit.local.cfg @@ -0,0 +1,3 @@ +if not 'MSP430' in config.root.targets: +    config.unsupported = True + diff --git a/llvm/test/MC/Disassembler/MSP430/msp430.txt b/llvm/test/MC/Disassembler/MSP430/msp430.txt new file mode 100644 index 00000000000..c7d6ff576da --- /dev/null +++ b/llvm/test/MC/Disassembler/MSP430/msp430.txt @@ -0,0 +1,27 @@ +# RUN: llvm-mc -disassemble %s -triple=msp430 | FileCheck %s +0x0f 0x47                     # CHECK: mov r7, r15 +0x2f 0x48                     # CHECK: mov @r8, r15 +0x3f 0x48                     # CHECK: mov @r8+, r15 +0x0f 0x43                     # CHECK: clr r15 +0x08 0x57                     # CHECK: add r7, r8 +0x28 0x57                     # CHECK: add @r7, r8 +0x38 0x57                     # CHECK: add @r7+, r8 +0x87 0x12                     # CHECK: call r7 +0x00 0x47                     # CHECK: br r7 +0x39 0xb2                     # CHECK: bit #8, r9 + +0xfe 0x3f                     # CHECK: jmp $-2 +0xfe 0x23                     # CHECK: jne $-2 + +0x3f 0x40 0x2a 0x00           # CHECK: mov #42, r15 +0x1f 0x48 0x2a 0x00           # CHECK: mov 42(r8), r15 +0x1f 0x42 0x2a 0x00           # CHECK: mov &42, r15 +0x1f 0x40 0x2a 0x00           # CHECK: mov 42, r15 +0xb0 0x12 0x81 0x01           # CHECK: call #385 +0x97 0x12 0x06 0x00           # CHECK: call 6(r7) +0xa7 0xb2 0x02 0x00           # CHECK: bit #34, 2(r7) +0xa9 0x57 0x08 0x00           # CHECK: add @r7, 8(r9) +0xb7 0xe7 0xfe 0xff           # CHECK: xor @r7+, -2(r7) + +0xbf 0x40 0x2a 0x00 0x0c 0x00 # CHECK: mov #42, 12(r15) +0x9a 0xb9 0x10 0x00 0x08 0x00 # CHECK: bit 16(r9), 8(r10) diff --git a/llvm/test/MC/MSP430/addrmode.s b/llvm/test/MC/MSP430/addrmode.s new file mode 100644 index 00000000000..46051c00fed --- /dev/null +++ b/llvm/test/MC/MSP430/addrmode.s @@ -0,0 +1,110 @@ +; RUN: llvm-mc -triple msp430 -show-encoding < %s | FileCheck %s + +foo: +  mov r8, r15 +  mov disp+2(r8), r15 +  mov disp+2, r15 +  mov &disp+2, r15 +  mov @r8, r15 +  mov @r8+, r15 +  mov #disp+2, r15 + +; CHECK: mov r8, r15           ; encoding: [0x0f,0x48] +; CHECK: mov disp+2(r8), r15   ; encoding: [0x1f,0x48,A,A] +; CHECK: mov disp+2, r15       ; encoding: [0x1f,0x40,A,A] +; CHECK: mov &disp+2, r15      ; encoding: [0x1f,0x42,A,A] +; CHECK: mov @r8, r15          ; encoding: [0x2f,0x48] +; CHECK: mov @r8+, r15         ; encoding: [0x3f,0x48] +; CHECK: mov #disp+2, r15      ; encoding: [0x3f,0x40,A,A] + +  mov #42, r15 +  mov #42, 12(r15) +  mov #42, &disp +  mov disp, disp+2 + +; CHECK: mov #42, r15          ; encoding: [0x3f,0x40,0x2a,0x00] +; CHECK: mov #42, 12(r15)      ; encoding: [0xbf,0x40,0x2a,0x00,0x0c,0x00] +; CHECK: mov #42, &disp        ; encoding: [0xb2,0x40,0x2a,0x00,A,A] +; CHECK: mov disp, disp+2      ; encoding: [0x90,0x40,A,A,B,B] + +  add r7, r8 +  add 6(r7), r8 +  add &disp, r8 +  add disp, r8 +  add @r9, r8 +  add @r9+, r8 +  add #42, r8 + +; CHECK: add r7, r8            ; encoding: [0x08,0x57] +; CHECK: add 6(r7), r8         ; encoding: [0x18,0x57,0x06,0x00] +; CHECK: add &disp, r8         ; encoding: [0x18,0x52,A,A] +; CHECK: add disp, r8          ; encoding: [0x18,0x50,A,A] +; CHECK: add @r9, r8           ; encoding: [0x28,0x59] +; CHECK: add @r9+, r8          ; encoding: [0x38,0x59] +; CHECK: add #42, r8           ; encoding: [0x38,0x50,0x2a,0x00] + +  add r7, 6(r5) +  add 6(r7), 6(r5) +  add &disp, 6(r5) +  add disp, 6(r5) +  add @r9, 6(r5) +  add @r9+, 6(r5) +  add #42, 6(r5) + +; CHECK: add r7, 6(r5)         ; encoding: [0x85,0x57,0x06,0x00] +; CHECK: add 6(r7), 6(r5)      ; encoding: [0x95,0x57,0x06,0x00,0x06,0x00] +; CHECK: add &disp, 6(r5)      ; encoding: [0x95,0x52,A,A,0x06,0x00] +; CHECK: add disp, 6(r5)       ; encoding: [0x95,0x50,A,A,0x06,0x00] +; CHECK: add @r9, 6(r5)        ; encoding: [0xa5,0x59,0x06,0x00] +; CHECK: add @r9+, 6(r5)       ; encoding: [0xb5,0x59,0x06,0x00] +; CHECK: add #42, 6(r5)        ; encoding: [0xb5,0x50,0x2a,0x00,0x06,0x00] + +  add r7, &disp +  add 6(r7), &disp +  add &disp, &disp +  add disp, &disp +  add @r9, &disp +  add @r9+, &disp +  add #42, &disp + +; CHECK: add r7, &disp         ; encoding: [0x82,0x57,A,A] +; CHECK: add 6(r7), &disp      ; encoding: [0x92,0x57,0x06,0x00,A,A] +; CHECK: add &disp, &disp      ; encoding: [0x92,0x52,A,A,B,B] +; CHECK: add disp, &disp       ; encoding: [0x92,0x50,A,A,B,B] +; CHECK: add @r9, &disp        ; encoding: [0xa2,0x59,A,A] +; CHECK: add @r9+, &disp       ; encoding: [0xb2,0x59,A,A] +; CHECK: add #42, &disp        ; encoding: [0xb2,0x50,0x2a,0x00,A,A] + +  add r7, disp +  add 6(r7), disp +  add &disp, disp +  add disp, disp +  add @r9, disp +  add @r9+, disp +  add #42, disp + +; CHECK: add r7, disp          ; encoding: [0x80,0x57,A,A] +; CHECK: add 6(r7), disp       ; encoding: [0x90,0x57,0x06,0x00,A,A] +; CHECK: add &disp, disp       ; encoding: [0x90,0x52,A,A,B,B] +; CHECK: add disp, disp        ; encoding: [0x90,0x50,A,A,B,B] +; CHECK: add @r9, disp         ; encoding: [0xa0,0x59,A,A] +; CHECK: add @r9+, disp        ; encoding: [0xb0,0x59,A,A] +; CHECK: add #42, disp         ; encoding: [0xb0,0x50,0x2a,0x00,A,A] + +  call r7 +  call 6(r7) +  call disp+6(r7) +  call &disp +  call disp +  call #disp + +; CHECK: call r7               ; encoding: [0x87,0x12] +; CHECK: call 6(r7)            ; encoding: [0x97,0x12,0x06,0x00] +; CHECK: call disp+6(r7)       ; encoding: [0x97,0x12,A,A] +; CHECK: call &disp            ; encoding: [0x92,0x12,A,A] +; CHECK: call disp             ; encoding: [0x90,0x12,A,A] +; CHECK: call #disp            ; encoding: [0xb0,0x12,A,A] + +disp: +  .word 0xcafe +  .word 0xbabe diff --git a/llvm/test/MC/MSP430/altreg.s b/llvm/test/MC/MSP430/altreg.s new file mode 100644 index 00000000000..fe1e3a43772 --- /dev/null +++ b/llvm/test/MC/MSP430/altreg.s @@ -0,0 +1,7 @@ +; RUN: llvm-mc -triple msp430 -show-encoding < %s | FileCheck %s +  mov pc, r0 ; CHECK: mov r0, r0 +  mov sp, r1 ; CHECK: mov r1, r1 +  mov sr, r2 ; CHECK: mov r2, r2 +  mov cg, r3 ; CHECK: mov r3, r3 +  mov fp, r4 ; CHECK: mov r4, r4 +  bic #8, SR ; CHECK: dint diff --git a/llvm/test/MC/MSP430/const.s b/llvm/test/MC/MSP430/const.s new file mode 100644 index 00000000000..f5cca109a50 --- /dev/null +++ b/llvm/test/MC/MSP430/const.s @@ -0,0 +1,10 @@ +; RUN: llvm-mc -triple msp430 -show-encoding < %s | FileCheck %s +  mov #4, r15 ; CHECK: mov #4, r15 ; encoding: [0x2f,0x42] +  mov #8, r15 ; CHECK: mov #8, r15 ; encoding: [0x3f,0x42] +  mov #0, r15 ; CHECK: clr r15     ; encoding: [0x0f,0x43] +  mov #1, r15 ; CHECK: mov #1, r15 ; encoding: [0x1f,0x43] +  mov #2, r15 ; CHECK: mov #2, r15 ; encoding: [0x2f,0x43] +  mov #-1, r7 ; CHECK: mov #-1, r7 ; encoding: [0x37,0x43] + +  push #8     ; CHECK: push #8     ; encoding: [0x32,0x12] +  push #42    ; CHECK: push #42    ; encoding: [0x30,0x12,0x2a,0x00] diff --git a/llvm/test/MC/MSP430/invalid.s b/llvm/test/MC/MSP430/invalid.s new file mode 100644 index 00000000000..2815b520dd5 --- /dev/null +++ b/llvm/test/MC/MSP430/invalid.s @@ -0,0 +1,19 @@ +; RUN: not llvm-mc -triple msp430 < %s 2>&1 | FileCheck %s +foo: +  ;; invalid operand count +  mov    r7        ; CHECK: :[[@LINE]]:3: error: too few operands for instruction + +  ;; invalid destination addressing modes +  mov    r7, @r15  ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction +  mov    r7, @r15+ ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction +  mov    r7, #0    ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction +  mov    r7, #123  ; CHECK: :[[@LINE]]:14: error: invalid operand for instruction + +  ;; invalid byte instructions +  swpb.b r7        ; CHECK: :[[@LINE]]:3: error: invalid instruction mnemonic +  sxt.b  r7        ; CHECK: :[[@LINE]]:3: error: invalid instruction mnemonic +  call.b r7        ; CHECK: :[[@LINE]]:3: error: invalid instruction mnemonic + +  ;; invalid conditional jump offsets +  jmp    -513      ; CHECK: :[[@LINE]]:10: error: invalid jump offset +  jmp    512       ; CHECK: :[[@LINE]]:10: error: invalid jump offset diff --git a/llvm/test/MC/MSP430/lit.local.cfg b/llvm/test/MC/MSP430/lit.local.cfg new file mode 100644 index 00000000000..b1cf1fbd21d --- /dev/null +++ b/llvm/test/MC/MSP430/lit.local.cfg @@ -0,0 +1,3 @@ +if not 'MSP430' in config.root.targets: +    config.unsupported = True + diff --git a/llvm/test/MC/MSP430/opcode.s b/llvm/test/MC/MSP430/opcode.s new file mode 100644 index 00000000000..14655fe091f --- /dev/null +++ b/llvm/test/MC/MSP430/opcode.s @@ -0,0 +1,163 @@ +; RUN: llvm-mc -triple msp430 -show-encoding %s \ +; RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s + +; RUN: llvm-mc -triple msp430 -filetype=obj %s \ +; RUN:     | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INST %s + +  ;; IForm8 instructions +  mov.b  r7, r8 ; CHECK-INST: mov.b  r7, r8 +                ; CHECK: encoding: [0x48,0x47] +  add.b  r7, r8 ; CHECK-INST: add.b  r7, r8 +                ; CHECK: encoding: [0x48,0x57] +  addc.b r7, r8 ; CHECK-INST: addc.b r7, r8 +                ; CHECK: encoding: [0x48,0x67] +  subc.b r7, r8 ; CHECK-INST: subc.b r7, r8 +                ; CHECK: encoding: [0x48,0x77] +  sub.b  r7, r8 ; CHECK-INST: sub.b  r7, r8 +                ; CHECK: encoding: [0x48,0x87] +  cmp.b  r7, r8 ; CHECK-INST: cmp.b  r7, r8 +                ; CHECK: encoding: [0x48,0x97] +  dadd.b r7, r8 ; CHECK-INST: dadd.b r7, r8 +                ; CHECK: encoding: [0x48,0xa7] +  bit.b  r7, r8 ; CHECK-INST: bit.b  r7, r8 +                ; CHECK: encoding: [0x48,0xb7] +  bic.b  r7, r8 ; CHECK-INST: bic.b  r7, r8 +                ; CHECK: encoding: [0x48,0xc7] +  bis.b  r7, r8 ; CHECK-INST: bis.b  r7, r8 +                ; CHECK: encoding: [0x48,0xd7] +  xor.b  r7, r8 ; CHECK-INST: xor.b  r7, r8 +                ; CHECK: encoding: [0x48,0xe7] +  and.b  r7, r8 ; CHECK-INST: and.b  r7, r8 +                ; CHECK: encoding: [0x48,0xf7] + +  ;; IForm16 instructions +  mov    r7, r8 ; CHECK-INST: mov    r7, r8 +                ; CHECK: encoding: [0x08,0x47] +  add    r7, r8 ; CHECK-INST: add    r7, r8 +                ; CHECK: encoding: [0x08,0x57] +  addc   r7, r8 ; CHECK-INST: addc   r7, r8 +                ; CHECK: encoding: [0x08,0x67] +  subc   r7, r8 ; CHECK-INST: subc   r7, r8 +                ; CHECK: encoding: [0x08,0x77] +  sub    r7, r8 ; CHECK-INST: sub    r7, r8 +                ; CHECK: encoding: [0x08,0x87] +  cmp    r7, r8 ; CHECK-INST: cmp    r7, r8 +                ; CHECK: encoding: [0x08,0x97] +  dadd   r7, r8 ; CHECK-INST: dadd   r7, r8 +                ; CHECK: encoding: [0x08,0xa7] +  bit    r7, r8 ; CHECK-INST: bit    r7, r8 +                ; CHECK: encoding: [0x08,0xb7] +  bic    r7, r8 ; CHECK-INST: bic    r7, r8 +                ; CHECK: encoding: [0x08,0xc7] +  bis    r7, r8 ; CHECK-INST: bis    r7, r8 +                ; CHECK: encoding: [0x08,0xd7] +  xor    r7, r8 ; CHECK-INST: xor    r7, r8 +                ; CHECK: encoding: [0x08,0xe7] +  and    r7, r8 ; CHECK-INST: and    r7, r8 +                ; CHECK: encoding: [0x08,0xf7] + +  ;; IIForm8 instructions +  rrc.b  r7     ; CHECK-INST: rrc.b  r7     +                ; CHECK: encoding: [0x47,0x10] +  rra.b  r7     ; CHECK-INST: rra.b  r7     +                ; CHECK: encoding: [0x47,0x11] +  push.b r7     ; CHECK-INST: push.b r7     +                ; CHECK: encoding: [0x47,0x12] + +  ;; IIForm16 instructions +  rrc    r7     ; CHECK-INST: rrc    r7     +                ; CHECK: encoding: [0x07,0x10] +  swpb   r7     ; CHECK-INST: swpb   r7     +                ; CHECK: encoding: [0x87,0x10] +  rra    r7     ; CHECK-INST: rra    r7     +                ; CHECK: encoding: [0x07,0x11] +  sxt    r7     ; CHECK-INST: sxt    r7     +                ; CHECK: encoding: [0x87,0x11] +  push   r7     ; CHECK-INST: push   r7     +                ; CHECK: encoding: [0x07,0x12] +  call   r7     ; CHECK-INST: call   r7     +                ; CHECK: encoding: [0x87,0x12] +  reti          ; CHECK-INST: reti          +                ; CHECK: encoding: [0x00,0x13] + +  ;; CJForm instructions +  jnz    -2     ; CHECK-INST: jne    $-2 +                ; CHECK: encoding: [0xfe,0x23] +  jne    -2     ; CHECK-INST: jne    $-2 +                ; CHECK: encoding: [0xfe,0x23] +  jeq    -2     ; CHECK-INST: jeq    $-2 +                ; CHECK: encoding: [0xfe,0x27] +  jz     -2     ; CHECK-INST: jeq    $-2 +                ; CHECK: encoding: [0xfe,0x27] +  jnc    -2     ; CHECK-INST: jlo    $-2 +                ; CHECK: encoding: [0xfe,0x2b] +  jlo    -2     ; CHECK-INST: jlo    $-2 +                ; CHECK: encoding: [0xfe,0x2b] +  jc     -2     ; CHECK-INST: jhs    $-2 +                ; CHECK: encoding: [0xfe,0x2f] +  jhs    -2     ; CHECK-INST: jhs    $-2 +                ; CHECK: encoding: [0xfe,0x2f] +  jn     -2     ; CHECK-INST: jn     $-2 +                ; CHECK: encoding: [0xfe,0x33] +  jge    -2     ; CHECK-INST: jge    $-2 +                ; CHECK: encoding: [0xfe,0x37] +  jl     -2     ; CHECK-INST: jl     $-2 +                ; CHECK: encoding: [0xfe,0x3b] +  jmp    $-2    ; CHECK-INST: jmp    $-2 +                ; CHECK: encoding: [0xfe,0x3f] + +  ;; Emulated arithmetic instructions +  adc    r7     ; CHECK-INST: adc    r7 +                ; CHECK: encoding: [0x07,0x63] +  dadc   r7     ; CHECK-INST: dadc   r7 +                ; CHECK: encoding: [0x07,0xa3] +  dec    r7     ; CHECK-INST: dec    r7 +                ; CHECK: encoding: [0x17,0x83] +  decd   r7     ; CHECK-INST: decd   r7 +                ; CHECK: encoding: [0x27,0x83] +  inc    r7     ; CHECK-INST: inc    r7 +                ; CHECK: encoding: [0x17,0x53] +  incd   r7     ; CHECK-INST: incd   r7 +                ; CHECK: encoding: [0x27,0x53] +  sbc    r7     ; CHECK-INST: sbc    r7 +                ; CHECK: encoding: [0x07,0x73] + +  ;; Emulated logical instructions +  inv    r7     ; CHECK-INST: inv    r7 +                ; CHECK: encoding: [0x37,0xe3] +  rla    r7     ; CHECK-INST: add    r7, r7 +                ; CHECK: encoding: [0x07,0x57] +  rlc    r7     ; CHECK-INST: addc   r7, r7 +                ; CHECK: encoding: [0x07,0x67] + +  ;; Emulated program flow control instructions +  br     r7     ; CHECK-INST: br     r7     +                ; CHECK: encoding: [0x00,0x47] +  dint          ; CHECK-INST: dint +                ; CHECK: encoding: [0x32,0xc2] +  eint          ; CHECK-INST: eint +                ; CHECK: encoding: [0x32,0xd2] +  nop           ; CHECK-INST: nop +                ; CHECK: encoding: [0x03,0x43] +  ret           ; CHECK-INST: ret           +                ; CHECK: encoding: [0x30,0x41] + +  ;; Emulated data instruction +  clr    r7     ; CHECK-INST: clr    r7 +                ; CHECK: encoding: [0x07,0x43] +  clrc          ; CHECK-INST: clrc +                ; CHECK: encoding: [0x12,0xc3] +  clrn          ; CHECK-INST: clrn +                ; CHECK: encoding: [0x22,0xc2] +  clrz          ; CHECK-INST: clrz +                ; CHECK: encoding: [0x22,0xc3] +  pop    r7     ; CHECK-INST: pop    r7 +                ; CHECK: encoding: [0x37,0x41] +  setc          ; CHECK-INST: setc +                ; CHECK: encoding: [0x12,0xd3] +  setn          ; CHECK-INST: setn +                ; CHECK: encoding: [0x22,0xd2] +  setz          ; CHECK-INST: setz +                ; CHECK: encoding: [0x22,0xd3] +  tst    r7     ; CHECK-INST: tst    r7 +                ; CHECK: encoding: [0x07,0x93] diff --git a/llvm/test/MC/MSP430/reloc.s b/llvm/test/MC/MSP430/reloc.s new file mode 100644 index 00000000000..42dd64a43c5 --- /dev/null +++ b/llvm/test/MC/MSP430/reloc.s @@ -0,0 +1,22 @@ +; RUN: llvm-mc -triple msp430 -show-encoding < %s | FileCheck %s + +         mov    disp+2(r8), r15 +; CHECK: mov    disp+2(r8), r15 ; encoding: [0x1f,0x48,A,A] +; CHECK:                        ;   fixup A - offset: 2, value: disp+2, kind: fixup_16_byte + +         mov    disp+2, r15 +; CHECK: mov    disp+2, r15     ; encoding: [0x1f,0x40,A,A] +; CHECK:                        ;   fixup A - offset: 2, value: disp+2, kind: fixup_16_pcrel_byte + +         mov    &disp+2, r15 +; CHECK: mov    &disp+2, r15    ; encoding: [0x1f,0x42,A,A] +; CHECK:                        ;   fixup A - offset: 2, value: disp+2, kind: fixup_16 + +         mov    disp, disp+2 +; CHECK: mov    disp, disp+2    ; encoding: [0x90,0x40,A,A,B,B] +; CHECK:                        ;   fixup A - offset: 2, value: disp, kind: fixup_16_pcrel_byte +; CHECK:                        ;   fixup B - offset: 4, value: disp+2, kind: fixup_16_pcrel_byte + +         jmp    foo +; CHECK: jmp    foo             ; encoding: [A,0b001111AA] +; CHECK:                        ;   fixup A - offset: 0, value: foo, kind: fixup_10_pcrel  | 

