Skip to content

Commit

Permalink
[MSP430] Add MC layer
Browse files Browse the repository at this point in the history
Reapply r346374 with the fixes for modules build.

Original summary:

This change implements assembler parser, code emitter, ELF object writer
and disassembler for the MSP430 ISA.  Also, more instruction forms are added
to the target description.

Patch by Michael Skvortsov!

llvm-svn: 346948
  • Loading branch information
asl committed Nov 15, 2018
1 parent 5e7486f commit 49045c6
Show file tree
Hide file tree
Showing 61 changed files with 1,740 additions and 1,309 deletions.
34 changes: 34 additions & 0 deletions llvm/include/llvm/BinaryFormat/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Object/ELFObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Object/ELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/MSP430/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)

Expand All @@ -26,3 +29,5 @@ add_llvm_target(MSP430CodeGen
add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)
add_subdirectory(AsmParser)
add_subdirectory(Disassembler)
36 changes: 29 additions & 7 deletions llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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())
Expand All @@ -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();
Expand All @@ -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;
}
}
7 changes: 7 additions & 0 deletions llvm/lib/Target/MSP430/InstPrinter/MSP430InstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

};
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/MSP430/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/MSP430/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
add_llvm_library(LLVMMSP430Desc
MSP430MCTargetDesc.cpp
MSP430AsmBackend.cpp
MSP430ELFObjectWriter.cpp
MSP430ELFStreamer.cpp
MSP430MCAsmInfo.cpp
MSP430MCCodeEmitter.cpp
MSP430MCTargetDesc.cpp
)
27 changes: 10 additions & 17 deletions llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
27 changes: 27 additions & 0 deletions llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/MSP430/MSP430.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/MSP430/MSP430.td
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}

Loading

0 comments on commit 49045c6

Please sign in to comment.