Trying to clean source code and compile blindly

But it's not working :(
AsmParser and Disassembler were removed for now, to simplify things.
This commit is contained in:
Damián Silvani 2015-08-06 20:37:08 -03:00
parent f918d78356
commit 5445972c1b
32 changed files with 184 additions and 5807 deletions

View File

@ -1,3 +0,0 @@
add_llvm_library(LLVMMos6502AsmParser
Mos6502AsmParser.cpp
)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/Mos6502/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 = Mos6502AsmParser
parent = Mos6502
required_libraries = MC MCParser Mos6502Desc Mos6502Info Support
add_to_library_groups = Mos6502

View File

@ -1,15 +0,0 @@
##===- lib/Target/Mos6502/AsmParser/Makefile ------------------*- Makefile-*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMos6502AsmParser
# Hack: we need to include 'main' Mos6502 target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

File diff suppressed because it is too large Load Diff

View File

@ -22,11 +22,10 @@ add_llvm_target(Mos6502CodeGen
Mos6502Subtarget.cpp
Mos6502TargetMachine.cpp
Mos6502MCInstLower.cpp
Mos6502TargetObjectFile.cpp
)
)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)
add_subdirectory(InstPrinter)
add_subdirectory(AsmParser)
add_subdirectory(Disassembler)
#add_subdirectory(AsmParser)
#add_subdirectory(Disassembler)

View File

@ -1,3 +0,0 @@
add_llvm_library(LLVMMos6502Disassembler
Mos6502Disassembler.cpp
)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/Mos6502/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 = Mos6502Disassembler
parent = Mos6502
required_libraries = MCDisassembler Mos6502Info Support
add_to_library_groups = Mos6502

View File

@ -1,16 +0,0 @@
##===- lib/Target/Mos6502/Disassembler/Makefile --------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMos6502Disassembler
# Hack: we need to include 'main' Mos6502 target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -1,493 +0,0 @@
//===- Mos6502Disassembler.cpp - Disassembler for Mos6502 -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the Mos6502 Disassembler.
//
//===----------------------------------------------------------------------===//
#include "Mos6502.h"
#include "Mos6502RegisterInfo.h"
#include "Mos6502Subtarget.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
#define DEBUG_TYPE "mos6502-disassembler"
typedef MCDisassembler::DecodeStatus DecodeStatus;
namespace {
/// A disassembler class for Mos6502.
class Mos6502Disassembler : public MCDisassembler {
public:
Mos6502Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
: MCDisassembler(STI, Ctx) {}
virtual ~Mos6502Disassembler() {}
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &VStream,
raw_ostream &CStream) const override;
};
}
namespace llvm {
extern Target TheMos6502Target;
}
static MCDisassembler *createMos6502Disassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new Mos6502Disassembler(STI, Ctx);
}
extern "C" void LLVMInitializeMos6502Disassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(TheMos6502Target,
createMos6502Disassembler);
}
static const unsigned IntRegDecoderTable[] = {
M6502::G0, M6502::G1, M6502::G2, M6502::G3,
M6502::G4, M6502::G5, M6502::G6, M6502::G7,
M6502::O0, M6502::O1, M6502::O2, M6502::O3,
M6502::O4, M6502::O5, M6502::O6, M6502::O7,
M6502::L0, M6502::L1, M6502::L2, M6502::L3,
M6502::L4, M6502::L5, M6502::L6, M6502::L7,
M6502::I0, M6502::I1, M6502::I2, M6502::I3,
M6502::I4, M6502::I5, M6502::I6, M6502::I7 };
static const unsigned FPRegDecoderTable[] = {
M6502::F0, M6502::F1, M6502::F2, M6502::F3,
M6502::F4, M6502::F5, M6502::F6, M6502::F7,
M6502::F8, M6502::F9, M6502::F10, M6502::F11,
M6502::F12, M6502::F13, M6502::F14, M6502::F15,
M6502::F16, M6502::F17, M6502::F18, M6502::F19,
M6502::F20, M6502::F21, M6502::F22, M6502::F23,
M6502::F24, M6502::F25, M6502::F26, M6502::F27,
M6502::F28, M6502::F29, M6502::F30, M6502::F31 };
static const unsigned DFPRegDecoderTable[] = {
M6502::D0, M6502::D16, M6502::D1, M6502::D17,
M6502::D2, M6502::D18, M6502::D3, M6502::D19,
M6502::D4, M6502::D20, M6502::D5, M6502::D21,
M6502::D6, M6502::D22, M6502::D7, M6502::D23,
M6502::D8, M6502::D24, M6502::D9, M6502::D25,
M6502::D10, M6502::D26, M6502::D11, M6502::D27,
M6502::D12, M6502::D28, M6502::D13, M6502::D29,
M6502::D14, M6502::D30, M6502::D15, M6502::D31 };
static const unsigned QFPRegDecoderTable[] = {
M6502::Q0, M6502::Q8, ~0U, ~0U,
M6502::Q1, M6502::Q9, ~0U, ~0U,
M6502::Q2, M6502::Q10, ~0U, ~0U,
M6502::Q3, M6502::Q11, ~0U, ~0U,
M6502::Q4, M6502::Q12, ~0U, ~0U,
M6502::Q5, M6502::Q13, ~0U, ~0U,
M6502::Q6, M6502::Q14, ~0U, ~0U,
M6502::Q7, M6502::Q15, ~0U, ~0U } ;
static const unsigned FCCRegDecoderTable[] = {
M6502::FCC0, M6502::FCC1, M6502::FCC2, M6502::FCC3 };
static const unsigned ASRRegDecoderTable[] = {
M6502::Y, M6502::ASR1, M6502::ASR2, M6502::ASR3,
M6502::ASR4, M6502::ASR5, M6502::ASR6, M6502::ASR7,
M6502::ASR8, M6502::ASR9, M6502::ASR10, M6502::ASR11,
M6502::ASR12, M6502::ASR13, M6502::ASR14, M6502::ASR15,
M6502::ASR16, M6502::ASR17, M6502::ASR18, M6502::ASR19,
M6502::ASR20, M6502::ASR21, M6502::ASR22, M6502::ASR23,
M6502::ASR24, M6502::ASR25, M6502::ASR26, M6502::ASR27,
M6502::ASR28, M6502::ASR29, M6502::ASR30, M6502::ASR31};
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = IntRegDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = IntRegDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = FPRegDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = DFPRegDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
unsigned Reg = QFPRegDecoderTable[RegNo];
if (Reg == ~0U)
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 3)
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
return MCDisassembler::Success;
}
static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
return MCDisassembler::Success;
}
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
#include "Mos6502GenDisassemblerTables.inc"
/// Read four bytes from the ArrayRef and return 32 bit word.
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
uint64_t &Size, uint32_t &Insn,
bool IsLittleEndian) {
// We want to read exactly 4 Bytes of data.
if (Bytes.size() < 4) {
Size = 0;
return MCDisassembler::Fail;
}
Insn = IsLittleEndian
? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
(Bytes[3] << 24)
: (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
(Bytes[0] << 24);
return MCDisassembler::Success;
}
DecodeStatus Mos6502Disassembler::getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address,
raw_ostream &VStream,
raw_ostream &CStream) const {
uint32_t Insn;
bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
DecodeStatus Result =
readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
if (Result == MCDisassembler::Fail)
return MCDisassembler::Fail;
// Calling the auto-generated decoder function.
Result =
decodeInstruction(DecoderTableMos650232, Instr, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
return MCDisassembler::Fail;
}
typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder,
bool isLoad, DecodeFunc DecodeRD) {
unsigned rd = fieldFromInstruction(insn, 25, 5);
unsigned rs1 = fieldFromInstruction(insn, 14, 5);
bool isImm = fieldFromInstruction(insn, 13, 1);
bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
unsigned asi = fieldFromInstruction(insn, 5, 8);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
else
rs2 = fieldFromInstruction(insn, 0, 5);
DecodeStatus status;
if (isLoad) {
status = DecodeRD(MI, rd, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
// Decode rs1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode imm|rs2.
if (isImm)
MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
if (hasAsi)
MI.addOperand(MCOperand::createImm(asi));
if (!isLoad) {
status = DecodeRD(MI, rd, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
return MCDisassembler::Success;
}
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeIntRegsRegisterClass);
}
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeFPRegsRegisterClass);
}
static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeDFPRegsRegisterClass);
}
static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, true,
DecodeQFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeIntRegsRegisterClass);
}
static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeDFPRegsRegisterClass);
}
static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
uint64_t Address, const void *Decoder) {
return DecodeMem(Inst, insn, Address, Decoder, false,
DecodeQFPRegsRegisterClass);
}
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
uint64_t Address, uint64_t Offset,
uint64_t Width, MCInst &MI,
const void *Decoder) {
const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
Offset, Width);
}
static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
uint64_t Address, const void *Decoder) {
unsigned tgt = fieldFromInstruction(insn, 0, 30);
tgt <<= 2;
if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
0, 30, MI, Decoder))
MI.addOperand(MCOperand::createImm(tgt));
return MCDisassembler::Success;
}
static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
uint64_t Address, const void *Decoder) {
unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
MI.addOperand(MCOperand::createImm(tgt));
return MCDisassembler::Success;
}
static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder) {
unsigned rd = fieldFromInstruction(insn, 25, 5);
unsigned rs1 = fieldFromInstruction(insn, 14, 5);
unsigned isImm = fieldFromInstruction(insn, 13, 1);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
else
rs2 = fieldFromInstruction(insn, 0, 5);
// Decode RD.
DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode RS1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode RS1 | SIMM13.
if (isImm)
MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
return MCDisassembler::Success;
}
static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder) {
unsigned rs1 = fieldFromInstruction(insn, 14, 5);
unsigned isImm = fieldFromInstruction(insn, 13, 1);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
else
rs2 = fieldFromInstruction(insn, 0, 5);
// Decode RS1.
DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode RS2 | SIMM13.
if (isImm)
MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
return MCDisassembler::Success;
}
static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
const void *Decoder) {
unsigned rd = fieldFromInstruction(insn, 25, 5);
unsigned rs1 = fieldFromInstruction(insn, 14, 5);
unsigned isImm = fieldFromInstruction(insn, 13, 1);
bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
unsigned asi = fieldFromInstruction(insn, 5, 8);
unsigned rs2 = 0;
unsigned simm13 = 0;
if (isImm)
simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
else
rs2 = fieldFromInstruction(insn, 0, 5);
// Decode RD.
DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode RS1.
status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
// Decode RS1 | SIMM13.
if (isImm)
MI.addOperand(MCOperand::createImm(simm13));
else {
status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
if (status != MCDisassembler::Success)
return status;
}
if (hasAsi)
MI.addOperand(MCOperand::createImm(asi));
return MCDisassembler::Success;
}

