xref: /llvm-project/llvm/lib/Target/VE/VEAsmPrinter.cpp (revision ed8019d9fbed2e6a6b08f8f73e9fa54a24f3ed52)
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