brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · f370547 Raw
145 lines · cpp
1//===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the ARM implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "ARMInstrInfo.h"14#include "ARM.h"15#include "ARMConstantPoolValue.h"16#include "ARMMachineFunctionInfo.h"17#include "ARMTargetMachine.h"18#include "llvm/CodeGen/LiveVariables.h"19#include "llvm/CodeGen/MachineFrameInfo.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineJumpTableInfo.h"22#include "llvm/IR/Function.h"23#include "llvm/IR/GlobalVariable.h"24#include "llvm/IR/Module.h"25#include "llvm/MC/MCInst.h"26using namespace llvm;27 28ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)29    : ARMBaseInstrInfo(STI, RI) {}30 31/// Return the noop instruction to use for a noop.32MCInst ARMInstrInfo::getNop() const {33  MCInst NopInst;34  if (hasNOP()) {35    NopInst.setOpcode(ARM::HINT);36    NopInst.addOperand(MCOperand::createImm(0));37    NopInst.addOperand(MCOperand::createImm(ARMCC::AL));38    NopInst.addOperand(MCOperand::createReg(0));39  } else {40    NopInst.setOpcode(ARM::MOVr);41    NopInst.addOperand(MCOperand::createReg(ARM::R0));42    NopInst.addOperand(MCOperand::createReg(ARM::R0));43    NopInst.addOperand(MCOperand::createImm(ARMCC::AL));44    NopInst.addOperand(MCOperand::createReg(0));45    NopInst.addOperand(MCOperand::createReg(0));46  }47  return NopInst;48}49 50unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {51  switch (Opc) {52  default:53    break;54  case ARM::LDR_PRE_IMM:55  case ARM::LDR_PRE_REG:56  case ARM::LDR_POST_IMM:57  case ARM::LDR_POST_REG:58    return ARM::LDRi12;59  case ARM::LDRH_PRE:60  case ARM::LDRH_POST:61    return ARM::LDRH;62  case ARM::LDRB_PRE_IMM:63  case ARM::LDRB_PRE_REG:64  case ARM::LDRB_POST_IMM:65  case ARM::LDRB_POST_REG:66    return ARM::LDRBi12;67  case ARM::LDRSH_PRE:68  case ARM::LDRSH_POST:69    return ARM::LDRSH;70  case ARM::LDRSB_PRE:71  case ARM::LDRSB_POST:72    return ARM::LDRSB;73  case ARM::STR_PRE_IMM:74  case ARM::STR_PRE_REG:75  case ARM::STR_POST_IMM:76  case ARM::STR_POST_REG:77    return ARM::STRi12;78  case ARM::STRH_PRE:79  case ARM::STRH_POST:80    return ARM::STRH;81  case ARM::STRB_PRE_IMM:82  case ARM::STRB_PRE_REG:83  case ARM::STRB_POST_IMM:84  case ARM::STRB_POST_REG:85    return ARM::STRBi12;86  }87 88  return 0;89}90 91void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {92  MachineFunction &MF = *MI->getParent()->getParent();93  const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();94  const TargetMachine &TM = MF.getTarget();95  Module &M = *MF.getFunction().getParent();96 97  if (M.getStackProtectorGuard() == "tls") {98    expandLoadStackGuardBase(MI, ARM::MRC, ARM::LDRi12);99    return;100  }101 102  const GlobalValue *GV =103      cast<GlobalValue>((*MI->memoperands_begin())->getValue());104 105  bool ForceELFGOTPIC = Subtarget.isTargetELF() && !GV->isDSOLocal();106  if (!Subtarget.useMovt() || ForceELFGOTPIC) {107    // For ELF non-PIC, use GOT PIC code sequence as well because R_ARM_GOT_ABS108    // does not have assembler support.109    if (TM.isPositionIndependent() || ForceELFGOTPIC)110      expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);111    else112      expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);113    return;114  }115 116  if (!TM.isPositionIndependent()) {117    expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);118    return;119  }120 121  if (!Subtarget.isGVIndirectSymbol(GV)) {122    expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);123    return;124  }125 126  MachineBasicBlock &MBB = *MI->getParent();127  DebugLoc DL = MI->getDebugLoc();128  Register Reg = MI->getOperand(0).getReg();129  MachineInstrBuilder MIB;130 131  MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)132            .addGlobalAddress(GV, 0, ARMII::MO_NONLAZY);133  auto Flags = MachineMemOperand::MOLoad |134               MachineMemOperand::MODereferenceable |135               MachineMemOperand::MOInvariant;136  MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand(137      MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, Align(4));138  MIB.addMemOperand(MMO);139  BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)140      .addReg(Reg, RegState::Kill)141      .addImm(0)142      .cloneMemRefs(*MI)143      .add(predOps(ARMCC::AL));144}145