View File

@ -18,6 +18,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
@ -34,10 +35,6 @@ namespace Mos6502 {
#define PRINT_ALIAS_INSTR
#include "Mos6502GenAsmWriter.inc"
bool Mos6502InstPrinter::isV9(const MCSubtargetInfo &STI) const {
return (STI.getFeatureBits()[Mos6502::FeatureV9]) != 0;
}
void Mos6502InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
{
OS << '%' << StringRef(getRegisterName(RegNo)).lower();
@ -53,6 +50,9 @@ void Mos6502InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
bool Mos6502InstPrinter::printMos6502AliasInstr(const MCInst *MI,
const MCSubtargetInfo &STI,
raw_ostream &O) {
return false;
/*
switch (MI->getOpcode()) {
default: return false;
case M6502::JMPLrr:
@ -102,6 +102,7 @@ bool Mos6502InstPrinter::printMos6502AliasInstr(const MCInst *MI,
return true;
}
}
*/
}
void Mos6502InstPrinter::printOperand(const MCInst *MI, int opNum,
@ -136,8 +137,8 @@ void Mos6502InstPrinter::printMemOperand(const MCInst *MI, int opNum,
}
const MCOperand &MO = MI->getOperand(opNum+1);
if (MO.isReg() && MO.getReg() == M6502::G0)
return; // don't print "+%g0"
//if (MO.isReg() && MO.getReg() == M6502::G0)
// return; // don't print "+%g0"
if (MO.isImm() && MO.getImm() == 0)
return; // don't print "+0"
@ -150,6 +151,7 @@ void Mos6502InstPrinter::printCCOperand(const MCInst *MI, int opNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
int CC = (int)MI->getOperand(opNum).getImm();
/*
switch (MI->getOpcode()) {
default: break;
case M6502::FBCOND:
@ -167,6 +169,7 @@ void Mos6502InstPrinter::printCCOperand(const MCInst *MI, int opNum,
CC = (CC < 16) ? (CC + 16) : CC;
break;
}
*/
O << MOS6502CondCodeToString((SPCC::CondCodes)CC);
}

View File

@ -32,7 +32,6 @@ public:
const MCSubtargetInfo &STI) override;
bool printMos6502AliasInstr(const MCInst *MI, const MCSubtargetInfo &STI,
raw_ostream &OS);
bool isV9(const MCSubtargetInfo &STI) const;
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI,

View File

@ -16,16 +16,16 @@
;===------------------------------------------------------------------------===;
[common]
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
subdirectories = InstPrinter MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
name = Mos6502
parent = Target
has_asmparser = 1
has_asmparser = 0
has_asmprinter = 1
has_disassembler = 1
has_jit = 1
has_disassembler = 0
has_jit = 0
[component_1]
type = Library

View File

@ -94,11 +94,11 @@ void Mos6502MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
unsigned tlsOpNo = 0;
switch (MI.getOpcode()) {
default: break;
case M6502::TLS_CALL: tlsOpNo = 1; break;
case M6502::TLS_ADDrr:
case M6502::TLS_ADDXrr:
case M6502::TLS_LDrr:
case M6502::TLS_LDXrr: tlsOpNo = 3; break;
//case M6502::TLS_CALL: tlsOpNo = 1; break;
//case M6502::TLS_ADDrr:
//case M6502::TLS_ADDXrr:
//case M6502::TLS_LDrr:
//case M6502::TLS_LDXrr: tlsOpNo = 3; break;
}
if (tlsOpNo != 0) {
const MCOperand &MO = MI.getOperand(tlsOpNo);
@ -146,6 +146,7 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
if (MO.isReg() || MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);
/*
if (MI.getOpcode() == M6502::TLS_CALL) {
// No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in
// encodeInstruction.
@ -160,6 +161,7 @@ getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
#endif
return 0;
}
*/
MCFixupKind fixupKind = (MCFixupKind)Mos6502::fixup_mos6502_call30;

View File

@ -36,9 +36,9 @@ using namespace llvm;
static MCAsmInfo *createMos6502MCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT) {
MCAsmInfo *MAI = new Mos6502ELFMCAsmInfo(TT);
unsigned Reg = MRI.getDwarfRegNum(M6502::O6, true);
MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
MAI->addInitialFrameState(Inst);
//unsigned Reg = MRI.getDwarfRegNum(M6502::O6, true);
//MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
//MAI->addInitialFrameState(Inst);
return MAI;
}
@ -50,7 +50,7 @@ static MCInstrInfo *createMos6502MCInstrInfo() {
static MCRegisterInfo *createMos6502MCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitMos6502MCRegisterInfo(X, M6502::O7);
//InitMos6502MCRegisterInfo(X, M6502::O7);
return X;
}

View File

@ -26,9 +26,11 @@ include "Mos6502InstrInfo.td"
def Mos6502InstrInfo : InstrInfo;
/*
def Mos6502AsmParser : AsmParser {
bit ShouldEmitMatchRegisterName = 0;
}
*/
//===----------------------------------------------------------------------===//
// MOS6502 processors supported.
@ -52,6 +54,6 @@ def Mos6502AsmWriter : AsmWriter {
def Mos6502 : Target {
// Pull in Instruction Info:
let InstructionSet = Mos6502InstrInfo;
let AssemblyParsers = [Mos6502AsmParser];
//let AssemblyParsers = [Mos6502AsmParser];
let AssemblyWriters = [Mos6502AsmWriter];
}

View File

@ -23,7 +23,6 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@ -113,7 +112,7 @@ static void EmitCall(MCStreamer &OutStreamer,
const MCSubtargetInfo &STI)
{
MCInst CallInst;
CallInst.setOpcode(M6502::CALL);
//CallInst.setOpcode(M6502::CALL);
CallInst.addOperand(Callee);
OutStreamer.EmitInstruction(CallInst, STI);
}
@ -123,12 +122,13 @@ static void EmitSETHI(MCStreamer &OutStreamer,
const MCSubtargetInfo &STI)
{
MCInst SETHIInst;
SETHIInst.setOpcode(M6502::SETHIi);
//SETHIInst.setOpcode(M6502::SETHIi);
SETHIInst.addOperand(RD);
SETHIInst.addOperand(Imm);
OutStreamer.EmitInstruction(SETHIInst, STI);
}
/*
static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
MCOperand &RS1, MCOperand &Src2, MCOperand &RD,
const MCSubtargetInfo &STI)
@ -140,23 +140,26 @@ static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
Inst.addOperand(Src2);
OutStreamer.EmitInstruction(Inst, STI);
}
*/
static void EmitOR(MCStreamer &OutStreamer,
MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
const MCSubtargetInfo &STI) {
EmitBinary(OutStreamer, M6502::ORri, RS1, Imm, RD, STI);
//EmitBinary(OutStreamer, M6502::ORri, RS1, Imm, RD, STI);
}
/*
static void EmitADD(MCStreamer &OutStreamer,
MCOperand &RS1, MCOperand &RS2, MCOperand &RD,
const MCSubtargetInfo &STI) {
EmitBinary(OutStreamer, M6502::ADDrr, RS1, RS2, RD, STI);
}
*/
static void EmitSHL(MCStreamer &OutStreamer,
MCOperand &RS1, MCOperand &Imm, MCOperand &RD,
const MCSubtargetInfo &STI) {
EmitBinary(OutStreamer, M6502::SLLri, RS1, Imm, RD, STI);
//EmitBinary(OutStreamer, M6502::SLLri, RS1, Imm, RD, STI);
}
@ -180,8 +183,8 @@ void Mos6502AsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
const MachineOperand &MO = MI->getOperand(0);
assert(MO.getReg() != M6502::O7 &&
"%o7 is assigned as destination for getpcx!");
//assert(MO.getReg() != M6502::O7 &&
// "%o7 is assigned as destination for getpcx!");
MCOperand MCRegOP = MCOperand::createReg(MO.getReg());
@ -216,11 +219,11 @@ void Mos6502AsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
OutContext));
EmitSHL(*OutStreamer, MCRegOP, imm, MCRegOP, STI);
// Use register %o7 to load the lower 32 bits.
MCOperand RegO7 = MCOperand::createReg(M6502::O7);
EmitHiLo(*OutStreamer, GOTLabel,
Mos6502MCExpr::VK_Mos6502_HI, Mos6502MCExpr::VK_Mos6502_LO,
RegO7, OutContext, STI);
EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
//MCOperand RegO7 = MCOperand::createReg(M6502::O7);
//EmitHiLo(*OutStreamer, GOTLabel,
// Mos6502MCExpr::VK_Mos6502_HI, Mos6502MCExpr::VK_Mos6502_LO,
// RegO7, OutContext, STI);
//EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
}
}
return;
@ -230,7 +233,7 @@ void Mos6502AsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
MCSymbol *EndLabel = OutContext.createTempSymbol();
MCSymbol *SethiLabel = OutContext.createTempSymbol();
MCOperand RegO7 = MCOperand::createReg(M6502::O7);
//MCOperand RegO7 = MCOperand::createReg(M6502::O7);
// <StartLabel>:
// call <EndLabel>
@ -253,7 +256,7 @@ void Mos6502AsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
GOTLabel, StartLabel, EndLabel,
OutContext);
EmitOR(*OutStreamer, MCRegOP, loImm, MCRegOP, STI);
EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
//EmitADD(*OutStreamer, MCRegOP, RegO7, MCRegOP, STI);
}
void Mos6502AsmPrinter::EmitInstruction(const MachineInstr *MI)
@ -264,9 +267,9 @@ void Mos6502AsmPrinter::EmitInstruction(const MachineInstr *MI)
case TargetOpcode::DBG_VALUE:
// FIXME: Debug Value.
return;
case M6502::GETPCX:
LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
return;
//case M6502::GETPCX:
// LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
// return;
}
MachineBasicBlock::const_instr_iterator I = MI;
MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
@ -277,23 +280,7 @@ void Mos6502AsmPrinter::EmitInstruction(const MachineInstr *MI)
} while ((++I != E) && I->isInsideBundle()); // Delay slot check.
}
void Mos6502AsmPrinter::EmitFunctionBodyStart() {
if (!MF->getSubtarget<Mos6502Subtarget>().is64Bit())
return;
const MachineRegisterInfo &MRI = MF->getRegInfo();
const unsigned globalRegs[] = { M6502::G2, M6502::G3, M6502::G6, M6502::G7, 0 };
for (unsigned i = 0; globalRegs[i] != 0; ++i) {
unsigned reg = globalRegs[i];
if (MRI.use_empty(reg))
continue;
if (reg == M6502::G6 || reg == M6502::G7)
getTargetStreamer().emitMos6502RegisterIgnore(reg);
else
getTargetStreamer().emitMos6502RegisterScratch(reg);
}
}
void Mos6502AsmPrinter::EmitFunctionBodyStart() {}
void Mos6502AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
@ -301,56 +288,6 @@ void Mos6502AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
const MachineOperand &MO = MI->getOperand (opNum);
Mos6502MCExpr::VariantKind TF = (Mos6502MCExpr::VariantKind) MO.getTargetFlags();
#ifndef NDEBUG
// Verify the target flags.
if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) {
if (MI->getOpcode() == M6502::CALL)
assert(TF == Mos6502MCExpr::VK_Mos6502_None &&
"Cannot handle target flags on call address");
else if (MI->getOpcode() == M6502::SETHIi || MI->getOpcode() == M6502::SETHIXi)
assert((TF == Mos6502MCExpr::VK_Mos6502_HI
|| TF == Mos6502MCExpr::VK_Mos6502_H44
|| TF == Mos6502MCExpr::VK_Mos6502_HH
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_GD_HI22
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDM_HI22
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDO_HIX22
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_IE_HI22
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LE_HIX22) &&
"Invalid target flags for address operand on sethi");
else if (MI->getOpcode() == M6502::TLS_CALL)
assert((TF == Mos6502MCExpr::VK_Mos6502_None
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_GD_CALL
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDM_CALL) &&
"Cannot handle target flags on tls call address");
else if (MI->getOpcode() == M6502::TLS_ADDrr)
assert((TF == Mos6502MCExpr::VK_Mos6502_TLS_GD_ADD
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDM_ADD
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDO_ADD
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_IE_ADD) &&
"Cannot handle target flags on add for TLS");
else if (MI->getOpcode() == M6502::TLS_LDrr)
assert(TF == Mos6502MCExpr::VK_Mos6502_TLS_IE_LD &&
"Cannot handle target flags on ld for TLS");
else if (MI->getOpcode() == M6502::TLS_LDXrr)
assert(TF == Mos6502MCExpr::VK_Mos6502_TLS_IE_LDX &&
"Cannot handle target flags on ldx for TLS");
else if (MI->getOpcode() == M6502::XORri || MI->getOpcode() == M6502::XORXri)
assert((TF == Mos6502MCExpr::VK_Mos6502_TLS_LDO_LOX10
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LE_LOX10) &&
"Cannot handle target flags on xor for TLS");
else
assert((TF == Mos6502MCExpr::VK_Mos6502_LO
|| TF == Mos6502MCExpr::VK_Mos6502_M44
|| TF == Mos6502MCExpr::VK_Mos6502_L44
|| TF == Mos6502MCExpr::VK_Mos6502_HM
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_GD_LO10
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_LDM_LO10
|| TF == Mos6502MCExpr::VK_Mos6502_TLS_IE_LO10 ) &&
"Invalid target flags for small address operand");
}
#endif
bool CloseParen = Mos6502MCExpr::printVariantKind(O, TF);
switch (MO.getType()) {
@ -394,9 +331,9 @@ void Mos6502AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
return;
}
if (MI->getOperand(opNum+1).isReg() &&
MI->getOperand(opNum+1).getReg() == M6502::G0)
return; // don't print "+%g0"
//if (MI->getOperand(opNum+1).isReg() &&
// MI->getOperand(opNum+1).getReg() == M6502::G0)
// return; // don't print "+%g0"
if (MI->getOperand(opNum+1).isImm() &&
MI->getOperand(opNum+1).getImm() == 0)
return; // don't print "+0"

