mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-09 01:38:03 +00:00
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:
parent
f918d78356
commit
5445972c1b
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMMos6502AsmParser
|
||||
Mos6502AsmParser.cpp
|
||||
)
|
@ -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
|
@ -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
@ -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)
|
||||
|
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMMos6502Disassembler
|
||||
Mos6502Disassembler.cpp
|
||||
)
|
@ -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
|
@ -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
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
*/
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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", []>;
|
||||
|
@ -30,4 +30,4 @@ using namespace llvm;
|
||||
#define GET_REGINFO_TARGET_DESC
|
||||
#include "Mos6502GenRegisterInfo.inc"
|
||||
|
||||
Mos6502RegisterInfo::Mos6502RegisterInfo() : Mos6502GenRegisterInfo(M6502::O7) {}
|
||||
Mos6502RegisterInfo::Mos6502RegisterInfo() : Mos6502GenRegisterInfo(0) {}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user