LLVM  14.0.0git
ARMMCInstLower.cpp
Go to the documentation of this file.
1 //===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains code to lower ARM MachineInstrs to their corresponding
10 // MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARM.h"
15 #include "ARMAsmPrinter.h"
16 #include "ARMBaseInstrInfo.h"
17 #include "ARMMachineFunctionInfo.h"
18 #include "ARMSubtarget.h"
21 #include "MCTargetDesc/ARMMCExpr.h"
22 #include "llvm/ADT/APFloat.h"
26 #include "llvm/IR/Constants.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCExpr.h"
29 #include "llvm/MC/MCInst.h"
30 #include "llvm/MC/MCInstBuilder.h"
31 #include "llvm/MC/MCStreamer.h"
33 #include <cassert>
34 #include <cstdint>
35 
36 using namespace llvm;
37 
38 MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
39  const MCSymbol *Symbol) {
42  SymbolVariant = MCSymbolRefExpr::VK_ARM_SBREL;
43 
44  const MCExpr *Expr =
45  MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
46  switch (MO.getTargetFlags() & ARMII::MO_OPTION_MASK) {
47  default:
48  llvm_unreachable("Unknown target flag on symbol operand");
49  case ARMII::MO_NO_FLAG:
50  break;
51  case ARMII::MO_LO16:
52  Expr =
53  MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
55  break;
56  case ARMII::MO_HI16:
57  Expr =
58  MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
60  break;
61  }
62 
63  if (!MO.isJTI() && MO.getOffset())
64  Expr = MCBinaryExpr::createAdd(Expr,
66  OutContext),
67  OutContext);
68  return MCOperand::createExpr(Expr);
69 
70 }
71 
73  MCOperand &MCOp) {
74  switch (MO.getType()) {
75  default: llvm_unreachable("unknown operand type");
77  // Ignore all implicit register operands.
78  if (MO.isImplicit())
79  return false;
80  assert(!MO.getSubReg() && "Subregs should be eliminated!");
81  MCOp = MCOperand::createReg(MO.getReg());
82  break;
84  MCOp = MCOperand::createImm(MO.getImm());
85  break;
88  MO.getMBB()->getSymbol(), OutContext));
89  break;
91  MCOp = GetSymbolRef(MO,
92  GetARMGVSymbol(MO.getGlobal(), MO.getTargetFlags()));
93  break;
95  MCOp = GetSymbolRef(MO,
97  break;
99  MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
100  break;
102  if (Subtarget->genExecuteOnly())
103  llvm_unreachable("execute-only should not generate constant pools");
104  MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
105  break;
107  MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
108  break;
110  APFloat Val = MO.getFPImm()->getValueAPF();
111  bool ignored;
113  MCOp = MCOperand::createDFPImm(bit_cast<uint64_t>(Val.convertToDouble()));
114  break;
115  }
117  // Ignore call clobbers.
118  return false;
119  }
120  return true;
121 }
122 
124  ARMAsmPrinter &AP) {
125  OutMI.setOpcode(MI->getOpcode());
126 
127  // In the MC layer, we keep modified immediates in their encoded form
128  bool EncodeImms = false;
129  switch (MI->getOpcode()) {
130  default: break;
131  case ARM::MOVi:
132  case ARM::MVNi:
133  case ARM::CMPri:
134  case ARM::CMNri:
135  case ARM::TSTri:
136  case ARM::TEQri:
137  case ARM::MSRi:
138  case ARM::ADCri:
139  case ARM::ADDri:
140  case ARM::ADDSri:
141  case ARM::SBCri:
142  case ARM::SUBri:
143  case ARM::SUBSri:
144  case ARM::ANDri:
145  case ARM::ORRri:
146  case ARM::EORri:
147  case ARM::BICri:
148  case ARM::RSBri:
149  case ARM::RSBSri:
150  case ARM::RSCri:
151  EncodeImms = true;
152  break;
153  }
154 
155  for (const MachineOperand &MO : MI->operands()) {
156  MCOperand MCOp;
157  if (AP.lowerOperand(MO, MCOp)) {
158  if (MCOp.isImm() && EncodeImms) {
159  int32_t Enc = ARM_AM::getSOImmVal(MCOp.getImm());
160  if (Enc != -1)
161  MCOp.setImm(Enc);
162  }
163  OutMI.addOperand(MCOp);
164  }
165  }
166 }
167 
168 void ARMAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind)
169 {
170  if (MI.getParent()->getParent()->getInfo<ARMFunctionInfo>()
171  ->isThumbFunction())
172  {
173  MI.emitError("An attempt to perform XRay instrumentation for a"
174  " Thumb function (not supported). Detected when emitting a sled.");
175  return;
176  }
177  static const int8_t NoopsInSledCount = 6;
178  // We want to emit the following pattern:
179  //
180  // .Lxray_sled_N:
181  // ALIGN
182  // B #20
183  // ; 6 NOP instructions (24 bytes)
184  // .tmpN
185  //
186  // We need the 24 bytes (6 instructions) because at runtime, we'd be patching
187  // over the full 28 bytes (7 instructions) with the following pattern:
188  //
189  // PUSH{ r0, lr }
190  // MOVW r0, #<lower 16 bits of function ID>
191  // MOVT r0, #<higher 16 bits of function ID>
192  // MOVW ip, #<lower 16 bits of address of __xray_FunctionEntry/Exit>
193  // MOVT ip, #<higher 16 bits of address of __xray_FunctionEntry/Exit>
194  // BLX ip
195  // POP{ r0, lr }
196  //
197  OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
198  auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
199  OutStreamer->emitLabel(CurSled);
201 
202  // Emit "B #20" instruction, which jumps over the next 24 bytes (because
203  // register pc is 8 bytes ahead of the jump instruction by the moment CPU
204  // is executing it).
205  // By analogy to ARMAsmPrinter::emitPseudoExpansionLowering() |case ARM::B|.
206  // It is not clear why |addReg(0)| is needed (the last operand).
207  EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::Bcc).addImm(20)
208  .addImm(ARMCC::AL).addReg(0));
209 
210  emitNops(NoopsInSledCount);
211 
212  OutStreamer->emitLabel(Target);
213  recordSled(CurSled, MI, Kind, 2);
214 }
215 
217 {
218  EmitSled(MI, SledKind::FUNCTION_ENTER);
219 }
220 
222 {
223  EmitSled(MI, SledKind::FUNCTION_EXIT);
224 }
225 
227 {
228  EmitSled(MI, SledKind::TAIL_CALL);
229 }
ARMSubtarget.h
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:63
llvm::ARMFunctionInfo
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
Definition: ARMMachineFunctionInfo.h:27
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MachineInstr.h
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:53
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::ARMII::MO_HI16
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
Definition: ARMBaseInfo.h:250
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
llvm::AsmPrinter::recordSled
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
Definition: AsmPrinter.cpp:3570
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition: MachineOperand.h:563
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::MachineOperand::getBlockAddress
const BlockAddress * getBlockAddress() const
Definition: MachineOperand.h:568
llvm::MCSymbolRefExpr::VK_ARM_SBREL
@ VK_ARM_SBREL
Definition: MCExpr.h:234
ErrorHandling.h
ARMMachineFunctionInfo.h
MCInstBuilder.h
MachineBasicBlock.h
llvm::MachineOperand::isJTI
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
Definition: MachineOperand.h:337
llvm::ARMAsmPrinter::LowerPATCHABLE_FUNCTION_ENTER
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
Definition: ARMMCInstLower.cpp:216
llvm::ConstantFP::getValueAPF
const APFloat & getValueAPF() const
Definition: Constants.h:297
ARMMCExpr.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::MachineOperand::getOffset
int64_t getOffset() const
Return the offset from the symbol in this operand.
Definition: MachineOperand.h:600
llvm::ARMMCExpr::createUpper16
static const ARMMCExpr * createUpper16(const MCExpr *Expr, MCContext &Ctx)
Definition: ARMMCExpr.h:38
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:52
llvm::AsmPrinter::EmitToStreamer
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:242
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
llvm::MachineBasicBlock::getSymbol
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Definition: MachineBasicBlock.cpp:60
llvm::ARMII::MO_NO_FLAG
@ MO_NO_FLAG
Definition: ARMBaseInfo.h:242
llvm::LowerARMMachineInstrToMCInst
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP)
Definition: ARMMCInstLower.cpp:123
llvm::MachineOperand::isImplicit
bool isImplicit() const
Definition: MachineOperand.h:380
llvm::ARM_AM::getSOImmVal
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
Definition: ARMAddressingModes.h:163
ARMBaseInfo.h
Constants.h
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:62
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::AsmPrinter::OutStreamer
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:96
MCContext.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
ARMAsmPrinter.h
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::APFloat::convertToDouble
double convertToDouble() const
Converts this APFloat to host double value.
Definition: APFloat.cpp:4895
APFloat.h
This file declares a class to represent arbitrary precision floating point values and provide a varie...
llvm::ARMFunctionInfo::isThumbFunction
bool isThumbFunction() const
Definition: ARMMachineFunctionInfo.h:150
llvm::ARMAsmPrinter::lowerOperand
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp)
Definition: ARMMCInstLower.cpp:72
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
llvm::ARMCC::AL
@ AL
Definition: ARMBaseInfo.h:45
llvm::APFloat
Definition: APFloat.h:701
llvm::ARMAsmPrinter
Definition: ARMAsmPrinter.h:31
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::MCSymbolRefExpr::VariantKind
VariantKind
Definition: MCExpr.h:194
llvm::MachineOperand::getTargetFlags
unsigned getTargetFlags() const
Definition: MachineOperand.h:221
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::AsmPrinter::GetBlockAddressSymbol
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
Definition: AsmPrinter.cpp:3133
llvm::MCInstBuilder
Definition: MCInstBuilder.h:21
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:219
llvm::MachineOperand::getFPImm
const ConstantFP * getFPImm() const
Definition: MachineOperand.h:547
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ARMBaseInstrInfo.h
llvm::AsmPrinter::OutContext
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:91
llvm::MCOperand::setImm
void setImm(int64_t Val)
Definition: MCInst.h:85
llvm::MachineOperand::MO_FPImmediate
@ MO_FPImmediate
Floating-point immediate operand.
Definition: MachineOperand.h:55
llvm::ARMAsmPrinter::GetCPISymbol
MCSymbol * GetCPISymbol(unsigned CPID) const override
Return the symbol for the specified constant pool entry.
Definition: ARMAsmPrinter.cpp:252
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
ARM.h
llvm::MachineOperand::MO_JumpTableIndex
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
Definition: MachineOperand.h:60
llvm::MCBinaryExpr::createAdd
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:524
llvm::AsmPrinter::GetExternalSymbolSymbol
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
Definition: AsmPrinter.cpp:3189
ARMAddressingModes.h
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:552
llvm::APFloatBase::IEEEdouble
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:173
llvm::AsmPrinter::GetJTISymbol
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
Definition: AsmPrinter.cpp:3170
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
llvm::AsmPrinter::SledKind::FUNCTION_EXIT
@ FUNCTION_EXIT
llvm::MachineOperand::MO_MachineBasicBlock
@ MO_MachineBasicBlock
MachineBasicBlock reference.
Definition: MachineOperand.h:56
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:303
llvm::MCOperand::createDFPImm
static MCOperand createDFPImm(uint64_t Val)
Definition: MCInst.h:155
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:365
llvm::AsmPrinter::SledKind::TAIL_CALL
@ TAIL_CALL
llvm::APFloatBase::rmTowardZero
static constexpr roundingMode rmTowardZero
Definition: APFloat.h:194
llvm::ARMII::MO_LO16
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
Definition: ARMBaseInfo.h:246
llvm::ARMAsmPrinter::LowerPATCHABLE_TAIL_CALL
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI)
Definition: ARMMCInstLower.cpp:226
llvm::AsmPrinter::emitNops
void emitNops(unsigned N)
Emit N NOP instructions.
Definition: AsmPrinter.cpp:3119
llvm::AsmPrinter::getSubtargetInfo
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:237
llvm::MachineOperand::MO_ExternalSymbol
@ MO_ExternalSymbol
Name of external global symbol.
Definition: MachineOperand.h:61
llvm::MachineOperand::getIndex
int getIndex() const
Definition: MachineOperand.h:557
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:385
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:79
llvm::APFloat::convert
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:4836
llvm::MachineOperand::getSymbolName
const char * getSymbolName() const
Definition: MachineOperand.h:608
MCStreamer.h
llvm::AsmPrinter::SledKind::FUNCTION_ENTER
@ FUNCTION_ENTER
MachineOperand.h
llvm::ARMMCExpr::createLower16
static const ARMMCExpr * createLower16(const MCExpr *Expr, MCContext &Ctx)
Definition: ARMMCExpr.h:42
llvm::ARMII::MO_SBREL
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
Definition: ARMBaseInfo.h:266
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::MachineOperand::MO_RegisterMask
@ MO_RegisterMask
Mask of preserved registers.
Definition: MachineOperand.h:64
MCExpr.h
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::ARMII::MO_OPTION_MASK
@ MO_OPTION_MASK
MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects just that part of the flag set.
Definition: ARMBaseInfo.h:254
llvm::ARMSubtarget::genExecuteOnly
bool genExecuteOnly() const
Definition: ARMSubtarget.h:733
llvm::MachineOperand::MO_ConstantPoolIndex
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
Definition: MachineOperand.h:58
llvm::ARMAsmPrinter::LowerPATCHABLE_FUNCTION_EXIT
void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI)
Definition: ARMMCInstLower.cpp:221