View File

@ -34,56 +34,12 @@ DisableLeafProc("disable-mos6502-leaf-proc",
cl::Hidden);
Mos6502FrameLowering::Mos6502FrameLowering(const Mos6502Subtarget &ST)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8) {}
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8, 0, 8) {}
void Mos6502FrameLowering::emitSPAdjustment(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
int NumBytes,
unsigned ADDrr,
unsigned ADDri) const {
DebugLoc dl = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
const Mos6502InstrInfo &TII =
*static_cast<const Mos6502InstrInfo *>(MF.getSubtarget().getInstrInfo());
if (NumBytes >= -4096 && NumBytes < 4096) {
BuildMI(MBB, MBBI, dl, TII.get(ADDri), M6502::O6)
.addReg(M6502::O6).addImm(NumBytes);
return;
}
// Emit this the hard way. This clobbers G1 which we always know is
// available here.
if (NumBytes >= 0) {
// Emit nonnegative numbers with sethi + or.
// sethi %hi(NumBytes), %g1
// or %g1, %lo(NumBytes), %g1
// add %sp, %g1, %sp
BuildMI(MBB, MBBI, dl, TII.get(M6502::SETHIi), M6502::G1)
.addImm(HI22(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(M6502::ORri), M6502::G1)
.addReg(M6502::G1).addImm(LO10(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(ADDrr), M6502::O6)
.addReg(M6502::O6).addReg(M6502::G1);
return ;
}
// Emit negative numbers with sethi + xor.
// sethi %hix(NumBytes), %g1
// xor %g1, %lox(NumBytes), %g1
// add %sp, %g1, %sp
BuildMI(MBB, MBBI, dl, TII.get(M6502::SETHIi), M6502::G1)
.addImm(HIX22(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(M6502::XORri), M6502::G1)
.addReg(M6502::G1).addImm(LOX10(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(ADDrr), M6502::O6)
.addReg(M6502::O6).addReg(M6502::G1);
}
void Mos6502FrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
/*
Mos6502MachineFunctionInfo *FuncInfo = MF.getInfo<Mos6502MachineFunctionInfo>();
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
@ -129,26 +85,12 @@ void Mos6502FrameLowering::emitPrologue(MachineFunction &MF,
MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA));
BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
*/
}
void Mos6502FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (!hasReservedCallFrame(MF)) {
MachineInstr &MI = *I;
int Size = MI.getOperand(0).getImm();
if (MI.getOpcode() == M6502::ADJCALLSTACKDOWN)
Size = -Size;
if (Size)
emitSPAdjustment(MF, MBB, I, Size, M6502::ADDrr, M6502::ADDri);
}
MBB.erase(I);
}
void Mos6502FrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
/*
Mos6502MachineFunctionInfo *FuncInfo = MF.getInfo<Mos6502MachineFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const Mos6502InstrInfo &TII =
@ -169,11 +111,7 @@ void Mos6502FrameLowering::emitEpilogue(MachineFunction &MF,
NumBytes = MF.getSubtarget<Mos6502Subtarget>().getAdjustedFrameSize(NumBytes);
emitSPAdjustment(MF, MBB, MBBI, NumBytes, M6502::ADDrr, M6502::ADDri);
}
bool Mos6502FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
// Reserve call frame if there are no variable sized objects on the stack.
return !MF.getFrameInfo()->hasVarSizedObjects();
*/
}
// hasFP - Return true if the specified function should have a dedicated frame
@ -185,6 +123,71 @@ bool Mos6502FrameLowering::hasFP(const MachineFunction &MF) const {
MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
}
/*
void Mos6502FrameLowering::emitSPAdjustment(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
int NumBytes,
unsigned ADDrr,
unsigned ADDri) const {
DebugLoc dl = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
const Mos6502InstrInfo &TII =
*static_cast<const Mos6502InstrInfo *>(MF.getSubtarget().getInstrInfo());
if (NumBytes >= -4096 && NumBytes < 4096) {
BuildMI(MBB, MBBI, dl, TII.get(ADDri), M6502::O6)
.addReg(M6502::O6).addImm(NumBytes);
return;
}
// Emit this the hard way. This clobbers G1 which we always know is
// available here.
if (NumBytes >= 0) {
// Emit nonnegative numbers with sethi + or.
// sethi %hi(NumBytes), %g1
// or %g1, %lo(NumBytes), %g1
// add %sp, %g1, %sp
BuildMI(MBB, MBBI, dl, TII.get(M6502::SETHIi), M6502::G1)
.addImm(HI22(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(M6502::ORri), M6502::G1)
.addReg(M6502::G1).addImm(LO10(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(ADDrr), M6502::O6)
.addReg(M6502::O6).addReg(M6502::G1);
return ;
}
// Emit negative numbers with sethi + xor.
// sethi %hix(NumBytes), %g1
// xor %g1, %lox(NumBytes), %g1
// add %sp, %g1, %sp
BuildMI(MBB, MBBI, dl, TII.get(M6502::SETHIi), M6502::G1)
.addImm(HIX22(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(M6502::XORri), M6502::G1)
.addReg(M6502::G1).addImm(LOX10(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(ADDrr), M6502::O6)
.addReg(M6502::O6).addReg(M6502::G1);
}
void Mos6502FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (!hasReservedCallFrame(MF)) {
MachineInstr &MI = *I;
int Size = MI.getOperand(0).getImm();
if (MI.getOpcode() == M6502::ADJCALLSTACKDOWN)
Size = -Size;
if (Size)
emitSPAdjustment(MF, MBB, I, Size, M6502::ADDrr, M6502::ADDri);
}
MBB.erase(I);
}
bool Mos6502FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
// Reserve call frame if there are no variable sized objects on the stack.
return !MF.getFrameInfo()->hasVarSizedObjects();
}
static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)
{
@ -256,3 +259,4 @@ void Mos6502FrameLowering::determineCalleeSaves(MachineFunction &MF,
}
}
*/

View File

@ -29,13 +29,15 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
/*
void
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool hasFP(const MachineFunction &MF) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
@ -52,7 +54,7 @@ private:
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
int NumBytes, unsigned ADDrr, unsigned ADDri) const;
*/
};
} // End llvm namespace

