1480093f4SDimitry Andric //===-- VEAsmPrinter.cpp - VE LLVM assembly writer ------------------------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file contains a printer that converts from our internal representation 10480093f4SDimitry Andric // of machine-dependent LLVM code to GAS-format VE assembly language. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 145ffd83dbSDimitry Andric #include "MCTargetDesc/VEInstPrinter.h" 155ffd83dbSDimitry Andric #include "MCTargetDesc/VEMCExpr.h" 16480093f4SDimitry Andric #include "MCTargetDesc/VETargetStreamer.h" 175ffd83dbSDimitry Andric #include "TargetInfo/VETargetInfo.h" 18480093f4SDimitry Andric #include "VE.h" 19480093f4SDimitry Andric #include "VEInstrInfo.h" 20480093f4SDimitry Andric #include "VETargetMachine.h" 21480093f4SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 22480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 23480093f4SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 24480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 25480093f4SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26480093f4SDimitry Andric #include "llvm/IR/Mangler.h" 27480093f4SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 28480093f4SDimitry Andric #include "llvm/MC/MCContext.h" 29480093f4SDimitry Andric #include "llvm/MC/MCInst.h" 30480093f4SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 31480093f4SDimitry Andric #include "llvm/MC/MCStreamer.h" 32480093f4SDimitry Andric #include "llvm/MC/MCSymbol.h" 33480093f4SDimitry Andric #include "llvm/Support/TargetRegistry.h" 34480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h" 35480093f4SDimitry Andric using namespace llvm; 36480093f4SDimitry Andric 37480093f4SDimitry Andric #define DEBUG_TYPE "ve-asmprinter" 38480093f4SDimitry Andric 39480093f4SDimitry Andric namespace { 40480093f4SDimitry Andric class VEAsmPrinter : public AsmPrinter { 41480093f4SDimitry Andric VETargetStreamer &getTargetStreamer() { 42480093f4SDimitry Andric return static_cast<VETargetStreamer &>(*OutStreamer->getTargetStreamer()); 43480093f4SDimitry Andric } 44480093f4SDimitry Andric 45480093f4SDimitry Andric public: 46480093f4SDimitry Andric explicit VEAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 47480093f4SDimitry Andric : AsmPrinter(TM, std::move(Streamer)) {} 48480093f4SDimitry Andric 49480093f4SDimitry Andric StringRef getPassName() const override { return "VE Assembly Printer"; } 50480093f4SDimitry Andric 515ffd83dbSDimitry Andric void lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 525ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 535ffd83dbSDimitry Andric void lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 545ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 555ffd83dbSDimitry Andric void lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 565ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 575ffd83dbSDimitry Andric 585ffd83dbSDimitry Andric void emitInstruction(const MachineInstr *MI) override; 59480093f4SDimitry Andric 60480093f4SDimitry Andric static const char *getRegisterName(unsigned RegNo) { 61480093f4SDimitry Andric return VEInstPrinter::getRegisterName(RegNo); 62480093f4SDimitry Andric } 63*e8d8bef9SDimitry Andric void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &OS); 64*e8d8bef9SDimitry Andric bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 65*e8d8bef9SDimitry Andric const char *ExtraCode, raw_ostream &O) override; 66480093f4SDimitry Andric }; 67480093f4SDimitry Andric } // end of anonymous namespace 68480093f4SDimitry Andric 695ffd83dbSDimitry Andric static MCOperand createVEMCOperand(VEMCExpr::VariantKind Kind, MCSymbol *Sym, 705ffd83dbSDimitry Andric MCContext &OutContext) { 715ffd83dbSDimitry Andric const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Sym, OutContext); 725ffd83dbSDimitry Andric const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, OutContext); 735ffd83dbSDimitry Andric return MCOperand::createExpr(expr); 745ffd83dbSDimitry Andric } 755ffd83dbSDimitry Andric 765ffd83dbSDimitry Andric static MCOperand createGOTRelExprOp(VEMCExpr::VariantKind Kind, 775ffd83dbSDimitry Andric MCSymbol *GOTLabel, MCContext &OutContext) { 785ffd83dbSDimitry Andric const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext); 795ffd83dbSDimitry Andric const VEMCExpr *expr = VEMCExpr::create(Kind, GOT, OutContext); 805ffd83dbSDimitry Andric return MCOperand::createExpr(expr); 815ffd83dbSDimitry Andric } 825ffd83dbSDimitry Andric 835ffd83dbSDimitry Andric static void emitSIC(MCStreamer &OutStreamer, MCOperand &RD, 845ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 855ffd83dbSDimitry Andric MCInst SICInst; 865ffd83dbSDimitry Andric SICInst.setOpcode(VE::SIC); 875ffd83dbSDimitry Andric SICInst.addOperand(RD); 885ffd83dbSDimitry Andric OutStreamer.emitInstruction(SICInst, STI); 895ffd83dbSDimitry Andric } 905ffd83dbSDimitry Andric 915ffd83dbSDimitry Andric static void emitBSIC(MCStreamer &OutStreamer, MCOperand &R1, MCOperand &R2, 925ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 935ffd83dbSDimitry Andric MCInst BSICInst; 945ffd83dbSDimitry Andric BSICInst.setOpcode(VE::BSICrii); 955ffd83dbSDimitry Andric BSICInst.addOperand(R1); 965ffd83dbSDimitry Andric BSICInst.addOperand(R2); 975ffd83dbSDimitry Andric MCOperand czero = MCOperand::createImm(0); 985ffd83dbSDimitry Andric BSICInst.addOperand(czero); 995ffd83dbSDimitry Andric BSICInst.addOperand(czero); 1005ffd83dbSDimitry Andric OutStreamer.emitInstruction(BSICInst, STI); 1015ffd83dbSDimitry Andric } 1025ffd83dbSDimitry Andric 1035ffd83dbSDimitry Andric static void emitLEAzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 1045ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1055ffd83dbSDimitry Andric MCInst LEAInst; 1065ffd83dbSDimitry Andric LEAInst.setOpcode(VE::LEAzii); 1075ffd83dbSDimitry Andric LEAInst.addOperand(RD); 1085ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 1095ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 1105ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 1115ffd83dbSDimitry Andric LEAInst.addOperand(Imm); 1125ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEAInst, STI); 1135ffd83dbSDimitry Andric } 1145ffd83dbSDimitry Andric 1155ffd83dbSDimitry Andric static void emitLEASLzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 1165ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1175ffd83dbSDimitry Andric MCInst LEASLInst; 1185ffd83dbSDimitry Andric LEASLInst.setOpcode(VE::LEASLzii); 1195ffd83dbSDimitry Andric LEASLInst.addOperand(RD); 1205ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 1215ffd83dbSDimitry Andric LEASLInst.addOperand(CZero); 1225ffd83dbSDimitry Andric LEASLInst.addOperand(CZero); 1235ffd83dbSDimitry Andric LEASLInst.addOperand(Imm); 1245ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEASLInst, STI); 1255ffd83dbSDimitry Andric } 1265ffd83dbSDimitry Andric 1275ffd83dbSDimitry Andric static void emitLEAzii(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 1285ffd83dbSDimitry Andric MCOperand &RD, const MCSubtargetInfo &STI) { 1295ffd83dbSDimitry Andric MCInst LEAInst; 1305ffd83dbSDimitry Andric LEAInst.setOpcode(VE::LEAzii); 1315ffd83dbSDimitry Andric LEAInst.addOperand(RD); 1325ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 1335ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 1345ffd83dbSDimitry Andric LEAInst.addOperand(RS1); 1355ffd83dbSDimitry Andric LEAInst.addOperand(Imm); 1365ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEAInst, STI); 1375ffd83dbSDimitry Andric } 1385ffd83dbSDimitry Andric 1395ffd83dbSDimitry Andric static void emitLEASLrri(MCStreamer &OutStreamer, MCOperand &RS1, 1405ffd83dbSDimitry Andric MCOperand &RS2, MCOperand &Imm, MCOperand &RD, 1415ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1425ffd83dbSDimitry Andric MCInst LEASLInst; 1435ffd83dbSDimitry Andric LEASLInst.setOpcode(VE::LEASLrri); 1445ffd83dbSDimitry Andric LEASLInst.addOperand(RD); 1455ffd83dbSDimitry Andric LEASLInst.addOperand(RS1); 1465ffd83dbSDimitry Andric LEASLInst.addOperand(RS2); 1475ffd83dbSDimitry Andric LEASLInst.addOperand(Imm); 1485ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEASLInst, STI); 1495ffd83dbSDimitry Andric } 1505ffd83dbSDimitry Andric 1515ffd83dbSDimitry Andric static void emitBinary(MCStreamer &OutStreamer, unsigned Opcode, MCOperand &RS1, 1525ffd83dbSDimitry Andric MCOperand &Src2, MCOperand &RD, 1535ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1545ffd83dbSDimitry Andric MCInst Inst; 1555ffd83dbSDimitry Andric Inst.setOpcode(Opcode); 1565ffd83dbSDimitry Andric Inst.addOperand(RD); 1575ffd83dbSDimitry Andric Inst.addOperand(RS1); 1585ffd83dbSDimitry Andric Inst.addOperand(Src2); 1595ffd83dbSDimitry Andric OutStreamer.emitInstruction(Inst, STI); 1605ffd83dbSDimitry Andric } 1615ffd83dbSDimitry Andric 1625ffd83dbSDimitry Andric static void emitANDrm(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 1635ffd83dbSDimitry Andric MCOperand &RD, const MCSubtargetInfo &STI) { 1645ffd83dbSDimitry Andric emitBinary(OutStreamer, VE::ANDrm, RS1, Imm, RD, STI); 1655ffd83dbSDimitry Andric } 1665ffd83dbSDimitry Andric 1675ffd83dbSDimitry Andric static void emitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, 1685ffd83dbSDimitry Andric VEMCExpr::VariantKind HiKind, VEMCExpr::VariantKind LoKind, 1695ffd83dbSDimitry Andric MCOperand &RD, MCContext &OutContext, 1705ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1715ffd83dbSDimitry Andric 1725ffd83dbSDimitry Andric MCOperand hi = createVEMCOperand(HiKind, GOTSym, OutContext); 1735ffd83dbSDimitry Andric MCOperand lo = createVEMCOperand(LoKind, GOTSym, OutContext); 1745ffd83dbSDimitry Andric emitLEAzzi(OutStreamer, lo, RD, STI); 1755ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 1765ffd83dbSDimitry Andric emitANDrm(OutStreamer, RD, M032, RD, STI); 1775ffd83dbSDimitry Andric emitLEASLzzi(OutStreamer, hi, RD, STI); 1785ffd83dbSDimitry Andric } 1795ffd83dbSDimitry Andric 1805ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 1815ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 1825ffd83dbSDimitry Andric MCSymbol *GOTLabel = 1835ffd83dbSDimitry Andric OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); 1845ffd83dbSDimitry Andric 1855ffd83dbSDimitry Andric const MachineOperand &MO = MI->getOperand(0); 1865ffd83dbSDimitry Andric MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 1875ffd83dbSDimitry Andric 1885ffd83dbSDimitry Andric if (!isPositionIndependent()) { 1895ffd83dbSDimitry Andric // Just load the address of GOT to MCRegOP. 1905ffd83dbSDimitry Andric switch (TM.getCodeModel()) { 1915ffd83dbSDimitry Andric default: 1925ffd83dbSDimitry Andric llvm_unreachable("Unsupported absolute code model"); 1935ffd83dbSDimitry Andric case CodeModel::Small: 1945ffd83dbSDimitry Andric case CodeModel::Medium: 1955ffd83dbSDimitry Andric case CodeModel::Large: 1965ffd83dbSDimitry Andric emitHiLo(*OutStreamer, GOTLabel, VEMCExpr::VK_VE_HI32, 1975ffd83dbSDimitry Andric VEMCExpr::VK_VE_LO32, MCRegOP, OutContext, STI); 1985ffd83dbSDimitry Andric break; 1995ffd83dbSDimitry Andric } 2005ffd83dbSDimitry Andric return; 2015ffd83dbSDimitry Andric } 2025ffd83dbSDimitry Andric 2035ffd83dbSDimitry Andric MCOperand RegGOT = MCOperand::createReg(VE::SX15); // GOT 2045ffd83dbSDimitry Andric MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric // lea %got, _GLOBAL_OFFSET_TABLE_@PC_LO(-24) 2075ffd83dbSDimitry Andric // and %got, %got, (32)0 2085ffd83dbSDimitry Andric // sic %plt 209*e8d8bef9SDimitry Andric // lea.sl %got, _GLOBAL_OFFSET_TABLE_@PC_HI(%plt, %got) 2105ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 2115ffd83dbSDimitry Andric MCOperand loImm = 2125ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PC_LO32, GOTLabel, OutContext); 2135ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 2145ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 2155ffd83dbSDimitry Andric emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 2165ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegPLT, STI); 2175ffd83dbSDimitry Andric MCOperand hiImm = 2185ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PC_HI32, GOTLabel, OutContext); 2195ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegGOT, RegPLT, hiImm, MCRegOP, STI); 2205ffd83dbSDimitry Andric } 2215ffd83dbSDimitry Andric 2225ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 2235ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 2245ffd83dbSDimitry Andric const MachineOperand &MO = MI->getOperand(0); 2255ffd83dbSDimitry Andric MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 2265ffd83dbSDimitry Andric const MachineOperand &Addr = MI->getOperand(1); 2275ffd83dbSDimitry Andric MCSymbol *AddrSym = nullptr; 2285ffd83dbSDimitry Andric 2295ffd83dbSDimitry Andric switch (Addr.getType()) { 2305ffd83dbSDimitry Andric default: 2315ffd83dbSDimitry Andric llvm_unreachable("<unknown operand type>"); 2325ffd83dbSDimitry Andric return; 2335ffd83dbSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2345ffd83dbSDimitry Andric report_fatal_error("MBB is not supported yet"); 2355ffd83dbSDimitry Andric return; 2365ffd83dbSDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2375ffd83dbSDimitry Andric report_fatal_error("ConstantPool is not supported yet"); 2385ffd83dbSDimitry Andric return; 2395ffd83dbSDimitry Andric case MachineOperand::MO_ExternalSymbol: 2405ffd83dbSDimitry Andric AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 2415ffd83dbSDimitry Andric break; 2425ffd83dbSDimitry Andric case MachineOperand::MO_GlobalAddress: 2435ffd83dbSDimitry Andric AddrSym = getSymbol(Addr.getGlobal()); 2445ffd83dbSDimitry Andric break; 2455ffd83dbSDimitry Andric } 2465ffd83dbSDimitry Andric 2475ffd83dbSDimitry Andric if (!isPositionIndependent()) { 2485ffd83dbSDimitry Andric llvm_unreachable("Unsupported uses of %plt in not PIC code"); 2495ffd83dbSDimitry Andric return; 2505ffd83dbSDimitry Andric } 2515ffd83dbSDimitry Andric 2525ffd83dbSDimitry Andric MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 2535ffd83dbSDimitry Andric 254*e8d8bef9SDimitry Andric // lea %dst, func@plt_lo(-24) 2555ffd83dbSDimitry Andric // and %dst, %dst, (32)0 2565ffd83dbSDimitry Andric // sic %plt ; FIXME: is it safe to use %plt here? 257*e8d8bef9SDimitry Andric // lea.sl %dst, func@plt_hi(%plt, %dst) 2585ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 2595ffd83dbSDimitry Andric MCOperand loImm = 2605ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, AddrSym, OutContext); 2615ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 2625ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 2635ffd83dbSDimitry Andric emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 2645ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegPLT, STI); 2655ffd83dbSDimitry Andric MCOperand hiImm = 2665ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, AddrSym, OutContext); 2675ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, MCRegOP, RegPLT, hiImm, MCRegOP, STI); 2685ffd83dbSDimitry Andric } 2695ffd83dbSDimitry Andric 2705ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 2715ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 2725ffd83dbSDimitry Andric const MachineOperand &Addr = MI->getOperand(0); 2735ffd83dbSDimitry Andric MCSymbol *AddrSym = nullptr; 2745ffd83dbSDimitry Andric 2755ffd83dbSDimitry Andric switch (Addr.getType()) { 2765ffd83dbSDimitry Andric default: 2775ffd83dbSDimitry Andric llvm_unreachable("<unknown operand type>"); 2785ffd83dbSDimitry Andric return; 2795ffd83dbSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2805ffd83dbSDimitry Andric report_fatal_error("MBB is not supported yet"); 2815ffd83dbSDimitry Andric return; 2825ffd83dbSDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2835ffd83dbSDimitry Andric report_fatal_error("ConstantPool is not supported yet"); 2845ffd83dbSDimitry Andric return; 2855ffd83dbSDimitry Andric case MachineOperand::MO_ExternalSymbol: 2865ffd83dbSDimitry Andric AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 2875ffd83dbSDimitry Andric break; 2885ffd83dbSDimitry Andric case MachineOperand::MO_GlobalAddress: 2895ffd83dbSDimitry Andric AddrSym = getSymbol(Addr.getGlobal()); 2905ffd83dbSDimitry Andric break; 2915ffd83dbSDimitry Andric } 2925ffd83dbSDimitry Andric 2935ffd83dbSDimitry Andric MCOperand RegLR = MCOperand::createReg(VE::SX10); // LR 2945ffd83dbSDimitry Andric MCOperand RegS0 = MCOperand::createReg(VE::SX0); // S0 2955ffd83dbSDimitry Andric MCOperand RegS12 = MCOperand::createReg(VE::SX12); // S12 2965ffd83dbSDimitry Andric MCSymbol *GetTLSLabel = OutContext.getOrCreateSymbol(Twine("__tls_get_addr")); 2975ffd83dbSDimitry Andric 2985ffd83dbSDimitry Andric // lea %s0, sym@tls_gd_lo(-24) 2995ffd83dbSDimitry Andric // and %s0, %s0, (32)0 3005ffd83dbSDimitry Andric // sic %lr 301*e8d8bef9SDimitry Andric // lea.sl %s0, sym@tls_gd_hi(%lr, %s0) 3025ffd83dbSDimitry Andric // lea %s12, __tls_get_addr@plt_lo(8) 3035ffd83dbSDimitry Andric // and %s12, %s12, (32)0 3045ffd83dbSDimitry Andric // lea.sl %s12, __tls_get_addr@plt_hi(%s12, %lr) 3055ffd83dbSDimitry Andric // bsic %lr, (, %s12) 3065ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 3075ffd83dbSDimitry Andric MCOperand loImm = 3085ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_LO32, AddrSym, OutContext); 3095ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, RegS0, STI); 3105ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 3115ffd83dbSDimitry Andric emitANDrm(*OutStreamer, RegS0, M032, RegS0, STI); 3125ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegLR, STI); 3135ffd83dbSDimitry Andric MCOperand hiImm = 3145ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_HI32, AddrSym, OutContext); 3155ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegS0, RegLR, hiImm, RegS0, STI); 3165ffd83dbSDimitry Andric MCOperand ci8 = MCOperand::createImm(8); 3175ffd83dbSDimitry Andric MCOperand loImm2 = 3185ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, GetTLSLabel, OutContext); 3195ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, ci8, loImm2, RegS12, STI); 3205ffd83dbSDimitry Andric emitANDrm(*OutStreamer, RegS12, M032, RegS12, STI); 3215ffd83dbSDimitry Andric MCOperand hiImm2 = 3225ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, GetTLSLabel, OutContext); 3235ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegS12, RegLR, hiImm2, RegS12, STI); 3245ffd83dbSDimitry Andric emitBSIC(*OutStreamer, RegLR, RegS12, STI); 3255ffd83dbSDimitry Andric } 3265ffd83dbSDimitry Andric 3275ffd83dbSDimitry Andric void VEAsmPrinter::emitInstruction(const MachineInstr *MI) { 328480093f4SDimitry Andric 329480093f4SDimitry Andric switch (MI->getOpcode()) { 330480093f4SDimitry Andric default: 331480093f4SDimitry Andric break; 332480093f4SDimitry Andric case TargetOpcode::DBG_VALUE: 333480093f4SDimitry Andric // FIXME: Debug Value. 334480093f4SDimitry Andric return; 3355ffd83dbSDimitry Andric case VE::GETGOT: 3365ffd83dbSDimitry Andric lowerGETGOTAndEmitMCInsts(MI, getSubtargetInfo()); 3375ffd83dbSDimitry Andric return; 3385ffd83dbSDimitry Andric case VE::GETFUNPLT: 3395ffd83dbSDimitry Andric lowerGETFunPLTAndEmitMCInsts(MI, getSubtargetInfo()); 3405ffd83dbSDimitry Andric return; 3415ffd83dbSDimitry Andric case VE::GETTLSADDR: 3425ffd83dbSDimitry Andric lowerGETTLSAddrAndEmitMCInsts(MI, getSubtargetInfo()); 3435ffd83dbSDimitry Andric return; 344480093f4SDimitry Andric } 3455ffd83dbSDimitry Andric 346480093f4SDimitry Andric MachineBasicBlock::const_instr_iterator I = MI->getIterator(); 347480093f4SDimitry Andric MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 348480093f4SDimitry Andric do { 349480093f4SDimitry Andric MCInst TmpInst; 350480093f4SDimitry Andric LowerVEMachineInstrToMCInst(&*I, TmpInst, *this); 351480093f4SDimitry Andric EmitToStreamer(*OutStreamer, TmpInst); 352480093f4SDimitry Andric } while ((++I != E) && I->isInsideBundle()); // Delay slot check. 353480093f4SDimitry Andric } 354480093f4SDimitry Andric 355*e8d8bef9SDimitry Andric void VEAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 356*e8d8bef9SDimitry Andric raw_ostream &O) { 357*e8d8bef9SDimitry Andric const MachineOperand &MO = MI->getOperand(OpNum); 358*e8d8bef9SDimitry Andric 359*e8d8bef9SDimitry Andric switch (MO.getType()) { 360*e8d8bef9SDimitry Andric case MachineOperand::MO_Register: 361*e8d8bef9SDimitry Andric O << "%" << StringRef(getRegisterName(MO.getReg())).lower(); 362*e8d8bef9SDimitry Andric break; 363*e8d8bef9SDimitry Andric default: 364*e8d8bef9SDimitry Andric llvm_unreachable("<unknown operand type>"); 365*e8d8bef9SDimitry Andric } 366*e8d8bef9SDimitry Andric } 367*e8d8bef9SDimitry Andric 368*e8d8bef9SDimitry Andric // PrintAsmOperand - Print out an operand for an inline asm expression. 369*e8d8bef9SDimitry Andric bool VEAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 370*e8d8bef9SDimitry Andric const char *ExtraCode, raw_ostream &O) { 371*e8d8bef9SDimitry Andric if (ExtraCode && ExtraCode[0]) { 372*e8d8bef9SDimitry Andric if (ExtraCode[1] != 0) 373*e8d8bef9SDimitry Andric return true; // Unknown modifier. 374*e8d8bef9SDimitry Andric 375*e8d8bef9SDimitry Andric switch (ExtraCode[0]) { 376*e8d8bef9SDimitry Andric default: 377*e8d8bef9SDimitry Andric // See if this is a generic print operand 378*e8d8bef9SDimitry Andric return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); 379*e8d8bef9SDimitry Andric case 'r': 380*e8d8bef9SDimitry Andric case 'v': 381*e8d8bef9SDimitry Andric break; 382*e8d8bef9SDimitry Andric } 383*e8d8bef9SDimitry Andric } 384*e8d8bef9SDimitry Andric 385*e8d8bef9SDimitry Andric printOperand(MI, OpNo, O); 386*e8d8bef9SDimitry Andric 387*e8d8bef9SDimitry Andric return false; 388*e8d8bef9SDimitry Andric } 389*e8d8bef9SDimitry Andric 390480093f4SDimitry Andric // Force static initialization. 391*e8d8bef9SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmPrinter() { 392480093f4SDimitry Andric RegisterAsmPrinter<VEAsmPrinter> X(getTheVETarget()); 393480093f4SDimitry Andric } 394