xref: /aosp_15_r20/external/llvm/lib/Target/SystemZ/SystemZMCInstLower.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SystemZMCInstLower.cpp - Lower MachineInstr to MCInst -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "SystemZMCInstLower.h"
11*9880d681SAndroid Build Coastguard Worker #include "SystemZAsmPrinter.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker using namespace llvm;
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker // Return the VK_* enumeration for MachineOperand target flags Flags.
getVariantKind(unsigned Flags)20*9880d681SAndroid Build Coastguard Worker static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) {
21*9880d681SAndroid Build Coastguard Worker   switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) {
22*9880d681SAndroid Build Coastguard Worker     case 0:
23*9880d681SAndroid Build Coastguard Worker       return MCSymbolRefExpr::VK_None;
24*9880d681SAndroid Build Coastguard Worker     case SystemZII::MO_GOT:
25*9880d681SAndroid Build Coastguard Worker       return MCSymbolRefExpr::VK_GOT;
26*9880d681SAndroid Build Coastguard Worker     case SystemZII::MO_INDNTPOFF:
27*9880d681SAndroid Build Coastguard Worker       return MCSymbolRefExpr::VK_INDNTPOFF;
28*9880d681SAndroid Build Coastguard Worker   }
29*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unrecognised MO_ACCESS_MODEL");
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker 
SystemZMCInstLower(MCContext & ctx,SystemZAsmPrinter & asmprinter)32*9880d681SAndroid Build Coastguard Worker SystemZMCInstLower::SystemZMCInstLower(MCContext &ctx,
33*9880d681SAndroid Build Coastguard Worker                                        SystemZAsmPrinter &asmprinter)
34*9880d681SAndroid Build Coastguard Worker   : Ctx(ctx), AsmPrinter(asmprinter) {}
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker const MCExpr *
getExpr(const MachineOperand & MO,MCSymbolRefExpr::VariantKind Kind) const37*9880d681SAndroid Build Coastguard Worker SystemZMCInstLower::getExpr(const MachineOperand &MO,
38*9880d681SAndroid Build Coastguard Worker                             MCSymbolRefExpr::VariantKind Kind) const {
39*9880d681SAndroid Build Coastguard Worker   const MCSymbol *Symbol;
40*9880d681SAndroid Build Coastguard Worker   bool HasOffset = true;
41*9880d681SAndroid Build Coastguard Worker   switch (MO.getType()) {
42*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_MachineBasicBlock:
43*9880d681SAndroid Build Coastguard Worker     Symbol = MO.getMBB()->getSymbol();
44*9880d681SAndroid Build Coastguard Worker     HasOffset = false;
45*9880d681SAndroid Build Coastguard Worker     break;
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_GlobalAddress:
48*9880d681SAndroid Build Coastguard Worker     Symbol = AsmPrinter.getSymbol(MO.getGlobal());
49*9880d681SAndroid Build Coastguard Worker     break;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ExternalSymbol:
52*9880d681SAndroid Build Coastguard Worker     Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
53*9880d681SAndroid Build Coastguard Worker     break;
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_JumpTableIndex:
56*9880d681SAndroid Build Coastguard Worker     Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
57*9880d681SAndroid Build Coastguard Worker     HasOffset = false;
58*9880d681SAndroid Build Coastguard Worker     break;
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ConstantPoolIndex:
61*9880d681SAndroid Build Coastguard Worker     Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
62*9880d681SAndroid Build Coastguard Worker     break;
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_BlockAddress:
65*9880d681SAndroid Build Coastguard Worker     Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
66*9880d681SAndroid Build Coastguard Worker     break;
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker   default:
69*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("unknown operand type");
70*9880d681SAndroid Build Coastguard Worker   }
71*9880d681SAndroid Build Coastguard Worker   const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, Ctx);
72*9880d681SAndroid Build Coastguard Worker   if (HasOffset)
73*9880d681SAndroid Build Coastguard Worker     if (int64_t Offset = MO.getOffset()) {
74*9880d681SAndroid Build Coastguard Worker       const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
75*9880d681SAndroid Build Coastguard Worker       Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
76*9880d681SAndroid Build Coastguard Worker     }
77*9880d681SAndroid Build Coastguard Worker   return Expr;
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker 
lowerOperand(const MachineOperand & MO) const80*9880d681SAndroid Build Coastguard Worker MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const {
81*9880d681SAndroid Build Coastguard Worker   switch (MO.getType()) {
82*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Register:
83*9880d681SAndroid Build Coastguard Worker     return MCOperand::createReg(MO.getReg());
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_Immediate:
86*9880d681SAndroid Build Coastguard Worker     return MCOperand::createImm(MO.getImm());
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   default: {
89*9880d681SAndroid Build Coastguard Worker     MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags());
90*9880d681SAndroid Build Coastguard Worker     return MCOperand::createExpr(getExpr(MO, Kind));
91*9880d681SAndroid Build Coastguard Worker   }
92*9880d681SAndroid Build Coastguard Worker   }
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker 
lower(const MachineInstr * MI,MCInst & OutMI) const95*9880d681SAndroid Build Coastguard Worker void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
96*9880d681SAndroid Build Coastguard Worker   OutMI.setOpcode(MI->getOpcode());
97*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
98*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(I);
99*9880d681SAndroid Build Coastguard Worker     // Ignore all implicit register operands.
100*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || !MO.isImplicit())
101*9880d681SAndroid Build Coastguard Worker       OutMI.addOperand(lowerOperand(MO));
102*9880d681SAndroid Build Coastguard Worker   }
103*9880d681SAndroid Build Coastguard Worker }
104