View File

@ -18,6 +18,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@ -59,165 +60,9 @@ public:
// Include the pieces autogenerated from the target description.
#include "Mos6502GenDAGISel.inc"
private:
SDNode* getGlobalBaseReg();
};
} // end anonymous namespace
SDNode* Mos6502DAGToDAGISel::getGlobalBaseReg() {
unsigned GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
return CurDAG->getRegister(GlobalBaseReg,
TLI->getPointerTy(CurDAG->getDataLayout()))
.getNode();
}
bool Mos6502DAGToDAGISel::SelectADDRri(SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(
FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
return true;
}
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress ||
Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
return false; // direct calls.
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
if (isInt<13>(CN->getSExtValue())) {
if (FrameIndexSDNode *FIN =
dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
// Constant offset from frame ref.
Base = CurDAG->getTargetFrameIndex(
FIN->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout()));
} else {
Base = Addr.getOperand(0);
}
Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),
MVT::i32);
return true;
}
}
if (Addr.getOperand(0).getOpcode() == SPISD::Lo) {
Base = Addr.getOperand(1);
Offset = Addr.getOperand(0).getOperand(0);
return true;
}
if (Addr.getOperand(1).getOpcode() == SPISD::Lo) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Addr;
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
return true;
}
bool Mos6502DAGToDAGISel::SelectADDRrr(SDValue Addr, SDValue &R1, SDValue &R2) {
if (Addr.getOpcode() == ISD::FrameIndex) return false;
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress ||
Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
return false; // direct calls.
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
if (isInt<13>(CN->getSExtValue()))
return false; // Let the reg+imm pattern catch this!
if (Addr.getOperand(0).getOpcode() == SPISD::Lo ||
Addr.getOperand(1).getOpcode() == SPISD::Lo)
return false; // Let the reg+imm pattern catch this!
R1 = Addr.getOperand(0);
R2 = Addr.getOperand(1);
return true;
}
R1 = Addr;
R2 = CurDAG->getRegister(M6502::G0, TLI->getPointerTy(CurDAG->getDataLayout()));
return true;
}
SDNode *Mos6502DAGToDAGISel::Select(SDNode *N) {
SDLoc dl(N);
if (N->isMachineOpcode()) {
N->setNodeId(-1);
return nullptr; // Already selected.
}
switch (N->getOpcode()) {
default: break;
case SPISD::GLOBAL_BASE_REG:
return getGlobalBaseReg();
case ISD::SDIV:
case ISD::UDIV: {
// sdivx / udivx handle 64-bit divides.
if (N->getValueType(0) == MVT::i64)
break;
// FIXME: should use a custom expander to expose the SRA to the dag.
SDValue DivLHS = N->getOperand(0);
SDValue DivRHS = N->getOperand(1);
// Set the Y register to the high-part.
SDValue TopPart;
if (N->getOpcode() == ISD::SDIV) {
TopPart = SDValue(CurDAG->getMachineNode(M6502::SRAri, dl, MVT::i32, DivLHS,
CurDAG->getTargetConstant(31, dl, MVT::i32)),
0);
} else {
TopPart = CurDAG->getRegister(M6502::G0, MVT::i32);
}
TopPart = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, M6502::Y, TopPart,
SDValue())
.getValue(1);
// FIXME: Handle div by immediate.
unsigned Opcode = N->getOpcode() == ISD::SDIV ? M6502::SDIVrr : M6502::UDIVrr;
return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS,
TopPart);
}
case ISD::MULHU:
case ISD::MULHS: {
// FIXME: Handle mul by immediate.
SDValue MulLHS = N->getOperand(0);
SDValue MulRHS = N->getOperand(1);
unsigned Opcode = N->getOpcode() == ISD::MULHU ? M6502::UMULrr : M6502::SMULrr;
SDNode *Mul =
CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, MulLHS, MulRHS);
SDValue ResultHigh = SDValue(Mul, 1);
ReplaceUses(SDValue(N, 0), ResultHigh);
return nullptr;
}
}
return SelectCode(N);
}
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
bool
Mos6502DAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
unsigned ConstraintID,
std::vector<SDValue> &OutOps) {
SDValue Op0, Op1;
switch (ConstraintID) {
default: return true;
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: // memory
if (!SelectADDRrr(Op, Op0, Op1))
SelectADDRri(Op, Op0, Op1);
break;
}
OutOps.push_back(Op0);
OutOps.push_back(Op1);
return false;
}
/// createMos6502ISelDag - This pass converts a legalized DAG into a
/// MOS6502-specific DAG, ready for instruction scheduling.

