mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-16 18:35:53 +00:00
Revert "[MSP430] Add MC layer"
This commit broke the module buildbots. Error: lib/Target/MSP430/MSP430GenAsmMatcher.inc:1027:1: error: redundant namespace 'llvm' [-Wmodules-import-nested-redundant] ^ git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346410 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6355fcebb3
commit
d1851a2b7a
@ -729,38 +729,6 @@ enum {
|
|||||||
#include "ELFRelocs/BPF.def"
|
#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
|
#undef ELF_RELOC
|
||||||
|
|
||||||
// Section header.
|
// Section header.
|
||||||
@ -865,8 +833,6 @@ enum : unsigned {
|
|||||||
SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
|
SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
|
||||||
SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
|
SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
|
||||||
|
|
||||||
SHT_MSP430_ATTRIBUTES = 0x70000003U,
|
|
||||||
|
|
||||||
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
|
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
|
||||||
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
|
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
|
||||||
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
|
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
#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)
|
|
@ -1021,8 +1021,6 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
|
|||||||
return "ELF32-lanai";
|
return "ELF32-lanai";
|
||||||
case ELF::EM_MIPS:
|
case ELF::EM_MIPS:
|
||||||
return "ELF32-mips";
|
return "ELF32-mips";
|
||||||
case ELF::EM_MSP430:
|
|
||||||
return "ELF32-msp430";
|
|
||||||
case ELF::EM_PPC:
|
case ELF::EM_PPC:
|
||||||
return "ELF32-ppc";
|
return "ELF32-ppc";
|
||||||
case ELF::EM_RISCV:
|
case ELF::EM_RISCV:
|
||||||
@ -1093,8 +1091,6 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
|
|||||||
default:
|
default:
|
||||||
report_fatal_error("Invalid ELFCLASS!");
|
report_fatal_error("Invalid ELFCLASS!");
|
||||||
}
|
}
|
||||||
case ELF::EM_MSP430:
|
|
||||||
return Triple::msp430;
|
|
||||||
case ELF::EM_PPC:
|
case ELF::EM_PPC:
|
||||||
return Triple::ppc;
|
return Triple::ppc;
|
||||||
case ELF::EM_PPC64:
|
case ELF::EM_PPC64:
|
||||||
|
@ -52,7 +52,6 @@ module LLVM_BinaryFormat {
|
|||||||
textual header "BinaryFormat/ELFRelocs/i386.def"
|
textual header "BinaryFormat/ELFRelocs/i386.def"
|
||||||
textual header "BinaryFormat/ELFRelocs/Lanai.def"
|
textual header "BinaryFormat/ELFRelocs/Lanai.def"
|
||||||
textual header "BinaryFormat/ELFRelocs/Mips.def"
|
textual header "BinaryFormat/ELFRelocs/Mips.def"
|
||||||
textual header "BinaryFormat/ELFRelocs/MSP430.def"
|
|
||||||
textual header "BinaryFormat/ELFRelocs/PowerPC64.def"
|
textual header "BinaryFormat/ELFRelocs/PowerPC64.def"
|
||||||
textual header "BinaryFormat/ELFRelocs/PowerPC.def"
|
textual header "BinaryFormat/ELFRelocs/PowerPC.def"
|
||||||
textual header "BinaryFormat/ELFRelocs/RISCV.def"
|
textual header "BinaryFormat/ELFRelocs/RISCV.def"
|
||||||
|
@ -139,13 +139,6 @@ StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ELF::EM_MSP430:
|
|
||||||
switch (Type) {
|
|
||||||
#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
add_llvm_library(LLVMMSP430AsmParser
|
|
||||||
MSP430AsmParser.cpp
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
;===- 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
|
|
@ -1,562 +0,0 @@
|
|||||||
//===- 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
|
|
@ -1,12 +1,9 @@
|
|||||||
set(LLVM_TARGET_DEFINITIONS MSP430.td)
|
set(LLVM_TARGET_DEFINITIONS MSP430.td)
|
||||||
|
|
||||||
tablegen(LLVM MSP430GenAsmMatcher.inc -gen-asm-matcher)
|
|
||||||
tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer)
|
tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer)
|
||||||
tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv)
|
tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv)
|
||||||
tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel)
|
tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel)
|
||||||
tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler)
|
|
||||||
tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
|
tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
|
||||||
tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter)
|
|
||||||
tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
|
tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
|
||||||
tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget)
|
tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget)
|
||||||
|
|
||||||
@ -29,5 +26,3 @@ add_llvm_target(MSP430CodeGen
|
|||||||
add_subdirectory(InstPrinter)
|
add_subdirectory(InstPrinter)
|
||||||
add_subdirectory(MCTargetDesc)
|
add_subdirectory(MCTargetDesc)
|
||||||
add_subdirectory(TargetInfo)
|
add_subdirectory(TargetInfo)
|
||||||
add_subdirectory(AsmParser)
|
|
||||||
add_subdirectory(Disassembler)
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
add_llvm_library(LLVMMSP430Disassembler
|
|
||||||
MSP430Disassembler.cpp
|
|
||||||
)
|
|
@ -1,23 +0,0 @@
|
|||||||
;====- 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
|
|
@ -1,375 +0,0 @@
|
|||||||
//===-- 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,20 +16,18 @@
|
|||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
#include "llvm/MC/MCInstrInfo.h"
|
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/FormattedStream.h"
|
#include "llvm/Support/FormattedStream.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
#define DEBUG_TYPE "asm-printer"
|
#define DEBUG_TYPE "asm-printer"
|
||||||
|
|
||||||
|
|
||||||
// Include the auto-generated portion of the assembly writer.
|
// Include the auto-generated portion of the assembly writer.
|
||||||
#define PRINT_ALIAS_INSTR
|
|
||||||
#include "MSP430GenAsmWriter.inc"
|
#include "MSP430GenAsmWriter.inc"
|
||||||
|
|
||||||
void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||||
StringRef Annot, const MCSubtargetInfo &STI) {
|
StringRef Annot, const MCSubtargetInfo &STI) {
|
||||||
if (!printAliasInstr(MI, O))
|
|
||||||
printInstruction(MI, O);
|
printInstruction(MI, O);
|
||||||
printAnnotation(O, Annot);
|
printAnnotation(O, Annot);
|
||||||
}
|
}
|
||||||
@ -37,13 +35,9 @@ void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
|||||||
void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo,
|
void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
const MCOperand &Op = MI->getOperand(OpNo);
|
const MCOperand &Op = MI->getOperand(OpNo);
|
||||||
if (Op.isImm()) {
|
if (Op.isImm())
|
||||||
int64_t Imm = Op.getImm() * 2 + 2;
|
O << Op.getImm();
|
||||||
O << "$";
|
else {
|
||||||
if (Imm >= 0)
|
|
||||||
O << '+';
|
|
||||||
O << Imm;
|
|
||||||
} else {
|
|
||||||
assert(Op.isExpr() && "unknown pcrel immediate operand");
|
assert(Op.isExpr() && "unknown pcrel immediate operand");
|
||||||
Op.getExpr()->print(O, &MAI);
|
Op.getExpr()->print(O, &MAI);
|
||||||
}
|
}
|
||||||
@ -78,7 +72,7 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
// vs
|
// vs
|
||||||
// mov.w glb(r1), r2
|
// mov.w glb(r1), r2
|
||||||
// Otherwise (!) msp430-as will silently miscompile the output :(
|
// Otherwise (!) msp430-as will silently miscompile the output :(
|
||||||
if (Base.getReg() == MSP430::SR)
|
if (!Base.getReg())
|
||||||
O << '&';
|
O << '&';
|
||||||
|
|
||||||
if (Disp.isExpr())
|
if (Disp.isExpr())
|
||||||
@ -89,23 +83,10 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print register base field
|
// Print register base field
|
||||||
if ((Base.getReg() != MSP430::SR) &&
|
if (Base.getReg())
|
||||||
(Base.getReg() != MSP430::PC))
|
|
||||||
O << '(' << getRegisterName(Base.getReg()) << ')';
|
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,
|
void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
unsigned CC = MI->getOperand(OpNo).getImm();
|
unsigned CC = MI->getOperand(OpNo).getImm();
|
||||||
@ -131,8 +112,5 @@ void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
case MSP430CC::COND_L:
|
case MSP430CC::COND_L:
|
||||||
O << 'l';
|
O << 'l';
|
||||||
break;
|
break;
|
||||||
case MSP430CC::COND_N:
|
|
||||||
O << 'n';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,20 +28,13 @@ namespace llvm {
|
|||||||
|
|
||||||
// Autogenerated by tblgen.
|
// Autogenerated by tblgen.
|
||||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
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);
|
static const char *getRegisterName(unsigned RegNo);
|
||||||
|
|
||||||
private:
|
|
||||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
||||||
const char *Modifier = nullptr);
|
const char *Modifier = nullptr);
|
||||||
void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
||||||
const char *Modifier = nullptr);
|
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);
|
void printCCOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -16,15 +16,13 @@
|
|||||||
;===------------------------------------------------------------------------===;
|
;===------------------------------------------------------------------------===;
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
|
subdirectories = InstPrinter MCTargetDesc TargetInfo
|
||||||
|
|
||||||
[component_0]
|
[component_0]
|
||||||
type = TargetGroup
|
type = TargetGroup
|
||||||
name = MSP430
|
name = MSP430
|
||||||
parent = Target
|
parent = Target
|
||||||
has_asmparser = 1
|
|
||||||
has_asmprinter = 1
|
has_asmprinter = 1
|
||||||
has_disassembler = 1
|
|
||||||
|
|
||||||
[component_1]
|
[component_1]
|
||||||
type = Library
|
type = Library
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
add_llvm_library(LLVMMSP430Desc
|
add_llvm_library(LLVMMSP430Desc
|
||||||
MSP430AsmBackend.cpp
|
|
||||||
MSP430ELFObjectWriter.cpp
|
|
||||||
MSP430ELFStreamer.cpp
|
|
||||||
MSP430MCAsmInfo.cpp
|
|
||||||
MSP430MCCodeEmitter.cpp
|
|
||||||
MSP430MCTargetDesc.cpp
|
MSP430MCTargetDesc.cpp
|
||||||
|
MSP430MCAsmInfo.cpp
|
||||||
)
|
)
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
//===-- 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);
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
//===-- 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);
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
//===-- 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
|
|
@ -1,53 +0,0 @@
|
|||||||
//===-- 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
|
|
@ -1,211 +0,0 @@
|
|||||||
//===-- 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
|
|
@ -58,15 +58,22 @@ static MCInstPrinter *createMSP430MCInstPrinter(const Triple &T,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LLVMInitializeMSP430TargetMC() {
|
extern "C" void LLVMInitializeMSP430TargetMC() {
|
||||||
Target &T = getTheMSP430Target();
|
// Register the MC asm info.
|
||||||
|
RegisterMCAsmInfo<MSP430MCAsmInfo> X(getTheMSP430Target());
|
||||||
|
|
||||||
RegisterMCAsmInfo<MSP430MCAsmInfo> X(T);
|
// Register the MC instruction info.
|
||||||
TargetRegistry::RegisterMCInstrInfo(T, createMSP430MCInstrInfo);
|
TargetRegistry::RegisterMCInstrInfo(getTheMSP430Target(),
|
||||||
TargetRegistry::RegisterMCRegInfo(T, createMSP430MCRegisterInfo);
|
createMSP430MCInstrInfo);
|
||||||
TargetRegistry::RegisterMCSubtargetInfo(T, createMSP430MCSubtargetInfo);
|
|
||||||
TargetRegistry::RegisterMCInstPrinter(T, createMSP430MCInstPrinter);
|
// Register the MC register info.
|
||||||
TargetRegistry::RegisterMCCodeEmitter(T, createMSP430MCCodeEmitter);
|
TargetRegistry::RegisterMCRegInfo(getTheMSP430Target(),
|
||||||
TargetRegistry::RegisterMCAsmBackend(T, createMSP430MCAsmBackend);
|
createMSP430MCRegisterInfo);
|
||||||
TargetRegistry::RegisterObjectTargetStreamer(
|
|
||||||
T, createMSP430ObjectTargetStreamer);
|
// Register the MC subtarget info.
|
||||||
|
TargetRegistry::RegisterMCSubtargetInfo(getTheMSP430Target(),
|
||||||
|
createMSP430MCSubtargetInfo);
|
||||||
|
|
||||||
|
// Register the MCInstPrinter.
|
||||||
|
TargetRegistry::RegisterMCInstPrinter(getTheMSP430Target(),
|
||||||
|
createMSP430MCInstPrinter);
|
||||||
}
|
}
|
||||||
|
@ -15,39 +15,12 @@
|
|||||||
#define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430MCTARGETDESC_H
|
#define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430MCTARGETDESC_H
|
||||||
|
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Target;
|
class Target;
|
||||||
class MCAsmBackend;
|
|
||||||
class MCCodeEmitter;
|
|
||||||
class MCInstrInfo;
|
|
||||||
class MCSubtargetInfo;
|
|
||||||
class MCRegisterInfo;
|
|
||||||
class MCContext;
|
|
||||||
class MCTargetOptions;
|
|
||||||
class MCObjectTargetWriter;
|
|
||||||
class MCStreamer;
|
|
||||||
class MCTargetStreamer;
|
|
||||||
|
|
||||||
Target &getTheMSP430Target();
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
// Defines symbolic names for MSP430 registers.
|
// Defines symbolic names for MSP430 registers.
|
||||||
|
@ -27,8 +27,6 @@ namespace MSP430CC {
|
|||||||
COND_LO = 3, // aka COND_NC
|
COND_LO = 3, // aka COND_NC
|
||||||
COND_GE = 4,
|
COND_GE = 4,
|
||||||
COND_L = 5,
|
COND_L = 5,
|
||||||
COND_N = 6, // jump if negative
|
|
||||||
COND_NONE, // unconditional
|
|
||||||
|
|
||||||
COND_INVALID = -1
|
COND_INVALID = -1
|
||||||
};
|
};
|
||||||
|
@ -64,29 +64,11 @@ include "MSP430InstrInfo.td"
|
|||||||
|
|
||||||
def MSP430InstrInfo : InstrInfo;
|
def MSP430InstrInfo : InstrInfo;
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
// Assembly Printers
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def MSP430AsmWriter : AsmWriter {
|
|
||||||
string AsmWriterClassName = "InstPrinter";
|
|
||||||
}
|
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
// Assembly Parsers
|
|
||||||
//===---------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
def MSP430AsmParser : AsmParser {
|
|
||||||
let AllowDuplicateRegisterNames = 1;
|
|
||||||
let ShouldEmitMatchRegisterAltName = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Target Declaration
|
// Target Declaration
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def MSP430 : Target {
|
def MSP430 : Target {
|
||||||
let InstructionSet = MSP430InstrInfo;
|
let InstructionSet = MSP430InstrInfo;
|
||||||
let AssemblyParsers = [MSP430AsmParser];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ namespace {
|
|||||||
MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
|
MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
|
||||||
: SelectionDAGISel(TM, OptLevel) {}
|
: SelectionDAGISel(TM, OptLevel) {}
|
||||||
|
|
||||||
private:
|
|
||||||
StringRef getPassName() const override {
|
StringRef getPassName() const override {
|
||||||
return "MSP430 DAG->DAG Pattern Instruction Selection";
|
return "MSP430 DAG->DAG Pattern Instruction Selection";
|
||||||
}
|
}
|
||||||
@ -113,9 +112,8 @@ namespace {
|
|||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
#include "MSP430GenDAGISel.inc"
|
#include "MSP430GenDAGISel.inc"
|
||||||
|
|
||||||
// Main method to transform nodes into machine nodes.
|
private:
|
||||||
void Select(SDNode *N) override;
|
void Select(SDNode *N) override;
|
||||||
|
|
||||||
bool tryIndexedLoad(SDNode *Op);
|
bool tryIndexedLoad(SDNode *Op);
|
||||||
bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8,
|
bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8,
|
||||||
unsigned Opc16);
|
unsigned Opc16);
|
||||||
@ -252,9 +250,11 @@ bool MSP430DAGToDAGISel::SelectAddr(SDValue N,
|
|||||||
if (MatchAddress(N, AM))
|
if (MatchAddress(N, AM))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (AM.BaseType == MSP430ISelAddressMode::RegBase)
|
EVT VT = N.getValueType();
|
||||||
|
if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
|
||||||
if (!AM.Base.Reg.getNode())
|
if (!AM.Base.Reg.getNode())
|
||||||
AM.Base.Reg = CurDAG->getRegister(MSP430::SR, MVT::i16);
|
AM.Base.Reg = CurDAG->getRegister(0, VT);
|
||||||
|
}
|
||||||
|
|
||||||
Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
|
Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
|
||||||
? CurDAG->getTargetFrameIndex(
|
? CurDAG->getTargetFrameIndex(
|
||||||
@ -336,10 +336,10 @@ bool MSP430DAGToDAGISel::tryIndexedLoad(SDNode *N) {
|
|||||||
unsigned Opcode = 0;
|
unsigned Opcode = 0;
|
||||||
switch (VT.SimpleTy) {
|
switch (VT.SimpleTy) {
|
||||||
case MVT::i8:
|
case MVT::i8:
|
||||||
Opcode = MSP430::MOV8rp;
|
Opcode = MSP430::MOV8rm_POST;
|
||||||
break;
|
break;
|
||||||
case MVT::i16:
|
case MVT::i16:
|
||||||
Opcode = MSP430::MOV16rp;
|
Opcode = MSP430::MOV16rm_POST;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -412,47 +412,47 @@ void MSP430DAGToDAGISel::Select(SDNode *Node) {
|
|||||||
break;
|
break;
|
||||||
case ISD::ADD:
|
case ISD::ADD:
|
||||||
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
||||||
MSP430::ADD8rp, MSP430::ADD16rp))
|
MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
|
||||||
return;
|
return;
|
||||||
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
||||||
MSP430::ADD8rp, MSP430::ADD16rp))
|
MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
case ISD::SUB:
|
case ISD::SUB:
|
||||||
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
||||||
MSP430::SUB8rp, MSP430::SUB16rp))
|
MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
||||||
MSP430::AND8rp, MSP430::AND16rp))
|
MSP430::AND8rm_POST, MSP430::AND16rm_POST))
|
||||||
return;
|
return;
|
||||||
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
||||||
MSP430::AND8rp, MSP430::AND16rp))
|
MSP430::AND8rm_POST, MSP430::AND16rm_POST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
||||||
MSP430::BIS8rp, MSP430::BIS16rp))
|
MSP430::OR8rm_POST, MSP430::OR16rm_POST))
|
||||||
return;
|
return;
|
||||||
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
||||||
MSP430::BIS8rp, MSP430::BIS16rp))
|
MSP430::OR8rm_POST, MSP430::OR16rm_POST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
break;
|
break;
|
||||||
case ISD::XOR:
|
case ISD::XOR:
|
||||||
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
|
||||||
MSP430::XOR8rp, MSP430::XOR16rp))
|
MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
|
||||||
return;
|
return;
|
||||||
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
|
||||||
MSP430::XOR8rp, MSP430::XOR16rp))
|
MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Other cases are autogenerated.
|
// Other cases are autogenerated.
|
||||||
|
@ -940,7 +940,18 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
|
|||||||
|
|
||||||
// Expand non-constant shifts to loops:
|
// Expand non-constant shifts to loops:
|
||||||
if (!isa<ConstantSDNode>(N->getOperand(1)))
|
if (!isa<ConstantSDNode>(N->getOperand(1)))
|
||||||
return Op;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
|
uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
|
||||||
|
|
||||||
@ -952,7 +963,7 @@ SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
|
|||||||
if (Opc == ISD::SRL && ShiftAmount) {
|
if (Opc == ISD::SRL && ShiftAmount) {
|
||||||
// Emit a special goodness here:
|
// Emit a special goodness here:
|
||||||
// srl A, 1 => clrc; rrc A
|
// srl A, 1 => clrc; rrc A
|
||||||
Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim);
|
Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
|
||||||
ShiftAmount -= 1;
|
ShiftAmount -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,14 +1342,15 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case MSP430ISD::RRA: return "MSP430ISD::RRA";
|
case MSP430ISD::RRA: return "MSP430ISD::RRA";
|
||||||
case MSP430ISD::RLA: return "MSP430ISD::RLA";
|
case MSP430ISD::RLA: return "MSP430ISD::RLA";
|
||||||
case MSP430ISD::RRC: return "MSP430ISD::RRC";
|
case MSP430ISD::RRC: return "MSP430ISD::RRC";
|
||||||
case MSP430ISD::RRCL: return "MSP430ISD::RRCL";
|
|
||||||
case MSP430ISD::CALL: return "MSP430ISD::CALL";
|
case MSP430ISD::CALL: return "MSP430ISD::CALL";
|
||||||
case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
|
case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
|
||||||
case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
|
case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
|
||||||
case MSP430ISD::CMP: return "MSP430ISD::CMP";
|
case MSP430ISD::CMP: return "MSP430ISD::CMP";
|
||||||
case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
|
case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
|
||||||
case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
|
case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
|
||||||
case MSP430ISD::DADD: return "MSP430ISD::DADD";
|
case MSP430ISD::SHL: return "MSP430ISD::SHL";
|
||||||
|
case MSP430ISD::SRA: return "MSP430ISD::SRA";
|
||||||
|
case MSP430ISD::SRL: return "MSP430ISD::SRL";
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1385,49 +1397,33 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI,
|
|||||||
const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
|
const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
|
||||||
|
|
||||||
unsigned Opc;
|
unsigned Opc;
|
||||||
bool ClearCarry = false;
|
|
||||||
const TargetRegisterClass * RC;
|
const TargetRegisterClass * RC;
|
||||||
switch (MI.getOpcode()) {
|
switch (MI.getOpcode()) {
|
||||||
default: llvm_unreachable("Invalid shift opcode!");
|
default: llvm_unreachable("Invalid shift opcode!");
|
||||||
case MSP430::Shl8:
|
case MSP430::Shl8:
|
||||||
Opc = MSP430::ADD8rr;
|
Opc = MSP430::SHL8r1;
|
||||||
RC = &MSP430::GR8RegClass;
|
RC = &MSP430::GR8RegClass;
|
||||||
break;
|
break;
|
||||||
case MSP430::Shl16:
|
case MSP430::Shl16:
|
||||||
Opc = MSP430::ADD16rr;
|
Opc = MSP430::SHL16r1;
|
||||||
RC = &MSP430::GR16RegClass;
|
RC = &MSP430::GR16RegClass;
|
||||||
break;
|
break;
|
||||||
case MSP430::Sra8:
|
case MSP430::Sra8:
|
||||||
Opc = MSP430::RRA8r;
|
Opc = MSP430::SAR8r1;
|
||||||
RC = &MSP430::GR8RegClass;
|
RC = &MSP430::GR8RegClass;
|
||||||
break;
|
break;
|
||||||
case MSP430::Sra16:
|
case MSP430::Sra16:
|
||||||
Opc = MSP430::RRA16r;
|
Opc = MSP430::SAR16r1;
|
||||||
RC = &MSP430::GR16RegClass;
|
RC = &MSP430::GR16RegClass;
|
||||||
break;
|
break;
|
||||||
case MSP430::Srl8:
|
case MSP430::Srl8:
|
||||||
ClearCarry = true;
|
Opc = MSP430::SAR8r1c;
|
||||||
Opc = MSP430::RRC8r;
|
|
||||||
RC = &MSP430::GR8RegClass;
|
RC = &MSP430::GR8RegClass;
|
||||||
break;
|
break;
|
||||||
case MSP430::Srl16:
|
case MSP430::Srl16:
|
||||||
ClearCarry = true;
|
Opc = MSP430::SAR16r1c;
|
||||||
Opc = MSP430::RRC16r;
|
|
||||||
RC = &MSP430::GR16RegClass;
|
RC = &MSP430::GR16RegClass;
|
||||||
break;
|
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();
|
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||||
@ -1480,14 +1476,6 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI,
|
|||||||
BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
|
BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
|
||||||
.addReg(ShiftAmtSrcReg).addMBB(BB)
|
.addReg(ShiftAmtSrcReg).addMBB(BB)
|
||||||
.addReg(ShiftAmtReg2).addMBB(LoopBB);
|
.addReg(ShiftAmtReg2).addMBB(LoopBB);
|
||||||
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)
|
BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
|
||||||
.addReg(ShiftReg);
|
.addReg(ShiftReg);
|
||||||
BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
|
BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
|
||||||
@ -1513,8 +1501,7 @@ MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
|||||||
|
|
||||||
if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
|
if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
|
||||||
Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
|
Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
|
||||||
Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
|
Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
|
||||||
Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
|
|
||||||
return EmitShiftInstr(MI, BB);
|
return EmitShiftInstr(MI, BB);
|
||||||
|
|
||||||
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
|
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
|
||||||
|
@ -36,9 +36,6 @@ namespace llvm {
|
|||||||
/// Y = RRC X, rotate right via carry
|
/// Y = RRC X, rotate right via carry
|
||||||
RRC,
|
RRC,
|
||||||
|
|
||||||
/// Rotate right via carry, carry gets cleared beforehand by clrc
|
|
||||||
RRCL,
|
|
||||||
|
|
||||||
/// CALL - These operations represent an abstract call
|
/// CALL - These operations represent an abstract call
|
||||||
/// instruction, which includes a bunch of information.
|
/// instruction, which includes a bunch of information.
|
||||||
CALL,
|
CALL,
|
||||||
@ -64,9 +61,8 @@ namespace llvm {
|
|||||||
/// is condition code and operand 4 is flag operand.
|
/// is condition code and operand 4 is flag operand.
|
||||||
SELECT_CC,
|
SELECT_CC,
|
||||||
|
|
||||||
/// DADD - Decimal addition with carry
|
/// SHL, SRA, SRL - Non-constant shifts.
|
||||||
/// TODO Nothing generates a node of this type yet.
|
SHL, SRA, SRL
|
||||||
DADD,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,431 +11,201 @@
|
|||||||
// Describe MSP430 instructions format here
|
// 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> {
|
class SourceMode<bits<2> val> {
|
||||||
bits<2> Value = val;
|
bits<2> Value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
def SrcReg : SourceMode<0>; // r
|
def SrcReg : SourceMode<0>;
|
||||||
def SrcMem : SourceMode<1>; // m
|
def SrcMem : SourceMode<1>;
|
||||||
def SrcIndReg : SourceMode<2>; // n
|
def SrcIndReg : SourceMode<2>;
|
||||||
def SrcPostInc : SourceMode<3>; // p
|
def SrcPostInc : SourceMode<3>;
|
||||||
def SrcImm : SourceMode<3>; // i
|
def SrcImm : SourceMode<3>;
|
||||||
// SrcCGImm : SourceMode< >; // c
|
|
||||||
|
|
||||||
class DestMode<bit val> {
|
class DestMode<bit val> {
|
||||||
bit Value = val;
|
bit Value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
def DstReg : DestMode<0>; // r
|
def DstReg : DestMode<0>;
|
||||||
def DstMem : DestMode<1>; // m
|
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>;
|
||||||
|
|
||||||
// Generic MSP430 Format
|
// Generic MSP430 Format
|
||||||
class MSP430Inst<dag outs, dag ins, int size, string asmstr> : Instruction {
|
class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f,
|
||||||
field bits<48> Inst;
|
string asmstr> : Instruction {
|
||||||
field bits<48> SoftFail = 0;
|
field bits<16> Inst;
|
||||||
|
|
||||||
let Namespace = "MSP430";
|
let Namespace = "MSP430";
|
||||||
|
|
||||||
dag OutOperandList = outs;
|
dag OutOperandList = outs;
|
||||||
dag InOperandList = ins;
|
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
|
// MSP430 Double Operand (Format I) Instructions
|
||||||
class IForm<bits<4> opcode, DestMode ad, bit bw, SourceMode as, int size,
|
class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: MSP430Inst<outs, ins, size, asmstr> {
|
: MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> {
|
||||||
let Pattern = pattern;
|
let Pattern = pattern;
|
||||||
|
|
||||||
bits<4> rs;
|
DestMode ad = dest;
|
||||||
bits<4> rd;
|
SourceMode as = src;
|
||||||
|
|
||||||
let Inst{15-12} = opcode;
|
let Inst{12-15} = opcode;
|
||||||
let Inst{11-8} = rs;
|
|
||||||
let Inst{7} = ad.Value;
|
let Inst{7} = ad.Value;
|
||||||
let Inst{6} = bw;
|
let Inst{6} = bw;
|
||||||
let Inst{5-4} = as.Value;
|
let Inst{4-5} = as.Value;
|
||||||
let Inst{3-0} = rd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8 bit IForm instructions
|
// 8 bit IForm instructions
|
||||||
class IForm8<bits<4> opcode, DestMode dest, SourceMode src, int size,
|
class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm<opcode, dest, 1, src, size, outs, ins, asmstr, pattern>;
|
: IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class I8rr<bits<4> opcode,
|
class I8rr<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstReg, SrcReg, 2, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
|
||||||
let DecoderNamespace = "Alpha";
|
|
||||||
}
|
|
||||||
|
|
||||||
class I8ri<bits<4> opcode,
|
class I8ri<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstReg, SrcImm, 4, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstReg, SrcImm, Size4Bytes, 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,
|
class I8rm<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstReg, SrcMem, 4, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstReg, SrcMem, Size4Bytes, 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,
|
class I8mr<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstMem, SrcReg, 4, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstMem, SrcReg, Size4Bytes, 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,
|
class I8mi<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstMem, SrcImm, 6, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstMem, SrcImm, Size6Bytes, 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,
|
class I8mm<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm8<opcode, DstMem, SrcMem, 6, outs, ins, asmstr, pattern> {
|
: IForm8<opcode, DstMem, SrcMem, Size6Bytes, 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
|
// 16 bit IForm instructions
|
||||||
class IForm16<bits<4> opcode, DestMode dest, SourceMode src, int size,
|
class IForm16<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm<opcode, dest, 0, src, size, outs, ins, asmstr, pattern>;
|
: IForm<opcode, dest, 0, src, sz, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class I16rr<bits<4> opcode,
|
class I16rr<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstReg, SrcReg, 2, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
|
||||||
let DecoderNamespace = "Alpha";
|
|
||||||
}
|
|
||||||
|
|
||||||
class I16ri<bits<4> opcode,
|
class I16ri<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstReg, SrcImm, 4, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstReg, SrcImm, Size4Bytes, 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,
|
class I16rm<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstReg, SrcMem, 4, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstReg, SrcMem, Size4Bytes, 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,
|
class I16mr<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstMem, SrcReg, 4, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstMem, SrcReg, Size4Bytes, 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,
|
class I16mi<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstMem, SrcImm, 6, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstMem, SrcImm, Size6Bytes, 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,
|
class I16mm<bits<4> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IForm16<opcode, DstMem, SrcMem, 6, outs, ins, asmstr, pattern> {
|
: IForm16<opcode, DstMem, SrcMem, Size6Bytes, 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
|
// MSP430 Single Operand (Format II) Instructions
|
||||||
class IIForm<bits<3> opcode, bit bw, SourceMode as, int size,
|
class IIForm<bits<9> opcode, bit bw, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: MSP430Inst<outs, ins, size, asmstr> {
|
: MSP430Inst<outs, ins, sz, SingleOpFrm, asmstr> {
|
||||||
let Pattern = pattern;
|
let Pattern = pattern;
|
||||||
|
|
||||||
bits<4> rs;
|
SourceMode as = src;
|
||||||
|
|
||||||
let Inst{15-10} = 0b000100;
|
let Inst{7-15} = opcode;
|
||||||
let Inst{9-7} = opcode;
|
|
||||||
let Inst{6} = bw;
|
let Inst{6} = bw;
|
||||||
let Inst{5-4} = as.Value;
|
let Inst{4-5} = as.Value;
|
||||||
let Inst{3-0} = rs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8 bit IIForm instructions
|
// 8 bit IIForm instructions
|
||||||
class IIForm8<bits<3> opcode, SourceMode src, int size,
|
class IIForm8<bits<9> opcode, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm<opcode, 1, src, size, outs, ins, asmstr, pattern>;
|
: IIForm<opcode, 1, src, sz, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class II8r<bits<3> opcode,
|
class II8r<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm8<opcode, SrcReg, 2, outs, ins, asmstr, pattern>;
|
: IIForm8<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class II8m<bits<3> opcode,
|
class II8m<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm8<opcode, SrcMem, 4, outs, ins, asmstr, pattern> {
|
: IIForm8<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
|
||||||
bits<20> src;
|
|
||||||
let rs = src{3-0};
|
|
||||||
let Inst{31-16} = src{19-4};
|
|
||||||
}
|
|
||||||
|
|
||||||
class II8i<bits<3> opcode,
|
class II8i<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm8<opcode, SrcImm, 4, outs, ins, asmstr, pattern> {
|
: IIForm8<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
|
||||||
bits<16> imm;
|
|
||||||
let rs = 0b0000;
|
|
||||||
let Inst{31-16} = imm;
|
|
||||||
}
|
|
||||||
|
|
||||||
class II8c<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} = 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
|
// 16 bit IIForm instructions
|
||||||
class IIForm16<bits<3> opcode, SourceMode src, int size,
|
class IIForm16<bits<9> opcode, SourceMode src, SizeVal sz,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm<opcode, 0, src, size, outs, ins, asmstr, pattern>;
|
: IIForm<opcode, 0, src, sz, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class II16r<bits<3> opcode,
|
class II16r<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm16<opcode, SrcReg, 2, outs, ins, asmstr, pattern>;
|
: IIForm16<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
|
||||||
|
|
||||||
class II16m<bits<3> opcode,
|
class II16m<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm16<opcode, SrcMem, 4, outs, ins, asmstr, pattern> {
|
: IIForm16<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
|
||||||
bits<20> src;
|
|
||||||
let rs = src{3-0};
|
|
||||||
let Inst{31-16} = src{19-4};
|
|
||||||
}
|
|
||||||
|
|
||||||
class II16i<bits<3> opcode,
|
class II16i<bits<9> opcode,
|
||||||
dag outs, dag ins, string asmstr, list<dag> pattern>
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: IIForm16<opcode, SrcImm, 4, outs, ins, asmstr, pattern> {
|
: IIForm16<opcode, SrcImm, Size4Bytes, 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
|
// MSP430 Conditional Jumps Instructions
|
||||||
class CJForm<dag outs, dag ins, string asmstr, list<dag> pattern>
|
class CJForm<bits<3> opcode, bits<3> cond,
|
||||||
: MSP430Inst<outs, ins, 2, asmstr> {
|
dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
|
: MSP430Inst<outs, ins, Size2Bytes, CondJumpFrm, asmstr> {
|
||||||
let Pattern = pattern;
|
let Pattern = pattern;
|
||||||
|
|
||||||
bits<3> cond;
|
let Inst{13-15} = opcode;
|
||||||
bits<10> dst;
|
let Inst{10-12} = cond;
|
||||||
|
|
||||||
let Inst{15-13} = 0b001;
|
|
||||||
let Inst{12-10} = cond;
|
|
||||||
let Inst{9-0} = dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pseudo instructions
|
// Pseudo instructions
|
||||||
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||||
: MSP430Inst<outs, ins, 0, asmstr> {
|
: MSP430Inst<outs, ins, SizeSpecial, PseudoFrm, asmstr> {
|
||||||
let Pattern = pattern;
|
let Pattern = pattern;
|
||||||
|
let Inst{15-0} = 0;
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,10 @@ unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
|
|||||||
unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
||||||
const MCInstrDesc &Desc = MI.getDesc();
|
const MCInstrDesc &Desc = MI.getDesc();
|
||||||
|
|
||||||
|
switch (Desc.TSFlags & MSP430II::SizeMask) {
|
||||||
|
default:
|
||||||
switch (Desc.getOpcode()) {
|
switch (Desc.getOpcode()) {
|
||||||
|
default: llvm_unreachable("Unknown instruction size!");
|
||||||
case TargetOpcode::CFI_INSTRUCTION:
|
case TargetOpcode::CFI_INSTRUCTION:
|
||||||
case TargetOpcode::EH_LABEL:
|
case TargetOpcode::EH_LABEL:
|
||||||
case TargetOpcode::IMPLICIT_DEF:
|
case TargetOpcode::IMPLICIT_DEF:
|
||||||
@ -315,6 +318,18 @@ unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
|||||||
*MF->getTarget().getMCAsmInfo());
|
*MF->getTarget().getMCAsmInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case MSP430II::SizeSpecial:
|
||||||
return Desc.getSize();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,22 @@ namespace llvm {
|
|||||||
|
|
||||||
class MSP430Subtarget;
|
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 {
|
class MSP430InstrInfo : public MSP430GenInstrInfo {
|
||||||
const MSP430RegisterInfo RI;
|
const MSP430RegisterInfo RI;
|
||||||
virtual void anchor();
|
virtual void anchor();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -110,9 +110,6 @@ LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
|
|||||||
return MCOperand::createExpr(Expr);
|
return MCOperand::createExpr(Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_REGINFO_ENUM
|
|
||||||
#include "MSP430GenRegisterInfo.inc"
|
|
||||||
|
|
||||||
void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
||||||
OutMI.setOpcode(MI->getOpcode());
|
OutMI.setOpcode(MI->getOpcode());
|
||||||
|
|
||||||
|
@ -11,31 +11,26 @@
|
|||||||
// Declarations that describe the MSP430 register file
|
// Declarations that describe the MSP430 register file
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
class MSP430Reg<bits<4> num, string n, list<string> alt = []> : Register<n> {
|
class MSP430Reg<bits<4> num, string n> : Register<n> {
|
||||||
field bits<4> Num = num;
|
field bits<4> Num = num;
|
||||||
let Namespace = "MSP430";
|
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> {
|
: RegisterWithSubRegs<n, subregs> {
|
||||||
field bits<4> Num = num;
|
field bits<4> Num = num;
|
||||||
let Namespace = "MSP430";
|
let Namespace = "MSP430";
|
||||||
let HWEncoding{3-0} = num;
|
|
||||||
let AltNames = alt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Registers
|
// Registers
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def PCB : MSP430Reg<0, "r0", ["pc"]>;
|
def PCB : MSP430Reg<0, "r0">;
|
||||||
def SPB : MSP430Reg<1, "r1", ["sp"]>;
|
def SPB : MSP430Reg<1, "r1">;
|
||||||
def SRB : MSP430Reg<2, "r2", ["sr"]>;
|
def SRB : MSP430Reg<2, "r2">;
|
||||||
def CGB : MSP430Reg<3, "r3", ["cg"]>;
|
def CGB : MSP430Reg<3, "r3">;
|
||||||
def FPB : MSP430Reg<4, "r4", ["fp"]>;
|
def FPB : MSP430Reg<4, "r4">;
|
||||||
def R5B : MSP430Reg<5, "r5">;
|
def R5B : MSP430Reg<5, "r5">;
|
||||||
def R6B : MSP430Reg<6, "r6">;
|
def R6B : MSP430Reg<6, "r6">;
|
||||||
def R7B : MSP430Reg<7, "r7">;
|
def R7B : MSP430Reg<7, "r7">;
|
||||||
@ -51,11 +46,11 @@ def R15B : MSP430Reg<15, "r15">;
|
|||||||
def subreg_8bit : SubRegIndex<8> { let Namespace = "MSP430"; }
|
def subreg_8bit : SubRegIndex<8> { let Namespace = "MSP430"; }
|
||||||
|
|
||||||
let SubRegIndices = [subreg_8bit] in {
|
let SubRegIndices = [subreg_8bit] in {
|
||||||
def PC : MSP430RegWithSubregs<0, "r0", [PCB], ["pc"]>;
|
def PC : MSP430RegWithSubregs<0, "r0", [PCB]>;
|
||||||
def SP : MSP430RegWithSubregs<1, "r1", [SPB], ["sp"]>;
|
def SP : MSP430RegWithSubregs<1, "r1", [SPB]>;
|
||||||
def SR : MSP430RegWithSubregs<2, "r2", [SRB], ["sr"]>;
|
def SR : MSP430RegWithSubregs<2, "r2", [SRB]>;
|
||||||
def CG : MSP430RegWithSubregs<3, "r3", [CGB], ["cg"]>;
|
def CG : MSP430RegWithSubregs<3, "r3", [CGB]>;
|
||||||
def FP : MSP430RegWithSubregs<4, "r4", [FPB], ["fp"]>;
|
def FP : MSP430RegWithSubregs<4, "r4", [FPB]>;
|
||||||
def R5 : MSP430RegWithSubregs<5, "r5", [R5B]>;
|
def R5 : MSP430RegWithSubregs<5, "r5", [R5B]>;
|
||||||
def R6 : MSP430RegWithSubregs<6, "r6", [R6B]>;
|
def R6 : MSP430RegWithSubregs<6, "r6", [R6B]>;
|
||||||
def R7 : MSP430RegWithSubregs<7, "r7", [R7B]>;
|
def R7 : MSP430RegWithSubregs<7, "r7", [R7B]>;
|
||||||
|
@ -8,7 +8,7 @@ define i16 @am1(i16 %x, i16* %a) nounwind {
|
|||||||
ret i16 %2
|
ret i16 %2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am1:
|
; CHECK-LABEL: am1:
|
||||||
; CHECK: bis 0(r13), r12
|
; CHECK: bis.w 0(r13), r12
|
||||||
|
|
||||||
@foo = external global i16
|
@foo = external global i16
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ define i16 @am2(i16 %x) nounwind {
|
|||||||
ret i16 %2
|
ret i16 %2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am2:
|
; CHECK-LABEL: am2:
|
||||||
; CHECK: bis &foo, r12
|
; CHECK: bis.w &foo, r12
|
||||||
|
|
||||||
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ define i16 @am4(i16 %x) nounwind {
|
|||||||
ret i16 %2
|
ret i16 %2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am4:
|
; CHECK-LABEL: am4:
|
||||||
; CHECK: bis &32, r12
|
; CHECK: bis.w &32, r12
|
||||||
|
|
||||||
define i16 @am5(i16 %x, i16* %a) nounwind {
|
define i16 @am5(i16 %x, i16* %a) nounwind {
|
||||||
%1 = getelementptr i16, i16* %a, i16 2
|
%1 = getelementptr i16, i16* %a, i16 2
|
||||||
@ -46,7 +46,7 @@ define i16 @am5(i16 %x, i16* %a) nounwind {
|
|||||||
ret i16 %3
|
ret i16 %3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am5:
|
; CHECK-LABEL: am5:
|
||||||
; CHECK: bis 4(r13), r12
|
; CHECK: bis.w 4(r13), r12
|
||||||
|
|
||||||
%S = type { i16, i16 }
|
%S = type { i16, i16 }
|
||||||
@baz = common global %S zeroinitializer, align 1
|
@baz = common global %S zeroinitializer, align 1
|
||||||
@ -57,7 +57,7 @@ define i16 @am6(i16 %x) nounwind {
|
|||||||
ret i16 %2
|
ret i16 %2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am6:
|
; CHECK-LABEL: am6:
|
||||||
; CHECK: bis &baz+2, r12
|
; CHECK: bis.w &baz+2, r12
|
||||||
|
|
||||||
%T = type { i16, [2 x i8] }
|
%T = type { i16, [2 x i8] }
|
||||||
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
||||||
|
@ -9,7 +9,7 @@ define void @am1(i16* %a, i16 %x) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am1:
|
; CHECK-LABEL: am1:
|
||||||
; CHECK: bis r13, 0(r12)
|
; CHECK: bis.w r13, 0(r12)
|
||||||
|
|
||||||
@foo = external global i16
|
@foo = external global i16
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ define void @am2(i16 %x) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am2:
|
; CHECK-LABEL: am2:
|
||||||
; CHECK: bis r12, &foo
|
; CHECK: bis.w r12, &foo
|
||||||
|
|
||||||
@bar = external global [2 x i8]
|
@bar = external global [2 x i8]
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ define void @am4(i16 %x) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am4:
|
; CHECK-LABEL: am4:
|
||||||
; CHECK: bis r12, &32
|
; CHECK: bis.w r12, &32
|
||||||
|
|
||||||
define void @am5(i16* %a, i16 %x) readonly {
|
define void @am5(i16* %a, i16 %x) readonly {
|
||||||
%1 = getelementptr inbounds i16, i16* %a, i16 2
|
%1 = getelementptr inbounds i16, i16* %a, i16 2
|
||||||
@ -51,7 +51,7 @@ define void @am5(i16* %a, i16 %x) readonly {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am5:
|
; CHECK-LABEL: am5:
|
||||||
; CHECK: bis r13, 4(r12)
|
; CHECK: bis.w r13, 4(r12)
|
||||||
|
|
||||||
%S = type { i16, i16 }
|
%S = type { i16, i16 }
|
||||||
@baz = common global %S zeroinitializer
|
@baz = common global %S zeroinitializer
|
||||||
@ -63,7 +63,7 @@ define void @am6(i16 %x) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am6:
|
; CHECK-LABEL: am6:
|
||||||
; CHECK: bis r12, &baz+2
|
; CHECK: bis.w r12, &baz+2
|
||||||
|
|
||||||
%T = type { i16, [2 x i8] }
|
%T = type { i16, [2 x i8] }
|
||||||
@duh = external global %T
|
@duh = external global %T
|
||||||
|
@ -7,7 +7,7 @@ define i16 @am1(i16* %a) nounwind {
|
|||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am1:
|
; CHECK-LABEL: am1:
|
||||||
; CHECK: mov 0(r12), r12
|
; CHECK: mov.w 0(r12), r12
|
||||||
|
|
||||||
@foo = external global i16
|
@foo = external global i16
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ define i16 @am2() nounwind {
|
|||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am2:
|
; CHECK-LABEL: am2:
|
||||||
; CHECK: mov &foo, r12
|
; CHECK: mov.w &foo, r12
|
||||||
|
|
||||||
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ define i16 @am4() nounwind {
|
|||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am4:
|
; CHECK-LABEL: am4:
|
||||||
; CHECK: mov &32, r12
|
; CHECK: mov.w &32, r12
|
||||||
|
|
||||||
define i16 @am5(i16* %a) nounwind {
|
define i16 @am5(i16* %a) nounwind {
|
||||||
%1 = getelementptr i16, i16* %a, i16 2
|
%1 = getelementptr i16, i16* %a, i16 2
|
||||||
@ -41,7 +41,7 @@ define i16 @am5(i16* %a) nounwind {
|
|||||||
ret i16 %2
|
ret i16 %2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am5:
|
; CHECK-LABEL: am5:
|
||||||
; CHECK: mov 4(r12), r12
|
; CHECK: mov.w 4(r12), r12
|
||||||
|
|
||||||
%S = type { i16, i16 }
|
%S = type { i16, i16 }
|
||||||
@baz = common global %S zeroinitializer, align 1
|
@baz = common global %S zeroinitializer, align 1
|
||||||
@ -51,7 +51,7 @@ define i16 @am6() nounwind {
|
|||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am6:
|
; CHECK-LABEL: am6:
|
||||||
; CHECK: mov &baz+2, r12
|
; CHECK: mov.w &baz+2, r12
|
||||||
|
|
||||||
%T = type { i16, [2 x i8] }
|
%T = type { i16, [2 x i8] }
|
||||||
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
||||||
|
@ -7,7 +7,7 @@ define void @am1(i16* %a, i16 %b) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am1:
|
; CHECK-LABEL: am1:
|
||||||
; CHECK: mov r13, 0(r12)
|
; CHECK: mov.w r13, 0(r12)
|
||||||
|
|
||||||
@foo = external global i16
|
@foo = external global i16
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ define void @am2(i16 %a) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am2:
|
; CHECK-LABEL: am2:
|
||||||
; CHECK: mov r12, &foo
|
; CHECK: mov.w r12, &foo
|
||||||
|
|
||||||
@bar = external global [2 x i8]
|
@bar = external global [2 x i8]
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ define void @am4(i16 %a) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am4:
|
; CHECK-LABEL: am4:
|
||||||
; CHECK: mov r12, &32
|
; CHECK: mov.w r12, &32
|
||||||
|
|
||||||
define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
|
define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
|
||||||
%1 = getelementptr inbounds i16, i16* %p, i16 2
|
%1 = getelementptr inbounds i16, i16* %p, i16 2
|
||||||
@ -41,7 +41,7 @@ define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am5:
|
; CHECK-LABEL: am5:
|
||||||
; CHECK: mov r13, 4(r12)
|
; CHECK: mov.w r13, 4(r12)
|
||||||
|
|
||||||
%S = type { i16, i16 }
|
%S = type { i16, i16 }
|
||||||
@baz = common global %S zeroinitializer, align 1
|
@baz = common global %S zeroinitializer, align 1
|
||||||
@ -51,7 +51,7 @@ define void @am6(i16 %a) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: am6:
|
; CHECK-LABEL: am6:
|
||||||
; CHECK: mov r12, &baz+2
|
; CHECK: mov.w r12, &baz+2
|
||||||
|
|
||||||
%T = type { i16, [2 x i8] }
|
%T = type { i16, [2 x i8] }
|
||||||
@duh = external global %T
|
@duh = external global %T
|
||||||
|
@ -6,14 +6,14 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define void @mov() nounwind {
|
define void @mov() nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov #2, &foo
|
; CHECK: mov.w #2, &foo
|
||||||
store i16 2, i16 * @foo
|
store i16 2, i16 * @foo
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @add() nounwind {
|
define void @add() nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: incd &foo
|
; CHECK: add.w #2, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = add i16 %1, 2
|
%2 = add i16 %1, 2
|
||||||
store i16 %2, i16 * @foo
|
store i16 %2, i16 * @foo
|
||||||
@ -22,7 +22,7 @@ define void @add() nounwind {
|
|||||||
|
|
||||||
define void @and() nounwind {
|
define void @and() nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and #2, &foo
|
; CHECK: and.w #2, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = and i16 %1, 2
|
%2 = and i16 %1, 2
|
||||||
store i16 %2, i16 * @foo
|
store i16 %2, i16 * @foo
|
||||||
@ -31,7 +31,7 @@ define void @and() nounwind {
|
|||||||
|
|
||||||
define void @bis() nounwind {
|
define void @bis() nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis #2, &foo
|
; CHECK: bis.w #2, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = or i16 %1, 2
|
%2 = or i16 %1, 2
|
||||||
store i16 %2, i16 * @foo
|
store i16 %2, i16 * @foo
|
||||||
@ -40,7 +40,7 @@ define void @bis() nounwind {
|
|||||||
|
|
||||||
define void @xor() nounwind {
|
define void @xor() nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor #2, &foo
|
; CHECK: xor.w #2, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = xor i16 %1, 2
|
%2 = xor i16 %1, 2
|
||||||
store i16 %2, i16 * @foo
|
store i16 %2, i16 * @foo
|
||||||
|
@ -6,7 +6,7 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define void @mov() nounwind {
|
define void @mov() nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov &bar, &foo
|
; CHECK: mov.w &bar, &foo
|
||||||
%1 = load i16, i16* @bar
|
%1 = load i16, i16* @bar
|
||||||
store i16 %1, i16* @foo
|
store i16 %1, i16* @foo
|
||||||
ret void
|
ret void
|
||||||
@ -14,7 +14,7 @@ define void @mov() nounwind {
|
|||||||
|
|
||||||
define void @add() nounwind {
|
define void @add() nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: add &bar, &foo
|
; CHECK: add.w &bar, &foo
|
||||||
%1 = load i16, i16* @bar
|
%1 = load i16, i16* @bar
|
||||||
%2 = load i16, i16* @foo
|
%2 = load i16, i16* @foo
|
||||||
%3 = add i16 %2, %1
|
%3 = add i16 %2, %1
|
||||||
@ -24,7 +24,7 @@ define void @add() nounwind {
|
|||||||
|
|
||||||
define void @and() nounwind {
|
define void @and() nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and &bar, &foo
|
; CHECK: and.w &bar, &foo
|
||||||
%1 = load i16, i16* @bar
|
%1 = load i16, i16* @bar
|
||||||
%2 = load i16, i16* @foo
|
%2 = load i16, i16* @foo
|
||||||
%3 = and i16 %2, %1
|
%3 = and i16 %2, %1
|
||||||
@ -34,7 +34,7 @@ define void @and() nounwind {
|
|||||||
|
|
||||||
define void @bis() nounwind {
|
define void @bis() nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis &bar, &foo
|
; CHECK: bis.w &bar, &foo
|
||||||
%1 = load i16, i16* @bar
|
%1 = load i16, i16* @bar
|
||||||
%2 = load i16, i16* @foo
|
%2 = load i16, i16* @foo
|
||||||
%3 = or i16 %2, %1
|
%3 = or i16 %2, %1
|
||||||
@ -44,7 +44,7 @@ define void @bis() nounwind {
|
|||||||
|
|
||||||
define void @xor() nounwind {
|
define void @xor() nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor &bar, &foo
|
; CHECK: xor.w &bar, &foo
|
||||||
%1 = load i16, i16* @bar
|
%1 = load i16, i16* @bar
|
||||||
%2 = load i16, i16* @foo
|
%2 = load i16, i16* @foo
|
||||||
%3 = xor i16 %2, %1
|
%3 = xor i16 %2, %1
|
||||||
@ -64,6 +64,6 @@ entry:
|
|||||||
%0 = load i16, i16* %retval ; <i16> [#uses=1]
|
%0 = load i16, i16* %retval ; <i16> [#uses=1]
|
||||||
ret i16 %0
|
ret i16 %0
|
||||||
; CHECK-LABEL: mov2:
|
; CHECK-LABEL: mov2:
|
||||||
; CHECK-DAG: mov 2(r1), 6(r1)
|
; CHECK-DAG: mov.w 2(r1), 6(r1)
|
||||||
; CHECK-DAG: mov 0(r1), 4(r1)
|
; CHECK-DAG: mov.w 0(r1), 4(r1)
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,14 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define void @mov(i16 %a) nounwind {
|
define void @mov(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov r12, &foo
|
; CHECK: mov.w r12, &foo
|
||||||
store i16 %a, i16* @foo
|
store i16 %a, i16* @foo
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @add(i16 %a) nounwind {
|
define void @add(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: add r12, &foo
|
; CHECK: add.w r12, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = add i16 %a, %1
|
%2 = add i16 %a, %1
|
||||||
store i16 %2, i16* @foo
|
store i16 %2, i16* @foo
|
||||||
@ -21,7 +21,7 @@ define void @add(i16 %a) nounwind {
|
|||||||
|
|
||||||
define void @and(i16 %a) nounwind {
|
define void @and(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and r12, &foo
|
; CHECK: and.w r12, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = and i16 %a, %1
|
%2 = and i16 %a, %1
|
||||||
store i16 %2, i16* @foo
|
store i16 %2, i16* @foo
|
||||||
@ -30,7 +30,7 @@ define void @and(i16 %a) nounwind {
|
|||||||
|
|
||||||
define void @bis(i16 %a) nounwind {
|
define void @bis(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis r12, &foo
|
; CHECK: bis.w r12, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = or i16 %a, %1
|
%2 = or i16 %a, %1
|
||||||
store i16 %2, i16* @foo
|
store i16 %2, i16* @foo
|
||||||
@ -39,7 +39,7 @@ define void @bis(i16 %a) nounwind {
|
|||||||
|
|
||||||
define void @bic(i16 zeroext %m) nounwind {
|
define void @bic(i16 zeroext %m) nounwind {
|
||||||
; CHECK-LABEL: bic:
|
; CHECK-LABEL: bic:
|
||||||
; CHECK: bic r12, &foo
|
; CHECK: bic.w r12, &foo
|
||||||
%1 = xor i16 %m, -1
|
%1 = xor i16 %m, -1
|
||||||
%2 = load i16, i16* @foo
|
%2 = load i16, i16* @foo
|
||||||
%3 = and i16 %2, %1
|
%3 = and i16 %2, %1
|
||||||
@ -49,7 +49,7 @@ define void @bic(i16 zeroext %m) nounwind {
|
|||||||
|
|
||||||
define void @xor(i16 %a) nounwind {
|
define void @xor(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor r12, &foo
|
; CHECK: xor.w r12, &foo
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = xor i16 %a, %1
|
%2 = xor i16 %a, %1
|
||||||
store i16 %2, i16* @foo
|
store i16 %2, i16* @foo
|
||||||
|
@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define i16 @mov() nounwind {
|
define i16 @mov() nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
ret i16 1
|
ret i16 1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @add(i16 %a, i16 %b) nounwind {
|
define i16 @add(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: inc r12
|
; CHECK: add.w #1, r12
|
||||||
%1 = add i16 %a, 1
|
%1 = add i16 %a, 1
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @and(i16 %a, i16 %b) nounwind {
|
define i16 @and(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
%1 = and i16 %a, 1
|
%1 = and i16 %a, 1
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @bis(i16 %a, i16 %b) nounwind {
|
define i16 @bis(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis #1, r12
|
; CHECK: bis.w #1, r12
|
||||||
%1 = or i16 %a, 1
|
%1 = or i16 %a, 1
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @xor(i16 %a, i16 %b) nounwind {
|
define i16 @xor(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor #1, r12
|
; CHECK: xor.w #1, r12
|
||||||
%1 = xor i16 %a, 1
|
%1 = xor i16 %a, 1
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define i16 @add(i16 %a) nounwind {
|
define i16 @add(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: add &foo, r12
|
; CHECK: add.w &foo, r12
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = add i16 %a, %1
|
%2 = add i16 %a, %1
|
||||||
ret i16 %2
|
ret i16 %2
|
||||||
@ -13,7 +13,7 @@ define i16 @add(i16 %a) nounwind {
|
|||||||
|
|
||||||
define i16 @and(i16 %a) nounwind {
|
define i16 @and(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and &foo, r12
|
; CHECK: and.w &foo, r12
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = and i16 %a, %1
|
%2 = and i16 %a, %1
|
||||||
ret i16 %2
|
ret i16 %2
|
||||||
@ -21,7 +21,7 @@ define i16 @and(i16 %a) nounwind {
|
|||||||
|
|
||||||
define i16 @bis(i16 %a) nounwind {
|
define i16 @bis(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis &foo, r12
|
; CHECK: bis.w &foo, r12
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = or i16 %a, %1
|
%2 = or i16 %a, %1
|
||||||
ret i16 %2
|
ret i16 %2
|
||||||
@ -29,7 +29,7 @@ define i16 @bis(i16 %a) nounwind {
|
|||||||
|
|
||||||
define i16 @bic(i16 %a) nounwind {
|
define i16 @bic(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: bic:
|
; CHECK-LABEL: bic:
|
||||||
; CHECK: bic &foo, r12
|
; CHECK: bic.w &foo, r12
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = xor i16 %1, -1
|
%2 = xor i16 %1, -1
|
||||||
%3 = and i16 %a, %2
|
%3 = and i16 %a, %2
|
||||||
@ -38,7 +38,7 @@ define i16 @bic(i16 %a) nounwind {
|
|||||||
|
|
||||||
define i16 @xor(i16 %a) nounwind {
|
define i16 @xor(i16 %a) nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor &foo, r12
|
; CHECK: xor.w &foo, r12
|
||||||
%1 = load i16, i16* @foo
|
%1 = load i16, i16* @foo
|
||||||
%2 = xor i16 %a, %1
|
%2 = xor i16 %a, %1
|
||||||
ret i16 %2
|
ret i16 %2
|
||||||
|
@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define i16 @mov(i16 %a, i16 %b) nounwind {
|
define i16 @mov(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov r13, r12
|
; CHECK: mov.w r13, r12
|
||||||
ret i16 %b
|
ret i16 %b
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @add(i16 %a, i16 %b) nounwind {
|
define i16 @add(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: add r13, r12
|
; CHECK: add.w r13, r12
|
||||||
%1 = add i16 %a, %b
|
%1 = add i16 %a, %b
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @and(i16 %a, i16 %b) nounwind {
|
define i16 @and(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and r13, r12
|
; CHECK: and.w r13, r12
|
||||||
%1 = and i16 %a, %b
|
%1 = and i16 %a, %b
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @bis(i16 %a, i16 %b) nounwind {
|
define i16 @bis(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis r13, r12
|
; CHECK: bis.w r13, r12
|
||||||
%1 = or i16 %a, %b
|
%1 = or i16 %a, %b
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i16 @bic(i16 %a, i16 %b) nounwind {
|
define i16 @bic(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: bic:
|
; CHECK-LABEL: bic:
|
||||||
; CHECK: bic r13, r12
|
; CHECK: bic.w r13, r12
|
||||||
%1 = xor i16 %b, -1
|
%1 = xor i16 %b, -1
|
||||||
%2 = and i16 %a, %1
|
%2 = and i16 %a, %1
|
||||||
ret i16 %2
|
ret i16 %2
|
||||||
@ -39,7 +39,7 @@ define i16 @bic(i16 %a, i16 %b) nounwind {
|
|||||||
|
|
||||||
define i16 @xor(i16 %a, i16 %b) nounwind {
|
define i16 @xor(i16 %a, i16 %b) nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor r13, r12
|
; CHECK: xor.w r13, r12
|
||||||
%1 = xor i16 %a, %b
|
%1 = xor i16 %a, %b
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ define void @mov() nounwind {
|
|||||||
|
|
||||||
define void @add() nounwind {
|
define void @add() nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: incd.b &foo
|
; CHECK: add.b #2, &foo
|
||||||
%1 = load i8, i8* @foo
|
%1 = load i8, i8* @foo
|
||||||
%2 = add i8 %1, 2
|
%2 = add i8 %1, 2
|
||||||
store i8 %2, i8 * @foo
|
store i8 %2, i8 * @foo
|
||||||
|
@ -10,7 +10,7 @@ define i8 @mov() nounwind {
|
|||||||
|
|
||||||
define i8 @add(i8 %a, i8 %b) nounwind {
|
define i8 @add(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: inc.b r12
|
; CHECK: add.b #1, r12
|
||||||
%1 = add i8 %a, 1
|
%1 = add i8 %a, 1
|
||||||
ret i8 %1
|
ret i8 %1
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ target triple = "msp430-generic-generic"
|
|||||||
|
|
||||||
define i8 @mov(i8 %a, i8 %b) nounwind {
|
define i8 @mov(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: mov:
|
; CHECK-LABEL: mov:
|
||||||
; CHECK: mov r13, r12
|
; CHECK: mov.{{[bw]}} r13, r12
|
||||||
ret i8 %b
|
ret i8 %b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,14 +17,14 @@ define i8 @add(i8 %a, i8 %b) nounwind {
|
|||||||
|
|
||||||
define i8 @and(i8 %a, i8 %b) nounwind {
|
define i8 @and(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and r13, r12
|
; CHECK: and.w r13, r12
|
||||||
%1 = and i8 %a, %b
|
%1 = and i8 %a, %b
|
||||||
ret i8 %1
|
ret i8 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8 @bis(i8 %a, i8 %b) nounwind {
|
define i8 @bis(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: bis:
|
; CHECK-LABEL: bis:
|
||||||
; CHECK: bis r13, r12
|
; CHECK: bis.w r13, r12
|
||||||
%1 = or i8 %a, %b
|
%1 = or i8 %a, %b
|
||||||
ret i8 %1
|
ret i8 %1
|
||||||
}
|
}
|
||||||
@ -39,7 +39,7 @@ define i8 @bic(i8 %a, i8 %b) nounwind {
|
|||||||
|
|
||||||
define i8 @xor(i8 %a, i8 %b) nounwind {
|
define i8 @xor(i8 %a, i8 %b) nounwind {
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor r13, r12
|
; CHECK: xor.w r13, r12
|
||||||
%1 = xor i8 %a, %b
|
%1 = xor i8 %a, %b
|
||||||
ret i8 %1
|
ret i8 %1
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ target triple = "msp430---elf"
|
|||||||
define void @test() {
|
define void @test() {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: test:
|
; CHECK-LABEL: test:
|
||||||
; CHECK: push r10
|
; CHECK: push.w r10
|
||||||
call void asm sideeffect "", "~{r10}"()
|
call void asm sideeffect "", "~{r10}"()
|
||||||
; CHECK: pop r10
|
; CHECK: pop.w r10
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ define i16 @bitwrr(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t3
|
ret i16 %t3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwrr:
|
; CHECK-LABEL: bitwrr:
|
||||||
; CHECK: bit r13, r12
|
; CHECK: bit.w r13, r12
|
||||||
|
|
||||||
define i16 @bitwri(i16 %a) nounwind {
|
define i16 @bitwri(i16 %a) nounwind {
|
||||||
%t1 = and i16 %a, 4080
|
%t1 = and i16 %a, 4080
|
||||||
@ -102,7 +102,7 @@ define i16 @bitwri(i16 %a) nounwind {
|
|||||||
ret i16 %t3
|
ret i16 %t3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwri:
|
; CHECK-LABEL: bitwri:
|
||||||
; CHECK: bit #4080, r12
|
; CHECK: bit.w #4080, r12
|
||||||
|
|
||||||
define i16 @bitwir(i16 %a) nounwind {
|
define i16 @bitwir(i16 %a) nounwind {
|
||||||
%t1 = and i16 4080, %a
|
%t1 = and i16 4080, %a
|
||||||
@ -111,7 +111,7 @@ define i16 @bitwir(i16 %a) nounwind {
|
|||||||
ret i16 %t3
|
ret i16 %t3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwir:
|
; CHECK-LABEL: bitwir:
|
||||||
; CHECK: bit #4080, r12
|
; CHECK: bit.w #4080, r12
|
||||||
|
|
||||||
define i16 @bitwmi() nounwind {
|
define i16 @bitwmi() nounwind {
|
||||||
%t1 = load i16, i16* @foo16
|
%t1 = load i16, i16* @foo16
|
||||||
@ -121,7 +121,7 @@ define i16 @bitwmi() nounwind {
|
|||||||
ret i16 %t4
|
ret i16 %t4
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwmi:
|
; CHECK-LABEL: bitwmi:
|
||||||
; CHECK: bit #4080, &foo16
|
; CHECK: bit.w #4080, &foo16
|
||||||
|
|
||||||
define i16 @bitwim() nounwind {
|
define i16 @bitwim() nounwind {
|
||||||
%t1 = load i16, i16* @foo16
|
%t1 = load i16, i16* @foo16
|
||||||
@ -131,7 +131,7 @@ define i16 @bitwim() nounwind {
|
|||||||
ret i16 %t4
|
ret i16 %t4
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwim:
|
; CHECK-LABEL: bitwim:
|
||||||
; CHECK: bit #4080, &foo16
|
; CHECK: bit.w #4080, &foo16
|
||||||
|
|
||||||
define i16 @bitwrm(i16 %a) nounwind {
|
define i16 @bitwrm(i16 %a) nounwind {
|
||||||
%t1 = load i16, i16* @foo16
|
%t1 = load i16, i16* @foo16
|
||||||
@ -141,7 +141,7 @@ define i16 @bitwrm(i16 %a) nounwind {
|
|||||||
ret i16 %t4
|
ret i16 %t4
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwrm:
|
; CHECK-LABEL: bitwrm:
|
||||||
; CHECK: bit &foo16, r12
|
; CHECK: bit.w &foo16, r12
|
||||||
|
|
||||||
define i16 @bitwmr(i16 %a) nounwind {
|
define i16 @bitwmr(i16 %a) nounwind {
|
||||||
%t1 = load i16, i16* @foo16
|
%t1 = load i16, i16* @foo16
|
||||||
@ -151,7 +151,7 @@ define i16 @bitwmr(i16 %a) nounwind {
|
|||||||
ret i16 %t4
|
ret i16 %t4
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwmr:
|
; CHECK-LABEL: bitwmr:
|
||||||
; CHECK: bit r12, &foo16
|
; CHECK: bit.w r12, &foo16
|
||||||
|
|
||||||
define i16 @bitwmm() nounwind {
|
define i16 @bitwmm() nounwind {
|
||||||
%t1 = load i16, i16* @foo16
|
%t1 = load i16, i16* @foo16
|
||||||
@ -162,5 +162,5 @@ define i16 @bitwmm() nounwind {
|
|||||||
ret i16 %t5
|
ret i16 %t5
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: bitwmm:
|
; CHECK-LABEL: bitwmm:
|
||||||
; CHECK: bit &bar16, &foo16
|
; CHECK: bit.w &bar16, &foo16
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ target triple = "msp430---elf"
|
|||||||
define i16 @callee(%struct.Foo* byval %f) nounwind {
|
define i16 @callee(%struct.Foo* byval %f) nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: callee:
|
; CHECK-LABEL: callee:
|
||||||
; CHECK: mov 2(r1), r12
|
; CHECK: mov.w 2(r1), r12
|
||||||
%0 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i32 0, i32 0
|
%0 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i32 0, i32 0
|
||||||
%1 = load i16, i16* %0, align 2
|
%1 = load i16, i16* %0, align 2
|
||||||
ret i16 %1
|
ret i16 %1
|
||||||
@ -18,9 +18,9 @@ entry:
|
|||||||
define void @caller() nounwind {
|
define void @caller() nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: caller:
|
; CHECK-LABEL: caller:
|
||||||
; CHECK: mov &foo+4, 4(r1)
|
; CHECK: mov.w &foo+4, 4(r1)
|
||||||
; CHECK-NEXT: mov &foo+2, 2(r1)
|
; CHECK-NEXT: mov.w &foo+2, 2(r1)
|
||||||
; CHECK-NEXT: mov &foo, 0(r1)
|
; CHECK-NEXT: mov.w &foo, 0(r1)
|
||||||
%call = call i16 @callee(%struct.Foo* byval @foo)
|
%call = call i16 @callee(%struct.Foo* byval @foo)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -7,50 +7,50 @@ define void @test() #0 {
|
|||||||
entry:
|
entry:
|
||||||
; CHECK: test:
|
; CHECK: test:
|
||||||
|
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: call #f_i16
|
; CHECK: call #f_i16
|
||||||
call void @f_i16(i16 1)
|
call void @f_i16(i16 1)
|
||||||
|
|
||||||
; CHECK: mov #772, r12
|
; CHECK: mov.w #772, r12
|
||||||
; CHECK: mov #258, r13
|
; CHECK: mov.w #258, r13
|
||||||
; CHECK: call #f_i32
|
; CHECK: call #f_i32
|
||||||
call void @f_i32(i32 16909060)
|
call void @f_i32(i32 16909060)
|
||||||
|
|
||||||
; CHECK: mov #1800, r12
|
; CHECK: mov.w #1800, r12
|
||||||
; CHECK: mov #1286, r13
|
; CHECK: mov.w #1286, r13
|
||||||
; CHECK: mov #772, r14
|
; CHECK: mov.w #772, r14
|
||||||
; CHECK: mov #258, r15
|
; CHECK: mov.w #258, r15
|
||||||
; CHECK: call #f_i64
|
; CHECK: call #f_i64
|
||||||
call void @f_i64(i64 72623859790382856)
|
call void @f_i64(i64 72623859790382856)
|
||||||
|
|
||||||
; CHECK: mov #772, r12
|
; CHECK: mov.w #772, r12
|
||||||
; CHECK: mov #258, r13
|
; CHECK: mov.w #258, r13
|
||||||
; CHECK: mov #1800, r14
|
; CHECK: mov.w #1800, r14
|
||||||
; CHECK: mov #1286, r15
|
; CHECK: mov.w #1286, r15
|
||||||
; CHECK: call #f_i32_i32
|
; CHECK: call #f_i32_i32
|
||||||
call void @f_i32_i32(i32 16909060, i32 84281096)
|
call void @f_i32_i32(i32 16909060, i32 84281096)
|
||||||
|
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: mov #772, r13
|
; CHECK: mov.w #772, r13
|
||||||
; CHECK: mov #258, r14
|
; CHECK: mov.w #258, r14
|
||||||
; CHECK: mov #2, r15
|
; CHECK: mov.w #2, r15
|
||||||
; CHECK: call #f_i16_i32_i16
|
; CHECK: call #f_i16_i32_i16
|
||||||
call void @f_i16_i32_i16(i16 1, i32 16909060, i16 2)
|
call void @f_i16_i32_i16(i16 1, i32 16909060, i16 2)
|
||||||
|
|
||||||
; CHECK: mov #1286, 0(r1)
|
; CHECK: mov.w #1286, 0(r1)
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: mov #772, r13
|
; CHECK: mov.w #772, r13
|
||||||
; CHECK: mov #258, r14
|
; CHECK: mov.w #258, r14
|
||||||
; CHECK: mov #1800, r15
|
; CHECK: mov.w #1800, r15
|
||||||
; CHECK: call #f_i16_i32_i32
|
; CHECK: call #f_i16_i32_i32
|
||||||
call void @f_i16_i32_i32(i16 1, i32 16909060, i32 84281096)
|
call void @f_i16_i32_i32(i16 1, i32 16909060, i32 84281096)
|
||||||
|
|
||||||
; CHECK: mov #258, 6(r1)
|
; CHECK: mov.w #258, 6(r1)
|
||||||
; CHECK: mov #772, 4(r1)
|
; CHECK: mov.w #772, 4(r1)
|
||||||
; CHECK: mov #1286, 2(r1)
|
; CHECK: mov.w #1286, 2(r1)
|
||||||
; CHECK: mov #1800, 0(r1)
|
; CHECK: mov.w #1800, 0(r1)
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: mov #2, r13
|
; CHECK: mov.w #2, r13
|
||||||
; CHECK: call #f_i16_i64_i16
|
; CHECK: call #f_i16_i64_i16
|
||||||
call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2)
|
call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2)
|
||||||
|
|
||||||
@ -63,75 +63,75 @@ entry:
|
|||||||
|
|
||||||
define void @f_i16(i16 %a) #0 {
|
define void @f_i16(i16 %a) #0 {
|
||||||
; CHECK: f_i16:
|
; CHECK: f_i16:
|
||||||
; CHECK: mov r12, &g_i16
|
; CHECK: mov.w r12, &g_i16
|
||||||
store volatile i16 %a, i16* @g_i16, align 2
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i32(i32 %a) #0 {
|
define void @f_i32(i32 %a) #0 {
|
||||||
; CHECK: f_i32:
|
; CHECK: f_i32:
|
||||||
; CHECK: mov r13, &g_i32+2
|
; CHECK: mov.w r13, &g_i32+2
|
||||||
; CHECK: mov r12, &g_i32
|
; CHECK: mov.w r12, &g_i32
|
||||||
store volatile i32 %a, i32* @g_i32, align 2
|
store volatile i32 %a, i32* @g_i32, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i64(i64 %a) #0 {
|
define void @f_i64(i64 %a) #0 {
|
||||||
; CHECK: f_i64:
|
; CHECK: f_i64:
|
||||||
; CHECK: mov r15, &g_i64+6
|
; CHECK: mov.w r15, &g_i64+6
|
||||||
; CHECK: mov r14, &g_i64+4
|
; CHECK: mov.w r14, &g_i64+4
|
||||||
; CHECK: mov r13, &g_i64+2
|
; CHECK: mov.w r13, &g_i64+2
|
||||||
; CHECK: mov r12, &g_i64
|
; CHECK: mov.w r12, &g_i64
|
||||||
store volatile i64 %a, i64* @g_i64, align 2
|
store volatile i64 %a, i64* @g_i64, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i32_i32(i32 %a, i32 %b) #0 {
|
define void @f_i32_i32(i32 %a, i32 %b) #0 {
|
||||||
; CHECK: f_i32_i32:
|
; CHECK: f_i32_i32:
|
||||||
; CHECK: mov r13, &g_i32+2
|
; CHECK: mov.w r13, &g_i32+2
|
||||||
; CHECK: mov r12, &g_i32
|
; CHECK: mov.w r12, &g_i32
|
||||||
store volatile i32 %a, i32* @g_i32, align 2
|
store volatile i32 %a, i32* @g_i32, align 2
|
||||||
; CHECK: mov r15, &g_i32+2
|
; CHECK: mov.w r15, &g_i32+2
|
||||||
; CHECK: mov r14, &g_i32
|
; CHECK: mov.w r14, &g_i32
|
||||||
store volatile i32 %b, i32* @g_i32, align 2
|
store volatile i32 %b, i32* @g_i32, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i16_i32_i32(i16 %a, i32 %b, i32 %c) #0 {
|
define void @f_i16_i32_i32(i16 %a, i32 %b, i32 %c) #0 {
|
||||||
; CHECK: f_i16_i32_i32:
|
; CHECK: f_i16_i32_i32:
|
||||||
; CHECK: mov r12, &g_i16
|
; CHECK: mov.w r12, &g_i16
|
||||||
store volatile i16 %a, i16* @g_i16, align 2
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
; CHECK: mov r14, &g_i32+2
|
; CHECK: mov.w r14, &g_i32+2
|
||||||
; CHECK: mov r13, &g_i32
|
; CHECK: mov.w r13, &g_i32
|
||||||
store volatile i32 %b, i32* @g_i32, align 2
|
store volatile i32 %b, i32* @g_i32, align 2
|
||||||
; CHECK: mov r15, &g_i32
|
; CHECK: mov.w r15, &g_i32
|
||||||
; CHECK: mov 4(r4), &g_i32+2
|
; CHECK: mov.w 4(r4), &g_i32+2
|
||||||
store volatile i32 %c, i32* @g_i32, align 2
|
store volatile i32 %c, i32* @g_i32, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {
|
define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {
|
||||||
; CHECK: f_i16_i32_i16:
|
; CHECK: f_i16_i32_i16:
|
||||||
; CHECK: mov r12, &g_i16
|
; CHECK: mov.w r12, &g_i16
|
||||||
store volatile i16 %a, i16* @g_i16, align 2
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
; CHECK: mov r14, &g_i32+2
|
; CHECK: mov.w r14, &g_i32+2
|
||||||
; CHECK: mov r13, &g_i32
|
; CHECK: mov.w r13, &g_i32
|
||||||
store volatile i32 %b, i32* @g_i32, align 2
|
store volatile i32 %b, i32* @g_i32, align 2
|
||||||
; CHECK: mov r15, &g_i16
|
; CHECK: mov.w r15, &g_i16
|
||||||
store volatile i16 %c, i16* @g_i16, align 2
|
store volatile i16 %c, i16* @g_i16, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {
|
define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {
|
||||||
; CHECK: f_i16_i64_i16:
|
; CHECK: f_i16_i64_i16:
|
||||||
; CHECK: mov r12, &g_i16
|
; CHECK: mov.w r12, &g_i16
|
||||||
store volatile i16 %a, i16* @g_i16, align 2
|
store volatile i16 %a, i16* @g_i16, align 2
|
||||||
;CHECK: mov 10(r4), &g_i64+6
|
;CHECK: mov.w 10(r4), &g_i64+6
|
||||||
;CHECK: mov 8(r4), &g_i64+4
|
;CHECK: mov.w 8(r4), &g_i64+4
|
||||||
;CHECK: mov 6(r4), &g_i64+2
|
;CHECK: mov.w 6(r4), &g_i64+2
|
||||||
;CHECK: mov 4(r4), &g_i64
|
;CHECK: mov.w 4(r4), &g_i64
|
||||||
store volatile i64 %b, i64* @g_i64, align 2
|
store volatile i64 %b, i64* @g_i64, align 2
|
||||||
;CHECK: mov r13, &g_i16
|
;CHECK: mov.w r13, &g_i16
|
||||||
store volatile i16 %c, i16* @g_i16, align 2
|
store volatile i16 %c, i16* @g_i16, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -8,21 +8,21 @@ entry:
|
|||||||
; CHECK: test:
|
; CHECK: test:
|
||||||
|
|
||||||
; CHECK: call #f_i16
|
; CHECK: call #f_i16
|
||||||
; CHECK: mov r12, &g_i16
|
; CHECK: mov.w r12, &g_i16
|
||||||
%0 = call i16 @f_i16()
|
%0 = call i16 @f_i16()
|
||||||
store volatile i16 %0, i16* @g_i16
|
store volatile i16 %0, i16* @g_i16
|
||||||
|
|
||||||
; CHECK: call #f_i32
|
; CHECK: call #f_i32
|
||||||
; CHECK: mov r13, &g_i32+2
|
; CHECK: mov.w r13, &g_i32+2
|
||||||
; CHECK: mov r12, &g_i32
|
; CHECK: mov.w r12, &g_i32
|
||||||
%1 = call i32 @f_i32()
|
%1 = call i32 @f_i32()
|
||||||
store volatile i32 %1, i32* @g_i32
|
store volatile i32 %1, i32* @g_i32
|
||||||
|
|
||||||
; CHECK: call #f_i64
|
; CHECK: call #f_i64
|
||||||
; CHECK: mov r15, &g_i64+6
|
; CHECK: mov.w r15, &g_i64+6
|
||||||
; CHECK: mov r14, &g_i64+4
|
; CHECK: mov.w r14, &g_i64+4
|
||||||
; CHECK: mov r13, &g_i64+2
|
; CHECK: mov.w r13, &g_i64+2
|
||||||
; CHECK: mov r12, &g_i64
|
; CHECK: mov.w r12, &g_i64
|
||||||
%2 = call i64 @f_i64()
|
%2 = call i64 @f_i64()
|
||||||
store volatile i64 %2, i64* @g_i64
|
store volatile i64 %2, i64* @g_i64
|
||||||
|
|
||||||
@ -35,25 +35,25 @@ entry:
|
|||||||
|
|
||||||
define i16 @f_i16() #0 {
|
define i16 @f_i16() #0 {
|
||||||
; CHECK: f_i16:
|
; CHECK: f_i16:
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
ret i16 1
|
ret i16 1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @f_i32() #0 {
|
define i32 @f_i32() #0 {
|
||||||
; CHECK: f_i32:
|
; CHECK: f_i32:
|
||||||
; CHECK: mov #772, r12
|
; CHECK: mov.w #772, r12
|
||||||
; CHECK: mov #258, r13
|
; CHECK: mov.w #258, r13
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
ret i32 16909060
|
ret i32 16909060
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @f_i64() #0 {
|
define i64 @f_i64() #0 {
|
||||||
; CHECK: f_i64:
|
; CHECK: f_i64:
|
||||||
; CHECK: mov #1800, r12
|
; CHECK: mov.w #1800, r12
|
||||||
; CHECK: mov #1286, r13
|
; CHECK: mov.w #1286, r13
|
||||||
; CHECK: mov #772, r14
|
; CHECK: mov.w #772, r14
|
||||||
; CHECK: mov #258, r15
|
; CHECK: mov.w #258, r15
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
ret i64 72623859790382856
|
ret i64 72623859790382856
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ target triple = "msp430---elf"
|
|||||||
define void @fp() nounwind {
|
define void @fp() nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: fp:
|
; CHECK-LABEL: fp:
|
||||||
; CHECK: push r4
|
; CHECK: push.w r4
|
||||||
; CHECK: mov r1, r4
|
; CHECK: mov.w r1, r4
|
||||||
; CHECK: sub #2, r1
|
; CHECK: sub.w #2, r1
|
||||||
%i = alloca i16, align 2
|
%i = alloca i16, align 2
|
||||||
; CHECK: clr -2(r4)
|
; CHECK: mov.w #0, -2(r4)
|
||||||
store i16 0, i16* %i, align 2
|
store i16 0, i16* %i, align 2
|
||||||
; CHECK: pop r4
|
; CHECK: pop.w r4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,15 +7,15 @@ target triple = "msp430---elf"
|
|||||||
define i16 @test(i16 %i) #0 {
|
define i16 @test(i16 %i) #0 {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: test:
|
; CHECK-LABEL: test:
|
||||||
; CHECK: sub #4, r1
|
; CHECK: sub.w #4, r1
|
||||||
; CHECK-NEXT: mov r12, 0(r1)
|
; CHECK-NEXT: mov.w r12, 0(r1)
|
||||||
; CHECK-NEXT: cmp #4, r12
|
; CHECK-NEXT: cmp.w #4, r12
|
||||||
; CHECK-NEXT: jhs .LBB0_3
|
; CHECK-NEXT: jhs .LBB0_3
|
||||||
%retval = alloca i16, align 2
|
%retval = alloca i16, align 2
|
||||||
%i.addr = alloca i16, align 2
|
%i.addr = alloca i16, align 2
|
||||||
store i16 %i, i16* %i.addr, align 2
|
store i16 %i, i16* %i.addr, align 2
|
||||||
%0 = load i16, i16* %i.addr, align 2
|
%0 = load i16, i16* %i.addr, align 2
|
||||||
; CHECK: add r12, r12
|
; CHECK: rla.w r12
|
||||||
; CHECK-NEXT: br .LJTI0_0(r12)
|
; CHECK-NEXT: br .LJTI0_0(r12)
|
||||||
switch i16 %0, label %sw.default [
|
switch i16 %0, label %sw.default [
|
||||||
i16 0, label %sw.bb
|
i16 0, label %sw.bb
|
||||||
|
@ -9,9 +9,9 @@ define void @test() nounwind {
|
|||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: test:
|
; CHECK-LABEL: test:
|
||||||
%0 = load i8*, i8** @buf, align 2
|
%0 = load i8*, i8** @buf, align 2
|
||||||
; CHECK: mov &buf, r12
|
; CHECK: mov.w &buf, r12
|
||||||
; CHECK-NEXT: mov #5, r13
|
; CHECK-NEXT: mov.w #5, r13
|
||||||
; CHECK-NEXT: mov #128, r14
|
; CHECK-NEXT: mov.w #128, r14
|
||||||
; CHECK-NEXT: call #memset
|
; CHECK-NEXT: call #memset
|
||||||
call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i1 false)
|
call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i1 false)
|
||||||
ret void
|
ret void
|
||||||
|
@ -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.
|
; only verifies that the code generator ran successfully.
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @f
|
; CHECK-LABEL: @f
|
||||||
; CHECK: mov &y, &x
|
; CHECK: mov.w &y, &x
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
define void @f() {
|
define void @f() {
|
||||||
entry:
|
entry:
|
||||||
|
@ -12,7 +12,7 @@ for.body: ; preds = %for.body, %entry
|
|||||||
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||||
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||||
; CHECK-LABEL: add:
|
; CHECK-LABEL: add:
|
||||||
; CHECK: add @r{{[0-9]+}}+, r{{[0-9]+}}
|
; CHECK: add.w @r{{[0-9]+}}+, r{{[0-9]+}}
|
||||||
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
||||||
%add = add i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
%add = add i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||||
%inc = add i16 %i.010, 1 ; <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]
|
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||||
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||||
; CHECK-LABEL: sub:
|
; CHECK-LABEL: sub:
|
||||||
; CHECK: sub @r{{[0-9]+}}+, r{{[0-9]+}}
|
; CHECK: sub.w @r{{[0-9]+}}+, r{{[0-9]+}}
|
||||||
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
||||||
%add = sub i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
%add = sub i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||||
%inc = add i16 %i.010, 1 ; <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]
|
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||||
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||||
; CHECK-LABEL: or:
|
; CHECK-LABEL: or:
|
||||||
; CHECK: bis @r{{[0-9]+}}+, r{{[0-9]+}}
|
; CHECK: bis.w @r{{[0-9]+}}+, r{{[0-9]+}}
|
||||||
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
||||||
%add = or i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
%add = or i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||||
%inc = add i16 %i.010, 1 ; <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]
|
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||||
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||||
; CHECK-LABEL: xor:
|
; CHECK-LABEL: xor:
|
||||||
; CHECK: xor @r{{[0-9]+}}+, r{{[0-9]+}}
|
; CHECK: xor.w @r{{[0-9]+}}+, r{{[0-9]+}}
|
||||||
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
||||||
%add = xor i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
%add = xor i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||||
%inc = add i16 %i.010, 1 ; <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]
|
%sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; <i16> [#uses=1]
|
||||||
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
%arrayidx = getelementptr i16, i16* %a, i16 %i.010 ; <i16*> [#uses=1]
|
||||||
; CHECK-LABEL: and:
|
; CHECK-LABEL: and:
|
||||||
; CHECK: and @r{{[0-9]+}}+, r{{[0-9]+}}
|
; CHECK: and.w @r{{[0-9]+}}+, r{{[0-9]+}}
|
||||||
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
%tmp4 = load i16, i16* %arrayidx ; <i16> [#uses=1]
|
||||||
%add = and i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
%add = and i16 %tmp4, %sum.09 ; <i16> [#uses=2]
|
||||||
%inc = add i16 %i.010, 1 ; <i16> [#uses=2]
|
%inc = add i16 %i.010, 1 ; <i16> [#uses=2]
|
||||||
|
@ -6,8 +6,8 @@ target triple = "msp430"
|
|||||||
; Test that CMP instruction is not removed by MachineCSE.
|
; Test that CMP instruction is not removed by MachineCSE.
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @f
|
; CHECK-LABEL: @f
|
||||||
; CHECK: cmp r15, r13
|
; CHECK: cmp.w r15, r13
|
||||||
; CHECK: cmp r15, r13
|
; CHECK: cmp.w r15, r13
|
||||||
; CHECK-NEXT: jeq .LBB0_2
|
; CHECK-NEXT: jeq .LBB0_2
|
||||||
define i16 @f(i16, i16, i16, i16) {
|
define i16 @f(i16, i16, i16, i16) {
|
||||||
entry:
|
entry:
|
||||||
|
@ -9,10 +9,10 @@ define i16 @sccweqand(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t3
|
ret i16 %t3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: sccweqand:
|
; CHECK-LABEL: sccweqand:
|
||||||
; CHECK: bit r13, r12
|
; CHECK: bit.w r13, r12
|
||||||
; CHECK: mov r2, r12
|
; CHECK: mov.w r2, r12
|
||||||
; CHECK: rra r12
|
; CHECK: rra.w r12
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
|
|
||||||
define i16 @sccwneand(i16 %a, i16 %b) nounwind {
|
define i16 @sccwneand(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = and i16 %a, %b
|
%t1 = and i16 %a, %b
|
||||||
@ -21,9 +21,9 @@ define i16 @sccwneand(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t3
|
ret i16 %t3
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: sccwneand:
|
; CHECK-LABEL: sccwneand:
|
||||||
; CHECK: bit r13, r12
|
; CHECK: bit.w r13, r12
|
||||||
; CHECK: mov r2, r12
|
; CHECK: mov.w r2, r12
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
|
|
||||||
define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp ne i16 %a, %b
|
%t1 = icmp ne i16 %a, %b
|
||||||
@ -31,11 +31,11 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccwne:
|
; CHECK-LABEL:sccwne:
|
||||||
; CHECK: cmp r13, r12
|
; CHECK: cmp.w r13, r12
|
||||||
; CHECK: mov r2, r13
|
; CHECK: mov.w r2, r13
|
||||||
; CHECK: rra r13
|
; CHECK: rra.w r13
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: bic r13, r12
|
; CHECK: bic.w r13, r12
|
||||||
|
|
||||||
define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp eq i16 %a, %b
|
%t1 = icmp eq i16 %a, %b
|
||||||
@ -43,10 +43,10 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccweq:
|
; CHECK-LABEL:sccweq:
|
||||||
; CHECK: cmp r13, r12
|
; CHECK: cmp.w r13, r12
|
||||||
; CHECK: mov r2, r12
|
; CHECK: mov.w r2, r12
|
||||||
; CHECK: rra r12
|
; CHECK: rra.w r12
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
|
|
||||||
define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp ugt i16 %a, %b
|
%t1 = icmp ugt i16 %a, %b
|
||||||
@ -54,9 +54,9 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccwugt:
|
; CHECK-LABEL:sccwugt:
|
||||||
; CHECK: cmp r12, r13
|
; CHECK: cmp.w r12, r13
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: bic r2, r12
|
; CHECK: bic.w r2, r12
|
||||||
|
|
||||||
define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp uge i16 %a, %b
|
%t1 = icmp uge i16 %a, %b
|
||||||
@ -64,9 +64,9 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccwuge:
|
; CHECK-LABEL:sccwuge:
|
||||||
; CHECK: cmp r13, r12
|
; CHECK: cmp.w r13, r12
|
||||||
; CHECK: mov r2, r12
|
; CHECK: mov.w r2, r12
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
|
|
||||||
define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp ult i16 %a, %b
|
%t1 = icmp ult i16 %a, %b
|
||||||
@ -74,9 +74,9 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccwult:
|
; CHECK-LABEL:sccwult:
|
||||||
; CHECK: cmp r13, r12
|
; CHECK: cmp.w r13, r12
|
||||||
; CHECK: mov #1, r12
|
; CHECK: mov.w #1, r12
|
||||||
; CHECK: bic r2, r12
|
; CHECK: bic.w r2, r12
|
||||||
|
|
||||||
define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp ule i16 %a, %b
|
%t1 = icmp ule i16 %a, %b
|
||||||
@ -84,9 +84,9 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
|||||||
ret i16 %t2
|
ret i16 %t2
|
||||||
}
|
}
|
||||||
; CHECK-LABEL:sccwule:
|
; CHECK-LABEL:sccwule:
|
||||||
; CHECK: cmp r12, r13
|
; CHECK: cmp.w r12, r13
|
||||||
; CHECK: mov r2, r12
|
; CHECK: mov.w r2, r12
|
||||||
; CHECK: and #1, r12
|
; CHECK: and.w #1, r12
|
||||||
|
|
||||||
define i16 @sccwsgt(i16 %a, i16 %b) nounwind {
|
define i16 @sccwsgt(i16 %a, i16 %b) nounwind {
|
||||||
%t1 = icmp sgt i16 %a, %b
|
%t1 = icmp sgt i16 %a, %b
|
||||||
|
@ -21,7 +21,7 @@ entry:
|
|||||||
define zeroext i8 @shl8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {
|
define zeroext i8 @shl8(i8 zeroext %a, i8 zeroext %cnt) nounwind readnone {
|
||||||
entry:
|
entry:
|
||||||
; CHECK: shl8
|
; CHECK: shl8
|
||||||
; CHECK: add.b
|
; CHECK: rla.b
|
||||||
%shl = shl i8 %a, %cnt
|
%shl = shl i8 %a, %cnt
|
||||||
ret i8 %shl
|
ret i8 %shl
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ entry:
|
|||||||
define zeroext i16 @lshr16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {
|
define zeroext i16 @lshr16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: lshr16:
|
; CHECK-LABEL: lshr16:
|
||||||
; CHECK: rrc
|
; CHECK: rrc.w
|
||||||
%shr = lshr i16 %a, %cnt
|
%shr = lshr i16 %a, %cnt
|
||||||
ret i16 %shr
|
ret i16 %shr
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ entry:
|
|||||||
define signext i16 @ashr16(i16 signext %a, i16 zeroext %cnt) nounwind readnone {
|
define signext i16 @ashr16(i16 signext %a, i16 zeroext %cnt) nounwind readnone {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: ashr16:
|
; CHECK-LABEL: ashr16:
|
||||||
; CHECK: rra
|
; CHECK: rra.w
|
||||||
%shr = ashr i16 %a, %cnt
|
%shr = ashr i16 %a, %cnt
|
||||||
ret i16 %shr
|
ret i16 %shr
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ entry:
|
|||||||
define zeroext i16 @shl16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {
|
define zeroext i16 @shl16(i16 zeroext %a, i16 zeroext %cnt) nounwind readnone {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: shl16:
|
; CHECK-LABEL: shl16:
|
||||||
; CHECK: add
|
; CHECK: rla.w
|
||||||
%shl = shl i16 %a, %cnt
|
%shl = shl i16 %a, %cnt
|
||||||
ret i16 %shl
|
ret i16 %shl
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ target triple = "msp430---elf"
|
|||||||
|
|
||||||
define %s @fred() #0 {
|
define %s @fred() #0 {
|
||||||
; CHECK-LABEL: fred:
|
; CHECK-LABEL: fred:
|
||||||
; CHECK: mov #2314, 14(r12)
|
; CHECK: mov.w #2314, 14(r12)
|
||||||
; CHECK: mov #2828, 12(r12)
|
; CHECK: mov.w #2828, 12(r12)
|
||||||
; CHECK: mov #3342, 10(r12)
|
; CHECK: mov.w #3342, 10(r12)
|
||||||
; CHECK: mov #3840, 8(r12)
|
; CHECK: mov.w #3840, 8(r12)
|
||||||
; CHECK: mov #258, 6(r12)
|
; CHECK: mov.w #258, 6(r12)
|
||||||
; CHECK: mov #772, 4(r12)
|
; CHECK: mov.w #772, 4(r12)
|
||||||
; CHECK: mov #1286, 2(r12)
|
; CHECK: mov.w #1286, 2(r12)
|
||||||
; CHECK: mov #1800, 0(r12)
|
; CHECK: mov.w #1800, 0(r12)
|
||||||
ret %s {i64 72623859790382856, i64 651345242494996224}
|
ret %s {i64 72623859790382856, i64 651345242494996224}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ target triple = "msp430"
|
|||||||
%struct.X = type { i8 }
|
%struct.X = type { i8 }
|
||||||
|
|
||||||
; CHECK-LABEL: @foo
|
; CHECK-LABEL: @foo
|
||||||
; CHECK: sub #4, r1
|
; CHECK: sub.w #4, r1
|
||||||
; CHECK: mov.b #1, 3(r1)
|
; CHECK: mov.b #1, 3(r1)
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
%1 = alloca %struct.X
|
%1 = alloca %struct.X
|
||||||
@ -21,7 +21,7 @@ define void @foo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: @bar
|
; CHECK-LABEL: @bar
|
||||||
; CHECK: sub #4, r1
|
; CHECK: sub.w #4, r1
|
||||||
; CHECK: mov.b #1, 3(r1)
|
; CHECK: mov.b #1, 3(r1)
|
||||||
define void @bar() {
|
define void @bar() {
|
||||||
%1 = alloca [3 x %struct.X]
|
%1 = alloca [3 x %struct.X]
|
||||||
@ -40,8 +40,8 @@ define void @bar() {
|
|||||||
%struct.Y = type { i8, i16 }
|
%struct.Y = type { i8, i16 }
|
||||||
|
|
||||||
; CHECK-LABEL: @baz
|
; CHECK-LABEL: @baz
|
||||||
; CHECK: sub #8, r1
|
; CHECK: sub.w #8, r1
|
||||||
; CHECK: mov #2, 6(r1)
|
; CHECK: mov.w #2, 6(r1)
|
||||||
define void @baz() {
|
define void @baz() {
|
||||||
%1 = alloca %struct.Y, align 2
|
%1 = alloca %struct.Y, align 2
|
||||||
%2 = alloca %struct.Y, align 2
|
%2 = alloca %struct.Y, align 2
|
||||||
|
@ -5,11 +5,11 @@ target triple = "msp430---elf"
|
|||||||
|
|
||||||
define void @test() #0 {
|
define void @test() #0 {
|
||||||
; CHECK-LABEL: test:
|
; CHECK-LABEL: test:
|
||||||
; CHECK: sub #2, r1
|
; CHECK: sub.w #2, r1
|
||||||
%1 = alloca i8, align 1
|
%1 = alloca i8, align 1
|
||||||
; CHECK-NEXT: clr.b 1(r1)
|
; CHECK-NEXT: mov.b #0, 1(r1)
|
||||||
store i8 0, i8* %1, align 1
|
store i8 0, i8* %1, align 1
|
||||||
; CHECK-NEXT: add #2, r1
|
; CHECK-NEXT: add.w #2, r1
|
||||||
; CHECK-NEXT: ret
|
; CHECK-NEXT: ret
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,12 @@ declare void @llvm.va_copy(i8*, i8*) nounwind
|
|||||||
define void @va_start(i16 %a, ...) nounwind {
|
define void @va_start(i16 %a, ...) nounwind {
|
||||||
entry:
|
entry:
|
||||||
; CHECK-LABEL: va_start:
|
; CHECK-LABEL: va_start:
|
||||||
; CHECK: sub #2, r1
|
; CHECK: sub.w #2, r1
|
||||||
%vl = alloca i8*, align 2
|
%vl = alloca i8*, align 2
|
||||||
%vl1 = bitcast i8** %vl to i8*
|
%vl1 = bitcast i8** %vl to i8*
|
||||||
; CHECK-NEXT: mov r1, [[REG:r[0-9]+]]
|
; CHECK-NEXT: mov.w r1, [[REG:r[0-9]+]]
|
||||||
; CHECK-NEXT: add #6, [[REG]]
|
; CHECK-NEXT: add.w #6, [[REG]]
|
||||||
; CHECK-NEXT: mov [[REG]], 0(r1)
|
; CHECK-NEXT: mov.w [[REG]], 0(r1)
|
||||||
call void @llvm.va_start(i8* %vl1)
|
call void @llvm.va_start(i8* %vl1)
|
||||||
call void @llvm.va_end(i8* %vl1)
|
call void @llvm.va_end(i8* %vl1)
|
||||||
ret void
|
ret void
|
||||||
@ -26,11 +26,11 @@ entry:
|
|||||||
; CHECK-LABEL: va_arg:
|
; CHECK-LABEL: va_arg:
|
||||||
%vl.addr = alloca i8*, align 2
|
%vl.addr = alloca i8*, align 2
|
||||||
store i8* %vl, i8** %vl.addr, align 2
|
store i8* %vl, i8** %vl.addr, align 2
|
||||||
; CHECK: mov r12, [[REG:r[0-9]+]]
|
; CHECK: mov.w r12, [[REG:r[0-9]+]]
|
||||||
; CHECK-NEXT: incd [[REG]]
|
; CHECK-NEXT: add.w #2, [[REG]]
|
||||||
; CHECK-NEXT: mov [[REG]], 0(r1)
|
; CHECK-NEXT: mov.w [[REG]], 0(r1)
|
||||||
%0 = va_arg i8** %vl.addr, i16
|
%0 = va_arg i8** %vl.addr, i16
|
||||||
; CHECK-NEXT: mov 0(r12), r12
|
; CHECK-NEXT: mov.w 0(r12), r12
|
||||||
ret i16 %0
|
ret i16 %0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,11 +39,11 @@ entry:
|
|||||||
; CHECK-LABEL: va_copy:
|
; CHECK-LABEL: va_copy:
|
||||||
%vl.addr = alloca i8*, align 2
|
%vl.addr = alloca i8*, align 2
|
||||||
%vl2 = alloca i8*, align 2
|
%vl2 = alloca i8*, align 2
|
||||||
; CHECK-DAG: mov r12, 2(r1)
|
; CHECK-DAG: mov.w r12, 2(r1)
|
||||||
store i8* %vl, i8** %vl.addr, align 2
|
store i8* %vl, i8** %vl.addr, align 2
|
||||||
%0 = bitcast i8** %vl2 to i8*
|
%0 = bitcast i8** %vl2 to i8*
|
||||||
%1 = bitcast i8** %vl.addr to i8*
|
%1 = bitcast i8** %vl.addr to i8*
|
||||||
; CHECK-DAG: mov r12, 0(r1)
|
; CHECK-DAG: mov.w r12, 0(r1)
|
||||||
call void @llvm.va_copy(i8* %0, i8* %1)
|
call void @llvm.va_copy(i8* %0, i8* %1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
if not 'MSP430' in config.root.targets:
|
|
||||||
config.unsupported = True
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
# 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)
|
|
@ -1,110 +0,0 @@
|
|||||||
; 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
|
|
@ -1,7 +0,0 @@
|
|||||||
; 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
|
|
@ -1,10 +0,0 @@
|
|||||||
; 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]
|
|
@ -1,19 +0,0 @@
|
|||||||
; 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
|
|
@ -1,3 +0,0 @@
|
|||||||
if not 'MSP430' in config.root.targets:
|
|
||||||
config.unsupported = True
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
|||||||
; 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]
|
|
@ -1,22 +0,0 @@
|
|||||||
; 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
|
|
Loading…
x
Reference in New Issue
Block a user