1064859bdSKazushi (Jam) Marukawa //===-- VEAsmPrinter.cpp - VE LLVM assembly writer ------------------------===// 2064859bdSKazushi (Jam) Marukawa // 3064859bdSKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4064859bdSKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information. 5064859bdSKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6064859bdSKazushi (Jam) Marukawa // 7064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===// 8064859bdSKazushi (Jam) Marukawa // 9064859bdSKazushi (Jam) Marukawa // This file contains a printer that converts from our internal representation 10064859bdSKazushi (Jam) Marukawa // of machine-dependent LLVM code to GAS-format VE assembly language. 11064859bdSKazushi (Jam) Marukawa // 12064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===// 13064859bdSKazushi (Jam) Marukawa 146bbbead7SKazushi (Jam) Marukawa #include "MCTargetDesc/VEInstPrinter.h" 1560431bd7SKazushi (Jam) Marukawa #include "MCTargetDesc/VEMCExpr.h" 16064859bdSKazushi (Jam) Marukawa #include "MCTargetDesc/VETargetStreamer.h" 17d8816261SKazushi (Jam) Marukawa #include "TargetInfo/VETargetInfo.h" 18064859bdSKazushi (Jam) Marukawa #include "VE.h" 19064859bdSKazushi (Jam) Marukawa #include "VEInstrInfo.h" 20064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/AsmPrinter.h" 21064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstr.h" 22064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineModuleInfoImpls.h" 23064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 24064859bdSKazushi (Jam) Marukawa #include "llvm/IR/Mangler.h" 25064859bdSKazushi (Jam) Marukawa #include "llvm/MC/MCAsmInfo.h" 26064859bdSKazushi (Jam) Marukawa #include "llvm/MC/MCContext.h" 27064859bdSKazushi (Jam) Marukawa #include "llvm/MC/MCInst.h" 28064859bdSKazushi (Jam) Marukawa #include "llvm/MC/MCStreamer.h" 29064859bdSKazushi (Jam) Marukawa #include "llvm/MC/MCSymbol.h" 3089b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h" 31064859bdSKazushi (Jam) Marukawa #include "llvm/Support/raw_ostream.h" 32064859bdSKazushi (Jam) Marukawa using namespace llvm; 33064859bdSKazushi (Jam) Marukawa 34064859bdSKazushi (Jam) Marukawa #define DEBUG_TYPE "ve-asmprinter" 35064859bdSKazushi (Jam) Marukawa 36064859bdSKazushi (Jam) Marukawa namespace { 37064859bdSKazushi (Jam) Marukawa class VEAsmPrinter : public AsmPrinter { 38064859bdSKazushi (Jam) Marukawa VETargetStreamer &getTargetStreamer() { 39064859bdSKazushi (Jam) Marukawa return static_cast<VETargetStreamer &>(*OutStreamer->getTargetStreamer()); 40064859bdSKazushi (Jam) Marukawa } 41064859bdSKazushi (Jam) Marukawa 42064859bdSKazushi (Jam) Marukawa public: 43064859bdSKazushi (Jam) Marukawa explicit VEAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 44064859bdSKazushi (Jam) Marukawa : AsmPrinter(TM, std::move(Streamer)) {} 45064859bdSKazushi (Jam) Marukawa 46064859bdSKazushi (Jam) Marukawa StringRef getPassName() const override { return "VE Assembly Printer"; } 47064859bdSKazushi (Jam) Marukawa 4860431bd7SKazushi (Jam) Marukawa void lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 4960431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI); 5060431bd7SKazushi (Jam) Marukawa void lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 5160431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI); 525526786aSKazushi (Jam) Marukawa void lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 535526786aSKazushi (Jam) Marukawa const MCSubtargetInfo &STI); 5460431bd7SKazushi (Jam) Marukawa 55bcd24b2dSFangrui Song void emitInstruction(const MachineInstr *MI) override; 56064859bdSKazushi (Jam) Marukawa 57*6ae84d66SSergei Barannikov static const char *getRegisterName(MCRegister Reg) { 58*6ae84d66SSergei Barannikov return VEInstPrinter::getRegisterName(Reg); 59064859bdSKazushi (Jam) Marukawa } 60b65ef65bSKazushi (Jam) Marukawa void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &OS); 61b65ef65bSKazushi (Jam) Marukawa bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 62b65ef65bSKazushi (Jam) Marukawa const char *ExtraCode, raw_ostream &O) override; 63b88aba9dSKazushi (Jam) Marukawa bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 64b88aba9dSKazushi (Jam) Marukawa const char *ExtraCode, raw_ostream &O) override; 65064859bdSKazushi (Jam) Marukawa }; 66064859bdSKazushi (Jam) Marukawa } // end of anonymous namespace 67064859bdSKazushi (Jam) Marukawa 6860431bd7SKazushi (Jam) Marukawa static MCOperand createVEMCOperand(VEMCExpr::VariantKind Kind, MCSymbol *Sym, 6960431bd7SKazushi (Jam) Marukawa MCContext &OutContext) { 7060431bd7SKazushi (Jam) Marukawa const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Sym, OutContext); 7160431bd7SKazushi (Jam) Marukawa const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, OutContext); 7260431bd7SKazushi (Jam) Marukawa return MCOperand::createExpr(expr); 7360431bd7SKazushi (Jam) Marukawa } 7460431bd7SKazushi (Jam) Marukawa 7560431bd7SKazushi (Jam) Marukawa static MCOperand createGOTRelExprOp(VEMCExpr::VariantKind Kind, 7660431bd7SKazushi (Jam) Marukawa MCSymbol *GOTLabel, MCContext &OutContext) { 7760431bd7SKazushi (Jam) Marukawa const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext); 7860431bd7SKazushi (Jam) Marukawa const VEMCExpr *expr = VEMCExpr::create(Kind, GOT, OutContext); 7960431bd7SKazushi (Jam) Marukawa return MCOperand::createExpr(expr); 8060431bd7SKazushi (Jam) Marukawa } 8160431bd7SKazushi (Jam) Marukawa 8260431bd7SKazushi (Jam) Marukawa static void emitSIC(MCStreamer &OutStreamer, MCOperand &RD, 8360431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 8460431bd7SKazushi (Jam) Marukawa MCInst SICInst; 8560431bd7SKazushi (Jam) Marukawa SICInst.setOpcode(VE::SIC); 8660431bd7SKazushi (Jam) Marukawa SICInst.addOperand(RD); 8760431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(SICInst, STI); 8860431bd7SKazushi (Jam) Marukawa } 8960431bd7SKazushi (Jam) Marukawa 905526786aSKazushi (Jam) Marukawa static void emitBSIC(MCStreamer &OutStreamer, MCOperand &R1, MCOperand &R2, 915526786aSKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 925526786aSKazushi (Jam) Marukawa MCInst BSICInst; 933c80478dSKazushi (Jam) Marukawa BSICInst.setOpcode(VE::BSICrii); 945526786aSKazushi (Jam) Marukawa BSICInst.addOperand(R1); 955526786aSKazushi (Jam) Marukawa BSICInst.addOperand(R2); 963c80478dSKazushi (Jam) Marukawa MCOperand czero = MCOperand::createImm(0); 973c80478dSKazushi (Jam) Marukawa BSICInst.addOperand(czero); 983c80478dSKazushi (Jam) Marukawa BSICInst.addOperand(czero); 995526786aSKazushi (Jam) Marukawa OutStreamer.emitInstruction(BSICInst, STI); 1005526786aSKazushi (Jam) Marukawa } 1015526786aSKazushi (Jam) Marukawa 10260431bd7SKazushi (Jam) Marukawa static void emitLEAzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 10360431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 10460431bd7SKazushi (Jam) Marukawa MCInst LEAInst; 105e981a46aSKazushi (Jam) Marukawa LEAInst.setOpcode(VE::LEAzii); 10660431bd7SKazushi (Jam) Marukawa LEAInst.addOperand(RD); 107e981a46aSKazushi (Jam) Marukawa MCOperand CZero = MCOperand::createImm(0); 108e981a46aSKazushi (Jam) Marukawa LEAInst.addOperand(CZero); 109e981a46aSKazushi (Jam) Marukawa LEAInst.addOperand(CZero); 11060431bd7SKazushi (Jam) Marukawa LEAInst.addOperand(Imm); 11160431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(LEAInst, STI); 11260431bd7SKazushi (Jam) Marukawa } 11360431bd7SKazushi (Jam) Marukawa 11460431bd7SKazushi (Jam) Marukawa static void emitLEASLzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 11560431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 11660431bd7SKazushi (Jam) Marukawa MCInst LEASLInst; 117e981a46aSKazushi (Jam) Marukawa LEASLInst.setOpcode(VE::LEASLzii); 11860431bd7SKazushi (Jam) Marukawa LEASLInst.addOperand(RD); 119e981a46aSKazushi (Jam) Marukawa MCOperand CZero = MCOperand::createImm(0); 120e981a46aSKazushi (Jam) Marukawa LEASLInst.addOperand(CZero); 121e981a46aSKazushi (Jam) Marukawa LEASLInst.addOperand(CZero); 12260431bd7SKazushi (Jam) Marukawa LEASLInst.addOperand(Imm); 12360431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(LEASLInst, STI); 12460431bd7SKazushi (Jam) Marukawa } 12560431bd7SKazushi (Jam) Marukawa 12660431bd7SKazushi (Jam) Marukawa static void emitLEAzii(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 12760431bd7SKazushi (Jam) Marukawa MCOperand &RD, const MCSubtargetInfo &STI) { 12860431bd7SKazushi (Jam) Marukawa MCInst LEAInst; 12960431bd7SKazushi (Jam) Marukawa LEAInst.setOpcode(VE::LEAzii); 13060431bd7SKazushi (Jam) Marukawa LEAInst.addOperand(RD); 131e981a46aSKazushi (Jam) Marukawa MCOperand CZero = MCOperand::createImm(0); 132e981a46aSKazushi (Jam) Marukawa LEAInst.addOperand(CZero); 13360431bd7SKazushi (Jam) Marukawa LEAInst.addOperand(RS1); 13460431bd7SKazushi (Jam) Marukawa LEAInst.addOperand(Imm); 13560431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(LEAInst, STI); 13660431bd7SKazushi (Jam) Marukawa } 13760431bd7SKazushi (Jam) Marukawa 13860431bd7SKazushi (Jam) Marukawa static void emitLEASLrri(MCStreamer &OutStreamer, MCOperand &RS1, 13960431bd7SKazushi (Jam) Marukawa MCOperand &RS2, MCOperand &Imm, MCOperand &RD, 14060431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 14160431bd7SKazushi (Jam) Marukawa MCInst LEASLInst; 14260431bd7SKazushi (Jam) Marukawa LEASLInst.setOpcode(VE::LEASLrri); 143e981a46aSKazushi (Jam) Marukawa LEASLInst.addOperand(RD); 14460431bd7SKazushi (Jam) Marukawa LEASLInst.addOperand(RS1); 14560431bd7SKazushi (Jam) Marukawa LEASLInst.addOperand(RS2); 14660431bd7SKazushi (Jam) Marukawa LEASLInst.addOperand(Imm); 14760431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(LEASLInst, STI); 14860431bd7SKazushi (Jam) Marukawa } 14960431bd7SKazushi (Jam) Marukawa 15060431bd7SKazushi (Jam) Marukawa static void emitBinary(MCStreamer &OutStreamer, unsigned Opcode, MCOperand &RS1, 15160431bd7SKazushi (Jam) Marukawa MCOperand &Src2, MCOperand &RD, 15260431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 15360431bd7SKazushi (Jam) Marukawa MCInst Inst; 15460431bd7SKazushi (Jam) Marukawa Inst.setOpcode(Opcode); 15560431bd7SKazushi (Jam) Marukawa Inst.addOperand(RD); 15660431bd7SKazushi (Jam) Marukawa Inst.addOperand(RS1); 15760431bd7SKazushi (Jam) Marukawa Inst.addOperand(Src2); 15860431bd7SKazushi (Jam) Marukawa OutStreamer.emitInstruction(Inst, STI); 15960431bd7SKazushi (Jam) Marukawa } 16060431bd7SKazushi (Jam) Marukawa 161015dee1aSKazushi (Jam) Marukawa static void emitANDrm(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 16260431bd7SKazushi (Jam) Marukawa MCOperand &RD, const MCSubtargetInfo &STI) { 163015dee1aSKazushi (Jam) Marukawa emitBinary(OutStreamer, VE::ANDrm, RS1, Imm, RD, STI); 16460431bd7SKazushi (Jam) Marukawa } 16560431bd7SKazushi (Jam) Marukawa 16660431bd7SKazushi (Jam) Marukawa static void emitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, 16760431bd7SKazushi (Jam) Marukawa VEMCExpr::VariantKind HiKind, VEMCExpr::VariantKind LoKind, 16860431bd7SKazushi (Jam) Marukawa MCOperand &RD, MCContext &OutContext, 16960431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 17060431bd7SKazushi (Jam) Marukawa 17160431bd7SKazushi (Jam) Marukawa MCOperand hi = createVEMCOperand(HiKind, GOTSym, OutContext); 17260431bd7SKazushi (Jam) Marukawa MCOperand lo = createVEMCOperand(LoKind, GOTSym, OutContext); 17360431bd7SKazushi (Jam) Marukawa emitLEAzzi(OutStreamer, lo, RD, STI); 174015dee1aSKazushi (Jam) Marukawa MCOperand M032 = MCOperand::createImm(M0(32)); 175015dee1aSKazushi (Jam) Marukawa emitANDrm(OutStreamer, RD, M032, RD, STI); 17660431bd7SKazushi (Jam) Marukawa emitLEASLzzi(OutStreamer, hi, RD, STI); 17760431bd7SKazushi (Jam) Marukawa } 17860431bd7SKazushi (Jam) Marukawa 17960431bd7SKazushi (Jam) Marukawa void VEAsmPrinter::lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 18060431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 18160431bd7SKazushi (Jam) Marukawa MCSymbol *GOTLabel = 18260431bd7SKazushi (Jam) Marukawa OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); 18360431bd7SKazushi (Jam) Marukawa 18460431bd7SKazushi (Jam) Marukawa const MachineOperand &MO = MI->getOperand(0); 18560431bd7SKazushi (Jam) Marukawa MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 18660431bd7SKazushi (Jam) Marukawa 18760431bd7SKazushi (Jam) Marukawa if (!isPositionIndependent()) { 18860431bd7SKazushi (Jam) Marukawa // Just load the address of GOT to MCRegOP. 18960431bd7SKazushi (Jam) Marukawa switch (TM.getCodeModel()) { 19060431bd7SKazushi (Jam) Marukawa default: 19160431bd7SKazushi (Jam) Marukawa llvm_unreachable("Unsupported absolute code model"); 19260431bd7SKazushi (Jam) Marukawa case CodeModel::Small: 19360431bd7SKazushi (Jam) Marukawa case CodeModel::Medium: 19460431bd7SKazushi (Jam) Marukawa case CodeModel::Large: 19560431bd7SKazushi (Jam) Marukawa emitHiLo(*OutStreamer, GOTLabel, VEMCExpr::VK_VE_HI32, 19660431bd7SKazushi (Jam) Marukawa VEMCExpr::VK_VE_LO32, MCRegOP, OutContext, STI); 19760431bd7SKazushi (Jam) Marukawa break; 19860431bd7SKazushi (Jam) Marukawa } 19960431bd7SKazushi (Jam) Marukawa return; 20060431bd7SKazushi (Jam) Marukawa } 20160431bd7SKazushi (Jam) Marukawa 20260431bd7SKazushi (Jam) Marukawa MCOperand RegGOT = MCOperand::createReg(VE::SX15); // GOT 20360431bd7SKazushi (Jam) Marukawa MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 20460431bd7SKazushi (Jam) Marukawa 20560431bd7SKazushi (Jam) Marukawa // lea %got, _GLOBAL_OFFSET_TABLE_@PC_LO(-24) 20660431bd7SKazushi (Jam) Marukawa // and %got, %got, (32)0 20760431bd7SKazushi (Jam) Marukawa // sic %plt 2083bfc9bb8SKazushi (Jam) Marukawa // lea.sl %got, _GLOBAL_OFFSET_TABLE_@PC_HI(%plt, %got) 20960431bd7SKazushi (Jam) Marukawa MCOperand cim24 = MCOperand::createImm(-24); 21060431bd7SKazushi (Jam) Marukawa MCOperand loImm = 21160431bd7SKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PC_LO32, GOTLabel, OutContext); 21260431bd7SKazushi (Jam) Marukawa emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 213015dee1aSKazushi (Jam) Marukawa MCOperand M032 = MCOperand::createImm(M0(32)); 214015dee1aSKazushi (Jam) Marukawa emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 21560431bd7SKazushi (Jam) Marukawa emitSIC(*OutStreamer, RegPLT, STI); 21660431bd7SKazushi (Jam) Marukawa MCOperand hiImm = 21760431bd7SKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PC_HI32, GOTLabel, OutContext); 21860431bd7SKazushi (Jam) Marukawa emitLEASLrri(*OutStreamer, RegGOT, RegPLT, hiImm, MCRegOP, STI); 21960431bd7SKazushi (Jam) Marukawa } 22060431bd7SKazushi (Jam) Marukawa 22160431bd7SKazushi (Jam) Marukawa void VEAsmPrinter::lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 22260431bd7SKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 22360431bd7SKazushi (Jam) Marukawa const MachineOperand &MO = MI->getOperand(0); 22460431bd7SKazushi (Jam) Marukawa MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 22560431bd7SKazushi (Jam) Marukawa const MachineOperand &Addr = MI->getOperand(1); 22660431bd7SKazushi (Jam) Marukawa MCSymbol *AddrSym = nullptr; 22760431bd7SKazushi (Jam) Marukawa 22860431bd7SKazushi (Jam) Marukawa switch (Addr.getType()) { 22960431bd7SKazushi (Jam) Marukawa default: 23060431bd7SKazushi (Jam) Marukawa llvm_unreachable("<unknown operand type>"); 23160431bd7SKazushi (Jam) Marukawa return; 23260431bd7SKazushi (Jam) Marukawa case MachineOperand::MO_MachineBasicBlock: 23360431bd7SKazushi (Jam) Marukawa report_fatal_error("MBB is not supported yet"); 23460431bd7SKazushi (Jam) Marukawa return; 23560431bd7SKazushi (Jam) Marukawa case MachineOperand::MO_ConstantPoolIndex: 23660431bd7SKazushi (Jam) Marukawa report_fatal_error("ConstantPool is not supported yet"); 23760431bd7SKazushi (Jam) Marukawa return; 23860431bd7SKazushi (Jam) Marukawa case MachineOperand::MO_ExternalSymbol: 23960431bd7SKazushi (Jam) Marukawa AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 24060431bd7SKazushi (Jam) Marukawa break; 24160431bd7SKazushi (Jam) Marukawa case MachineOperand::MO_GlobalAddress: 24260431bd7SKazushi (Jam) Marukawa AddrSym = getSymbol(Addr.getGlobal()); 24360431bd7SKazushi (Jam) Marukawa break; 24460431bd7SKazushi (Jam) Marukawa } 24560431bd7SKazushi (Jam) Marukawa 24660431bd7SKazushi (Jam) Marukawa if (!isPositionIndependent()) { 24760431bd7SKazushi (Jam) Marukawa llvm_unreachable("Unsupported uses of %plt in not PIC code"); 24860431bd7SKazushi (Jam) Marukawa return; 24960431bd7SKazushi (Jam) Marukawa } 25060431bd7SKazushi (Jam) Marukawa 25160431bd7SKazushi (Jam) Marukawa MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 25260431bd7SKazushi (Jam) Marukawa 2533bfc9bb8SKazushi (Jam) Marukawa // lea %dst, func@plt_lo(-24) 25460431bd7SKazushi (Jam) Marukawa // and %dst, %dst, (32)0 25560431bd7SKazushi (Jam) Marukawa // sic %plt ; FIXME: is it safe to use %plt here? 2563bfc9bb8SKazushi (Jam) Marukawa // lea.sl %dst, func@plt_hi(%plt, %dst) 25760431bd7SKazushi (Jam) Marukawa MCOperand cim24 = MCOperand::createImm(-24); 25860431bd7SKazushi (Jam) Marukawa MCOperand loImm = 25960431bd7SKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, AddrSym, OutContext); 26060431bd7SKazushi (Jam) Marukawa emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 261015dee1aSKazushi (Jam) Marukawa MCOperand M032 = MCOperand::createImm(M0(32)); 262015dee1aSKazushi (Jam) Marukawa emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 26360431bd7SKazushi (Jam) Marukawa emitSIC(*OutStreamer, RegPLT, STI); 26460431bd7SKazushi (Jam) Marukawa MCOperand hiImm = 26560431bd7SKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, AddrSym, OutContext); 26660431bd7SKazushi (Jam) Marukawa emitLEASLrri(*OutStreamer, MCRegOP, RegPLT, hiImm, MCRegOP, STI); 26760431bd7SKazushi (Jam) Marukawa } 26860431bd7SKazushi (Jam) Marukawa 2695526786aSKazushi (Jam) Marukawa void VEAsmPrinter::lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 2705526786aSKazushi (Jam) Marukawa const MCSubtargetInfo &STI) { 2715526786aSKazushi (Jam) Marukawa const MachineOperand &Addr = MI->getOperand(0); 2725526786aSKazushi (Jam) Marukawa MCSymbol *AddrSym = nullptr; 2735526786aSKazushi (Jam) Marukawa 2745526786aSKazushi (Jam) Marukawa switch (Addr.getType()) { 2755526786aSKazushi (Jam) Marukawa default: 2765526786aSKazushi (Jam) Marukawa llvm_unreachable("<unknown operand type>"); 2775526786aSKazushi (Jam) Marukawa return; 2785526786aSKazushi (Jam) Marukawa case MachineOperand::MO_MachineBasicBlock: 2795526786aSKazushi (Jam) Marukawa report_fatal_error("MBB is not supported yet"); 2805526786aSKazushi (Jam) Marukawa return; 2815526786aSKazushi (Jam) Marukawa case MachineOperand::MO_ConstantPoolIndex: 2825526786aSKazushi (Jam) Marukawa report_fatal_error("ConstantPool is not supported yet"); 2835526786aSKazushi (Jam) Marukawa return; 2845526786aSKazushi (Jam) Marukawa case MachineOperand::MO_ExternalSymbol: 2855526786aSKazushi (Jam) Marukawa AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 2865526786aSKazushi (Jam) Marukawa break; 2875526786aSKazushi (Jam) Marukawa case MachineOperand::MO_GlobalAddress: 2885526786aSKazushi (Jam) Marukawa AddrSym = getSymbol(Addr.getGlobal()); 2895526786aSKazushi (Jam) Marukawa break; 2905526786aSKazushi (Jam) Marukawa } 2915526786aSKazushi (Jam) Marukawa 2925526786aSKazushi (Jam) Marukawa MCOperand RegLR = MCOperand::createReg(VE::SX10); // LR 2935526786aSKazushi (Jam) Marukawa MCOperand RegS0 = MCOperand::createReg(VE::SX0); // S0 2945526786aSKazushi (Jam) Marukawa MCOperand RegS12 = MCOperand::createReg(VE::SX12); // S12 2955526786aSKazushi (Jam) Marukawa MCSymbol *GetTLSLabel = OutContext.getOrCreateSymbol(Twine("__tls_get_addr")); 2965526786aSKazushi (Jam) Marukawa 2975526786aSKazushi (Jam) Marukawa // lea %s0, sym@tls_gd_lo(-24) 2985526786aSKazushi (Jam) Marukawa // and %s0, %s0, (32)0 2995526786aSKazushi (Jam) Marukawa // sic %lr 3003bfc9bb8SKazushi (Jam) Marukawa // lea.sl %s0, sym@tls_gd_hi(%lr, %s0) 3015526786aSKazushi (Jam) Marukawa // lea %s12, __tls_get_addr@plt_lo(8) 3025526786aSKazushi (Jam) Marukawa // and %s12, %s12, (32)0 3035526786aSKazushi (Jam) Marukawa // lea.sl %s12, __tls_get_addr@plt_hi(%s12, %lr) 3045526786aSKazushi (Jam) Marukawa // bsic %lr, (, %s12) 3055526786aSKazushi (Jam) Marukawa MCOperand cim24 = MCOperand::createImm(-24); 3065526786aSKazushi (Jam) Marukawa MCOperand loImm = 3075526786aSKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_LO32, AddrSym, OutContext); 3085526786aSKazushi (Jam) Marukawa emitLEAzii(*OutStreamer, cim24, loImm, RegS0, STI); 309015dee1aSKazushi (Jam) Marukawa MCOperand M032 = MCOperand::createImm(M0(32)); 310015dee1aSKazushi (Jam) Marukawa emitANDrm(*OutStreamer, RegS0, M032, RegS0, STI); 3115526786aSKazushi (Jam) Marukawa emitSIC(*OutStreamer, RegLR, STI); 3125526786aSKazushi (Jam) Marukawa MCOperand hiImm = 3135526786aSKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_HI32, AddrSym, OutContext); 3145526786aSKazushi (Jam) Marukawa emitLEASLrri(*OutStreamer, RegS0, RegLR, hiImm, RegS0, STI); 3155526786aSKazushi (Jam) Marukawa MCOperand ci8 = MCOperand::createImm(8); 3165526786aSKazushi (Jam) Marukawa MCOperand loImm2 = 3175526786aSKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, GetTLSLabel, OutContext); 3185526786aSKazushi (Jam) Marukawa emitLEAzii(*OutStreamer, ci8, loImm2, RegS12, STI); 319015dee1aSKazushi (Jam) Marukawa emitANDrm(*OutStreamer, RegS12, M032, RegS12, STI); 3205526786aSKazushi (Jam) Marukawa MCOperand hiImm2 = 3215526786aSKazushi (Jam) Marukawa createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, GetTLSLabel, OutContext); 3225526786aSKazushi (Jam) Marukawa emitLEASLrri(*OutStreamer, RegS12, RegLR, hiImm2, RegS12, STI); 3235526786aSKazushi (Jam) Marukawa emitBSIC(*OutStreamer, RegLR, RegS12, STI); 3245526786aSKazushi (Jam) Marukawa } 3255526786aSKazushi (Jam) Marukawa 326bcd24b2dSFangrui Song void VEAsmPrinter::emitInstruction(const MachineInstr *MI) { 3273e0bf1c7SDavid Green VE_MC::verifyInstructionPredicates(MI->getOpcode(), 3283e0bf1c7SDavid Green getSubtargetInfo().getFeatureBits()); 329064859bdSKazushi (Jam) Marukawa 330064859bdSKazushi (Jam) Marukawa switch (MI->getOpcode()) { 331064859bdSKazushi (Jam) Marukawa default: 332064859bdSKazushi (Jam) Marukawa break; 333064859bdSKazushi (Jam) Marukawa case TargetOpcode::DBG_VALUE: 334064859bdSKazushi (Jam) Marukawa // FIXME: Debug Value. 335064859bdSKazushi (Jam) Marukawa return; 33660431bd7SKazushi (Jam) Marukawa case VE::GETGOT: 33760431bd7SKazushi (Jam) Marukawa lowerGETGOTAndEmitMCInsts(MI, getSubtargetInfo()); 33860431bd7SKazushi (Jam) Marukawa return; 33960431bd7SKazushi (Jam) Marukawa case VE::GETFUNPLT: 34060431bd7SKazushi (Jam) Marukawa lowerGETFunPLTAndEmitMCInsts(MI, getSubtargetInfo()); 34160431bd7SKazushi (Jam) Marukawa return; 3425526786aSKazushi (Jam) Marukawa case VE::GETTLSADDR: 3435526786aSKazushi (Jam) Marukawa lowerGETTLSAddrAndEmitMCInsts(MI, getSubtargetInfo()); 3445526786aSKazushi (Jam) Marukawa return; 345064859bdSKazushi (Jam) Marukawa } 34660431bd7SKazushi (Jam) Marukawa 347064859bdSKazushi (Jam) Marukawa MachineBasicBlock::const_instr_iterator I = MI->getIterator(); 348064859bdSKazushi (Jam) Marukawa MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 349064859bdSKazushi (Jam) Marukawa do { 350064859bdSKazushi (Jam) Marukawa MCInst TmpInst; 351064859bdSKazushi (Jam) Marukawa LowerVEMachineInstrToMCInst(&*I, TmpInst, *this); 352064859bdSKazushi (Jam) Marukawa EmitToStreamer(*OutStreamer, TmpInst); 353064859bdSKazushi (Jam) Marukawa } while ((++I != E) && I->isInsideBundle()); // Delay slot check. 354064859bdSKazushi (Jam) Marukawa } 355064859bdSKazushi (Jam) Marukawa 356b65ef65bSKazushi (Jam) Marukawa void VEAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 357b65ef65bSKazushi (Jam) Marukawa raw_ostream &O) { 358b65ef65bSKazushi (Jam) Marukawa const MachineOperand &MO = MI->getOperand(OpNum); 359b65ef65bSKazushi (Jam) Marukawa 360b65ef65bSKazushi (Jam) Marukawa switch (MO.getType()) { 361b65ef65bSKazushi (Jam) Marukawa case MachineOperand::MO_Register: 362b65ef65bSKazushi (Jam) Marukawa O << "%" << StringRef(getRegisterName(MO.getReg())).lower(); 363b65ef65bSKazushi (Jam) Marukawa break; 364b88aba9dSKazushi (Jam) Marukawa case MachineOperand::MO_Immediate: 365b88aba9dSKazushi (Jam) Marukawa O << (int)MO.getImm(); 366b88aba9dSKazushi (Jam) Marukawa break; 367b65ef65bSKazushi (Jam) Marukawa default: 368b65ef65bSKazushi (Jam) Marukawa llvm_unreachable("<unknown operand type>"); 369b65ef65bSKazushi (Jam) Marukawa } 370b65ef65bSKazushi (Jam) Marukawa } 371b65ef65bSKazushi (Jam) Marukawa 372b65ef65bSKazushi (Jam) Marukawa // PrintAsmOperand - Print out an operand for an inline asm expression. 373b65ef65bSKazushi (Jam) Marukawa bool VEAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 374b65ef65bSKazushi (Jam) Marukawa const char *ExtraCode, raw_ostream &O) { 375b65ef65bSKazushi (Jam) Marukawa if (ExtraCode && ExtraCode[0]) { 376b65ef65bSKazushi (Jam) Marukawa if (ExtraCode[1] != 0) 377b65ef65bSKazushi (Jam) Marukawa return true; // Unknown modifier. 378b65ef65bSKazushi (Jam) Marukawa 379b65ef65bSKazushi (Jam) Marukawa switch (ExtraCode[0]) { 380b65ef65bSKazushi (Jam) Marukawa default: 381b65ef65bSKazushi (Jam) Marukawa // See if this is a generic print operand 382b65ef65bSKazushi (Jam) Marukawa return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); 383b65ef65bSKazushi (Jam) Marukawa case 'r': 384c84b2c49SKazushi (Jam) Marukawa case 'v': 385b65ef65bSKazushi (Jam) Marukawa break; 386b65ef65bSKazushi (Jam) Marukawa } 387b65ef65bSKazushi (Jam) Marukawa } 388b65ef65bSKazushi (Jam) Marukawa 389b65ef65bSKazushi (Jam) Marukawa printOperand(MI, OpNo, O); 390b65ef65bSKazushi (Jam) Marukawa 391b65ef65bSKazushi (Jam) Marukawa return false; 392b65ef65bSKazushi (Jam) Marukawa } 393b65ef65bSKazushi (Jam) Marukawa 394b88aba9dSKazushi (Jam) Marukawa bool VEAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 395b88aba9dSKazushi (Jam) Marukawa const char *ExtraCode, 396b88aba9dSKazushi (Jam) Marukawa raw_ostream &O) { 397b88aba9dSKazushi (Jam) Marukawa if (ExtraCode && ExtraCode[0]) 398b88aba9dSKazushi (Jam) Marukawa return true; // Unknown modifier 399b88aba9dSKazushi (Jam) Marukawa 400b88aba9dSKazushi (Jam) Marukawa if (MI->getOperand(OpNo+1).isImm() && 401b88aba9dSKazushi (Jam) Marukawa MI->getOperand(OpNo+1).getImm() == 0) { 402b88aba9dSKazushi (Jam) Marukawa // don't print "+0" 403b88aba9dSKazushi (Jam) Marukawa } else { 404b88aba9dSKazushi (Jam) Marukawa printOperand(MI, OpNo+1, O); 405b88aba9dSKazushi (Jam) Marukawa } 406b88aba9dSKazushi (Jam) Marukawa if (MI->getOperand(OpNo).isImm() && 407b88aba9dSKazushi (Jam) Marukawa MI->getOperand(OpNo).getImm() == 0) { 408b88aba9dSKazushi (Jam) Marukawa if (MI->getOperand(OpNo+1).isImm() && 409b88aba9dSKazushi (Jam) Marukawa MI->getOperand(OpNo+1).getImm() == 0) { 410b88aba9dSKazushi (Jam) Marukawa O << "0"; 411b88aba9dSKazushi (Jam) Marukawa } else { 412b88aba9dSKazushi (Jam) Marukawa // don't print "(0)" 413b88aba9dSKazushi (Jam) Marukawa } 414b88aba9dSKazushi (Jam) Marukawa } else { 415b88aba9dSKazushi (Jam) Marukawa O << "("; 416b88aba9dSKazushi (Jam) Marukawa printOperand(MI, OpNo, O); 417b88aba9dSKazushi (Jam) Marukawa O << ")"; 418b88aba9dSKazushi (Jam) Marukawa } 419b88aba9dSKazushi (Jam) Marukawa return false; 420b88aba9dSKazushi (Jam) Marukawa } 421b88aba9dSKazushi (Jam) Marukawa 422064859bdSKazushi (Jam) Marukawa // Force static initialization. 4231eb812e0SSergei Trofimovich extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmPrinter() { 424064859bdSKazushi (Jam) Marukawa RegisterAsmPrinter<VEAsmPrinter> X(getTheVETarget()); 425064859bdSKazushi (Jam) Marukawa } 426