File diff suppressed because it is too large Load Diff

View File

@ -21,40 +21,12 @@
namespace llvm {
class Mos6502Subtarget;
namespace SPISD {
enum NodeType : unsigned {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
CMPICC, // Compare two GPR operands, set icc+xcc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRXCC, // Branch to dest on xcc condition (64-bit only).
BRFCC, // Branch to dest on fcc condition
SELECT_ICC, // Select between two values using the current ICC flags.
SELECT_XCC, // Select between two values using the current XCC flags.
SELECT_FCC, // Select between two values using the current FCC flags.
Hi, Lo, // Hi/Lo operations, typically on a global address.
FTOI, // FP to Int within a FP register.
ITOF, // Int to FP within a FP register.
FTOX, // FP to Int64 within a FP register.
XTOF, // Int64 to FP within a FP register.
CALL, // A call instruction.
RET_FLAG, // Return with a flag operand.
GLOBAL_BASE_REG, // Global base reg for PIC.
FLUSHW, // FLUSH register windows to stack.
TLS_ADD, // For Thread Local Storage (TLS).
TLS_LD,
TLS_CALL
};
}
class Mos6502TargetLowering : public TargetLowering {
const Mos6502Subtarget *Subtarget;
public:
Mos6502TargetLowering(TargetMachine &TM, const Mos6502Subtarget &STI);
/*
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
/// computeKnownBitsForTargetNode - Determine which of the bits specified
@ -176,6 +148,7 @@ namespace llvm {
MachineBasicBlock *BB,
unsigned Opcode,
unsigned CondCode = 0) const;
*/
};
} // end namespace llvm

View File

