diff --git a/lib/Target/WDC65816/MCTargetDesc/CMakeLists.txt b/lib/Target/WDC65816/MCTargetDesc/CMakeLists.txt index e8964d20..39065e77 100644 --- a/lib/Target/WDC65816/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/WDC65816/MCTargetDesc/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_library(LLVMWDC65816Desc WDC65816MCTargetDesc.cpp WDC65816MCAsmInfo.cpp + WDC65816TargetStreamer.cpp ) add_dependencies(LLVMWDC65816Desc WDC65816CommonTableGen) diff --git a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.cpp b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.cpp index a898b821..9c14bec0 100644 --- a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.cpp +++ b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.cpp @@ -16,14 +16,17 @@ using namespace llvm; -void WDC65816ELFMCAsmInfo::anchor() { } +void WDC65816MCAsmInfo::anchor() { } -WDC65816ELFMCAsmInfo::WDC65816ELFMCAsmInfo(StringRef TT) { +WDC65816MCAsmInfo::WDC65816MCAsmInfo(StringRef TT) { IsLittleEndian = true; Triple TheTriple(TT); PointerSize = CalleeSaveStackSlotSize = 4; + // Disable the ".file " parameter + HasSingleParameterDotFile = false; + #if 0 // WDC_TODO - Do I need any of this? Data16bitsDirective = "\t.half\t"; Data32bitsDirective = "\t.word\t"; diff --git a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.h b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.h index 4bbc1541..ea60e3fd 100644 --- a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.h +++ b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCAsmInfo.h @@ -14,15 +14,15 @@ #ifndef WDC65816TARGETASMINFO_H #define WDC65816TARGETASMINFO_H -#include "llvm/MC/MCAsmInfoELF.h" +#include "llvm/MC/MCAsmInfo.h" namespace llvm { class StringRef; - class WDC65816ELFMCAsmInfo : public MCAsmInfoELF { + class WDC65816MCAsmInfo : public MCAsmInfo { virtual void anchor(); public: - explicit WDC65816ELFMCAsmInfo(StringRef TT); + explicit WDC65816MCAsmInfo(StringRef TT); }; } // namespace llvm diff --git a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCTargetDesc.cpp b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCTargetDesc.cpp index d470a2b9..cc389fdd 100644 --- a/lib/Target/WDC65816/MCTargetDesc/WDC65816MCTargetDesc.cpp +++ b/lib/Target/WDC65816/MCTargetDesc/WDC65816MCTargetDesc.cpp @@ -13,6 +13,7 @@ #include "WDC65816MCTargetDesc.h" #include "WDC65816MCAsmInfo.h" +#include "WDC65816TargetStreamer.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -65,9 +66,22 @@ static MCCodeGenInfo *createWDC65816MCCodeGenInfo(StringRef TT, Reloc::Model RM, } +static MCStreamer * +createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { + WDC65816TargetStreamer *S = new WDC65816TargetAsmStreamer(OS); + + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); +} + + extern "C" void LLVMInitializeWDC65816TargetMC() { // Register the MC asm info. - RegisterMCAsmInfo X(TheWDC65816Target); + RegisterMCAsmInfo X(TheWDC65816Target); // Register the MC codegen info. TargetRegistry::RegisterMCCodeGenInfo(TheWDC65816Target, @@ -82,4 +96,7 @@ extern "C" void LLVMInitializeWDC65816TargetMC() { // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(TheWDC65816Target, createWDC65816MCSubtargetInfo); + + // Register the asm streamer. + TargetRegistry::RegisterAsmStreamer(TheWDC65816Target, createMCAsmStreamer); } diff --git a/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.cpp b/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.cpp new file mode 100644 index 00000000..761ecc29 --- /dev/null +++ b/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.cpp @@ -0,0 +1,22 @@ +// +// WDC65816TargetAsmStreamer.cpp +// llvm +// +// Created by Jeremy Rand on 2016-04-11. +// Copyright © 2016 Jeremy Rand. All rights reserved. +// + +#include "WDC65816TargetStreamer.h" + + +using namespace llvm; + + +// pin vtable to this file +void WDC65816TargetStreamer::anchor() {} + + +WDC65816TargetAsmStreamer::~WDC65816TargetAsmStreamer() +{ + +} diff --git a/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.h b/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.h new file mode 100644 index 00000000..05f54adf --- /dev/null +++ b/lib/Target/WDC65816/MCTargetDesc/WDC65816TargetStreamer.h @@ -0,0 +1,34 @@ +// +// WDC65816TargetAsmStreamer.h +// llvm +// +// Created by Jeremy Rand on 2016-04-11. +// Copyright © 2016 Jeremy Rand. All rights reserved. +// + +#ifndef WDC65816TargetStreamer_h +#define WDC65816TargetStreamer_h + + +#include "llvm/MC/MCStreamer.h" + + +namespace llvm { + + + class WDC65816TargetStreamer : public MCTargetStreamer { + virtual void anchor(); + + public: + // Add pure virtual functions here to the base class... + }; + + class WDC65816TargetAsmStreamer : public WDC65816TargetStreamer { + formatted_raw_ostream &OS; + public: + WDC65816TargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS) {} + virtual ~WDC65816TargetAsmStreamer(); + }; +} + +#endif /* WDC65816TargetStreamer_h */ diff --git a/lib/Target/WDC65816/WDC65816AsmPrinter.cpp b/lib/Target/WDC65816/WDC65816AsmPrinter.cpp index 5802c96b..ab026955 100644 --- a/lib/Target/WDC65816/WDC65816AsmPrinter.cpp +++ b/lib/Target/WDC65816/WDC65816AsmPrinter.cpp @@ -54,30 +54,6 @@ namespace { printInstruction(MI, OS); OutStreamer.EmitRawText(OS.str()); } -#if 0 // WDC_TODO - How much of this do we need? - void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS); - - virtual void EmitFunctionBodyStart(); - - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); - - virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) - const; - void EmitGlobalRegisterDecl(unsigned reg) { - SmallString<128> Str; - raw_svector_ostream OS(Str); - OS << "\t.register " - << "%" << StringRef(getRegisterName(reg)).lower() - << ", " - << ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch"); - OutStreamer.EmitRawText(OS.str()); - } -#endif }; } // end of anonymous namespace @@ -94,7 +70,7 @@ void WDC65816AsmPrinter::printOperand(const MachineInstr *MI, int opNum, O << StringRef(getRegisterName(MO.getReg())); return; case MachineOperand::MO_Immediate: - O << MO.getImm(); + O << "#" << MO.getImm(); return; case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); @@ -123,259 +99,6 @@ bool WDC65816AsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum, return true; } -#if 0 // WDC_TODO - How much of this do we need? -void WDC65816AsmPrinter::EmitFunctionBodyStart() { - const MachineRegisterInfo &MRI = MF->getRegInfo(); - const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 }; - for (unsigned i = 0; globalRegs[i] != 0; ++i) { - unsigned reg = globalRegs[i]; - if (MRI.use_empty(reg)) - continue; - EmitGlobalRegisterDecl(reg); - } -} - -void WDC65816AsmPrinter::printOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand (opNum); - unsigned TF = MO.getTargetFlags(); -#ifndef NDEBUG - // Verify the target flags. - if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { - if (MI->getOpcode() == SP::CALL) - assert(TF == SPII::MO_NO_FLAG && - "Cannot handle target flags on call address"); - else if (MI->getOpcode() == SP::SETHIi) - assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH - || TF == SPII::MO_TLS_GD_HI22 - || TF == SPII::MO_TLS_LDM_HI22 - || TF == SPII::MO_TLS_LDO_HIX22 - || TF == SPII::MO_TLS_IE_HI22 - || TF == SPII::MO_TLS_LE_HIX22) && - "Invalid target flags for address operand on sethi"); - else if (MI->getOpcode() == SP::TLS_CALL) - assert((TF == SPII::MO_NO_FLAG - || TF == SPII::MO_TLS_GD_CALL - || TF == SPII::MO_TLS_LDM_CALL) && - "Cannot handle target flags on tls call address"); - else if (MI->getOpcode() == SP::TLS_ADDrr) - assert((TF == SPII::MO_TLS_GD_ADD || TF == SPII::MO_TLS_LDM_ADD - || TF == SPII::MO_TLS_LDO_ADD || TF == SPII::MO_TLS_IE_ADD) && - "Cannot handle target flags on add for TLS"); - else if (MI->getOpcode() == SP::TLS_LDrr) - assert(TF == SPII::MO_TLS_IE_LD && - "Cannot handle target flags on ld for TLS"); - else if (MI->getOpcode() == SP::TLS_LDXrr) - assert(TF == SPII::MO_TLS_IE_LDX && - "Cannot handle target flags on ldx for TLS"); - else if (MI->getOpcode() == SP::XORri) - assert((TF == SPII::MO_TLS_LDO_LOX10 || TF == SPII::MO_TLS_LE_LOX10) && - "Cannot handle target flags on xor for TLS"); - else - assert((TF == SPII::MO_LO || TF == SPII::MO_M44 || TF == SPII::MO_L44 - || TF == SPII::MO_HM - || TF == SPII::MO_TLS_GD_LO10 - || TF == SPII::MO_TLS_LDM_LO10 - || TF == SPII::MO_TLS_IE_LO10 ) && - "Invalid target flags for small address operand"); - } -#endif - - bool CloseParen = true; - switch (TF) { - default: - llvm_unreachable("Unknown target flags on operand"); - case SPII::MO_NO_FLAG: - CloseParen = false; - break; - case SPII::MO_LO: O << "%lo("; break; - case SPII::MO_HI: O << "%hi("; break; - case SPII::MO_H44: O << "%h44("; break; - case SPII::MO_M44: O << "%m44("; break; - case SPII::MO_L44: O << "%l44("; break; - case SPII::MO_HH: O << "%hh("; break; - case SPII::MO_HM: O << "%hm("; break; - case SPII::MO_TLS_GD_HI22: O << "%tgd_hi22("; break; - case SPII::MO_TLS_GD_LO10: O << "%tgd_lo10("; break; - case SPII::MO_TLS_GD_ADD: O << "%tgd_add("; break; - case SPII::MO_TLS_GD_CALL: O << "%tgd_call("; break; - case SPII::MO_TLS_LDM_HI22: O << "%tldm_hi22("; break; - case SPII::MO_TLS_LDM_LO10: O << "%tldm_lo10("; break; - case SPII::MO_TLS_LDM_ADD: O << "%tldm_add("; break; - case SPII::MO_TLS_LDM_CALL: O << "%tldm_call("; break; - case SPII::MO_TLS_LDO_HIX22: O << "%tldo_hix22("; break; - case SPII::MO_TLS_LDO_LOX10: O << "%tldo_lox10("; break; - case SPII::MO_TLS_LDO_ADD: O << "%tldo_add("; break; - case SPII::MO_TLS_IE_HI22: O << "%tie_hi22("; break; - case SPII::MO_TLS_IE_LO10: O << "%tie_lo10("; break; - case SPII::MO_TLS_IE_LD: O << "%tie_ld("; break; - case SPII::MO_TLS_IE_LDX: O << "%tie_ldx("; break; - case SPII::MO_TLS_IE_ADD: O << "%tie_add("; break; - case SPII::MO_TLS_LE_HIX22: O << "%tle_hix22("; break; - case SPII::MO_TLS_LE_LOX10: O << "%tle_lox10("; break; - } - - switch (MO.getType()) { - case MachineOperand::MO_Register: - O << "%" << StringRef(getRegisterName(MO.getReg())).lower(); - break; - - case MachineOperand::MO_Immediate: - O << (int)MO.getImm(); - break; - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - return; - case MachineOperand::MO_GlobalAddress: - O << *getSymbol(MO.getGlobal()); - break; - case MachineOperand::MO_BlockAddress: - O << GetBlockAddressSymbol(MO.getBlockAddress())->getName(); - break; - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - break; - case MachineOperand::MO_ConstantPoolIndex: - O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getIndex(); - break; - default: - llvm_unreachable(""); - } - if (CloseParen) O << ")"; -} - -void WDC65816AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, - raw_ostream &O, const char *Modifier) { - printOperand(MI, opNum, O); - - // If this is an ADD operand, emit it like normal operands. - if (Modifier && !strcmp(Modifier, "arith")) { - O << ", "; - printOperand(MI, opNum+1, O); - return; - } - - if (MI->getOperand(opNum+1).isReg() && - MI->getOperand(opNum+1).getReg() == SP::G0) - return; // don't print "+%g0" - if (MI->getOperand(opNum+1).isImm() && - MI->getOperand(opNum+1).getImm() == 0) - return; // don't print "+0" - - O << "+"; - printOperand(MI, opNum+1, O); -} - -bool WDC65816AsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum, - raw_ostream &O) { - std::string operand = ""; - const MachineOperand &MO = MI->getOperand(opNum); - switch (MO.getType()) { - default: llvm_unreachable("Operand is not a register"); - case MachineOperand::MO_Register: - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Operand is not a physical register "); - assert(MO.getReg() != SP::O7 && - "%o7 is assigned as destination for getpcx!"); - operand = "%" + StringRef(getRegisterName(MO.getReg())).lower(); - break; - } - - unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber(); - unsigned bbNum = MI->getParent()->getNumber(); - - O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n"; - O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ; - - O << "\t sethi\t" - << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum - << ")), " << operand << '\n' ; - - O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ; - O << "\tor\t" << operand - << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum - << ")), " << operand << '\n'; - O << "\tadd\t" << operand << ", %o7, " << operand << '\n'; - - return true; -} - -void WDC65816AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - int CC = (int)MI->getOperand(opNum).getImm(); - O << SPARCCondCodeToString((SPCC::CondCodes)CC); -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool WDC65816AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode, - raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: - // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); - case 'r': - break; - } - } - - printOperand(MI, OpNo, O); - - return false; -} - -bool WDC65816AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, unsigned AsmVariant, - const char *ExtraCode, - raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier - - O << '['; - printMemOperand(MI, OpNo, O); - O << ']'; - - return false; -} - -/// isBlockOnlyReachableByFallthough - Return true if the basic block has -/// exactly one predecessor and the control transfer mechanism between -/// the predecessor and this block is a fall-through. -/// -/// This overrides AsmPrinter's implementation to handle delay slots. -bool WDC65816AsmPrinter:: -isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { - // If this is a landing pad, it isn't a fall through. If it has no preds, - // then nothing falls through to it. - if (MBB->isLandingPad() || MBB->pred_empty()) - return false; - - // If there isn't exactly one predecessor, it can't be a fall through. - MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; - ++PI2; - if (PI2 != MBB->pred_end()) - return false; - - // The predecessor has to be immediately before this block. - const MachineBasicBlock *Pred = *PI; - - if (!Pred->isLayoutSuccessor(MBB)) - return false; - - // Check if the last terminator is an unconditional branch. - MachineBasicBlock::const_iterator I = Pred->end(); - while (I != Pred->begin() && !(--I)->isTerminator()) - ; // Noop - return I == Pred->end() || !I->isBarrier(); -} - -#endif // Force static initialization. extern "C" void LLVMInitializeWDC65816AsmPrinter() { diff --git a/lib/Target/WDC65816/WDC65816InstrInfo.td b/lib/Target/WDC65816/WDC65816InstrInfo.td index 42da5c0e..8ebcf90c 100644 --- a/lib/Target/WDC65816/WDC65816InstrInfo.td +++ b/lib/Target/WDC65816/WDC65816InstrInfo.td @@ -110,7 +110,7 @@ def WDCRET : SDNode<"WDCISD::RET_FLAG", SDTNone, [SDNPHasChain, SDNP def ADCimm : Group1$src2", + "ADC $src2", [(set AccRegs:$dst, (add AccRegs:$src1, imm:$src2))]>; def ADCabs : Group1$src2", + "AND $src2", [(set AccRegs:$dst, (and AccRegs:$src1, imm:$src2))]>; def ANDabs : Group1$src2", + "CMP $src2", []>; def CMPabs : Group1$src2", + "EOR $src2", [(set AccRegs:$dst, (xor AccRegs:$src1, imm:$src2))]>; def EORabs : Group1$src", + "LDA $src", [(set AccRegs:$dst, imm:$src)]>; def LDAabs : Group1$src2", + "ORA $src2", [(set AccRegs:$dst, (or AccRegs:$src1, imm:$src2))]>; def ORAabs : Group1$src2", + "SBC $src2", [(set AccRegs:$dst, (sub AccRegs:$src1, imm:$src2))]>; def SBCabs : Group1$src2", + "BIT $src2", []>; def BITabs : Group3