From 91e7016b1f8c6ec874bb149618e9015ada6ebcd6 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Fri, 11 Jul 2014 23:47:17 -0400 Subject: [PATCH] More work to get a basic WDC65816 infrastructure in and compiling. --- lib/Target/WDC65816/Makefile | 5 +- lib/Target/WDC65816/WDC65816.h | 1 - lib/Target/WDC65816/WDC65816FrameLowering.cpp | 253 +++ lib/Target/WDC65816/WDC65816FrameLowering.h | 59 + lib/Target/WDC65816/WDC65816ISelLowering.h | 0 lib/Target/WDC65816/WDC65816InstrFormats.td | 232 +++ lib/Target/WDC65816/WDC65816InstrInfo.td | 1351 +++++++++++++++++ lib/Target/WDC65816/WDC65816TargetMachine.cpp | 6 +- 8 files changed, 1902 insertions(+), 5 deletions(-) create mode 100644 lib/Target/WDC65816/WDC65816FrameLowering.cpp create mode 100644 lib/Target/WDC65816/WDC65816FrameLowering.h create mode 100644 lib/Target/WDC65816/WDC65816ISelLowering.h create mode 100644 lib/Target/WDC65816/WDC65816InstrFormats.td create mode 100644 lib/Target/WDC65816/WDC65816InstrInfo.td diff --git a/lib/Target/WDC65816/Makefile b/lib/Target/WDC65816/Makefile index dd82f02a..378221f1 100644 --- a/lib/Target/WDC65816/Makefile +++ b/lib/Target/WDC65816/Makefile @@ -12,7 +12,10 @@ LIBRARYNAME = LLVMWDC65816CodeGen TARGET = WDC65816 # Make sure that tblgen is run, first thing. -BUILT_SOURCES = +BUILT_SOURCES = WDC65816GenRegisterInfo.inc WDC65816GenInstrInfo.inc \ + WDC65816GenAsmWriter.inc WDC65816GenDAGISel.inc \ + WDC65816GenSubtargetInfo.inc WDC65816GenCallingConv.inc \ + WDC65816GenCodeEmitter.inc # DIRS = InstPrinter Disassembler AsmParser TargetInfo MCTargetDesc diff --git a/lib/Target/WDC65816/WDC65816.h b/lib/Target/WDC65816/WDC65816.h index ae7852ad..2fbeff85 100644 --- a/lib/Target/WDC65816/WDC65816.h +++ b/lib/Target/WDC65816/WDC65816.h @@ -24,7 +24,6 @@ namespace llvm { class formatted_raw_ostream; FunctionPass *createWDC65816ISelDag(WDC65816TargetMachine &TM); - FunctionPass *createWDC65816DelaySlotFillerPass(TargetMachine &TM); } // end namespace llvm; diff --git a/lib/Target/WDC65816/WDC65816FrameLowering.cpp b/lib/Target/WDC65816/WDC65816FrameLowering.cpp new file mode 100644 index 00000000..1e9d9a08 --- /dev/null +++ b/lib/Target/WDC65816/WDC65816FrameLowering.cpp @@ -0,0 +1,253 @@ +//===-- WDC65816FrameLowering.cpp - WDC65816 Frame Information ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the WDC65816 implementation of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#include "WDC65816FrameLowering.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetOptions.h" + +using namespace llvm; + +#if 0 // JSR TODO - Do I need any of this? +static cl::opt +DisableLeafProc("disable-sparc-leaf-proc", + cl::init(false), + cl::desc("Disable Sparc leaf procedure optimization."), + cl::Hidden); + + +void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + int NumBytes, + unsigned ADDrr, + unsigned ADDri) const { + + DebugLoc dl = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc(); + const SparcInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + + if (NumBytes >= -4096 && NumBytes < 4096) { + BuildMI(MBB, MBBI, dl, TII.get(ADDri), SP::O6) + .addReg(SP::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(SP::SETHIi), SP::G1) + .addImm(HI22(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1) + .addReg(SP::G1).addImm(LO10(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6) + .addReg(SP::O6).addReg(SP::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(SP::SETHIi), SP::G1) + .addImm(HIX22(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(SP::XORri), SP::G1) + .addReg(SP::G1).addImm(LOX10(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6) + .addReg(SP::O6).addReg(SP::G1); +} + +void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { + SparcMachineFunctionInfo *FuncInfo = MF.getInfo(); + + MachineBasicBlock &MBB = MF.front(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const SparcInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + MachineBasicBlock::iterator MBBI = MBB.begin(); + DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + + // Get the number of bytes to allocate from the FrameInfo + int NumBytes = (int) MFI->getStackSize(); + + unsigned SAVEri = SP::SAVEri; + unsigned SAVErr = SP::SAVErr; + if (FuncInfo->isLeafProc()) { + if (NumBytes == 0) + return; + SAVEri = SP::ADDri; + SAVErr = SP::ADDrr; + } + NumBytes = - SubTarget.getAdjustedFrameSize(NumBytes); + emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri); + + MachineModuleInfo &MMI = MF.getMMI(); + const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); + MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(SP::PROLOG_LABEL)).addSym(FrameLabel); + + unsigned regFP = MRI->getDwarfRegNum(SP::I6, true); + + // Emit ".cfi_def_cfa_register 30". + MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, + regFP)); + // Emit ".cfi_window_save". + MMI.addFrameInst(MCCFIInstruction::createWindowSave(FrameLabel)); + + unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true); + unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true); + // Emit ".cfi_register 15, 31". + MMI.addFrameInst(MCCFIInstruction::createRegister(FrameLabel, + regOutRA, + regInRA)); +} + +void SparcFrameLowering:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + if (!hasReservedCallFrame(MF)) { + MachineInstr &MI = *I; + int Size = MI.getOperand(0).getImm(); + if (MI.getOpcode() == SP::ADJCALLSTACKDOWN) + Size = -Size; + + if (Size) + emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri); + } + MBB.erase(I); +} + + +void SparcFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + SparcMachineFunctionInfo *FuncInfo = MF.getInfo(); + MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); + const SparcInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + DebugLoc dl = MBBI->getDebugLoc(); + assert(MBBI->getOpcode() == SP::RETL && + "Can only put epilog before 'retl' instruction!"); + if (!FuncInfo->isLeafProc()) { + BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0) + .addReg(SP::G0); + return; + } + MachineFrameInfo *MFI = MF.getFrameInfo(); + + int NumBytes = (int) MFI->getStackSize(); + if (NumBytes == 0) + return; + + NumBytes = SubTarget.getAdjustedFrameSize(NumBytes); + emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri); +} + +bool SparcFrameLowering::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 +// pointer register. This is true if the function has variable sized allocas or +// if frame pointer elimination is disabled. +bool SparcFrameLowering::hasFP(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return MF.getTarget().Options.DisableFramePointerElim(MF) || + MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); +} + + +static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI) +{ + + for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) + if (MRI->isPhysRegUsed(reg)) + return false; + + for (unsigned reg = SP::L0; reg <= SP::L7; ++reg) + if (MRI->isPhysRegUsed(reg)) + return false; + + return true; +} + +bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const +{ + + MachineRegisterInfo &MRI = MF.getRegInfo(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + return !(MFI->hasCalls() // has calls + || MRI.isPhysRegUsed(SP::L0) // Too many registers needed + || MRI.isPhysRegUsed(SP::O6) // %SP is used + || hasFP(MF)); // need %FP +} + +void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const { + + MachineRegisterInfo &MRI = MF.getRegInfo(); + + // Remap %i[0-7] to %o[0-7]. + for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) { + if (!MRI.isPhysRegUsed(reg)) + continue; + unsigned mapped_reg = (reg - SP::I0 + SP::O0); + assert(!MRI.isPhysRegUsed(mapped_reg)); + + // Replace I register with O register. + MRI.replaceRegWith(reg, mapped_reg); + + // Mark the reg unused. + MRI.setPhysRegUnused(reg); + } + + // Rewrite MBB's Live-ins. + for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); + MBB != E; ++MBB) { + for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) { + if (!MBB->isLiveIn(reg)) + continue; + MBB->removeLiveIn(reg); + MBB->addLiveIn(reg - SP::I0 + SP::O0); + } + } + + assert(verifyLeafProcRegUse(&MRI)); +#ifdef XDEBUG + MF.verify(0, "After LeafProc Remapping"); +#endif +} + +void SparcFrameLowering::processFunctionBeforeCalleeSavedScan +(MachineFunction &MF, RegScavenger *RS) const { + + if (!DisableLeafProc && isLeafProc(MF)) { + SparcMachineFunctionInfo *MFI = MF.getInfo(); + MFI->setLeafProc(true); + + remapRegsForLeafProc(MF); + } + +} + +#endif diff --git a/lib/Target/WDC65816/WDC65816FrameLowering.h b/lib/Target/WDC65816/WDC65816FrameLowering.h new file mode 100644 index 00000000..dbf689d1 --- /dev/null +++ b/lib/Target/WDC65816/WDC65816FrameLowering.h @@ -0,0 +1,59 @@ +//===-- WDC65816FrameLowering.h - Define frame lowering for Sparc --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +// +//===----------------------------------------------------------------------===// + +#ifndef WDC65816_FRAMEINFO_H +#define WDC65816_FRAMEINFO_H + +#include "WDC65816.h" +#include "llvm/Target/TargetFrameLowering.h" + +namespace llvm { + + class WDC65816FrameLowering : public TargetFrameLowering { + public: + explicit WDC65816FrameLowering(void) + : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 1, 0) {} +#if 0 // JSR TODO - do I need any of this? + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into + /// the function. + void emitPrologue(MachineFunction &MF) const; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + + void eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const; + + bool hasReservedCallFrame(const MachineFunction &MF) const; + bool hasFP(const MachineFunction &MF) const; + void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS = NULL) const; + + private: + // Remap input registers to output registers for leaf procedure. + void remapRegsForLeafProc(MachineFunction &MF) const; + + // Returns true if MF is a leaf procedure. + bool isLeafProc(MachineFunction &MF) const; + + + // Emits code for adjusting SP in function prologue/epilogue. + void emitSPAdjustment(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, + int NumBytes, unsigned ADDrr, unsigned ADDri) const; +#endif + }; + +} // End llvm namespace + +#endif diff --git a/lib/Target/WDC65816/WDC65816ISelLowering.h b/lib/Target/WDC65816/WDC65816ISelLowering.h new file mode 100644 index 00000000..e69de29b diff --git a/lib/Target/WDC65816/WDC65816InstrFormats.td b/lib/Target/WDC65816/WDC65816InstrFormats.td new file mode 100644 index 00000000..3a7716f4 --- /dev/null +++ b/lib/Target/WDC65816/WDC65816InstrFormats.td @@ -0,0 +1,232 @@ +//===- WDCInstrFormats.td - WDC 65816 Instruction Formats ----*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class InstWDC pattern> : Instruction { + field bits<8> Inst; + + let Namespace = "WDC"; + + dag OutOperandList = outs; + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; +} + +//===----------------------------------------------------------------------===// +// Group #1 instructions in the WDC 65816 +//===----------------------------------------------------------------------===// + +class OpGrp1 val> { + bits<3> Value = val; +} + +def OpGrp1ADC : OpGrp1<3>; +def OpGrp1AND : OpGrp1<1>; +def OpGrp1CMP : OpGrp1<6>; +def OpGrp1EOR : OpGrp1<2>; +def OpGrp1LDA : OpGrp1<5>; +def OpGrp1ORA : OpGrp1<0>; +def OpGrp1SBC : OpGrp1<7>; +def OpGrp1STA : OpGrp1<4>; + + +class AddrModeGrp1 val> { + bits<5> Value = val; +} + +def AddrModeGrp1Imm : AddrModeGrp1<9>; +def AddrModeGrp1DP : AddrModeGrp1<5>; +def AddrModeGrp1Abs : AddrModeGrp1<13>; +def AddrModeGrp1DPIdxX : AddrModeGrp1<21>; +def AddrModeGrp1AbsIdxX : AddrModeGrp1<29>; +def AddrModeGrp1AbsIdxY : AddrModeGrp1<25>; +def AddrModeGrp1DPIdxIndirX : AddrModeGrp1<1>; +def AddrModeGrp1DPIndirIdxY : AddrModeGrp1<17>; +def AddrModeGrp1DPIndir : AddrModeGrp1<18>; +def AddrModeGrp1DPIndirLongIndY : AddrModeGrp1<23>; +def AddrModeGrp1DPIndirLong : AddrModeGrp1<7>; +def AddrModeGrp1AbsLong : AddrModeGrp1<15>; +def AddrModeGrp1AbsLongIdxX : AddrModeGrp1<31>; +def AddrModeGrp1StackRel : AddrModeGrp1<3>; +def AddrModeGrp1StackRelIndirIdxY : AddrModeGrp1<19>; + + +// Group 1 instructions +class Group1 pattern> + : InstWDC { + OpGrp1 op = opVal; + AddrModeGrp1 addrMode = addrModeVal; + + let Inst{7-5} = op.Value; + let Inst{4-0} = addrMode.Value; +} + +//===----------------------------------------------------------------------===// +// Group #2 instructions in the WDC 65816 +//===----------------------------------------------------------------------===// + + +class OpGrp2 val> { + bits<3> Value = val; +} + +def OpGrp2ASL : OpGrp2<0>; +def OpGrp2DEC : OpGrp2<6>; +def OpGrp2INC : OpGrp2<7>; +def OpGrp2LSR : OpGrp2<2>; +def OpGrp2ROL : OpGrp2<1>; +def OpGrp2ROR : OpGrp2<3>; +def OpGrp2STXY : OpGrp2<4>; +def OpGrp2LDXY : OpGrp2<5>; + + +class AddrModeGrp2 val> { + bits<3> Value = val; +} + +def AddrModeGrp2Acc : AddrModeGrp2<2>; +def AddrModeGrp2DP : AddrModeGrp2<1>; +def AddrModeGrp2Abs : AddrModeGrp2<3>; +def AddrModeGrp2DPIdx : AddrModeGrp2<5>; +def AddrModeGrp2AbsIdx : AddrModeGrp2<7>; +def AddrModeGrp2Imm : AddrModeGrp2<0>; + +// Group 2 instructions +class Group2 pattern> + : InstWDC { + OpGrp2 op = opVal; + AddrModeGrp2 addrMode = addrModeVal; + + let Inst{7-5} = op.Value; + let Inst{4-2} = addrMode.Value; + let Inst{1-0} = 2; +} + + +// Group 2 Y instructions +class Group2_Y pattern> + : Group2 { + OpGrp2 op = opVal; + AddrModeGrp2 addrMode = addrModeVal; + + let Inst{7-5} = op.Value; + let Inst{4-2} = addrMode.Value; + let Inst{1-0} = 0; +} + + + +//===----------------------------------------------------------------------===// +// Group #3 instructions in the WDC 65816 +//===----------------------------------------------------------------------===// + +class OpGrp3 val> { + bits<8> Value = val; +} + + +def OpGrp3BCC : OpGrp3<0x90>; +def OpGrp3BCS : OpGrp3<0xB0>; +def OpGrp3BEQ : OpGrp3<0xF0>; +def OpGrp3BITImm : OpGrp3<0x89>; +def OpGrp3BITAbs : OpGrp3<0x2C>; +def OpGrp3BITDp : OpGrp3<0x24>; +def OpGrp3BITAbsi : OpGrp3<0x3C>; +def OpGrp3BITDpi : OpGrp3<0x34>; +def OpGrp3BMI : OpGrp3<0x30>; +def OpGrp3BNE : OpGrp3<0xD0>; +def OpGrp3BPL : OpGrp3<0x10>; +def OpGrp3BRA : OpGrp3<0x80>; +def OpGrp3BRK : OpGrp3<0x00>; +def OpGrp3BRL : OpGrp3<0x82>; +def OpGrp3BVC : OpGrp3<0x50>; +def OpGrp3BVS : OpGrp3<0x70>; +def OpGrp3CLC : OpGrp3<0x18>; +def OpGrp3CLD : OpGrp3<0xD8>; +def OpGrp3CLI : OpGrp3<0x58>; +def OpGrp3CLV : OpGrp3<0xB8>; +def OpGrp3COP : OpGrp3<0x02>; +def OpGrp3CPXimm : OpGrp3<0xE0>; +def OpGrp3CPXabs : OpGrp3<0xEC>; +def OpGrp3CPXdp : OpGrp3<0xE4>; +def OpGrp3CPYimm : OpGrp3<0xC0>; +def OpGrp3CPYabs : OpGrp3<0xCC>; +def OpGrp3CPYdp : OpGrp3<0xC4>; +def OpGrp3DEX : OpGrp3<0xCA>; +def OpGrp3DEY : OpGrp3<0x88>; +def OpGrp3INX : OpGrp3<0xE8>; +def OpGrp3INY : OpGrp3<0xC8>; +def OpGrp3JMPabs : OpGrp3<0x4C>; +def OpGrp3JMPindir : OpGrp3<0x6C>; +def OpGrp3JMPindiri : OpGrp3<0x7C>; +def OpGrp3JMLabs : OpGrp3<0x5C>; +def OpGrp3JMLindir : OpGrp3<0xDC>; +def OpGrp3JSL : OpGrp3<0x22>; +def OpGrp3JSRabs : OpGrp3<0x20>; +def OpGrp3JSRindiri : OpGrp3<0xFC>; +def OpGrp3MVN : OpGrp3<0x54>; +def OpGrp3MVP : OpGrp3<0x44>; +def OpGrp3NOP : OpGrp3<0xEA>; +def OpGrp3PEA : OpGrp3<0xF4>; +def OpGrp3PEI : OpGrp3<0xD4>; +def OpGrp3PER : OpGrp3<0x62>; +def OpGrp3PHA : OpGrp3<0x48>; +def OpGrp3PHB : OpGrp3<0x8B>; +def OpGrp3PHD : OpGrp3<0x0B>; +def OpGrp3PHK : OpGrp3<0x4B>; +def OpGrp3PHP : OpGrp3<0x08>; +def OpGrp3PHX : OpGrp3<0xDA>; +def OpGrp3PHY : OpGrp3<0x5A>; +def OpGrp3PLA : OpGrp3<0x68>; +def OpGrp3PLB : OpGrp3<0xAB>; +def OpGrp3PLD : OpGrp3<0x2B>; +def OpGrp3PLP : OpGrp3<0x28>; +def OpGrp3PLX : OpGrp3<0xFA>; +def OpGrp3PLY : OpGrp3<0x7A>; +def OpGrp3REP : OpGrp3<0xC2>; +def OpGrp3RTI : OpGrp3<0x40>; +def OpGrp3RTL : OpGrp3<0x6B>; +def OpGrp3RTS : OpGrp3<0x60>; +def OpGrp3SEC : OpGrp3<0x38>; +def OpGrp3SED : OpGrp3<0xF8>; +def OpGrp3SEI : OpGrp3<0x78>; +def OpGrp3SEP : OpGrp3<0xE2>; +def OpGrp3STP : OpGrp3<0xDB>; +def OpGrp3STZabs : OpGrp3<0x9C>; +def OpGrp3STZdp : OpGrp3<0x64>; +def OpGrp3STZabsi : OpGrp3<0x9E>; +def OpGrp3STZdpi : OpGrp3<0x74>; +def OpGrp3TAX : OpGrp3<0xAA>; +def OpGrp3TAY : OpGrp3<0xA8>; +def OpGrp3TCD : OpGrp3<0x5B>; +def OpGrp3TCS : OpGrp3<0x1B>; +def OpGrp3TDC : OpGrp3<0x7B>; +def OpGrp3TRBabs : OpGrp3<0x1C>; +def OpGrp3TRBdp : OpGrp3<0x14>; +def OpGrp3TSBabs : OpGrp3<0x0C>; +def OpGrp3TSBdp : OpGrp3<0x04>; +def OpGrp3TSC : OpGrp3<0x3B>; +def OpGrp3TSX : OpGrp3<0xBA>; +def OpGrp3TXA : OpGrp3<0x8A>; +def OpGrp3TXS : OpGrp3<0x9A>; +def OpGrp3TXY : OpGrp3<0x9B>; +def OpGrp3TYA : OpGrp3<0x98>; +def OpGrp3TYX : OpGrp3<0xB8>; +def OpGrp3WAI : OpGrp3<0xCB>; +def OpGrp3WDM : OpGrp3<0xCB>; +def OpGrp3XBA : OpGrp3<0xEB>; +def OpGrp3XCE : OpGrp3<0xFB>; + + +class Group3 pattern> + : InstWDC { + OpGrp3 op = opVal; + + let Inst = op.Value; +} diff --git a/lib/Target/WDC65816/WDC65816InstrInfo.td b/lib/Target/WDC65816/WDC65816InstrInfo.td new file mode 100644 index 00000000..e977b0e1 --- /dev/null +++ b/lib/Target/WDC65816/WDC65816InstrInfo.td @@ -0,0 +1,1351 @@ +//===- WDCInstrInfo.td - Target Description for WDC 65816 Target ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the WDC 65816 instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction format superclass +//===----------------------------------------------------------------------===// + +include "WDC65816InstrFormats.td" + +//===----------------------------------------------------------------------===// +// Feature predicates. +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// Instruction Pattern Stuff +//===----------------------------------------------------------------------===// + +// Adressing modes. +def ADDRabs : ComplexPattern; +def ADDRabsl : ComplexPattern; +def ADDRdp : ComplexPattern; + + +//===----------------------------------------------------------------------===// +// WDC 65816 Flag Conditions +//===----------------------------------------------------------------------===// + +// Note that these values must be kept in sync with the CCOp::CondCode enum +// values. + + +//===----------------------------------------------------------------------===// +// Instruction Class Templates +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + + +// Group #1 Instructions + +// JSR TODO - Need to set all of the DAG patterns +// JSR TODO - Addresses are 32-bit to llvm but can we toss the upper byte for long addressing modes which are 24-bit +// JSR TODO - Need to specify flag behaviour, especially carry for ADC, SBC, CMP + +def ADCimm : Group1$src2", + [(set AccRegs:$dst, (add AccRegs:$src1, i16imm:$src2))]>; + +def ADCabs : Group1; + +def ADCabsl : Group1$src2", + [(set AccRegs:$dst, (add AccRegs:$src1, (load ADDRabsl:$src2)))]>; + +def ADCdp : Group1; + +def ADCdpindir : Group1; + +def ADCdpindirl : Group1; + +def ADCabsix : Group1; + +def ADCabsiy : Group1; + +def ADCabsixl : Group1$src2,$src3", + []>; + +def ADCdpix : Group1; + +def ADCdpiindirx : Group1; + +def ADCdpindiriy : Group1; + +def ADCdpindirliy : Group1; + +def ADCsr : Group1; + +def ADCsrindir : Group1; + +def ANDimm : Group1$src2", + [(set AccRegs:$dst, (and AccRegs:$src1, i16imm:$src2))]>; + +def ANDabs : Group1; + +def ANDabsl : Group1$src2", + [(set AccRegs:$dst, (and AccRegs:$src1, (load ADDRabsl:$src2)))]>; + +def ANDdp : Group1; + +def ANDdpindir : Group1; + +def ANDdpindirl : Group1; + +def ANDabsix : Group1; + +def ANDabsiy : Group1; + +def ANDabsixl : Group1$src2,$src3", + []>; + +def ANDdpix : Group1; + +def ANDdpiindirx : Group1; + +def ANDdpindiriy : Group1; + +def ANDdpindirliy : Group1; + +def ANDsr : Group1; + +def ANDsrindir : Group1; + +def CMPimm : Group1$src2", + []>; + +def CMPabs : Group1; + +def CMPabsl : Group1$src2", + []>; + +def CMPdp : Group1; + +def CMPdpindir : Group1; + +def CMPdpindirl : Group1; + +def CMPabsix : Group1; + +def CMPabsiy : Group1; + +def CMPabsixl : Group1$src2,$src3", + []>; + +def CMPdpix : Group1; + +def CMPdpiindirx : Group1; + +def CMPdpindiriy : Group1; + +def CMPdpindirliy : Group1; + +def CMPsr : Group1; + +def CMPsrindir : Group1; + +def EORimm : Group1$src2", + [(set AccRegs:$dst, (xor AccRegs:$src1, i16imm:$src2))]>; + +def EORabs : Group1; + +def EORabsl : Group1$src2", + [(set AccRegs:$dst, (xor AccRegs:$src1, (load ADDRabsl:$src2)))]>; + +def EORdp : Group1; + +def EORdpindir : Group1; + +def EORdpindirl : Group1; + +def EORabsix : Group1; + +def EORabsiy : Group1; + +def EORabsixl : Group1$src2,$src3", + []>; + +def EORdpix : Group1; + +def EORdpiindirx : Group1; + +def EORdpindiriy : Group1; + +def EORdpindirliy : Group1; + +def EORsr : Group1; + +def EORsrindir : Group1; + +def LDAimm : Group1$src1", + [(set AccRegs:$dst, i16imm:$src)]>; + +def LDAabs : Group1; + +def LDAabsl : Group1$src2", + [(set AccRegs:$dst, (load ADDRabsl:$src2))]>; + +def LDAdp : Group1; + +def LDAdpindir : Group1; + +def LDAdpindirl : Group1; + +def LDAabsix : Group1; + +def LDAabsiy : Group1; + +def LDAabsixl : Group1$src2,$src3", + []>; + +def LDAdpix : Group1; + +def LDAdpiindirx : Group1; + +def LDAdpindiriy : Group1; + +def LDAdpindirliy : Group1; + +def LDAsr : Group1; + +def LDAsrindir : Group1; + +def ORAimm : Group1$src2", + [(set AccRegs:$dst, (or AccRegs:$src1, i16imm:$src2))]>; + +def ORAabs : Group1; + +def ORAabsl : Group1$src2", + [(set AccRegs:$dst, (or AccRegs:$src1, (load ADDRabsl:$src2)))]>; + +def ORAdp : Group1; + +def ORAdpindir : Group1; + +def ORAdpindirl : Group1; + +def ORAabsix : Group1; + +def ORAabsiy : Group1; + +def ORAabsixl : Group1$src2,$src3", + []>; + +def ORAdpix : Group1; + +def ORAdpiindirx : Group1; + +def ORAdpindiriy : Group1; + +def ORAdpindirliy : Group1; + +def ORAsr : Group1; + +def ORAsrindir : Group1; + +def SBCimm : Group1$src2", + [(set AccRegs:$dst, (sub AccRegs:$src1, i16imm:$src2))]>; + +def SBCabs : Group1; + +def SBCabsl : Group1$src2", + [(set AccRegs:$dst, (sub AccRegs:$src1, (load ADDRabsl:$src2)))]>; + +def SBCdp : Group1; + +def SBCdpindir : Group1; + +def SBCdpindirl : Group1; + +def SBCabsix : Group1; + +def SBCabsiy : Group1; + +def SBCabsixl : Group1$src2,$src3", + []>; + +def SBCdpix : Group1; + +def SBCdpiindirx : Group1; + +def SBCdpindiriy : Group1; + +def SBCdpindirliy : Group1; + +def SBCsr : Group1; + +def SBCsrindir : Group1; + +def STAabs : Group1; + +def STAabsl : Group1$dst", + [(store AccRegs:$src, ADDRabsl:$dst)]>; + +def STAdp : Group1; + +def STAdpindir : Group1; + +def STAdpindirl : Group1; + +def STAabsix : Group1; + +def STAabsiy : Group1; + +def STAabsixl : Group1$src2,$src3", + []>; + +def STAdpix : Group1; + +def STAdpiindirx : Group1; + +def STAdpindiriy : Group1; + +def STAdpindirliy : Group1; + +def STAsr : Group1; + +def STAsrindir : Group1; + +// Group #2 Instructions + +def ASLacc : Group2; + +def ASLabs : Group2; + +def ASLdp : Group2; + +def ASLabsix : Group2; + +def ASLdpix : Group2; + +def DECacc : Group2; + +def DECabs : Group2; + +def DECdp : Group2; + +def DECabsix : Group2; + +def DECdpix : Group2; + +def INCacc : Group2; + +def INCabs : Group2; + +def INCdp : Group2; + +def INCabsix : Group2; + +def INCdpix : Group2; + +def LDXimm : Group2; + +def LDXabs : Group2; + +def LDXdp : Group2; + +def LDXabsiy : Group2; + +def LDXdpiy : Group2; + +def LDYimm : Group2_Y; + +def LDYabs : Group2_Y; + +def LDYdp : Group2_Y; + +def LDYabsix : Group2_Y; + +def LDYdpix : Group2_Y; + +def LSRacc : Group2; + +def LSRabs : Group2; + +def LSRdp : Group2; + +def LSRabsix : Group2; + +def LSRdpix : Group2; + +def ROLacc : Group2; + +def ROLabs : Group2; + +def ROLdp : Group2; + +def ROLabsix : Group2; + +def ROLdpix : Group2; + +def RORacc : Group2; + +def RORabs : Group2; + +def RORdp : Group2; + +def RORabsix : Group2; + +def RORdpix : Group2; + +def STXabs : Group2; + +def STXdp : Group2; + +def STXdpiy : Group2; + +def STYabs : Group2_Y; + +def STYdp : Group2_Y; + +def STYdpix : Group2_Y; + + + +// Group #3 Instructions + +def BCC : Group3; + +def BCS : Group3; + +def BEQ : Group3; + +def BITimm : Group3$src2", + []>; + +def BITabs : Group3; + +def BITdp : Group3; + +def BITabsix : Group3; + +def BITdpix : Group3; + +def BMI : Group3; + +def BNE : Group3; + +def BPL : Group3; + +def BRA : Group3; + +def BRK : Group3; + +def BRL : Group3; + +def BVC : Group3; + +def BVS : Group3; + +def CLC : Group3; + +def CLD : Group3; + +def CLI : Group3; + +def CLV : Group3; + +def COP : Group3; + +def CPXimm : Group3; + +def CPXabs : Group3; + +def CPXdp : Group3; + +def CPYimm : Group3; + +def CPYabs : Group3; + +def CPYdp : Group3; + +def DEX : Group3; + +def DEY : Group3; + +def INX : Group3; + +def INY : Group3; + +def JMPabs : Group3; + +def JMPindir : Group3; + +def JMPindiri : Group3; + +def JMLabs : Group3$src", + []>; + +def JMLindirl : Group3$src]", + []>; + +def JSL : Group3$src", + []>; + +def JSRabs : Group3; + +def JSRindiri : Group3; + +def MVN : Group3; + +def MVP : Group3; + +def NOP : Group3; + +def PEA : Group3; + +def PEI : Group3; + +def PER : Group3; + +def PHA : Group3; + +def PHB : Group3; + +def PHD : Group3; + +def PHK : Group3; + +def PHP : Group3; + +def PHX : Group3; + +def PHY : Group3; + +def PLA : Group3; + +def PLB : Group3; + +def PLD : Group3; + +def PLP : Group3; + +def PLX : Group3; + +def PLY : Group3; + +def REP : Group3; + +def RTI : Group3; + +def RTL : Group3; + +def RTS : Group3; + +def SEC : Group3; + +def SED : Group3; + +def SEI : Group3; + +def SEP : Group3; + +def STP : Group3; + +def STZabs : Group3; + +def STZdp : Group3; + +def STZabsi : Group3; + +def STZdpi : Group3; + +def TAX : Group3; + +def TAY : Group3; + +def TCB : Group3; + +def TCS : Group3; + +def TDC : Group3; + +def TRBabs : Group3; + +def TRBdp : Group3; + +def TSBabs : Group3; + +def TSBdp : Group3; + +def TSC : Group3; + +def TSX : Group3; + +def TXA : Group3; + +def TXS : Group3; + +def TXY : Group3; + +def TYA : Group3; + +def TYX : Group3; + +def WAI : Group3; + +def WDM : Group3; + +def XBA : Group3; + +def XCE : Group3; + + +//===----------------------------------------------------------------------===// +// Non-Instruction Patterns +//===----------------------------------------------------------------------===// + diff --git a/lib/Target/WDC65816/WDC65816TargetMachine.cpp b/lib/Target/WDC65816/WDC65816TargetMachine.cpp index afa61834..503f6245 100644 --- a/lib/Target/WDC65816/WDC65816TargetMachine.cpp +++ b/lib/Target/WDC65816/WDC65816TargetMachine.cpp @@ -31,10 +31,10 @@ WDC65816TargetMachine::WDC65816TargetMachine(const Target &T, StringRef TT, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), -DL(Subtarget.getDataLayout()), -InstrInfo(Subtarget), +DL("e-p:32:8:8-i16:8:8-f32:8:8-f68:8:8-n16"), +InstrInfo(), TLInfo(*this), TSInfo(*this), -FrameLowering(Subtarget) { +FrameLowering() { initAsmInfo(); }