@ -35,420 +35,3 @@ void Mos6502InstrInfo::anchor() {}
Mos6502InstrInfo::Mos6502InstrInfo(Mos6502Subtarget &ST)
: Mos6502GenInstrInfo(M6502::ADJCALLSTACKDOWN, M6502::ADJCALLSTACKUP), RI(),
Subtarget(ST) {}
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than loading from the stack slot.
unsigned Mos6502InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
if (MI->getOpcode() == M6502::LDri ||
MI->getOpcode() == M6502::LDXri ||
MI->getOpcode() == M6502::LDFri ||
MI->getOpcode() == M6502::LDDFri ||
MI->getOpcode() == M6502::LDQFri) {
if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
MI->getOperand(2).getImm() == 0) {
FrameIndex = MI->getOperand(1).getIndex();
return MI->getOperand(0).getReg();
}
}
return 0;
}
/// isStoreToStackSlot - If the specified machine instruction is a direct
/// store to a stack slot, return the virtual or physical register number of
/// the source reg along with the FrameIndex of the loaded stack slot. If
/// not, return 0. This predicate must return 0 if the instruction has
/// any side effects other than storing to the stack slot.
unsigned Mos6502InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
if (MI->getOpcode() == M6502::STri ||
MI->getOpcode() == M6502::STXri ||
MI->getOpcode() == M6502::STFri ||
MI->getOpcode() == M6502::STDFri ||
MI->getOpcode() == M6502::STQFri) {
if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
MI->getOperand(1).getImm() == 0) {
FrameIndex = MI->getOperand(0).getIndex();
return MI->getOperand(2).getReg();
}
}
return 0;
}
static bool IsIntegerCC(unsigned CC)
{
return (CC <= SPCC::ICC_VC);
}
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
{
switch(CC) {
case SPCC::ICC_A: return SPCC::ICC_N;
case SPCC::ICC_N: return SPCC::ICC_A;
case SPCC::ICC_NE: return SPCC::ICC_E;
case SPCC::ICC_E: return SPCC::ICC_NE;
case SPCC::ICC_G: return SPCC::ICC_LE;
case SPCC::ICC_LE: return SPCC::ICC_G;
case SPCC::ICC_GE: return SPCC::ICC_L;
case SPCC::ICC_L: return SPCC::ICC_GE;
case SPCC::ICC_GU: return SPCC::ICC_LEU;
case SPCC::ICC_LEU: return SPCC::ICC_GU;
case SPCC::ICC_CC: return SPCC::ICC_CS;
case SPCC::ICC_CS: return SPCC::ICC_CC;
case SPCC::ICC_POS: return SPCC::ICC_NEG;
case SPCC::ICC_NEG: return SPCC::ICC_POS;
case SPCC::ICC_VC: return SPCC::ICC_VS;
case SPCC::ICC_VS: return SPCC::ICC_VC;
case SPCC::FCC_A: return SPCC::FCC_N;
case SPCC::FCC_N: return SPCC::FCC_A;
case SPCC::FCC_U: return SPCC::FCC_O;
case SPCC::FCC_O: return SPCC::FCC_U;
case SPCC::FCC_G: return SPCC::FCC_ULE;
case SPCC::FCC_LE: return SPCC::FCC_UG;
case SPCC::FCC_UG: return SPCC::FCC_LE;
case SPCC::FCC_ULE: return SPCC::FCC_G;
case SPCC::FCC_L: return SPCC::FCC_UGE;
case SPCC::FCC_GE: return SPCC::FCC_UL;
case SPCC::FCC_UL: return SPCC::FCC_GE;
case SPCC::FCC_UGE: return SPCC::FCC_L;
case SPCC::FCC_LG: return SPCC::FCC_UE;
case SPCC::FCC_UE: return SPCC::FCC_LG;
case SPCC::FCC_NE: return SPCC::FCC_E;
case SPCC::FCC_E: return SPCC::FCC_NE;
}
llvm_unreachable("Invalid cond code");
}
bool Mos6502InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const
{
MachineBasicBlock::iterator I = MBB.end();
MachineBasicBlock::iterator UnCondBrIter = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
// When we see a non-terminator, we are done.
if (!isUnpredicatedTerminator(I))
break;
// Terminator is not a branch.
if (!I->isBranch())
return true;
// Handle Unconditional branches.
if (I->getOpcode() == M6502::BA) {
UnCondBrIter = I;
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
}
while (std::next(I) != MBB.end())
std::next(I)->eraseFromParent();
Cond.clear();
FBB = nullptr;
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
TBB = nullptr;
I->eraseFromParent();
I = MBB.end();
UnCondBrIter = MBB.end();
continue;
}
TBB = I->getOperand(0).getMBB();
continue;
}
unsigned Opcode = I->getOpcode();
if (Opcode != M6502::BCOND && Opcode != M6502::FBCOND)
return true; // Unknown Opcode.
SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
if (Cond.empty()) {
MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
if (AllowModify && UnCondBrIter != MBB.end() &&
MBB.isLayoutSuccessor(TargetBB)) {
// Transform the code
//
// brCC L1
// ba L2
// L1:
// ..
// L2:
//
// into
//
// brnCC L2
// L1:
// ...
// L2:
//
BranchCode = GetOppositeBranchCondition(BranchCode);
MachineBasicBlock::iterator OldInst = I;
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(Opcode))
.addMBB(UnCondBrIter->getOperand(0).getMBB()).addImm(BranchCode);
BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(M6502::BA))
.addMBB(TargetBB);
OldInst->eraseFromParent();
UnCondBrIter->eraseFromParent();
UnCondBrIter = MBB.end();
I = MBB.end();
continue;
}
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(MachineOperand::CreateImm(BranchCode));
continue;
}
// FIXME: Handle subsequent conditional branches.
// For now, we can't handle multiple conditional branches.
return true;
}
return false;
}
unsigned
Mos6502InstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
ArrayRef<MachineOperand> Cond,
DebugLoc DL) const {
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
assert((Cond.size() == 1 || Cond.size() == 0) &&
"Mos6502 branch conditions should have one component!");
if (Cond.empty()) {
assert(!FBB && "Unconditional branch with multiple successors!");
BuildMI(&MBB, DL, get(M6502::BA)).addMBB(TBB);
return 1;
}
// Conditional branch
unsigned CC = Cond[0].getImm();
if (IsIntegerCC(CC))
BuildMI(&MBB, DL, get(M6502::BCOND)).addMBB(TBB).addImm(CC);
else
BuildMI(&MBB, DL, get(M6502::FBCOND)).addMBB(TBB).addImm(CC);
if (!FBB)
return 1;
BuildMI(&MBB, DL, get(M6502::BA)).addMBB(FBB);
return 2;
}
unsigned Mos6502InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const
{
MachineBasicBlock::iterator I = MBB.end();
unsigned Count = 0;
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
continue;
if (I->getOpcode() != M6502::BA
&& I->getOpcode() != M6502::BCOND
&& I->getOpcode() != M6502::FBCOND)
break; // Not a branch
I->eraseFromParent();
I = MBB.end();
++Count;
}
return Count;
}
void Mos6502InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
unsigned numSubRegs = 0;
unsigned movOpc = 0;
const unsigned *subRegIdx = nullptr;
const unsigned DFP_FP_SubRegsIdx[] = { M6502::sub_even, M6502::sub_odd };
const unsigned QFP_DFP_SubRegsIdx[] = { M6502::sub_even64, M6502::sub_odd64 };
const unsigned QFP_FP_SubRegsIdx[] = { M6502::sub_even, M6502::sub_odd,
M6502::sub_odd64_then_sub_even,
M6502::sub_odd64_then_sub_odd };
if (M6502::IntRegsRegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(M6502::ORrr), DestReg).addReg(M6502::G0)
.addReg(SrcReg, getKillRegState(KillSrc));
else if (M6502::FPRegsRegClass.contains(DestReg, SrcReg))
BuildMI(MBB, I, DL, get(M6502::FMOVS), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
else if (M6502::DFPRegsRegClass.contains(DestReg, SrcReg)) {
if (Subtarget.isV9()) {
BuildMI(MBB, I, DL, get(M6502::FMOVD), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
} else {
// Use two FMOVS instructions.
subRegIdx = DFP_FP_SubRegsIdx;
numSubRegs = 2;
movOpc = M6502::FMOVS;
}
} else if (M6502::QFPRegsRegClass.contains(DestReg, SrcReg)) {
if (Subtarget.isV9()) {
if (Subtarget.hasHardQuad()) {
BuildMI(MBB, I, DL, get(M6502::FMOVQ), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
} else {
// Use two FMOVD instructions.
subRegIdx = QFP_DFP_SubRegsIdx;
numSubRegs = 2;
movOpc = M6502::FMOVD;
}
} else {
// Use four FMOVS instructions.
subRegIdx = QFP_FP_SubRegsIdx;
numSubRegs = 4;
movOpc = M6502::FMOVS;
}
} else if (M6502::ASRRegsRegClass.contains(DestReg) &&
M6502::IntRegsRegClass.contains(SrcReg)) {
BuildMI(MBB, I, DL, get(M6502::WRASRrr), DestReg)
.addReg(M6502::G0)
.addReg(SrcReg, getKillRegState(KillSrc));
} else if (M6502::IntRegsRegClass.contains(DestReg) &&
M6502::ASRRegsRegClass.contains(SrcReg)) {
BuildMI(MBB, I, DL, get(M6502::RDASR), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
} else
llvm_unreachable("Impossible reg-to-reg copy");
if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0)
return;
const TargetRegisterInfo *TRI = &getRegisterInfo();
MachineInstr *MovMI = nullptr;
for (unsigned i = 0; i != numSubRegs; ++i) {
unsigned Dst = TRI->getSubReg(DestReg, subRegIdx[i]);
unsigned Src = TRI->getSubReg(SrcReg, subRegIdx[i]);
assert(Dst && Src && "Bad sub-register");
MovMI = BuildMI(MBB, I, DL, get(movOpc), Dst).addReg(Src);
}
// Add implicit super-register defs and kills to the last MovMI.
MovMI->addRegisterDefined(DestReg, TRI);
if (KillSrc)
MovMI->addRegisterKilled(SrcReg, TRI);
}
void Mos6502InstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction *MF = MBB.getParent();
const MachineFrameInfo &MFI = *MF->getFrameInfo();
MachineMemOperand *MMO =
MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
MachineMemOperand::MOStore,
MFI.getObjectSize(FI),
MFI.getObjectAlignment(FI));
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
if (RC == &M6502::I64RegsRegClass)
BuildMI(MBB, I, DL, get(M6502::STXri)).addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
else if (RC == &M6502::IntRegsRegClass)
BuildMI(MBB, I, DL, get(M6502::STri)).addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
else if (RC == &M6502::FPRegsRegClass)
BuildMI(MBB, I, DL, get(M6502::STFri)).addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
else if (M6502::DFPRegsRegClass.hasSubClassEq(RC))
BuildMI(MBB, I, DL, get(M6502::STDFri)).addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
else if (M6502::QFPRegsRegClass.hasSubClassEq(RC))
// Use STQFri irrespective of its legality. If STQ is not legal, it will be
// lowered into two STDs in eliminateFrameIndex.
BuildMI(MBB, I, DL, get(M6502::STQFri)).addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
else
llvm_unreachable("Can't store this register to stack slot");
}
void Mos6502InstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
if (I != MBB.end()) DL = I->getDebugLoc();
MachineFunction *MF = MBB.getParent();
const MachineFrameInfo &MFI = *MF->getFrameInfo();
MachineMemOperand *MMO =
MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI),
MachineMemOperand::MOLoad,
MFI.getObjectSize(FI),
MFI.getObjectAlignment(FI));
if (RC == &M6502::I64RegsRegClass)
BuildMI(MBB, I, DL, get(M6502::LDXri), DestReg).addFrameIndex(FI).addImm(0)
.addMemOperand(MMO);
else if (RC == &M6502::IntRegsRegClass)
BuildMI(MBB, I, DL, get(M6502::LDri), DestReg).addFrameIndex(FI).addImm(0)
.addMemOperand(MMO);
else if (RC == &M6502::FPRegsRegClass)
BuildMI(MBB, I, DL, get(M6502::LDFri), DestReg).addFrameIndex(FI).addImm(0)
.addMemOperand(MMO);
else if (M6502::DFPRegsRegClass.hasSubClassEq(RC))
BuildMI(MBB, I, DL, get(M6502::LDDFri), DestReg).addFrameIndex(FI).addImm(0)
.addMemOperand(MMO);
else if (M6502::QFPRegsRegClass.hasSubClassEq(RC))
// Use LDQFri irrespective of its legality. If LDQ is not legal, it will be
// lowered into two LDDs in eliminateFrameIndex.
BuildMI(MBB, I, DL, get(M6502::LDQFri), DestReg).addFrameIndex(FI).addImm(0)
.addMemOperand(MMO);
else
llvm_unreachable("Can't load this register from stack slot");
}
unsigned Mos6502InstrInfo::getGlobalBaseReg(MachineFunction *MF) const
{
Mos6502MachineFunctionInfo *Mos6502FI = MF->getInfo<Mos6502MachineFunctionInfo>();
unsigned GlobalBaseReg = Mos6502FI->getGlobalBaseReg();
if (GlobalBaseReg != 0)
return GlobalBaseReg;
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
MachineRegisterInfo &RegInfo = MF->getRegInfo();
const TargetRegisterClass *PtrRC =
Subtarget.is64Bit() ? &M6502::I64RegsRegClass : &M6502::IntRegsRegClass;
GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
DebugLoc dl;
BuildMI(FirstMBB, MBBI, dl, get(M6502::GETPCX), GlobalBaseReg);
Mos6502FI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;
}

