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