diff options
Diffstat (limited to 'llvm/lib/Target/MSP430/MCTargetDesc')
5 files changed, 582 insertions, 0 deletions
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..adf2384f6e9 --- /dev/null +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp @@ -0,0 +1,211 @@ +//===-- 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); +  size_t WordCount = Size / 2; + +  while (WordCount--) { +    support::endian::write(OS, (uint16_t)BinaryOpCode, support::little); +    BinaryOpCode >>= 16; +  } +} + +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  | 