View File

@ -24,18 +24,6 @@ namespace llvm {
class Mos6502Subtarget;
/// SPII - This namespace holds all of the target specific flags that
/// instruction info tracks.
///
namespace SPII {
enum {
Pseudo = (1<<0),
Load = (1<<1),
Store = (1<<2),
DelaySlot = (1<<3)
};
}
class Mos6502InstrInfo : public Mos6502GenInstrInfo {
const Mos6502RegisterInfo RI;
const Mos6502Subtarget& Subtarget;
@ -49,6 +37,7 @@ public:
///
const Mos6502RegisterInfo &getRegisterInfo() const { return RI; }
/*
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
/// the destination along with the FrameIndex of the loaded stack slot. If
@ -94,6 +83,7 @@ public:
const TargetRegisterInfo *TRI) const override;
unsigned getGlobalBaseReg(MachineFunction *MF) const;
*/
};
}

View File

@ -44,4 +44,27 @@ let Defs = [X, SREG] in
(ins XR:$src),
"inx",
[(set XR:$dst, (add XR:$src, 1)), (implicit SREG)]>;
def DEX : InstM6502<(outs XR:$dst),
(ins XR:$src),
"dex",
[(set XR:$dst, (sub XR:$src, 1)), (implicit SREG)]>;
}
let Defs = [Y, SREG] in
{
def INY : InstM6502<(outs YR:$dst),
(ins YR:$src),
"iny",
[(set YR:$dst, (add YR:$src, 1)), (implicit SREG)]>;
def DEY : InstM6502<(outs YR:$dst),
(ins YR:$src),
"dey",
[(set YR:$dst, (sub YR:$src, 1)), (implicit SREG)]>;
}
def NOP : InstM6502<(outs), (ins), "nop", []>;
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins), "#ADJCALLSTACKDOWN", []>;
def ADJCALLSTACKUP : Pseudo<(outs), (ins), "#ADJCALLSTACKUP", []>;

View File

@ -30,4 +30,4 @@ using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "Mos6502GenRegisterInfo.inc"
Mos6502RegisterInfo::Mos6502RegisterInfo() : Mos6502GenRegisterInfo(M6502::O7) {}
Mos6502RegisterInfo::Mos6502RegisterInfo() : Mos6502GenRegisterInfo(0) {}

View File

@ -22,6 +22,17 @@
namespace llvm {
struct Mos6502RegisterInfo : public Mos6502GenRegisterInfo {
Mos6502RegisterInfo();
const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
/// Stack Frame Processing Methods
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
unsigned FIOperandNum,
RegScavenger *RS = NULL) const override;
/// Debug information queries.
unsigned getFrameRegister(const MachineFunction &MF) const override;
};
} // end namespace llvm

View File

