Both conceptually belong to the same subtarget, so it should not be necessary to pass in the context TargetRegisterInfo to any TargetInstrInfo member. Add this reference so those superfluous arguments can be removed. Most targets placed their TargetRegisterInfo as a member in TargetInstrInfo. A few had this owned by the TargetSubtargetInfo, so unify all targets to look the same.
145 lines
4.5 KiB
C++
145 lines
4.5 KiB
C++
//===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the ARM implementation of the TargetInstrInfo class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ARMInstrInfo.h"
|
|
#include "ARM.h"
|
|
#include "ARMConstantPoolValue.h"
|
|
#include "ARMMachineFunctionInfo.h"
|
|
#include "ARMTargetMachine.h"
|
|
#include "llvm/CodeGen/LiveVariables.h"
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/GlobalVariable.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
using namespace llvm;
|
|
|
|
ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
|
|
: ARMBaseInstrInfo(STI, RI) {}
|
|
|
|
/// Return the noop instruction to use for a noop.
|
|
MCInst ARMInstrInfo::getNop() const {
|
|
MCInst NopInst;
|
|
if (hasNOP()) {
|
|
NopInst.setOpcode(ARM::HINT);
|
|
NopInst.addOperand(MCOperand::createImm(0));
|
|
NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
|
|
NopInst.addOperand(MCOperand::createReg(0));
|
|
} else {
|
|
NopInst.setOpcode(ARM::MOVr);
|
|
NopInst.addOperand(MCOperand::createReg(ARM::R0));
|
|
NopInst.addOperand(MCOperand::createReg(ARM::R0));
|
|
NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
|
|
NopInst.addOperand(MCOperand::createReg(0));
|
|
NopInst.addOperand(MCOperand::createReg(0));
|
|
}
|
|
return NopInst;
|
|
}
|
|
|
|
unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
|
|
switch (Opc) {
|
|
default:
|
|
break;
|
|
case ARM::LDR_PRE_IMM:
|
|
case ARM::LDR_PRE_REG:
|
|
case ARM::LDR_POST_IMM:
|
|
case ARM::LDR_POST_REG:
|
|
return ARM::LDRi12;
|
|
case ARM::LDRH_PRE:
|
|
case ARM::LDRH_POST:
|
|
return ARM::LDRH;
|
|
case ARM::LDRB_PRE_IMM:
|
|
case ARM::LDRB_PRE_REG:
|
|
case ARM::LDRB_POST_IMM:
|
|
case ARM::LDRB_POST_REG:
|
|
return ARM::LDRBi12;
|
|
case ARM::LDRSH_PRE:
|
|
case ARM::LDRSH_POST:
|
|
return ARM::LDRSH;
|
|
case ARM::LDRSB_PRE:
|
|
case ARM::LDRSB_POST:
|
|
return ARM::LDRSB;
|
|
case ARM::STR_PRE_IMM:
|
|
case ARM::STR_PRE_REG:
|
|
case ARM::STR_POST_IMM:
|
|
case ARM::STR_POST_REG:
|
|
return ARM::STRi12;
|
|
case ARM::STRH_PRE:
|
|
case ARM::STRH_POST:
|
|
return ARM::STRH;
|
|
case ARM::STRB_PRE_IMM:
|
|
case ARM::STRB_PRE_REG:
|
|
case ARM::STRB_POST_IMM:
|
|
case ARM::STRB_POST_REG:
|
|
return ARM::STRBi12;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
|
|
MachineFunction &MF = *MI->getParent()->getParent();
|
|
const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
|
|
const TargetMachine &TM = MF.getTarget();
|
|
Module &M = *MF.getFunction().getParent();
|
|
|
|
if (M.getStackProtectorGuard() == "tls") {
|
|
expandLoadStackGuardBase(MI, ARM::MRC, ARM::LDRi12);
|
|
return;
|
|
}
|
|
|
|
const GlobalValue *GV =
|
|
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
|
|
|
|
bool ForceELFGOTPIC = Subtarget.isTargetELF() && !GV->isDSOLocal();
|
|
if (!Subtarget.useMovt() || ForceELFGOTPIC) {
|
|
// For ELF non-PIC, use GOT PIC code sequence as well because R_ARM_GOT_ABS
|
|
// does not have assembler support.
|
|
if (TM.isPositionIndependent() || ForceELFGOTPIC)
|
|
expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
|
|
else
|
|
expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12);
|
|
return;
|
|
}
|
|
|
|
if (!TM.isPositionIndependent()) {
|
|
expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12);
|
|
return;
|
|
}
|
|
|
|
if (!Subtarget.isGVIndirectSymbol(GV)) {
|
|
expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
|
|
return;
|
|
}
|
|
|
|
MachineBasicBlock &MBB = *MI->getParent();
|
|
DebugLoc DL = MI->getDebugLoc();
|
|
Register Reg = MI->getOperand(0).getReg();
|
|
MachineInstrBuilder MIB;
|
|
|
|
MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg)
|
|
.addGlobalAddress(GV, 0, ARMII::MO_NONLAZY);
|
|
auto Flags = MachineMemOperand::MOLoad |
|
|
MachineMemOperand::MODereferenceable |
|
|
MachineMemOperand::MOInvariant;
|
|
MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand(
|
|
MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, Align(4));
|
|
MIB.addMemOperand(MMO);
|
|
BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg)
|
|
.addReg(Reg, RegState::Kill)
|
|
.addImm(0)
|
|
.cloneMemRefs(*MI)
|
|
.add(predOps(ARMCC::AL));
|
|
}
|