@ -28,56 +28,17 @@ void Mos6502Subtarget::anchor() { }
Mos6502Subtarget &Mos6502Subtarget::initializeSubtargetDependencies(StringRef CPU,
StringRef FS) {
IsV9 = false;
V8DeprecatedInsts = false;
IsVIS = false;
HasHardQuad = false;
UsePopc = false;
// Determine default and user specified characteristics
std::string CPUName = CPU;
if (CPUName.empty())
CPUName = (Is64Bit) ? "v9" : "v8";
// Parse features string.
ParseSubtargetFeatures(CPUName, FS);
// Popc is a v9-only instruction.
if (!IsV9)
UsePopc = false;
return *this;
}
Mos6502Subtarget::Mos6502Subtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, TargetMachine &TM,
bool is64Bit)
: Mos6502GenSubtargetInfo(TT, CPU, FS), Is64Bit(is64Bit),
const std::string &FS, TargetMachine &TM)
: Mos6502GenSubtargetInfo(TT, CPU, FS),
InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
FrameLowering(*this) {}
int Mos6502Subtarget::getAdjustedFrameSize(int frameSize) const {
if (is64Bit()) {
// All 64-bit stack frames must be 16-byte aligned, and must reserve space
// for spilling the 16 window registers at %sp+BIAS..%sp+BIAS+128.
frameSize += 128;
// Frames with calls must also reserve space for 6 outgoing arguments
// whether they are used or not. LowerCall_64 takes care of that.
assert(frameSize % 16 == 0 && "Stack size not 16-byte aligned");
} else {
// Emit the correct save instruction based on the number of bytes in
// the frame. Minimum stack frame size according to V8 ABI is:
// 16 words for register window spill
// 1 word for address of returned aggregate-value
// + 6 words for passing parameters on the stack
// ----------
// 23 words * 4 bytes per word = 92 bytes
frameSize += 92;
// Round up to next doubleword boundary -- a double-word boundary
// is required by the ABI.
frameSize = RoundUpToAlignment(frameSize, 8);
}
return frameSize;
}

View File

@ -31,12 +31,7 @@ class StringRef;
class Mos6502Subtarget : public Mos6502GenSubtargetInfo {
virtual void anchor();
bool IsV9;
bool V8DeprecatedInsts;
bool IsVIS, IsVIS2, IsVIS3;
bool Is64Bit;
bool HasHardQuad;
bool UsePopc;
Mos6502InstrInfo InstrInfo;
Mos6502TargetLowering TLInfo;
TargetSelectionDAGInfo TSInfo;
@ -44,7 +39,7 @@ class Mos6502Subtarget : public Mos6502GenSubtargetInfo {
public:
Mos6502Subtarget(const Triple &TT, const std::string &CPU,
const std::string &FS, TargetMachine &TM, bool is64bit);
const std::string &FS, TargetMachine &TM);
const Mos6502InstrInfo *getInstrInfo() const override { return &InstrInfo; }
const TargetFrameLowering *getFrameLowering() const override {
@ -60,32 +55,10 @@ public:
return &TSInfo;
}
bool isV9() const { return IsV9; }
bool isVIS() const { return IsVIS; }
bool isVIS2() const { return IsVIS2; }
bool isVIS3() const { return IsVIS3; }
bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; }
bool hasHardQuad() const { return HasHardQuad; }
bool usePopc() const { return UsePopc; }
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
Mos6502Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
bool is64Bit() const { return Is64Bit; }
/// The 64-bit ABI uses biased stack and frame pointers, so the stack frame
/// of the current function is the area from [%sp+BIAS] to [%fp+BIAS].
int64_t getStackPointerBias() const {
return is64Bit() ? 2047 : 0;
}
/// Given a actual stack size as determined by FrameInfo, this function
/// returns adjusted framesize which includes space for register window
/// spills and arguments.
int getAdjustedFrameSize(int stackSize) const;
};
} // end namespace llvm

View File

@ -1,4 +1,4 @@
//===-- Mos6502TargetMachine.cpp - Define TargetMachine for Mos6502 -----------===//
//===-- Mos6502TargetMachine.cpp - Define TargetMachine for Mos6502 -------===//
//
// The LLVM Compiler Infrastructure
//
@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//
#include "Mos6502TargetMachine.h"
#include "Mos6502TargetObjectFile.h"
#include "Mos6502.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/LegacyPassManager.h"
@ -21,37 +20,18 @@ using namespace llvm;
extern "C" void LLVMInitializeMos6502Target() {
// Register the target.
RegisterTargetMachine<Mos6502TargetMachine> Z(TheMos6502Target);
RegisterTargetMachine<Mos6502TargetMachine> X(TheMos6502Target);
}
static std::string computeDataLayout(const Triple &T) {
std::string Ret = "e";
Ret += "-m:e";
Ret += "-p:32:32";
// Alignments for 64 bit integers.
Ret += "-i64:64";
// On Mos6502V9 128 floats are aligned to 128 bits, on others only to 64.
// On Mos6502V9 registers can hold 64 or 32 bits, on others only 32.
Ret += "-f128:64-n32";
Ret += "-S64";
return Ret;
}
/// Mos6502TargetMachine ctor - Create an ILP32 architecture model
///
Mos6502TargetMachine::Mos6502TargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
RM, CM, OL),
TLOF(make_unique<Mos6502ELFTargetObjectFile>()),
Subtarget(TT, CPU, FS, *this, false) {
: LLVMTargetMachine(T, "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8",
TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, *this)
{
initAsmInfo();
}
@ -89,4 +69,4 @@ bool Mos6502PassConfig::addInstSelector() {
return false;
}
void Mos6502PassConfig::addPreEmitPass(){}
void Mos6502PassConfig::addPreEmitPass() {}

View File

@ -1,4 +1,4 @@
//===-- Mos6502TargetMachine.h - Define TargetMachine for Mos6502 ---*- C++ -*-===//
//===------- Mos6502TargetMachine.h - Define TargetMachine ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -21,7 +21,6 @@
namespace llvm {
class Mos6502TargetMachine : public LLVMTargetMachine {
std::unique_ptr<TargetLoweringObjectFile> TLOF;
Mos6502Subtarget Subtarget;
public:
@ -36,9 +35,6 @@ public:
// Pass Pipeline Configuration
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
TargetLoweringObjectFile *getObjFileLowering() const override {
return TLOF.get();
}
};
} // end namespace llvm

View File

@ -1,43 +0,0 @@
//===------- Mos6502TargetObjectFile.cpp - Mos6502 Object Info Impl -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Mos6502TargetObjectFile.h"
#include "MCTargetDesc/Mos6502MCExpr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;
const MCExpr *Mos6502ELFTargetObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
const TargetMachine &TM, MachineModuleInfo *MMI,
MCStreamer &Streamer) const {
if (Encoding & dwarf::DW_EH_PE_pcrel) {
MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
MCSymbol *SSym = getSymbolWithGlobalValueBase(GV, ".DW.stub", Mang, TM);
// Add information about the stub reference to ELFMMI so that the stub
// gets emitted by the asmprinter.
MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
if (!StubSym.getPointer()) {
MCSymbol *Sym = TM.getSymbol(GV, Mang);
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
}
MCContext &Ctx = getContext();
return Mos6502MCExpr::create(Mos6502MCExpr::VK_Mos6502_R_DISP32,
MCSymbolRefExpr::create(SSym, Ctx), Ctx);
}
return TargetLoweringObjectFileELF::getTTypeGlobalReference(
GV, Encoding, Mang, TM, MMI, Streamer);
}

View File

@ -1,35 +0,0 @@
//===-- Mos6502TargetObjectFile.h - Mos6502 Object Info -------------*- 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_MOS6502_MOS6502TARGETOBJECTFILE_H
#define LLVM_LIB_TARGET_MOS6502_MOS6502TARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
class MCContext;
class TargetMachine;
class Mos6502ELFTargetObjectFile : public TargetLoweringObjectFileELF {
public:
Mos6502ELFTargetObjectFile() :
TargetLoweringObjectFileELF()
{}
const MCExpr *
getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
Mangler &Mang, const TargetMachine &TM,
MachineModuleInfo *MMI,
MCStreamer &Streamer) const override;
};
} // end namespace llvm
#endif