[llvm] r209577 - AArch64/ARM64: move ARM64 into AArch64's place
Tim Northover
tnorthover at apple.com
Sat May 24 05:50:31 PDT 2014
Copied: llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64LoadStoreOptimizer.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64LoadStoreOptimizer.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64LoadStoreOptimizer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64LoadStoreOptimizer.cpp - ARM64 load/store opt. pass --*- C++ -*-=//
+//=- AArch64LoadStoreOptimizer.cpp - AArch64 load/store opt. pass -*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64InstrInfo.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
+#include "AArch64InstrInfo.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -29,9 +29,9 @@
#include "llvm/ADT/Statistic.h"
using namespace llvm;
-#define DEBUG_TYPE "arm64-ldst-opt"
+#define DEBUG_TYPE "aarch64-ldst-opt"
-/// ARM64AllocLoadStoreOpt - Post-register allocation pass to combine
+/// AArch64AllocLoadStoreOpt - Post-register allocation pass to combine
/// load / store instructions to form ldp / stp instructions.
STATISTIC(NumPairCreated, "Number of load/store pair instructions generated");
@@ -40,21 +40,21 @@ STATISTIC(NumPreFolded, "Number of pre-i
STATISTIC(NumUnscaledPairCreated,
"Number of load/store from unscaled generated");
-static cl::opt<unsigned> ScanLimit("arm64-load-store-scan-limit", cl::init(20),
+static cl::opt<unsigned> ScanLimit("aarch64-load-store-scan-limit", cl::init(20),
cl::Hidden);
// Place holder while testing unscaled load/store combining
static cl::opt<bool>
-EnableARM64UnscaledMemOp("arm64-unscaled-mem-op", cl::Hidden,
- cl::desc("Allow ARM64 unscaled load/store combining"),
+EnableAArch64UnscaledMemOp("aarch64-unscaled-mem-op", cl::Hidden,
+ cl::desc("Allow AArch64 unscaled load/store combining"),
cl::init(true));
namespace {
-struct ARM64LoadStoreOpt : public MachineFunctionPass {
+struct AArch64LoadStoreOpt : public MachineFunctionPass {
static char ID;
- ARM64LoadStoreOpt() : MachineFunctionPass(ID) {}
+ AArch64LoadStoreOpt() : MachineFunctionPass(ID) {}
- const ARM64InstrInfo *TII;
+ const AArch64InstrInfo *TII;
const TargetRegisterInfo *TRI;
// Scan the instructions looking for a load/store that can be combined
@@ -102,76 +102,76 @@ struct ARM64LoadStoreOpt : public Machin
bool runOnMachineFunction(MachineFunction &Fn) override;
const char *getPassName() const override {
- return "ARM64 load / store optimization pass";
+ return "AArch64 load / store optimization pass";
}
private:
int getMemSize(MachineInstr *MemMI);
};
-char ARM64LoadStoreOpt::ID = 0;
+char AArch64LoadStoreOpt::ID = 0;
}
static bool isUnscaledLdst(unsigned Opc) {
switch (Opc) {
default:
return false;
- case ARM64::STURSi:
+ case AArch64::STURSi:
return true;
- case ARM64::STURDi:
+ case AArch64::STURDi:
return true;
- case ARM64::STURQi:
+ case AArch64::STURQi:
return true;
- case ARM64::STURWi:
+ case AArch64::STURWi:
return true;
- case ARM64::STURXi:
+ case AArch64::STURXi:
return true;
- case ARM64::LDURSi:
+ case AArch64::LDURSi:
return true;
- case ARM64::LDURDi:
+ case AArch64::LDURDi:
return true;
- case ARM64::LDURQi:
+ case AArch64::LDURQi:
return true;
- case ARM64::LDURWi:
+ case AArch64::LDURWi:
return true;
- case ARM64::LDURXi:
+ case AArch64::LDURXi:
return true;
}
}
// Size in bytes of the data moved by an unscaled load or store
-int ARM64LoadStoreOpt::getMemSize(MachineInstr *MemMI) {
+int AArch64LoadStoreOpt::getMemSize(MachineInstr *MemMI) {
switch (MemMI->getOpcode()) {
default:
llvm_unreachable("Opcode has has unknown size!");
- case ARM64::STRSui:
- case ARM64::STURSi:
+ case AArch64::STRSui:
+ case AArch64::STURSi:
return 4;
- case ARM64::STRDui:
- case ARM64::STURDi:
+ case AArch64::STRDui:
+ case AArch64::STURDi:
return 8;
- case ARM64::STRQui:
- case ARM64::STURQi:
+ case AArch64::STRQui:
+ case AArch64::STURQi:
return 16;
- case ARM64::STRWui:
- case ARM64::STURWi:
+ case AArch64::STRWui:
+ case AArch64::STURWi:
return 4;
- case ARM64::STRXui:
- case ARM64::STURXi:
+ case AArch64::STRXui:
+ case AArch64::STURXi:
return 8;
- case ARM64::LDRSui:
- case ARM64::LDURSi:
+ case AArch64::LDRSui:
+ case AArch64::LDURSi:
return 4;
- case ARM64::LDRDui:
- case ARM64::LDURDi:
+ case AArch64::LDRDui:
+ case AArch64::LDURDi:
return 8;
- case ARM64::LDRQui:
- case ARM64::LDURQi:
+ case AArch64::LDRQui:
+ case AArch64::LDURQi:
return 16;
- case ARM64::LDRWui:
- case ARM64::LDURWi:
+ case AArch64::LDRWui:
+ case AArch64::LDURWi:
return 4;
- case ARM64::LDRXui:
- case ARM64::LDURXi:
+ case AArch64::LDRXui:
+ case AArch64::LDURXi:
return 8;
}
}
@@ -180,36 +180,36 @@ static unsigned getMatchingPairOpcode(un
switch (Opc) {
default:
llvm_unreachable("Opcode has no pairwise equivalent!");
- case ARM64::STRSui:
- case ARM64::STURSi:
- return ARM64::STPSi;
- case ARM64::STRDui:
- case ARM64::STURDi:
- return ARM64::STPDi;
- case ARM64::STRQui:
- case ARM64::STURQi:
- return ARM64::STPQi;
- case ARM64::STRWui:
- case ARM64::STURWi:
- return ARM64::STPWi;
- case ARM64::STRXui:
- case ARM64::STURXi:
- return ARM64::STPXi;
- case ARM64::LDRSui:
- case ARM64::LDURSi:
- return ARM64::LDPSi;
- case ARM64::LDRDui:
- case ARM64::LDURDi:
- return ARM64::LDPDi;
- case ARM64::LDRQui:
- case ARM64::LDURQi:
- return ARM64::LDPQi;
- case ARM64::LDRWui:
- case ARM64::LDURWi:
- return ARM64::LDPWi;
- case ARM64::LDRXui:
- case ARM64::LDURXi:
- return ARM64::LDPXi;
+ case AArch64::STRSui:
+ case AArch64::STURSi:
+ return AArch64::STPSi;
+ case AArch64::STRDui:
+ case AArch64::STURDi:
+ return AArch64::STPDi;
+ case AArch64::STRQui:
+ case AArch64::STURQi:
+ return AArch64::STPQi;
+ case AArch64::STRWui:
+ case AArch64::STURWi:
+ return AArch64::STPWi;
+ case AArch64::STRXui:
+ case AArch64::STURXi:
+ return AArch64::STPXi;
+ case AArch64::LDRSui:
+ case AArch64::LDURSi:
+ return AArch64::LDPSi;
+ case AArch64::LDRDui:
+ case AArch64::LDURDi:
+ return AArch64::LDPDi;
+ case AArch64::LDRQui:
+ case AArch64::LDURQi:
+ return AArch64::LDPQi;
+ case AArch64::LDRWui:
+ case AArch64::LDURWi:
+ return AArch64::LDPWi;
+ case AArch64::LDRXui:
+ case AArch64::LDURXi:
+ return AArch64::LDPXi;
}
}
@@ -217,16 +217,16 @@ static unsigned getPreIndexedOpcode(unsi
switch (Opc) {
default:
llvm_unreachable("Opcode has no pre-indexed equivalent!");
- case ARM64::STRSui: return ARM64::STRSpre;
- case ARM64::STRDui: return ARM64::STRDpre;
- case ARM64::STRQui: return ARM64::STRQpre;
- case ARM64::STRWui: return ARM64::STRWpre;
- case ARM64::STRXui: return ARM64::STRXpre;
- case ARM64::LDRSui: return ARM64::LDRSpre;
- case ARM64::LDRDui: return ARM64::LDRDpre;
- case ARM64::LDRQui: return ARM64::LDRQpre;
- case ARM64::LDRWui: return ARM64::LDRWpre;
- case ARM64::LDRXui: return ARM64::LDRXpre;
+ case AArch64::STRSui: return AArch64::STRSpre;
+ case AArch64::STRDui: return AArch64::STRDpre;
+ case AArch64::STRQui: return AArch64::STRQpre;
+ case AArch64::STRWui: return AArch64::STRWpre;
+ case AArch64::STRXui: return AArch64::STRXpre;
+ case AArch64::LDRSui: return AArch64::LDRSpre;
+ case AArch64::LDRDui: return AArch64::LDRDpre;
+ case AArch64::LDRQui: return AArch64::LDRQpre;
+ case AArch64::LDRWui: return AArch64::LDRWpre;
+ case AArch64::LDRXui: return AArch64::LDRXpre;
}
}
@@ -234,33 +234,33 @@ static unsigned getPostIndexedOpcode(uns
switch (Opc) {
default:
llvm_unreachable("Opcode has no post-indexed wise equivalent!");
- case ARM64::STRSui:
- return ARM64::STRSpost;
- case ARM64::STRDui:
- return ARM64::STRDpost;
- case ARM64::STRQui:
- return ARM64::STRQpost;
- case ARM64::STRWui:
- return ARM64::STRWpost;
- case ARM64::STRXui:
- return ARM64::STRXpost;
- case ARM64::LDRSui:
- return ARM64::LDRSpost;
- case ARM64::LDRDui:
- return ARM64::LDRDpost;
- case ARM64::LDRQui:
- return ARM64::LDRQpost;
- case ARM64::LDRWui:
- return ARM64::LDRWpost;
- case ARM64::LDRXui:
- return ARM64::LDRXpost;
+ case AArch64::STRSui:
+ return AArch64::STRSpost;
+ case AArch64::STRDui:
+ return AArch64::STRDpost;
+ case AArch64::STRQui:
+ return AArch64::STRQpost;
+ case AArch64::STRWui:
+ return AArch64::STRWpost;
+ case AArch64::STRXui:
+ return AArch64::STRXpost;
+ case AArch64::LDRSui:
+ return AArch64::LDRSpost;
+ case AArch64::LDRDui:
+ return AArch64::LDRDpost;
+ case AArch64::LDRQui:
+ return AArch64::LDRQpost;
+ case AArch64::LDRWui:
+ return AArch64::LDRWpost;
+ case AArch64::LDRXui:
+ return AArch64::LDRXpost;
}
}
MachineBasicBlock::iterator
-ARM64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator Paired,
- bool mergeForward) {
+AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator Paired,
+ bool mergeForward) {
MachineBasicBlock::iterator NextI = I;
++NextI;
// If NextI is the second of the two instructions to be merged, we need
@@ -271,7 +271,8 @@ ARM64LoadStoreOpt::mergePairedInsns(Mach
++NextI;
bool IsUnscaled = isUnscaledLdst(I->getOpcode());
- int OffsetStride = IsUnscaled && EnableARM64UnscaledMemOp ? getMemSize(I) : 1;
+ int OffsetStride =
+ IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(I) : 1;
unsigned NewOpc = getMatchingPairOpcode(I->getOpcode());
// Insert our new paired instruction after whichever of the paired
@@ -294,7 +295,7 @@ ARM64LoadStoreOpt::mergePairedInsns(Mach
}
// Handle Unscaled
int OffsetImm = RtMI->getOperand(2).getImm();
- if (IsUnscaled && EnableARM64UnscaledMemOp)
+ if (IsUnscaled && EnableAArch64UnscaledMemOp)
OffsetImm /= OffsetStride;
// Construct the new instruction.
@@ -372,8 +373,8 @@ static int alignTo(int Num, int PowOf2)
/// findMatchingInsn - Scan the instructions looking for a load/store that can
/// be combined with the current instruction into a load/store pair.
MachineBasicBlock::iterator
-ARM64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
- bool &mergeForward, unsigned Limit) {
+AArch64LoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
+ bool &mergeForward, unsigned Limit) {
MachineBasicBlock::iterator E = I->getParent()->end();
MachineBasicBlock::iterator MBBI = I;
MachineInstr *FirstMI = I;
@@ -394,7 +395,7 @@ ARM64LoadStoreOpt::findMatchingInsn(Mach
if (FirstMI->modifiesRegister(BaseReg, TRI))
return E;
int OffsetStride =
- IsUnscaled && EnableARM64UnscaledMemOp ? getMemSize(FirstMI) : 1;
+ IsUnscaled && EnableAArch64UnscaledMemOp ? getMemSize(FirstMI) : 1;
if (!inBoundsForPair(IsUnscaled, Offset, OffsetStride))
return E;
@@ -444,7 +445,7 @@ ARM64LoadStoreOpt::findMatchingInsn(Mach
// If the alignment requirements of the paired (scaled) instruction
// can't express the offset of the unscaled input, bail and keep
// looking.
- if (IsUnscaled && EnableARM64UnscaledMemOp &&
+ if (IsUnscaled && EnableAArch64UnscaledMemOp &&
(alignTo(MinOffset, OffsetStride) != MinOffset)) {
trackRegDefsUses(MI, ModifiedRegs, UsedRegs, TRI);
continue;
@@ -507,10 +508,10 @@ ARM64LoadStoreOpt::findMatchingInsn(Mach
}
MachineBasicBlock::iterator
-ARM64LoadStoreOpt::mergePreIdxUpdateInsn(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator Update) {
- assert((Update->getOpcode() == ARM64::ADDXri ||
- Update->getOpcode() == ARM64::SUBXri) &&
+AArch64LoadStoreOpt::mergePreIdxUpdateInsn(MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator Update) {
+ assert((Update->getOpcode() == AArch64::ADDXri ||
+ Update->getOpcode() == AArch64::SUBXri) &&
"Unexpected base register update instruction to merge!");
MachineBasicBlock::iterator NextI = I;
// Return the instruction following the merged instruction, which is
@@ -520,9 +521,9 @@ ARM64LoadStoreOpt::mergePreIdxUpdateInsn
++NextI;
int Value = Update->getOperand(2).getImm();
- assert(ARM64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
+ assert(AArch64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
"Can't merge 1 << 12 offset into pre-indexed load / store");
- if (Update->getOpcode() == ARM64::SUBXri)
+ if (Update->getOpcode() == AArch64::SUBXri)
Value = -Value;
unsigned NewOpc = getPreIndexedOpcode(I->getOpcode());
@@ -550,11 +551,10 @@ ARM64LoadStoreOpt::mergePreIdxUpdateInsn
return NextI;
}
-MachineBasicBlock::iterator
-ARM64LoadStoreOpt::mergePostIdxUpdateInsn(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator Update) {
- assert((Update->getOpcode() == ARM64::ADDXri ||
- Update->getOpcode() == ARM64::SUBXri) &&
+MachineBasicBlock::iterator AArch64LoadStoreOpt::mergePostIdxUpdateInsn(
+ MachineBasicBlock::iterator I, MachineBasicBlock::iterator Update) {
+ assert((Update->getOpcode() == AArch64::ADDXri ||
+ Update->getOpcode() == AArch64::SUBXri) &&
"Unexpected base register update instruction to merge!");
MachineBasicBlock::iterator NextI = I;
// Return the instruction following the merged instruction, which is
@@ -564,9 +564,9 @@ ARM64LoadStoreOpt::mergePostIdxUpdateIns
++NextI;
int Value = Update->getOperand(2).getImm();
- assert(ARM64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
+ assert(AArch64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 &&
"Can't merge 1 << 12 offset into post-indexed load / store");
- if (Update->getOpcode() == ARM64::SUBXri)
+ if (Update->getOpcode() == AArch64::SUBXri)
Value = -Value;
unsigned NewOpc = getPostIndexedOpcode(I->getOpcode());
@@ -599,17 +599,17 @@ static bool isMatchingUpdateInsn(Machine
switch (MI->getOpcode()) {
default:
break;
- case ARM64::SUBXri:
+ case AArch64::SUBXri:
// Negate the offset for a SUB instruction.
Offset *= -1;
// FALLTHROUGH
- case ARM64::ADDXri:
+ case AArch64::ADDXri:
// Make sure it's a vanilla immediate operand, not a relocation or
// anything else we can't handle.
if (!MI->getOperand(2).isImm())
break;
// Watch out for 1 << 12 shifted value.
- if (ARM64_AM::getShiftValue(MI->getOperand(3).getImm()))
+ if (AArch64_AM::getShiftValue(MI->getOperand(3).getImm()))
break;
// If the instruction has the base register as source and dest and the
// immediate will fit in a signed 9-bit integer, then we have a match.
@@ -627,9 +627,8 @@ static bool isMatchingUpdateInsn(Machine
return false;
}
-MachineBasicBlock::iterator
-ARM64LoadStoreOpt::findMatchingUpdateInsnForward(MachineBasicBlock::iterator I,
- unsigned Limit, int Value) {
+MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnForward(
+ MachineBasicBlock::iterator I, unsigned Limit, int Value) {
MachineBasicBlock::iterator E = I->getParent()->end();
MachineInstr *MemMI = I;
MachineBasicBlock::iterator MBBI = I;
@@ -682,9 +681,8 @@ ARM64LoadStoreOpt::findMatchingUpdateIns
return E;
}
-MachineBasicBlock::iterator
-ARM64LoadStoreOpt::findMatchingUpdateInsnBackward(MachineBasicBlock::iterator I,
- unsigned Limit) {
+MachineBasicBlock::iterator AArch64LoadStoreOpt::findMatchingUpdateInsnBackward(
+ MachineBasicBlock::iterator I, unsigned Limit) {
MachineBasicBlock::iterator B = I->getParent()->begin();
MachineBasicBlock::iterator E = I->getParent()->end();
MachineInstr *MemMI = I;
@@ -736,7 +734,7 @@ ARM64LoadStoreOpt::findMatchingUpdateIns
return E;
}
-bool ARM64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) {
+bool AArch64LoadStoreOpt::optimizeBlock(MachineBasicBlock &MBB) {
bool Modified = false;
// Two tranformations to do here:
// 1) Find loads and stores that can be merged into a single load or store
@@ -762,27 +760,27 @@ bool ARM64LoadStoreOpt::optimizeBlock(Ma
// Just move on to the next instruction.
++MBBI;
break;
- case ARM64::STRSui:
- case ARM64::STRDui:
- case ARM64::STRQui:
- case ARM64::STRXui:
- case ARM64::STRWui:
- case ARM64::LDRSui:
- case ARM64::LDRDui:
- case ARM64::LDRQui:
- case ARM64::LDRXui:
- case ARM64::LDRWui:
+ case AArch64::STRSui:
+ case AArch64::STRDui:
+ case AArch64::STRQui:
+ case AArch64::STRXui:
+ case AArch64::STRWui:
+ case AArch64::LDRSui:
+ case AArch64::LDRDui:
+ case AArch64::LDRQui:
+ case AArch64::LDRXui:
+ case AArch64::LDRWui:
// do the unscaled versions as well
- case ARM64::STURSi:
- case ARM64::STURDi:
- case ARM64::STURQi:
- case ARM64::STURWi:
- case ARM64::STURXi:
- case ARM64::LDURSi:
- case ARM64::LDURDi:
- case ARM64::LDURQi:
- case ARM64::LDURWi:
- case ARM64::LDURXi: {
+ case AArch64::STURSi:
+ case AArch64::STURDi:
+ case AArch64::STURQi:
+ case AArch64::STURWi:
+ case AArch64::STURXi:
+ case AArch64::LDURSi:
+ case AArch64::LDURDi:
+ case AArch64::LDURQi:
+ case AArch64::LDURWi:
+ case AArch64::LDURXi: {
// If this is a volatile load/store, don't mess with it.
if (MI->hasOrderedMemoryRef()) {
++MBBI;
@@ -794,7 +792,7 @@ bool ARM64LoadStoreOpt::optimizeBlock(Ma
break;
}
// Check if this load/store has a hint to avoid pair formation.
- // MachineMemOperands hints are set by the ARM64StorePairSuppress pass.
+ // MachineMemOperands hints are set by the AArch64StorePairSuppress pass.
if (TII->isLdStPairSuppressed(MI)) {
++MBBI;
break;
@@ -833,27 +831,27 @@ bool ARM64LoadStoreOpt::optimizeBlock(Ma
// Just move on to the next instruction.
++MBBI;
break;
- case ARM64::STRSui:
- case ARM64::STRDui:
- case ARM64::STRQui:
- case ARM64::STRXui:
- case ARM64::STRWui:
- case ARM64::LDRSui:
- case ARM64::LDRDui:
- case ARM64::LDRQui:
- case ARM64::LDRXui:
- case ARM64::LDRWui:
+ case AArch64::STRSui:
+ case AArch64::STRDui:
+ case AArch64::STRQui:
+ case AArch64::STRXui:
+ case AArch64::STRWui:
+ case AArch64::LDRSui:
+ case AArch64::LDRDui:
+ case AArch64::LDRQui:
+ case AArch64::LDRXui:
+ case AArch64::LDRWui:
// do the unscaled versions as well
- case ARM64::STURSi:
- case ARM64::STURDi:
- case ARM64::STURQi:
- case ARM64::STURWi:
- case ARM64::STURXi:
- case ARM64::LDURSi:
- case ARM64::LDURDi:
- case ARM64::LDURQi:
- case ARM64::LDURWi:
- case ARM64::LDURXi: {
+ case AArch64::STURSi:
+ case AArch64::STURDi:
+ case AArch64::STURQi:
+ case AArch64::STURWi:
+ case AArch64::STURXi:
+ case AArch64::LDURSi:
+ case AArch64::LDURDi:
+ case AArch64::LDURQi:
+ case AArch64::LDURWi:
+ case AArch64::LDURXi: {
// Make sure this is a reg+imm (as opposed to an address reloc).
if (!MI->getOperand(2).isImm()) {
++MBBI;
@@ -922,9 +920,9 @@ bool ARM64LoadStoreOpt::optimizeBlock(Ma
return Modified;
}
-bool ARM64LoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
+bool AArch64LoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
const TargetMachine &TM = Fn.getTarget();
- TII = static_cast<const ARM64InstrInfo *>(TM.getInstrInfo());
+ TII = static_cast<const AArch64InstrInfo *>(TM.getInstrInfo());
TRI = TM.getRegisterInfo();
bool Modified = false;
@@ -939,6 +937,6 @@ bool ARM64LoadStoreOpt::runOnMachineFunc
/// createARMLoadStoreOptimizationPass - returns an instance of the load / store
/// optimization pass.
-FunctionPass *llvm::createARM64LoadStoreOptimizationPass() {
- return new ARM64LoadStoreOpt();
+FunctionPass *llvm::createAArch64LoadStoreOptimizationPass() {
+ return new AArch64LoadStoreOpt();
}
Copied: llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64MCInstLower.cpp - Convert ARM64 MachineInstr to an MCInst---===//
+//==-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst --==//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains code to lower ARM64 MachineInstrs to their corresponding
+// This file contains code to lower AArch64 MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//
-#include "ARM64MCInstLower.h"
-#include "MCTargetDesc/ARM64MCExpr.h"
-#include "Utils/ARM64BaseInfo.h"
+#include "AArch64MCInstLower.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -25,46 +25,46 @@
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
-ARM64MCInstLower::ARM64MCInstLower(MCContext &ctx, Mangler &mang,
- AsmPrinter &printer)
+AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, Mangler &mang,
+ AsmPrinter &printer)
: Ctx(ctx), Printer(printer), TargetTriple(printer.getTargetTriple()) {}
MCSymbol *
-ARM64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
+AArch64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
return Printer.getSymbol(MO.getGlobal());
}
MCSymbol *
-ARM64MCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
+AArch64MCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
-MCOperand ARM64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO,
- MCSymbol *Sym) const {
+MCOperand AArch64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO,
+ MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
- if ((MO.getTargetFlags() & ARM64II::MO_GOT) != 0) {
- if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_PAGE)
+ if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
+ if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
RefKind = MCSymbolRefExpr::VK_GOTPAGE;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) ==
- ARM64II::MO_PAGEOFF)
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
+ AArch64II::MO_PAGEOFF)
RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF;
else
assert(0 && "Unexpected target flags with MO_GOT on GV operand");
- } else if ((MO.getTargetFlags() & ARM64II::MO_TLS) != 0) {
- if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_PAGE)
+ } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
+ if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
RefKind = MCSymbolRefExpr::VK_TLVPPAGE;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) ==
- ARM64II::MO_PAGEOFF)
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
+ AArch64II::MO_PAGEOFF)
RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF;
else
llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
} else {
- if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_PAGE)
+ if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
RefKind = MCSymbolRefExpr::VK_PAGE;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) ==
- ARM64II::MO_PAGEOFF)
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
+ AArch64II::MO_PAGEOFF)
RefKind = MCSymbolRefExpr::VK_PAGEOFF;
}
const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
@@ -74,13 +74,13 @@ MCOperand ARM64MCInstLower::lowerSymbolO
return MCOperand::CreateExpr(Expr);
}
-MCOperand ARM64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
- MCSymbol *Sym) const {
+MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
+ MCSymbol *Sym) const {
uint32_t RefFlags = 0;
- if (MO.getTargetFlags() & ARM64II::MO_GOT)
- RefFlags |= ARM64MCExpr::VK_GOT;
- else if (MO.getTargetFlags() & ARM64II::MO_TLS) {
+ if (MO.getTargetFlags() & AArch64II::MO_GOT)
+ RefFlags |= AArch64MCExpr::VK_GOT;
+ else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
TLSModel::Model Model;
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
@@ -93,39 +93,40 @@ MCOperand ARM64MCInstLower::lowerSymbolO
}
switch (Model) {
case TLSModel::InitialExec:
- RefFlags |= ARM64MCExpr::VK_GOTTPREL;
+ RefFlags |= AArch64MCExpr::VK_GOTTPREL;
break;
case TLSModel::LocalExec:
- RefFlags |= ARM64MCExpr::VK_TPREL;
+ RefFlags |= AArch64MCExpr::VK_TPREL;
break;
case TLSModel::LocalDynamic:
- RefFlags |= ARM64MCExpr::VK_DTPREL;
+ RefFlags |= AArch64MCExpr::VK_DTPREL;
break;
case TLSModel::GeneralDynamic:
- RefFlags |= ARM64MCExpr::VK_TLSDESC;
+ RefFlags |= AArch64MCExpr::VK_TLSDESC;
break;
}
} else {
// No modifier means this is a generic reference, classified as absolute for
// the cases where it matters (:abs_g0: etc).
- RefFlags |= ARM64MCExpr::VK_ABS;
+ RefFlags |= AArch64MCExpr::VK_ABS;
}
- if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_PAGE)
- RefFlags |= ARM64MCExpr::VK_PAGE;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_PAGEOFF)
- RefFlags |= ARM64MCExpr::VK_PAGEOFF;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_G3)
- RefFlags |= ARM64MCExpr::VK_G3;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_G2)
- RefFlags |= ARM64MCExpr::VK_G2;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_G1)
- RefFlags |= ARM64MCExpr::VK_G1;
- else if ((MO.getTargetFlags() & ARM64II::MO_FRAGMENT) == ARM64II::MO_G0)
- RefFlags |= ARM64MCExpr::VK_G0;
+ if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
+ RefFlags |= AArch64MCExpr::VK_PAGE;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
+ AArch64II::MO_PAGEOFF)
+ RefFlags |= AArch64MCExpr::VK_PAGEOFF;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
+ RefFlags |= AArch64MCExpr::VK_G3;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
+ RefFlags |= AArch64MCExpr::VK_G2;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
+ RefFlags |= AArch64MCExpr::VK_G1;
+ else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
+ RefFlags |= AArch64MCExpr::VK_G0;
- if (MO.getTargetFlags() & ARM64II::MO_NC)
- RefFlags |= ARM64MCExpr::VK_NC;
+ if (MO.getTargetFlags() & AArch64II::MO_NC)
+ RefFlags |= AArch64MCExpr::VK_NC;
const MCExpr *Expr =
MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, Ctx);
@@ -133,15 +134,15 @@ MCOperand ARM64MCInstLower::lowerSymbolO
Expr = MCBinaryExpr::CreateAdd(
Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx);
- ARM64MCExpr::VariantKind RefKind;
- RefKind = static_cast<ARM64MCExpr::VariantKind>(RefFlags);
- Expr = ARM64MCExpr::Create(Expr, RefKind, Ctx);
+ AArch64MCExpr::VariantKind RefKind;
+ RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
+ Expr = AArch64MCExpr::Create(Expr, RefKind, Ctx);
return MCOperand::CreateExpr(Expr);
}
-MCOperand ARM64MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
- MCSymbol *Sym) const {
+MCOperand AArch64MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
+ MCSymbol *Sym) const {
if (TargetTriple.isOSDarwin())
return lowerSymbolOperandDarwin(MO, Sym);
@@ -149,8 +150,8 @@ MCOperand ARM64MCInstLower::LowerSymbolO
return lowerSymbolOperandELF(MO, Sym);
}
-bool ARM64MCInstLower::lowerOperand(const MachineOperand &MO,
- MCOperand &MCOp) const {
+bool AArch64MCInstLower::lowerOperand(const MachineOperand &MO,
+ MCOperand &MCOp) const {
switch (MO.getType()) {
default:
assert(0 && "unknown operand type");
@@ -190,7 +191,7 @@ bool ARM64MCInstLower::lowerOperand(cons
return true;
}
-void ARM64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
+void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(MI->getOpcode());
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
Copied: llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.h?p2=llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.h&p1=llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64MCInstLower.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64MCInstLower.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64MCInstLower.h - Lower MachineInstr to MCInst ----------------===//
+//===-- AArch64MCInstLower.h - Lower MachineInstr to MCInst ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64_MCINSTLOWER_H
-#define ARM64_MCINSTLOWER_H
+#ifndef AArch64_MCINSTLOWER_H
+#define AArch64_MCINSTLOWER_H
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
@@ -25,15 +25,15 @@ class MachineModuleInfoMachO;
class MachineOperand;
class Mangler;
-/// ARM64MCInstLower - This class is used to lower an MachineInstr
+/// AArch64MCInstLower - This class is used to lower an MachineInstr
/// into an MCInst.
-class LLVM_LIBRARY_VISIBILITY ARM64MCInstLower {
+class LLVM_LIBRARY_VISIBILITY AArch64MCInstLower {
MCContext &Ctx;
AsmPrinter &Printer;
Triple TargetTriple;
public:
- ARM64MCInstLower(MCContext &ctx, Mangler &mang, AsmPrinter &printer);
+ AArch64MCInstLower(MCContext &ctx, Mangler &mang, AsmPrinter &printer);
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
Copied: llvm/trunk/lib/Target/AArch64/AArch64MachineFunctionInfo.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64MachineFunctionInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MachineFunctionInfo.h?p2=llvm/trunk/lib/Target/AArch64/AArch64MachineFunctionInfo.h&p1=llvm/trunk/lib/Target/ARM64/ARM64MachineFunctionInfo.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64MachineFunctionInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64MachineFunctionInfo.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64MachineFuctionInfo.h - ARM64 machine function info --*- C++ -*-===//
+//=- AArch64MachineFuctionInfo.h - AArch64 machine function info --*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares ARM64-specific per-machine-function information.
+// This file declares AArch64-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64MACHINEFUNCTIONINFO_H
-#define ARM64MACHINEFUNCTIONINFO_H
+#ifndef AArch64MACHINEFUNCTIONINFO_H
+#define AArch64MACHINEFUNCTIONINFO_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -21,9 +21,9 @@
namespace llvm {
-/// ARM64FunctionInfo - This class is derived from MachineFunctionInfo and
-/// contains private ARM64-specific information for each MachineFunction.
-class ARM64FunctionInfo : public MachineFunctionInfo {
+/// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and
+/// contains private AArch64-specific information for each MachineFunction.
+class AArch64FunctionInfo : public MachineFunctionInfo {
/// Number of bytes of arguments this function has on the stack. If the callee
/// is expected to restore the argument stack this should be a multiple of 16,
@@ -73,12 +73,12 @@ class ARM64FunctionInfo : public Machine
unsigned VarArgsFPRSize;
public:
- ARM64FunctionInfo()
+ AArch64FunctionInfo()
: BytesInStackArgArea(0), ArgumentStackToRestore(0), HasStackFrame(false),
NumLocalDynamicTLSAccesses(0), VarArgsStackIndex(0), VarArgsGPRIndex(0),
VarArgsGPRSize(0), VarArgsFPRIndex(0), VarArgsFPRSize(0) {}
- explicit ARM64FunctionInfo(MachineFunction &MF)
+ explicit AArch64FunctionInfo(MachineFunction &MF)
: BytesInStackArgArea(0), ArgumentStackToRestore(0), HasStackFrame(false),
NumLocalDynamicTLSAccesses(0), VarArgsStackIndex(0), VarArgsGPRIndex(0),
VarArgsGPRSize(0), VarArgsFPRIndex(0), VarArgsFPRSize(0) {
@@ -160,4 +160,4 @@ private:
};
} // End llvm namespace
-#endif // ARM64MACHINEFUNCTIONINFO_H
+#endif // AArch64MACHINEFUNCTIONINFO_H
Copied: llvm/trunk/lib/Target/AArch64/AArch64PerfectShuffle.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64PerfectShuffle.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64PerfectShuffle.h?p2=llvm/trunk/lib/Target/AArch64/AArch64PerfectShuffle.h&p1=llvm/trunk/lib/Target/ARM64/ARM64PerfectShuffle.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64PerfectShuffle.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64PerfectShuffle.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64PerfectShuffle.h - AdvSIMD Perfect Shuffle Table -------------===//
+//===-- AArch64PerfectShuffle.h - AdvSIMD Perfect Shuffle Table -----------===//
//
// The LLVM Compiler Infrastructure
//
Copied: llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64PromoteConstant.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64PromoteConstant.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64PromoteConstant.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64PromoteConstant.cpp Sat May 24 07:50:23 2014
@@ -1,5 +1,4 @@
-
-//===-- ARM64PromoteConstant.cpp --- Promote constant to global for ARM64 -===//
+//=- AArch64PromoteConstant.cpp --- Promote constant to global for AArch64 -==//
//
// The LLVM Compiler Infrastructure
//
@@ -8,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ARM64PromoteConstant pass which promotes constants
+// This file implements the AArch64PromoteConstant pass which promotes constants
// to global variables when this is likely to be more efficient. Currently only
// types related to constant vector (i.e., constant vector, array of constant
// vectors, constant structure with a constant vector field, etc.) are promoted
@@ -21,7 +20,7 @@
// FIXME: This pass may be useful for other targets too.
//===----------------------------------------------------------------------===//
-#include "ARM64.h"
+#include "AArch64.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
@@ -41,17 +40,17 @@
using namespace llvm;
-#define DEBUG_TYPE "arm64-promote-const"
+#define DEBUG_TYPE "aarch64-promote-const"
// Stress testing mode - disable heuristics.
-static cl::opt<bool> Stress("arm64-stress-promote-const", cl::Hidden,
+static cl::opt<bool> Stress("aarch64-stress-promote-const", cl::Hidden,
cl::desc("Promote all vector constants"));
STATISTIC(NumPromoted, "Number of promoted constants");
STATISTIC(NumPromotedUses, "Number of promoted constants uses");
//===----------------------------------------------------------------------===//
-// ARM64PromoteConstant
+// AArch64PromoteConstant
//===----------------------------------------------------------------------===//
namespace {
@@ -81,13 +80,13 @@ namespace {
///
/// Therefore the final assembly final has 4 different loads. With this pass
/// enabled, only one load is issued for the constants.
-class ARM64PromoteConstant : public ModulePass {
+class AArch64PromoteConstant : public ModulePass {
public:
static char ID;
- ARM64PromoteConstant() : ModulePass(ID) {}
+ AArch64PromoteConstant() : ModulePass(ID) {}
- const char *getPassName() const override { return "ARM64 Promote Constant"; }
+ const char *getPassName() const override { return "AArch64 Promote Constant"; }
/// Iterate over the functions and promote the interesting constants into
/// global variables with module scope.
@@ -202,20 +201,20 @@ private:
};
} // end anonymous namespace
-char ARM64PromoteConstant::ID = 0;
+char AArch64PromoteConstant::ID = 0;
namespace llvm {
-void initializeARM64PromoteConstantPass(PassRegistry &);
+void initializeAArch64PromoteConstantPass(PassRegistry &);
}
-INITIALIZE_PASS_BEGIN(ARM64PromoteConstant, "arm64-promote-const",
- "ARM64 Promote Constant Pass", false, false)
+INITIALIZE_PASS_BEGIN(AArch64PromoteConstant, "aarch64-promote-const",
+ "AArch64 Promote Constant Pass", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_END(ARM64PromoteConstant, "arm64-promote-const",
- "ARM64 Promote Constant Pass", false, false)
+INITIALIZE_PASS_END(AArch64PromoteConstant, "aarch64-promote-const",
+ "AArch64 Promote Constant Pass", false, false)
-ModulePass *llvm::createARM64PromoteConstantPass() {
- return new ARM64PromoteConstant();
+ModulePass *llvm::createAArch64PromoteConstantPass() {
+ return new AArch64PromoteConstant();
}
/// Check if the given type uses a vector type.
@@ -330,7 +329,7 @@ static bool shouldConvert(const Constant
}
Instruction *
-ARM64PromoteConstant::findInsertionPoint(Value::user_iterator &Use) {
+AArch64PromoteConstant::findInsertionPoint(Value::user_iterator &Use) {
// If this user is a phi, the insertion point is in the related
// incoming basic block.
PHINode *PhiInst = dyn_cast<PHINode>(*Use);
@@ -344,9 +343,9 @@ ARM64PromoteConstant::findInsertionPoint
return InsertionPoint;
}
-bool ARM64PromoteConstant::isDominated(Instruction *NewPt,
- Value::user_iterator &UseIt,
- InsertionPoints &InsertPts) {
+bool AArch64PromoteConstant::isDominated(Instruction *NewPt,
+ Value::user_iterator &UseIt,
+ InsertionPoints &InsertPts) {
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
*NewPt->getParent()->getParent()).getDomTree();
@@ -371,9 +370,9 @@ bool ARM64PromoteConstant::isDominated(I
return false;
}
-bool ARM64PromoteConstant::tryAndMerge(Instruction *NewPt,
- Value::user_iterator &UseIt,
- InsertionPoints &InsertPts) {
+bool AArch64PromoteConstant::tryAndMerge(Instruction *NewPt,
+ Value::user_iterator &UseIt,
+ InsertionPoints &InsertPts) {
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>(
*NewPt->getParent()->getParent()).getDomTree();
BasicBlock *NewBB = NewPt->getParent();
@@ -422,7 +421,7 @@ bool ARM64PromoteConstant::tryAndMerge(I
return false;
}
-void ARM64PromoteConstant::computeInsertionPoints(
+void AArch64PromoteConstant::computeInsertionPoints(
Constant *Val, InsertionPointsPerFunc &InsPtsPerFunc) {
DEBUG(dbgs() << "** Compute insertion points **\n");
for (Value::user_iterator UseIt = Val->user_begin(),
@@ -464,9 +463,8 @@ void ARM64PromoteConstant::computeInsert
}
}
-bool
-ARM64PromoteConstant::insertDefinitions(Constant *Cst,
- InsertionPointsPerFunc &InsPtsPerFunc) {
+bool AArch64PromoteConstant::insertDefinitions(
+ Constant *Cst, InsertionPointsPerFunc &InsPtsPerFunc) {
// We will create one global variable per Module.
DenseMap<Module *, GlobalVariable *> ModuleToMergedGV;
bool HasChanged = false;
@@ -533,13 +531,13 @@ ARM64PromoteConstant::insertDefinitions(
return HasChanged;
}
-bool ARM64PromoteConstant::computeAndInsertDefinitions(Constant *Val) {
+bool AArch64PromoteConstant::computeAndInsertDefinitions(Constant *Val) {
InsertionPointsPerFunc InsertPtsPerFunc;
computeInsertionPoints(Val, InsertPtsPerFunc);
return insertDefinitions(Val, InsertPtsPerFunc);
}
-bool ARM64PromoteConstant::promoteConstant(Constant *Cst) {
+bool AArch64PromoteConstant::promoteConstant(Constant *Cst) {
assert(Cst && "Given variable is not a valid constant.");
if (!shouldConvert(Cst))
@@ -553,7 +551,7 @@ bool ARM64PromoteConstant::promoteConsta
return computeAndInsertDefinitions(Cst);
}
-bool ARM64PromoteConstant::runOnFunction(Function &F) {
+bool AArch64PromoteConstant::runOnFunction(Function &F) {
// Look for instructions using constant vector. Promote that constant to a
// global variable. Create as few loads of this variable as possible and
// update the uses accordingly.
Copied: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64RegisterInfo.cpp - ARM64 Register Information -----------------===//
+//===- AArch64RegisterInfo.cpp - AArch64 Register Information -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,15 +7,16 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the ARM64 implementation of the TargetRegisterInfo class.
+// This file contains the AArch64 implementation of the TargetRegisterInfo
+// class.
//
//===----------------------------------------------------------------------===//
-#include "ARM64RegisterInfo.h"
-#include "ARM64FrameLowering.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64Subtarget.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
+#include "AArch64RegisterInfo.h"
+#include "AArch64FrameLowering.h"
+#include "AArch64InstrInfo.h"
+#include "AArch64Subtarget.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -30,39 +31,39 @@
using namespace llvm;
#define GET_REGINFO_TARGET_DESC
-#include "ARM64GenRegisterInfo.inc"
+#include "AArch64GenRegisterInfo.inc"
-ARM64RegisterInfo::ARM64RegisterInfo(const ARM64InstrInfo *tii,
- const ARM64Subtarget *sti)
- : ARM64GenRegisterInfo(ARM64::LR), TII(tii), STI(sti) {}
+AArch64RegisterInfo::AArch64RegisterInfo(const AArch64InstrInfo *tii,
+ const AArch64Subtarget *sti)
+ : AArch64GenRegisterInfo(AArch64::LR), TII(tii), STI(sti) {}
const MCPhysReg *
-ARM64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
assert(MF && "Invalid MachineFunction pointer.");
if (MF->getFunction()->getCallingConv() == CallingConv::AnyReg)
- return CSR_ARM64_AllRegs_SaveList;
+ return CSR_AArch64_AllRegs_SaveList;
else
- return CSR_ARM64_AAPCS_SaveList;
+ return CSR_AArch64_AAPCS_SaveList;
}
const uint32_t *
-ARM64RegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
+AArch64RegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
if (CC == CallingConv::AnyReg)
- return CSR_ARM64_AllRegs_RegMask;
+ return CSR_AArch64_AllRegs_RegMask;
else
- return CSR_ARM64_AAPCS_RegMask;
+ return CSR_AArch64_AAPCS_RegMask;
}
-const uint32_t *ARM64RegisterInfo::getTLSCallPreservedMask() const {
+const uint32_t *AArch64RegisterInfo::getTLSCallPreservedMask() const {
if (STI->isTargetDarwin())
- return CSR_ARM64_TLS_Darwin_RegMask;
+ return CSR_AArch64_TLS_Darwin_RegMask;
assert(STI->isTargetELF() && "only expect Darwin or ELF TLS");
- return CSR_ARM64_TLS_ELF_RegMask;
+ return CSR_AArch64_TLS_ELF_RegMask;
}
const uint32_t *
-ARM64RegisterInfo::getThisReturnPreservedMask(CallingConv::ID) const {
+AArch64RegisterInfo::getThisReturnPreservedMask(CallingConv::ID) const {
// This should return a register mask that is the same as that returned by
// getCallPreservedMask but that additionally preserves the register used for
// the first i64 argument (which must also be the register used to return a
@@ -70,57 +71,58 @@ ARM64RegisterInfo::getThisReturnPreserve
//
// In case that the calling convention does not use the same register for
// both, the function should return NULL (does not currently apply)
- return CSR_ARM64_AAPCS_ThisReturn_RegMask;
+ return CSR_AArch64_AAPCS_ThisReturn_RegMask;
}
-BitVector ARM64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+BitVector
+AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
// FIXME: avoid re-calculating this every time.
BitVector Reserved(getNumRegs());
- Reserved.set(ARM64::SP);
- Reserved.set(ARM64::XZR);
- Reserved.set(ARM64::WSP);
- Reserved.set(ARM64::WZR);
+ Reserved.set(AArch64::SP);
+ Reserved.set(AArch64::XZR);
+ Reserved.set(AArch64::WSP);
+ Reserved.set(AArch64::WZR);
if (TFI->hasFP(MF) || STI->isTargetDarwin()) {
- Reserved.set(ARM64::FP);
- Reserved.set(ARM64::W29);
+ Reserved.set(AArch64::FP);
+ Reserved.set(AArch64::W29);
}
if (STI->isTargetDarwin()) {
- Reserved.set(ARM64::X18); // Platform register
- Reserved.set(ARM64::W18);
+ Reserved.set(AArch64::X18); // Platform register
+ Reserved.set(AArch64::W18);
}
if (hasBasePointer(MF)) {
- Reserved.set(ARM64::X19);
- Reserved.set(ARM64::W19);
+ Reserved.set(AArch64::X19);
+ Reserved.set(AArch64::W19);
}
return Reserved;
}
-bool ARM64RegisterInfo::isReservedReg(const MachineFunction &MF,
+bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
unsigned Reg) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
switch (Reg) {
default:
break;
- case ARM64::SP:
- case ARM64::XZR:
- case ARM64::WSP:
- case ARM64::WZR:
+ case AArch64::SP:
+ case AArch64::XZR:
+ case AArch64::WSP:
+ case AArch64::WZR:
return true;
- case ARM64::X18:
- case ARM64::W18:
+ case AArch64::X18:
+ case AArch64::W18:
return STI->isTargetDarwin();
- case ARM64::FP:
- case ARM64::W29:
+ case AArch64::FP:
+ case AArch64::W29:
return TFI->hasFP(MF) || STI->isTargetDarwin();
- case ARM64::W19:
- case ARM64::X19:
+ case AArch64::W19:
+ case AArch64::X19:
return hasBasePointer(MF);
}
@@ -128,21 +130,21 @@ bool ARM64RegisterInfo::isReservedReg(co
}
const TargetRegisterClass *
-ARM64RegisterInfo::getPointerRegClass(const MachineFunction &MF,
+AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
- return &ARM64::GPR64RegClass;
+ return &AArch64::GPR64RegClass;
}
const TargetRegisterClass *
-ARM64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
- if (RC == &ARM64::CCRRegClass)
+AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
+ if (RC == &AArch64::CCRRegClass)
return nullptr; // Can't copy NZCV.
return RC;
}
-unsigned ARM64RegisterInfo::getBaseRegister() const { return ARM64::X19; }
+unsigned AArch64RegisterInfo::getBaseRegister() const { return AArch64::X19; }
-bool ARM64RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
+bool AArch64RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
// In the presence of variable sized objects, if the fixed stack size is
@@ -165,37 +167,39 @@ bool ARM64RegisterInfo::hasBasePointer(c
return false;
}
-unsigned ARM64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+unsigned
+AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
- return TFI->hasFP(MF) ? ARM64::FP : ARM64::SP;
+ return TFI->hasFP(MF) ? AArch64::FP : AArch64::SP;
}
-bool
-ARM64RegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
+bool AArch64RegisterInfo::requiresRegisterScavenging(
+ const MachineFunction &MF) const {
return true;
}
-bool ARM64RegisterInfo::requiresVirtualBaseRegisters(const MachineFunction &MF)
- const {
+bool AArch64RegisterInfo::requiresVirtualBaseRegisters(
+ const MachineFunction &MF) const {
return true;
}
bool
-ARM64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
+AArch64RegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- // ARM64FrameLowering::resolveFrameIndexReference() can always fall back
+ // AArch64FrameLowering::resolveFrameIndexReference() can always fall back
// to the stack pointer, so only put the emergency spill slot next to the
// FP when there's no better way to access it (SP or base pointer).
return MFI->hasVarSizedObjects() && !hasBasePointer(MF);
}
-bool ARM64RegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF)
- const {
+bool AArch64RegisterInfo::requiresFrameIndexScavenging(
+ const MachineFunction &MF) const {
return true;
}
-bool ARM64RegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
+bool
+AArch64RegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
// Only consider eliminating leaf frames.
if (MFI->hasCalls() || (MF.getTarget().Options.DisableFramePointerElim(MF) &&
@@ -208,8 +212,8 @@ bool ARM64RegisterInfo::cannotEliminateF
/// reference would be better served by a base register other than FP
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
/// references it should create new base registers for.
-bool ARM64RegisterInfo::needsFrameBaseReg(MachineInstr *MI,
- int64_t Offset) const {
+bool AArch64RegisterInfo::needsFrameBaseReg(MachineInstr *MI,
+ int64_t Offset) const {
for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i)
assert(i < MI->getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
@@ -268,30 +272,30 @@ bool ARM64RegisterInfo::needsFrameBaseRe
return true;
}
-bool ARM64RegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
- int64_t Offset) const {
+bool AArch64RegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
+ int64_t Offset) const {
assert(Offset <= INT_MAX && "Offset too big to fit in int.");
assert(MI && "Unable to get the legal offset for nil instruction.");
int SaveOffset = Offset;
- return isARM64FrameOffsetLegal(*MI, SaveOffset) & ARM64FrameOffsetIsLegal;
+ return isAArch64FrameOffsetLegal(*MI, SaveOffset) & AArch64FrameOffsetIsLegal;
}
/// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
/// at the beginning of the basic block.
-void ARM64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
- unsigned BaseReg,
- int FrameIdx,
- int64_t Offset) const {
+void AArch64RegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ unsigned BaseReg,
+ int FrameIdx,
+ int64_t Offset) const {
MachineBasicBlock::iterator Ins = MBB->begin();
DebugLoc DL; // Defaults to "unknown"
if (Ins != MBB->end())
DL = Ins->getDebugLoc();
- const MCInstrDesc &MCID = TII->get(ARM64::ADDXri);
+ const MCInstrDesc &MCID = TII->get(AArch64::ADDXri);
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
const MachineFunction &MF = *MBB->getParent();
MRI.constrainRegClass(BaseReg, TII->getRegClass(MCID, 0, this, MF));
- unsigned Shifter = ARM64_AM::getShifterImm(ARM64_AM::LSL, 0);
+ unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0);
BuildMI(*MBB, Ins, DL, MCID, BaseReg)
.addFrameIndex(FrameIdx)
@@ -299,8 +303,8 @@ void ARM64RegisterInfo::materializeFrame
.addImm(Shifter);
}
-void ARM64RegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
- int64_t Offset) const {
+void AArch64RegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
+ int64_t Offset) const {
int Off = Offset; // ARM doesn't need the general 64-bit offsets
unsigned i = 0;
@@ -308,20 +312,20 @@ void ARM64RegisterInfo::resolveFrameInde
++i;
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
}
- bool Done = rewriteARM64FrameIndex(MI, i, BaseReg, Off, TII);
+ bool Done = rewriteAArch64FrameIndex(MI, i, BaseReg, Off, TII);
assert(Done && "Unable to resolve frame index!");
(void)Done;
}
-void ARM64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
- int SPAdj, unsigned FIOperandNum,
- RegScavenger *RS) const {
+void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
+ int SPAdj, unsigned FIOperandNum,
+ RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
- const ARM64FrameLowering *TFI = static_cast<const ARM64FrameLowering *>(
+ const AArch64FrameLowering *TFI = static_cast<const AArch64FrameLowering *>(
MF.getTarget().getFrameLowering());
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
@@ -341,7 +345,7 @@ void ARM64RegisterInfo::eliminateFrameIn
// Modify MI as necessary to handle as much of 'Offset' as possible
Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg);
- if (rewriteARM64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
+ if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
return;
assert((!RS || !RS->isScavengingFrameIndex(FrameIndex)) &&
@@ -351,48 +355,48 @@ void ARM64RegisterInfo::eliminateFrameIn
// as much as possible above. Handle the rest, providing a register that is
// SP+LargeImm.
unsigned ScratchReg =
- MF.getRegInfo().createVirtualRegister(&ARM64::GPR64RegClass);
+ MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
emitFrameOffset(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, TII);
MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false, true);
}
namespace llvm {
-unsigned ARM64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
- MachineFunction &MF) const {
+unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
+ MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
switch (RC->getID()) {
default:
return 0;
- case ARM64::GPR32RegClassID:
- case ARM64::GPR32spRegClassID:
- case ARM64::GPR32allRegClassID:
- case ARM64::GPR64spRegClassID:
- case ARM64::GPR64allRegClassID:
- case ARM64::GPR64RegClassID:
- case ARM64::GPR32commonRegClassID:
- case ARM64::GPR64commonRegClassID:
+ case AArch64::GPR32RegClassID:
+ case AArch64::GPR32spRegClassID:
+ case AArch64::GPR32allRegClassID:
+ case AArch64::GPR64spRegClassID:
+ case AArch64::GPR64allRegClassID:
+ case AArch64::GPR64RegClassID:
+ case AArch64::GPR32commonRegClassID:
+ case AArch64::GPR64commonRegClassID:
return 32 - 1 // XZR/SP
- (TFI->hasFP(MF) || STI->isTargetDarwin()) // FP
- STI->isTargetDarwin() // X18 reserved as platform register
- hasBasePointer(MF); // X19
- case ARM64::FPR8RegClassID:
- case ARM64::FPR16RegClassID:
- case ARM64::FPR32RegClassID:
- case ARM64::FPR64RegClassID:
- case ARM64::FPR128RegClassID:
+ case AArch64::FPR8RegClassID:
+ case AArch64::FPR16RegClassID:
+ case AArch64::FPR32RegClassID:
+ case AArch64::FPR64RegClassID:
+ case AArch64::FPR128RegClassID:
return 32;
- case ARM64::DDRegClassID:
- case ARM64::DDDRegClassID:
- case ARM64::DDDDRegClassID:
- case ARM64::QQRegClassID:
- case ARM64::QQQRegClassID:
- case ARM64::QQQQRegClassID:
+ case AArch64::DDRegClassID:
+ case AArch64::DDDRegClassID:
+ case AArch64::DDDDRegClassID:
+ case AArch64::QQRegClassID:
+ case AArch64::QQQRegClassID:
+ case AArch64::QQQQRegClassID:
return 32;
- case ARM64::FPR128_loRegClassID:
+ case AArch64::FPR128_loRegClassID:
return 16;
}
}
Copied: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h?p2=llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h&p1=llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64RegisterInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64RegisterInfo.h - ARM64 Register Information Impl ----*- C++ -*-===//
+//==- AArch64RegisterInfo.h - AArch64 Register Information Impl --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -7,31 +7,31 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the ARM64 implementation of the MRegisterInfo class.
+// This file contains the AArch64 implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ARM64REGISTERINFO_H
-#define LLVM_TARGET_ARM64REGISTERINFO_H
+#ifndef LLVM_TARGET_AArch64REGISTERINFO_H
+#define LLVM_TARGET_AArch64REGISTERINFO_H
#define GET_REGINFO_HEADER
-#include "ARM64GenRegisterInfo.inc"
+#include "AArch64GenRegisterInfo.inc"
namespace llvm {
-class ARM64InstrInfo;
-class ARM64Subtarget;
+class AArch64InstrInfo;
+class AArch64Subtarget;
class MachineFunction;
class RegScavenger;
class TargetRegisterClass;
-struct ARM64RegisterInfo : public ARM64GenRegisterInfo {
+struct AArch64RegisterInfo : public AArch64GenRegisterInfo {
private:
- const ARM64InstrInfo *TII;
- const ARM64Subtarget *STI;
+ const AArch64InstrInfo *TII;
+ const AArch64Subtarget *STI;
public:
- ARM64RegisterInfo(const ARM64InstrInfo *tii, const ARM64Subtarget *sti);
+ AArch64RegisterInfo(const AArch64InstrInfo *tii, const AArch64Subtarget *sti);
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
@@ -98,4 +98,4 @@ public:
} // end namespace llvm
-#endif // LLVM_TARGET_ARM64REGISTERINFO_H
+#endif // LLVM_TARGET_AArch64REGISTERINFO_H
Added: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td (added)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td Sat May 24 07:50:23 2014
@@ -0,0 +1,593 @@
+//=- AArch64RegisterInfo.td - Describe the AArch64 Regisers --*- tablegen -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+
+class AArch64Reg<bits<16> enc, string n, list<Register> subregs = [],
+ list<string> altNames = []>
+ : Register<n, altNames> {
+ let HWEncoding = enc;
+ let Namespace = "AArch64";
+ let SubRegs = subregs;
+}
+
+let Namespace = "AArch64" in {
+ def sub_32 : SubRegIndex<32>;
+
+ def bsub : SubRegIndex<8>;
+ def hsub : SubRegIndex<16>;
+ def ssub : SubRegIndex<32>;
+ def dsub : SubRegIndex<32>;
+ def qhisub : SubRegIndex<64>;
+ def qsub : SubRegIndex<64>;
+ // Note: Code depends on these having consecutive numbers
+ def dsub0 : SubRegIndex<64>;
+ def dsub1 : SubRegIndex<64>;
+ def dsub2 : SubRegIndex<64>;
+ def dsub3 : SubRegIndex<64>;
+ // Note: Code depends on these having consecutive numbers
+ def qsub0 : SubRegIndex<128>;
+ def qsub1 : SubRegIndex<128>;
+ def qsub2 : SubRegIndex<128>;
+ def qsub3 : SubRegIndex<128>;
+}
+
+let Namespace = "AArch64" in {
+ def vreg : RegAltNameIndex;
+ def vlist1 : RegAltNameIndex;
+}
+
+//===----------------------------------------------------------------------===//
+// Registers
+//===----------------------------------------------------------------------===//
+def W0 : AArch64Reg<0, "w0" >, DwarfRegNum<[0]>;
+def W1 : AArch64Reg<1, "w1" >, DwarfRegNum<[1]>;
+def W2 : AArch64Reg<2, "w2" >, DwarfRegNum<[2]>;
+def W3 : AArch64Reg<3, "w3" >, DwarfRegNum<[3]>;
+def W4 : AArch64Reg<4, "w4" >, DwarfRegNum<[4]>;
+def W5 : AArch64Reg<5, "w5" >, DwarfRegNum<[5]>;
+def W6 : AArch64Reg<6, "w6" >, DwarfRegNum<[6]>;
+def W7 : AArch64Reg<7, "w7" >, DwarfRegNum<[7]>;
+def W8 : AArch64Reg<8, "w8" >, DwarfRegNum<[8]>;
+def W9 : AArch64Reg<9, "w9" >, DwarfRegNum<[9]>;
+def W10 : AArch64Reg<10, "w10">, DwarfRegNum<[10]>;
+def W11 : AArch64Reg<11, "w11">, DwarfRegNum<[11]>;
+def W12 : AArch64Reg<12, "w12">, DwarfRegNum<[12]>;
+def W13 : AArch64Reg<13, "w13">, DwarfRegNum<[13]>;
+def W14 : AArch64Reg<14, "w14">, DwarfRegNum<[14]>;
+def W15 : AArch64Reg<15, "w15">, DwarfRegNum<[15]>;
+def W16 : AArch64Reg<16, "w16">, DwarfRegNum<[16]>;
+def W17 : AArch64Reg<17, "w17">, DwarfRegNum<[17]>;
+def W18 : AArch64Reg<18, "w18">, DwarfRegNum<[18]>;
+def W19 : AArch64Reg<19, "w19">, DwarfRegNum<[19]>;
+def W20 : AArch64Reg<20, "w20">, DwarfRegNum<[20]>;
+def W21 : AArch64Reg<21, "w21">, DwarfRegNum<[21]>;
+def W22 : AArch64Reg<22, "w22">, DwarfRegNum<[22]>;
+def W23 : AArch64Reg<23, "w23">, DwarfRegNum<[23]>;
+def W24 : AArch64Reg<24, "w24">, DwarfRegNum<[24]>;
+def W25 : AArch64Reg<25, "w25">, DwarfRegNum<[25]>;
+def W26 : AArch64Reg<26, "w26">, DwarfRegNum<[26]>;
+def W27 : AArch64Reg<27, "w27">, DwarfRegNum<[27]>;
+def W28 : AArch64Reg<28, "w28">, DwarfRegNum<[28]>;
+def W29 : AArch64Reg<29, "w29">, DwarfRegNum<[29]>;
+def W30 : AArch64Reg<30, "w30">, DwarfRegNum<[30]>;
+def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
+def WZR : AArch64Reg<31, "wzr">, DwarfRegAlias<WSP>;
+
+let SubRegIndices = [sub_32] in {
+def X0 : AArch64Reg<0, "x0", [W0]>, DwarfRegAlias<W0>;
+def X1 : AArch64Reg<1, "x1", [W1]>, DwarfRegAlias<W1>;
+def X2 : AArch64Reg<2, "x2", [W2]>, DwarfRegAlias<W2>;
+def X3 : AArch64Reg<3, "x3", [W3]>, DwarfRegAlias<W3>;
+def X4 : AArch64Reg<4, "x4", [W4]>, DwarfRegAlias<W4>;
+def X5 : AArch64Reg<5, "x5", [W5]>, DwarfRegAlias<W5>;
+def X6 : AArch64Reg<6, "x6", [W6]>, DwarfRegAlias<W6>;
+def X7 : AArch64Reg<7, "x7", [W7]>, DwarfRegAlias<W7>;
+def X8 : AArch64Reg<8, "x8", [W8]>, DwarfRegAlias<W8>;
+def X9 : AArch64Reg<9, "x9", [W9]>, DwarfRegAlias<W9>;
+def X10 : AArch64Reg<10, "x10", [W10]>, DwarfRegAlias<W10>;
+def X11 : AArch64Reg<11, "x11", [W11]>, DwarfRegAlias<W11>;
+def X12 : AArch64Reg<12, "x12", [W12]>, DwarfRegAlias<W12>;
+def X13 : AArch64Reg<13, "x13", [W13]>, DwarfRegAlias<W13>;
+def X14 : AArch64Reg<14, "x14", [W14]>, DwarfRegAlias<W14>;
+def X15 : AArch64Reg<15, "x15", [W15]>, DwarfRegAlias<W15>;
+def X16 : AArch64Reg<16, "x16", [W16]>, DwarfRegAlias<W16>;
+def X17 : AArch64Reg<17, "x17", [W17]>, DwarfRegAlias<W17>;
+def X18 : AArch64Reg<18, "x18", [W18]>, DwarfRegAlias<W18>;
+def X19 : AArch64Reg<19, "x19", [W19]>, DwarfRegAlias<W19>;
+def X20 : AArch64Reg<20, "x20", [W20]>, DwarfRegAlias<W20>;
+def X21 : AArch64Reg<21, "x21", [W21]>, DwarfRegAlias<W21>;
+def X22 : AArch64Reg<22, "x22", [W22]>, DwarfRegAlias<W22>;
+def X23 : AArch64Reg<23, "x23", [W23]>, DwarfRegAlias<W23>;
+def X24 : AArch64Reg<24, "x24", [W24]>, DwarfRegAlias<W24>;
+def X25 : AArch64Reg<25, "x25", [W25]>, DwarfRegAlias<W25>;
+def X26 : AArch64Reg<26, "x26", [W26]>, DwarfRegAlias<W26>;
+def X27 : AArch64Reg<27, "x27", [W27]>, DwarfRegAlias<W27>;
+def X28 : AArch64Reg<28, "x28", [W28]>, DwarfRegAlias<W28>;
+def FP : AArch64Reg<29, "x29", [W29]>, DwarfRegAlias<W29>;
+def LR : AArch64Reg<30, "x30", [W30]>, DwarfRegAlias<W30>;
+def SP : AArch64Reg<31, "sp", [WSP]>, DwarfRegAlias<WSP>;
+def XZR : AArch64Reg<31, "xzr", [WZR]>, DwarfRegAlias<WSP>;
+}
+
+// Condition code register.
+def NZCV : AArch64Reg<0, "nzcv">;
+
+// GPR register classes with the intersections of GPR32/GPR32sp and
+// GPR64/GPR64sp for use by the coalescer.
+def GPR32common : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 0, 30)> {
+ let AltOrders = [(rotl GPR32common, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+def GPR64common : RegisterClass<"AArch64", [i64], 64,
+ (add (sequence "X%u", 0, 28), FP, LR)> {
+ let AltOrders = [(rotl GPR64common, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+// GPR register classes which exclude SP/WSP.
+def GPR32 : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WZR)> {
+ let AltOrders = [(rotl GPR32, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+def GPR64 : RegisterClass<"AArch64", [i64], 64, (add GPR64common, XZR)> {
+ let AltOrders = [(rotl GPR64, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+
+// GPR register classes which include SP/WSP.
+def GPR32sp : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WSP)> {
+ let AltOrders = [(rotl GPR32sp, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+def GPR64sp : RegisterClass<"AArch64", [i64], 64, (add GPR64common, SP)> {
+ let AltOrders = [(rotl GPR64sp, 8)];
+ let AltOrderSelect = [{ return 1; }];
+}
+
+def GPR32sponly : RegisterClass<"AArch64", [i32], 32, (add WSP)>;
+def GPR64sponly : RegisterClass<"AArch64", [i64], 64, (add SP)>;
+
+def GPR64spPlus0Operand : AsmOperandClass {
+ let Name = "GPR64sp0";
+ let RenderMethod = "addRegOperands";
+ let ParserMethod = "tryParseGPR64sp0Operand";
+}
+
+def GPR64sp0 : RegisterOperand<GPR64sp> {
+ let ParserMatchClass = GPR64spPlus0Operand;
+}
+
+// GPR register classes which include WZR/XZR AND SP/WSP. This is not a
+// constraint used by any instructions, it is used as a common super-class.
+def GPR32all : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WZR, WSP)>;
+def GPR64all : RegisterClass<"AArch64", [i64], 64, (add GPR64common, XZR, SP)>;
+
+// For tail calls, we can't use callee-saved registers, as they are restored
+// to the saved value before the tail call, which would clobber a call address.
+// This is for indirect tail calls to store the address of the destination.
+def tcGPR64 : RegisterClass<"AArch64", [i64], 64, (sub GPR64common, X19, X20, X21,
+ X22, X23, X24, X25, X26,
+ X27, X28)>;
+
+// GPR register classes for post increment amount of vector load/store that
+// has alternate printing when Rm=31 and prints a constant immediate value
+// equal to the total number of bytes transferred.
+
+// FIXME: TableGen *should* be able to do these itself now. There appears to be
+// a bug in counting how many operands a Post-indexed MCInst should have which
+// means the aliases don't trigger.
+def GPR64pi1 : RegisterOperand<GPR64, "printPostIncOperand<1>">;
+def GPR64pi2 : RegisterOperand<GPR64, "printPostIncOperand<2>">;
+def GPR64pi3 : RegisterOperand<GPR64, "printPostIncOperand<3>">;
+def GPR64pi4 : RegisterOperand<GPR64, "printPostIncOperand<4>">;
+def GPR64pi6 : RegisterOperand<GPR64, "printPostIncOperand<6>">;
+def GPR64pi8 : RegisterOperand<GPR64, "printPostIncOperand<8>">;
+def GPR64pi12 : RegisterOperand<GPR64, "printPostIncOperand<12>">;
+def GPR64pi16 : RegisterOperand<GPR64, "printPostIncOperand<16>">;
+def GPR64pi24 : RegisterOperand<GPR64, "printPostIncOperand<24>">;
+def GPR64pi32 : RegisterOperand<GPR64, "printPostIncOperand<32>">;
+def GPR64pi48 : RegisterOperand<GPR64, "printPostIncOperand<48>">;
+def GPR64pi64 : RegisterOperand<GPR64, "printPostIncOperand<64>">;
+
+// Condition code regclass.
+def CCR : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
+ let CopyCost = -1; // Don't allow copying of status registers.
+
+ // CCR is not allocatable.
+ let isAllocatable = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Floating Point Scalar Registers
+//===----------------------------------------------------------------------===//
+
+def B0 : AArch64Reg<0, "b0">, DwarfRegNum<[64]>;
+def B1 : AArch64Reg<1, "b1">, DwarfRegNum<[65]>;
+def B2 : AArch64Reg<2, "b2">, DwarfRegNum<[66]>;
+def B3 : AArch64Reg<3, "b3">, DwarfRegNum<[67]>;
+def B4 : AArch64Reg<4, "b4">, DwarfRegNum<[68]>;
+def B5 : AArch64Reg<5, "b5">, DwarfRegNum<[69]>;
+def B6 : AArch64Reg<6, "b6">, DwarfRegNum<[70]>;
+def B7 : AArch64Reg<7, "b7">, DwarfRegNum<[71]>;
+def B8 : AArch64Reg<8, "b8">, DwarfRegNum<[72]>;
+def B9 : AArch64Reg<9, "b9">, DwarfRegNum<[73]>;
+def B10 : AArch64Reg<10, "b10">, DwarfRegNum<[74]>;
+def B11 : AArch64Reg<11, "b11">, DwarfRegNum<[75]>;
+def B12 : AArch64Reg<12, "b12">, DwarfRegNum<[76]>;
+def B13 : AArch64Reg<13, "b13">, DwarfRegNum<[77]>;
+def B14 : AArch64Reg<14, "b14">, DwarfRegNum<[78]>;
+def B15 : AArch64Reg<15, "b15">, DwarfRegNum<[79]>;
+def B16 : AArch64Reg<16, "b16">, DwarfRegNum<[80]>;
+def B17 : AArch64Reg<17, "b17">, DwarfRegNum<[81]>;
+def B18 : AArch64Reg<18, "b18">, DwarfRegNum<[82]>;
+def B19 : AArch64Reg<19, "b19">, DwarfRegNum<[83]>;
+def B20 : AArch64Reg<20, "b20">, DwarfRegNum<[84]>;
+def B21 : AArch64Reg<21, "b21">, DwarfRegNum<[85]>;
+def B22 : AArch64Reg<22, "b22">, DwarfRegNum<[86]>;
+def B23 : AArch64Reg<23, "b23">, DwarfRegNum<[87]>;
+def B24 : AArch64Reg<24, "b24">, DwarfRegNum<[88]>;
+def B25 : AArch64Reg<25, "b25">, DwarfRegNum<[89]>;
+def B26 : AArch64Reg<26, "b26">, DwarfRegNum<[90]>;
+def B27 : AArch64Reg<27, "b27">, DwarfRegNum<[91]>;
+def B28 : AArch64Reg<28, "b28">, DwarfRegNum<[92]>;
+def B29 : AArch64Reg<29, "b29">, DwarfRegNum<[93]>;
+def B30 : AArch64Reg<30, "b30">, DwarfRegNum<[94]>;
+def B31 : AArch64Reg<31, "b31">, DwarfRegNum<[95]>;
+
+let SubRegIndices = [bsub] in {
+def H0 : AArch64Reg<0, "h0", [B0]>, DwarfRegAlias<B0>;
+def H1 : AArch64Reg<1, "h1", [B1]>, DwarfRegAlias<B1>;
+def H2 : AArch64Reg<2, "h2", [B2]>, DwarfRegAlias<B2>;
+def H3 : AArch64Reg<3, "h3", [B3]>, DwarfRegAlias<B3>;
+def H4 : AArch64Reg<4, "h4", [B4]>, DwarfRegAlias<B4>;
+def H5 : AArch64Reg<5, "h5", [B5]>, DwarfRegAlias<B5>;
+def H6 : AArch64Reg<6, "h6", [B6]>, DwarfRegAlias<B6>;
+def H7 : AArch64Reg<7, "h7", [B7]>, DwarfRegAlias<B7>;
+def H8 : AArch64Reg<8, "h8", [B8]>, DwarfRegAlias<B8>;
+def H9 : AArch64Reg<9, "h9", [B9]>, DwarfRegAlias<B9>;
+def H10 : AArch64Reg<10, "h10", [B10]>, DwarfRegAlias<B10>;
+def H11 : AArch64Reg<11, "h11", [B11]>, DwarfRegAlias<B11>;
+def H12 : AArch64Reg<12, "h12", [B12]>, DwarfRegAlias<B12>;
+def H13 : AArch64Reg<13, "h13", [B13]>, DwarfRegAlias<B13>;
+def H14 : AArch64Reg<14, "h14", [B14]>, DwarfRegAlias<B14>;
+def H15 : AArch64Reg<15, "h15", [B15]>, DwarfRegAlias<B15>;
+def H16 : AArch64Reg<16, "h16", [B16]>, DwarfRegAlias<B16>;
+def H17 : AArch64Reg<17, "h17", [B17]>, DwarfRegAlias<B17>;
+def H18 : AArch64Reg<18, "h18", [B18]>, DwarfRegAlias<B18>;
+def H19 : AArch64Reg<19, "h19", [B19]>, DwarfRegAlias<B19>;
+def H20 : AArch64Reg<20, "h20", [B20]>, DwarfRegAlias<B20>;
+def H21 : AArch64Reg<21, "h21", [B21]>, DwarfRegAlias<B21>;
+def H22 : AArch64Reg<22, "h22", [B22]>, DwarfRegAlias<B22>;
+def H23 : AArch64Reg<23, "h23", [B23]>, DwarfRegAlias<B23>;
+def H24 : AArch64Reg<24, "h24", [B24]>, DwarfRegAlias<B24>;
+def H25 : AArch64Reg<25, "h25", [B25]>, DwarfRegAlias<B25>;
+def H26 : AArch64Reg<26, "h26", [B26]>, DwarfRegAlias<B26>;
+def H27 : AArch64Reg<27, "h27", [B27]>, DwarfRegAlias<B27>;
+def H28 : AArch64Reg<28, "h28", [B28]>, DwarfRegAlias<B28>;
+def H29 : AArch64Reg<29, "h29", [B29]>, DwarfRegAlias<B29>;
+def H30 : AArch64Reg<30, "h30", [B30]>, DwarfRegAlias<B30>;
+def H31 : AArch64Reg<31, "h31", [B31]>, DwarfRegAlias<B31>;
+}
+
+let SubRegIndices = [hsub] in {
+def S0 : AArch64Reg<0, "s0", [H0]>, DwarfRegAlias<B0>;
+def S1 : AArch64Reg<1, "s1", [H1]>, DwarfRegAlias<B1>;
+def S2 : AArch64Reg<2, "s2", [H2]>, DwarfRegAlias<B2>;
+def S3 : AArch64Reg<3, "s3", [H3]>, DwarfRegAlias<B3>;
+def S4 : AArch64Reg<4, "s4", [H4]>, DwarfRegAlias<B4>;
+def S5 : AArch64Reg<5, "s5", [H5]>, DwarfRegAlias<B5>;
+def S6 : AArch64Reg<6, "s6", [H6]>, DwarfRegAlias<B6>;
+def S7 : AArch64Reg<7, "s7", [H7]>, DwarfRegAlias<B7>;
+def S8 : AArch64Reg<8, "s8", [H8]>, DwarfRegAlias<B8>;
+def S9 : AArch64Reg<9, "s9", [H9]>, DwarfRegAlias<B9>;
+def S10 : AArch64Reg<10, "s10", [H10]>, DwarfRegAlias<B10>;
+def S11 : AArch64Reg<11, "s11", [H11]>, DwarfRegAlias<B11>;
+def S12 : AArch64Reg<12, "s12", [H12]>, DwarfRegAlias<B12>;
+def S13 : AArch64Reg<13, "s13", [H13]>, DwarfRegAlias<B13>;
+def S14 : AArch64Reg<14, "s14", [H14]>, DwarfRegAlias<B14>;
+def S15 : AArch64Reg<15, "s15", [H15]>, DwarfRegAlias<B15>;
+def S16 : AArch64Reg<16, "s16", [H16]>, DwarfRegAlias<B16>;
+def S17 : AArch64Reg<17, "s17", [H17]>, DwarfRegAlias<B17>;
+def S18 : AArch64Reg<18, "s18", [H18]>, DwarfRegAlias<B18>;
+def S19 : AArch64Reg<19, "s19", [H19]>, DwarfRegAlias<B19>;
+def S20 : AArch64Reg<20, "s20", [H20]>, DwarfRegAlias<B20>;
+def S21 : AArch64Reg<21, "s21", [H21]>, DwarfRegAlias<B21>;
+def S22 : AArch64Reg<22, "s22", [H22]>, DwarfRegAlias<B22>;
+def S23 : AArch64Reg<23, "s23", [H23]>, DwarfRegAlias<B23>;
+def S24 : AArch64Reg<24, "s24", [H24]>, DwarfRegAlias<B24>;
+def S25 : AArch64Reg<25, "s25", [H25]>, DwarfRegAlias<B25>;
+def S26 : AArch64Reg<26, "s26", [H26]>, DwarfRegAlias<B26>;
+def S27 : AArch64Reg<27, "s27", [H27]>, DwarfRegAlias<B27>;
+def S28 : AArch64Reg<28, "s28", [H28]>, DwarfRegAlias<B28>;
+def S29 : AArch64Reg<29, "s29", [H29]>, DwarfRegAlias<B29>;
+def S30 : AArch64Reg<30, "s30", [H30]>, DwarfRegAlias<B30>;
+def S31 : AArch64Reg<31, "s31", [H31]>, DwarfRegAlias<B31>;
+}
+
+let SubRegIndices = [ssub], RegAltNameIndices = [vreg, vlist1] in {
+def D0 : AArch64Reg<0, "d0", [S0], ["v0", ""]>, DwarfRegAlias<B0>;
+def D1 : AArch64Reg<1, "d1", [S1], ["v1", ""]>, DwarfRegAlias<B1>;
+def D2 : AArch64Reg<2, "d2", [S2], ["v2", ""]>, DwarfRegAlias<B2>;
+def D3 : AArch64Reg<3, "d3", [S3], ["v3", ""]>, DwarfRegAlias<B3>;
+def D4 : AArch64Reg<4, "d4", [S4], ["v4", ""]>, DwarfRegAlias<B4>;
+def D5 : AArch64Reg<5, "d5", [S5], ["v5", ""]>, DwarfRegAlias<B5>;
+def D6 : AArch64Reg<6, "d6", [S6], ["v6", ""]>, DwarfRegAlias<B6>;
+def D7 : AArch64Reg<7, "d7", [S7], ["v7", ""]>, DwarfRegAlias<B7>;
+def D8 : AArch64Reg<8, "d8", [S8], ["v8", ""]>, DwarfRegAlias<B8>;
+def D9 : AArch64Reg<9, "d9", [S9], ["v9", ""]>, DwarfRegAlias<B9>;
+def D10 : AArch64Reg<10, "d10", [S10], ["v10", ""]>, DwarfRegAlias<B10>;
+def D11 : AArch64Reg<11, "d11", [S11], ["v11", ""]>, DwarfRegAlias<B11>;
+def D12 : AArch64Reg<12, "d12", [S12], ["v12", ""]>, DwarfRegAlias<B12>;
+def D13 : AArch64Reg<13, "d13", [S13], ["v13", ""]>, DwarfRegAlias<B13>;
+def D14 : AArch64Reg<14, "d14", [S14], ["v14", ""]>, DwarfRegAlias<B14>;
+def D15 : AArch64Reg<15, "d15", [S15], ["v15", ""]>, DwarfRegAlias<B15>;
+def D16 : AArch64Reg<16, "d16", [S16], ["v16", ""]>, DwarfRegAlias<B16>;
+def D17 : AArch64Reg<17, "d17", [S17], ["v17", ""]>, DwarfRegAlias<B17>;
+def D18 : AArch64Reg<18, "d18", [S18], ["v18", ""]>, DwarfRegAlias<B18>;
+def D19 : AArch64Reg<19, "d19", [S19], ["v19", ""]>, DwarfRegAlias<B19>;
+def D20 : AArch64Reg<20, "d20", [S20], ["v20", ""]>, DwarfRegAlias<B20>;
+def D21 : AArch64Reg<21, "d21", [S21], ["v21", ""]>, DwarfRegAlias<B21>;
+def D22 : AArch64Reg<22, "d22", [S22], ["v22", ""]>, DwarfRegAlias<B22>;
+def D23 : AArch64Reg<23, "d23", [S23], ["v23", ""]>, DwarfRegAlias<B23>;
+def D24 : AArch64Reg<24, "d24", [S24], ["v24", ""]>, DwarfRegAlias<B24>;
+def D25 : AArch64Reg<25, "d25", [S25], ["v25", ""]>, DwarfRegAlias<B25>;
+def D26 : AArch64Reg<26, "d26", [S26], ["v26", ""]>, DwarfRegAlias<B26>;
+def D27 : AArch64Reg<27, "d27", [S27], ["v27", ""]>, DwarfRegAlias<B27>;
+def D28 : AArch64Reg<28, "d28", [S28], ["v28", ""]>, DwarfRegAlias<B28>;
+def D29 : AArch64Reg<29, "d29", [S29], ["v29", ""]>, DwarfRegAlias<B29>;
+def D30 : AArch64Reg<30, "d30", [S30], ["v30", ""]>, DwarfRegAlias<B30>;
+def D31 : AArch64Reg<31, "d31", [S31], ["v31", ""]>, DwarfRegAlias<B31>;
+}
+
+let SubRegIndices = [dsub], RegAltNameIndices = [vreg, vlist1] in {
+def Q0 : AArch64Reg<0, "q0", [D0], ["v0", ""]>, DwarfRegAlias<B0>;
+def Q1 : AArch64Reg<1, "q1", [D1], ["v1", ""]>, DwarfRegAlias<B1>;
+def Q2 : AArch64Reg<2, "q2", [D2], ["v2", ""]>, DwarfRegAlias<B2>;
+def Q3 : AArch64Reg<3, "q3", [D3], ["v3", ""]>, DwarfRegAlias<B3>;
+def Q4 : AArch64Reg<4, "q4", [D4], ["v4", ""]>, DwarfRegAlias<B4>;
+def Q5 : AArch64Reg<5, "q5", [D5], ["v5", ""]>, DwarfRegAlias<B5>;
+def Q6 : AArch64Reg<6, "q6", [D6], ["v6", ""]>, DwarfRegAlias<B6>;
+def Q7 : AArch64Reg<7, "q7", [D7], ["v7", ""]>, DwarfRegAlias<B7>;
+def Q8 : AArch64Reg<8, "q8", [D8], ["v8", ""]>, DwarfRegAlias<B8>;
+def Q9 : AArch64Reg<9, "q9", [D9], ["v9", ""]>, DwarfRegAlias<B9>;
+def Q10 : AArch64Reg<10, "q10", [D10], ["v10", ""]>, DwarfRegAlias<B10>;
+def Q11 : AArch64Reg<11, "q11", [D11], ["v11", ""]>, DwarfRegAlias<B11>;
+def Q12 : AArch64Reg<12, "q12", [D12], ["v12", ""]>, DwarfRegAlias<B12>;
+def Q13 : AArch64Reg<13, "q13", [D13], ["v13", ""]>, DwarfRegAlias<B13>;
+def Q14 : AArch64Reg<14, "q14", [D14], ["v14", ""]>, DwarfRegAlias<B14>;
+def Q15 : AArch64Reg<15, "q15", [D15], ["v15", ""]>, DwarfRegAlias<B15>;
+def Q16 : AArch64Reg<16, "q16", [D16], ["v16", ""]>, DwarfRegAlias<B16>;
+def Q17 : AArch64Reg<17, "q17", [D17], ["v17", ""]>, DwarfRegAlias<B17>;
+def Q18 : AArch64Reg<18, "q18", [D18], ["v18", ""]>, DwarfRegAlias<B18>;
+def Q19 : AArch64Reg<19, "q19", [D19], ["v19", ""]>, DwarfRegAlias<B19>;
+def Q20 : AArch64Reg<20, "q20", [D20], ["v20", ""]>, DwarfRegAlias<B20>;
+def Q21 : AArch64Reg<21, "q21", [D21], ["v21", ""]>, DwarfRegAlias<B21>;
+def Q22 : AArch64Reg<22, "q22", [D22], ["v22", ""]>, DwarfRegAlias<B22>;
+def Q23 : AArch64Reg<23, "q23", [D23], ["v23", ""]>, DwarfRegAlias<B23>;
+def Q24 : AArch64Reg<24, "q24", [D24], ["v24", ""]>, DwarfRegAlias<B24>;
+def Q25 : AArch64Reg<25, "q25", [D25], ["v25", ""]>, DwarfRegAlias<B25>;
+def Q26 : AArch64Reg<26, "q26", [D26], ["v26", ""]>, DwarfRegAlias<B26>;
+def Q27 : AArch64Reg<27, "q27", [D27], ["v27", ""]>, DwarfRegAlias<B27>;
+def Q28 : AArch64Reg<28, "q28", [D28], ["v28", ""]>, DwarfRegAlias<B28>;
+def Q29 : AArch64Reg<29, "q29", [D29], ["v29", ""]>, DwarfRegAlias<B29>;
+def Q30 : AArch64Reg<30, "q30", [D30], ["v30", ""]>, DwarfRegAlias<B30>;
+def Q31 : AArch64Reg<31, "q31", [D31], ["v31", ""]>, DwarfRegAlias<B31>;
+}
+
+def FPR8 : RegisterClass<"AArch64", [untyped], 8, (sequence "B%u", 0, 31)> {
+ let Size = 8;
+}
+def FPR16 : RegisterClass<"AArch64", [f16], 16, (sequence "H%u", 0, 31)> {
+ let Size = 16;
+}
+def FPR32 : RegisterClass<"AArch64", [f32, i32], 32,(sequence "S%u", 0, 31)>;
+def FPR64 : RegisterClass<"AArch64", [f64, i64, v2f32, v1f64, v8i8, v4i16, v2i32,
+ v1i64],
+ 64, (sequence "D%u", 0, 31)>;
+// We don't (yet) have an f128 legal type, so don't use that here. We
+// normalize 128-bit vectors to v2f64 for arg passing and such, so use
+// that here.
+def FPR128 : RegisterClass<"AArch64",
+ [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, f128],
+ 128, (sequence "Q%u", 0, 31)>;
+
+// The lower 16 vector registers. Some instructions can only take registers
+// in this range.
+def FPR128_lo : RegisterClass<"AArch64",
+ [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
+ 128, (trunc FPR128, 16)>;
+
+// Pairs, triples, and quads of 64-bit vector registers.
+def DSeqPairs : RegisterTuples<[dsub0, dsub1], [(rotl FPR64, 0), (rotl FPR64, 1)]>;
+def DSeqTriples : RegisterTuples<[dsub0, dsub1, dsub2],
+ [(rotl FPR64, 0), (rotl FPR64, 1),
+ (rotl FPR64, 2)]>;
+def DSeqQuads : RegisterTuples<[dsub0, dsub1, dsub2, dsub3],
+ [(rotl FPR64, 0), (rotl FPR64, 1),
+ (rotl FPR64, 2), (rotl FPR64, 3)]>;
+def DD : RegisterClass<"AArch64", [untyped], 64, (add DSeqPairs)> {
+ let Size = 128;
+}
+def DDD : RegisterClass<"AArch64", [untyped], 64, (add DSeqTriples)> {
+ let Size = 196;
+}
+def DDDD : RegisterClass<"AArch64", [untyped], 64, (add DSeqQuads)> {
+ let Size = 256;
+}
+
+// Pairs, triples, and quads of 128-bit vector registers.
+def QSeqPairs : RegisterTuples<[qsub0, qsub1], [(rotl FPR128, 0), (rotl FPR128, 1)]>;
+def QSeqTriples : RegisterTuples<[qsub0, qsub1, qsub2],
+ [(rotl FPR128, 0), (rotl FPR128, 1),
+ (rotl FPR128, 2)]>;
+def QSeqQuads : RegisterTuples<[qsub0, qsub1, qsub2, qsub3],
+ [(rotl FPR128, 0), (rotl FPR128, 1),
+ (rotl FPR128, 2), (rotl FPR128, 3)]>;
+def QQ : RegisterClass<"AArch64", [untyped], 128, (add QSeqPairs)> {
+ let Size = 256;
+}
+def QQQ : RegisterClass<"AArch64", [untyped], 128, (add QSeqTriples)> {
+ let Size = 384;
+}
+def QQQQ : RegisterClass<"AArch64", [untyped], 128, (add QSeqQuads)> {
+ let Size = 512;
+}
+
+
+// Vector operand versions of the FP registers. Alternate name printing and
+// assmebler matching.
+def VectorReg64AsmOperand : AsmOperandClass {
+ let Name = "VectorReg64";
+ let PredicateMethod = "isVectorReg";
+}
+def VectorReg128AsmOperand : AsmOperandClass {
+ let Name = "VectorReg128";
+ let PredicateMethod = "isVectorReg";
+}
+
+def V64 : RegisterOperand<FPR64, "printVRegOperand"> {
+ let ParserMatchClass = VectorReg64AsmOperand;
+}
+
+def V128 : RegisterOperand<FPR128, "printVRegOperand"> {
+ let ParserMatchClass = VectorReg128AsmOperand;
+}
+
+def VectorRegLoAsmOperand : AsmOperandClass { let Name = "VectorRegLo"; }
+def V128_lo : RegisterOperand<FPR128_lo, "printVRegOperand"> {
+ let ParserMatchClass = VectorRegLoAsmOperand;
+}
+
+class TypedVecListAsmOperand<int count, int regsize, int lanes, string kind>
+ : AsmOperandClass {
+ let Name = "TypedVectorList" # count # "_" # lanes # kind;
+
+ let PredicateMethod
+ = "isTypedVectorList<" # count # ", " # lanes # ", '" # kind # "'>";
+ let RenderMethod = "addVectorList" # regsize # "Operands<" # count # ">";
+}
+
+class TypedVecListRegOperand<RegisterClass Reg, int lanes, string kind>
+ : RegisterOperand<Reg, "printTypedVectorList<" # lanes # ", '"
+ # kind # "'>">;
+
+multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
+ // With implicit types (probably on instruction instead). E.g. { v0, v1 }
+ def _64AsmOperand : AsmOperandClass {
+ let Name = NAME # "64";
+ let PredicateMethod = "isImplicitlyTypedVectorList<" # count # ">";
+ let RenderMethod = "addVectorList64Operands<" # count # ">";
+ }
+
+ def "64" : RegisterOperand<Reg64, "printImplicitlyTypedVectorList"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_64AsmOperand");
+ }
+
+ def _128AsmOperand : AsmOperandClass {
+ let Name = NAME # "128";
+ let PredicateMethod = "isImplicitlyTypedVectorList<" # count # ">";
+ let RenderMethod = "addVectorList128Operands<" # count # ">";
+ }
+
+ def "128" : RegisterOperand<Reg128, "printImplicitlyTypedVectorList"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_128AsmOperand");
+ }
+
+ // 64-bit register lists with explicit type.
+
+ // { v0.8b, v1.8b }
+ def _8bAsmOperand : TypedVecListAsmOperand<count, 64, 8, "b">;
+ def "8b" : TypedVecListRegOperand<Reg64, 8, "b"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_8bAsmOperand");
+ }
+
+ // { v0.4h, v1.4h }
+ def _4hAsmOperand : TypedVecListAsmOperand<count, 64, 4, "h">;
+ def "4h" : TypedVecListRegOperand<Reg64, 4, "h"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_4hAsmOperand");
+ }
+
+ // { v0.2s, v1.2s }
+ def _2sAsmOperand : TypedVecListAsmOperand<count, 64, 2, "s">;
+ def "2s" : TypedVecListRegOperand<Reg64, 2, "s"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_2sAsmOperand");
+ }
+
+ // { v0.1d, v1.1d }
+ def _1dAsmOperand : TypedVecListAsmOperand<count, 64, 1, "d">;
+ def "1d" : TypedVecListRegOperand<Reg64, 1, "d"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_1dAsmOperand");
+ }
+
+ // 128-bit register lists with explicit type
+
+ // { v0.16b, v1.16b }
+ def _16bAsmOperand : TypedVecListAsmOperand<count, 128, 16, "b">;
+ def "16b" : TypedVecListRegOperand<Reg128, 16, "b"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_16bAsmOperand");
+ }
+
+ // { v0.8h, v1.8h }
+ def _8hAsmOperand : TypedVecListAsmOperand<count, 128, 8, "h">;
+ def "8h" : TypedVecListRegOperand<Reg128, 8, "h"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_8hAsmOperand");
+ }
+
+ // { v0.4s, v1.4s }
+ def _4sAsmOperand : TypedVecListAsmOperand<count, 128, 4, "s">;
+ def "4s" : TypedVecListRegOperand<Reg128, 4, "s"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_4sAsmOperand");
+ }
+
+ // { v0.2d, v1.2d }
+ def _2dAsmOperand : TypedVecListAsmOperand<count, 128, 2, "d">;
+ def "2d" : TypedVecListRegOperand<Reg128, 2, "d"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_2dAsmOperand");
+ }
+
+ // { v0.b, v1.b }
+ def _bAsmOperand : TypedVecListAsmOperand<count, 128, 0, "b">;
+ def "b" : TypedVecListRegOperand<Reg128, 0, "b"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_bAsmOperand");
+ }
+
+ // { v0.h, v1.h }
+ def _hAsmOperand : TypedVecListAsmOperand<count, 128, 0, "h">;
+ def "h" : TypedVecListRegOperand<Reg128, 0, "h"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_hAsmOperand");
+ }
+
+ // { v0.s, v1.s }
+ def _sAsmOperand : TypedVecListAsmOperand<count, 128, 0, "s">;
+ def "s" : TypedVecListRegOperand<Reg128, 0, "s"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_sAsmOperand");
+ }
+
+ // { v0.d, v1.d }
+ def _dAsmOperand : TypedVecListAsmOperand<count, 128, 0, "d">;
+ def "d" : TypedVecListRegOperand<Reg128, 0, "d"> {
+ let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_dAsmOperand");
+ }
+
+
+}
+
+defm VecListOne : VectorList<1, FPR64, FPR128>;
+defm VecListTwo : VectorList<2, DD, QQ>;
+defm VecListThree : VectorList<3, DDD, QQQ>;
+defm VecListFour : VectorList<4, DDDD, QQQQ>;
+
+
+// Register operand versions of the scalar FP registers.
+def FPR16Op : RegisterOperand<FPR16, "printOperand">;
+def FPR32Op : RegisterOperand<FPR32, "printOperand">;
+def FPR64Op : RegisterOperand<FPR64, "printOperand">;
+def FPR128Op : RegisterOperand<FPR128, "printOperand">;
Copied: llvm/trunk/lib/Target/AArch64/AArch64SchedA53.td (from r209576, llvm/trunk/lib/Target/ARM64/ARM64SchedA53.td)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SchedA53.td?p2=llvm/trunk/lib/Target/AArch64/AArch64SchedA53.td&p1=llvm/trunk/lib/Target/ARM64/ARM64SchedA53.td&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64SchedA53.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SchedA53.td Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//=- ARM64SchedA53.td - ARM Cortex-A53 Scheduling Definitions -*- tablegen -*-=//
+//==- AArch64SchedA53.td - Cortex-A53 Scheduling Definitions -*- tablegen -*-=//
//
// The LLVM Compiler Infrastructure
//
Copied: llvm/trunk/lib/Target/AArch64/AArch64SchedCyclone.td (from r209576, llvm/trunk/lib/Target/ARM64/ARM64SchedCyclone.td)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SchedCyclone.td?p2=llvm/trunk/lib/Target/AArch64/AArch64SchedCyclone.td&p1=llvm/trunk/lib/Target/ARM64/ARM64SchedCyclone.td&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64SchedCyclone.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SchedCyclone.td Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//=- ARMSchedCyclone.td - ARM64 Cyclone Scheduling Defs ------*- tablegen -*-=//
+//=- ARMSchedCyclone.td - AArch64 Cyclone Scheduling Defs ----*- tablegen -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the machine model for ARM64 Cyclone to support
+// This file defines the machine model for AArch64 Cyclone to support
// instruction scheduling and other instruction cost heuristics.
//
//===----------------------------------------------------------------------===//
@@ -239,13 +239,13 @@ def : WriteRes<WriteST, [CyUnitLS]> {
def CyWriteLDIdx : SchedWriteVariant<[
SchedVar<ScaledIdxPred, [WriteIS, WriteLD]>, // Load from scaled register.
SchedVar<NoSchedPred, [WriteLD]>]>; // Load from register offset.
-def : SchedAlias<WriteLDIdx, CyWriteLDIdx>; // Map ARM64->Cyclone type.
+def : SchedAlias<WriteLDIdx, CyWriteLDIdx>; // Map AArch64->Cyclone type.
// EXAMPLE: STR Xn, Xm [, lsl 3]
def CyWriteSTIdx : SchedWriteVariant<[
SchedVar<ScaledIdxPred, [WriteIS, WriteST]>, // Store to scaled register.
SchedVar<NoSchedPred, [WriteST]>]>; // Store to register offset.
-def : SchedAlias<WriteSTIdx, CyWriteSTIdx>; // Map ARM64->Cyclone type.
+def : SchedAlias<WriteSTIdx, CyWriteSTIdx>; // Map AArch64->Cyclone type.
// Read the (unshifted) base register Xn in the second micro-op one cycle later.
// EXAMPLE: LDR Xn, Xm [, lsl 3]
@@ -253,7 +253,7 @@ def ReadBaseRS : SchedReadAdvance<1>;
def CyReadAdrBase : SchedReadVariant<[
SchedVar<ScaledIdxPred, [ReadBaseRS]>, // Read base reg after shifting offset.
SchedVar<NoSchedPred, [ReadDefault]>]>; // Read base reg with no shift.
-def : SchedAlias<ReadAdrBase, CyReadAdrBase>; // Map ARM64->Cyclone type.
+def : SchedAlias<ReadAdrBase, CyReadAdrBase>; // Map AArch64->Cyclone type.
//---
// 7.8.9,7.8.11. Load/Store, paired
Copied: llvm/trunk/lib/Target/AArch64/AArch64Schedule.td (from r209576, llvm/trunk/lib/Target/ARM64/ARM64Schedule.td)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Schedule.td?p2=llvm/trunk/lib/Target/AArch64/AArch64Schedule.td&p1=llvm/trunk/lib/Target/ARM64/ARM64Schedule.td&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64Schedule.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64Schedule.td Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARMSchedule.td - ARM Scheduling Definitions --------*- tablegen -*-===//
+//==-- AArch64Schedule.td - AArch64 Scheduling Definitions -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,12 +11,12 @@
// const MachineInstr *MI and const TargetSchedModel *SchedModel
// are defined by default.
def : PredicateProlog<[{
- const ARM64InstrInfo *TII =
- static_cast<const ARM64InstrInfo*>(SchedModel->getInstrInfo());
+ const AArch64InstrInfo *TII =
+ static_cast<const AArch64InstrInfo*>(SchedModel->getInstrInfo());
(void)TII;
}]>;
-// ARM64 Scheduler Definitions
+// AArch64 Scheduler Definitions
def WriteImm : SchedWrite; // MOVN, MOVZ
// TODO: Provide variants for MOV32/64imm Pseudos that dynamically
Copied: llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64SelectionDAGInfo.cpp - ARM64 SelectionDAG Info ---------------===//
+//===-- AArch64SelectionDAGInfo.cpp - AArch64 SelectionDAG Info -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,22 +7,22 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ARM64SelectionDAGInfo class.
+// This file implements the AArch64SelectionDAGInfo class.
//
//===----------------------------------------------------------------------===//
-#include "ARM64TargetMachine.h"
+#include "AArch64TargetMachine.h"
using namespace llvm;
-#define DEBUG_TYPE "arm64-selectiondag-info"
+#define DEBUG_TYPE "aarch64-selectiondag-info"
-ARM64SelectionDAGInfo::ARM64SelectionDAGInfo(const TargetMachine &TM)
+AArch64SelectionDAGInfo::AArch64SelectionDAGInfo(const TargetMachine &TM)
: TargetSelectionDAGInfo(TM),
- Subtarget(&TM.getSubtarget<ARM64Subtarget>()) {}
+ Subtarget(&TM.getSubtarget<AArch64Subtarget>()) {}
-ARM64SelectionDAGInfo::~ARM64SelectionDAGInfo() {}
+AArch64SelectionDAGInfo::~AArch64SelectionDAGInfo() {}
-SDValue ARM64SelectionDAGInfo::EmitTargetCodeForMemset(
+SDValue AArch64SelectionDAGInfo::EmitTargetCodeForMemset(
SelectionDAG &DAG, SDLoc dl, SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, unsigned Align, bool isVolatile,
MachinePointerInfo DstPtrInfo) const {
@@ -34,8 +34,9 @@ SDValue ARM64SelectionDAGInfo::EmitTarge
// For small size (< 256), it is not beneficial to use bzero
// instead of memset.
if (bzeroEntry && (!SizeValue || SizeValue->getZExtValue() > 256)) {
- const ARM64TargetLowering &TLI = *static_cast<const ARM64TargetLowering *>(
- DAG.getTarget().getTargetLowering());
+ const AArch64TargetLowering &TLI =
+ *static_cast<const AArch64TargetLowering *>(
+ DAG.getTarget().getTargetLowering());
EVT IntPtr = TLI.getPointerTy();
Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
Copied: llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.h?p2=llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.h&p1=llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64SelectionDAGInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SelectionDAGInfo.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64SelectionDAGInfo.h - ARM64 SelectionDAG Info -------*- C++ -*-===//
+//===-- AArch64SelectionDAGInfo.h - AArch64 SelectionDAG Info ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,25 +7,25 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the ARM64 subclass for TargetSelectionDAGInfo.
+// This file defines the AArch64 subclass for TargetSelectionDAGInfo.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64SELECTIONDAGINFO_H
-#define ARM64SELECTIONDAGINFO_H
+#ifndef AArch64SELECTIONDAGINFO_H
+#define AArch64SELECTIONDAGINFO_H
#include "llvm/Target/TargetSelectionDAGInfo.h"
namespace llvm {
-class ARM64SelectionDAGInfo : public TargetSelectionDAGInfo {
+class AArch64SelectionDAGInfo : public TargetSelectionDAGInfo {
/// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
/// make the right decision when generating code for different targets.
- const ARM64Subtarget *Subtarget;
+ const AArch64Subtarget *Subtarget;
public:
- explicit ARM64SelectionDAGInfo(const TargetMachine &TM);
- ~ARM64SelectionDAGInfo();
+ explicit AArch64SelectionDAGInfo(const TargetMachine &TM);
+ ~AArch64SelectionDAGInfo();
SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
SDValue Dst, SDValue Src, SDValue Size,
Copied: llvm/trunk/lib/Target/AArch64/AArch64StorePairSuppress.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64StorePairSuppress.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64StorePairSuppress.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64StorePairSuppress.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64StorePairSuppress.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64StorePairSuppress.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64StorePairSuppress.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===---- ARM64StorePairSuppress.cpp --- Suppress store pair formation ----===//
+//===--- AArch64StorePairSuppress.cpp --- Suppress store pair formation ---===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,7 +11,7 @@
// store pairs. Later we may do the same for floating point loads.
// ===---------------------------------------------------------------------===//
-#include "ARM64InstrInfo.h"
+#include "AArch64InstrInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -23,11 +23,11 @@
using namespace llvm;
-#define DEBUG_TYPE "arm64-stp-suppress"
+#define DEBUG_TYPE "aarch64-stp-suppress"
namespace {
-class ARM64StorePairSuppress : public MachineFunctionPass {
- const ARM64InstrInfo *TII;
+class AArch64StorePairSuppress : public MachineFunctionPass {
+ const AArch64InstrInfo *TII;
const TargetRegisterInfo *TRI;
const MachineRegisterInfo *MRI;
MachineFunction *MF;
@@ -37,10 +37,10 @@ class ARM64StorePairSuppress : public Ma
public:
static char ID;
- ARM64StorePairSuppress() : MachineFunctionPass(ID) {}
+ AArch64StorePairSuppress() : MachineFunctionPass(ID) {}
virtual const char *getPassName() const override {
- return "ARM64 Store Pair Suppression";
+ return "AArch64 Store Pair Suppression";
}
bool runOnMachineFunction(MachineFunction &F) override;
@@ -57,11 +57,11 @@ private:
MachineFunctionPass::getAnalysisUsage(AU);
}
};
-char ARM64StorePairSuppress::ID = 0;
+char AArch64StorePairSuppress::ID = 0;
} // anonymous
-FunctionPass *llvm::createARM64StorePairSuppressPass() {
- return new ARM64StorePairSuppress();
+FunctionPass *llvm::createAArch64StorePairSuppressPass() {
+ return new AArch64StorePairSuppress();
}
/// Return true if an STP can be added to this block without increasing the
@@ -70,7 +70,7 @@ FunctionPass *llvm::createARM64StorePair
/// critical path. If the critical path is longer than the resource height, the
/// extra vector ops can limit physreg renaming. Otherwise, it could simply
/// oversaturate the vector units.
-bool ARM64StorePairSuppress::shouldAddSTPToBlock(const MachineBasicBlock *BB) {
+bool AArch64StorePairSuppress::shouldAddSTPToBlock(const MachineBasicBlock *BB) {
if (!MinInstr)
MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
@@ -79,7 +79,7 @@ bool ARM64StorePairSuppress::shouldAddST
// Get the machine model's scheduling class for STPQi.
// Bypass TargetSchedule's SchedClass resolution since we only have an opcode.
- unsigned SCIdx = TII->get(ARM64::STPDi).getSchedClass();
+ unsigned SCIdx = TII->get(AArch64::STPDi).getSchedClass();
const MCSchedClassDesc *SCDesc =
SchedModel.getMCSchedModel()->getSchedClassDesc(SCIdx);
@@ -103,22 +103,22 @@ bool ARM64StorePairSuppress::shouldAddST
/// tell us if it's profitable with no cpu knowledge here.
///
/// FIXME: We plan to develop a decent Target abstraction for simple loads and
-/// stores. Until then use a nasty switch similar to ARM64LoadStoreOptimizer.
-bool ARM64StorePairSuppress::isNarrowFPStore(const MachineInstr &MI) {
+/// stores. Until then use a nasty switch similar to AArch64LoadStoreOptimizer.
+bool AArch64StorePairSuppress::isNarrowFPStore(const MachineInstr &MI) {
switch (MI.getOpcode()) {
default:
return false;
- case ARM64::STRSui:
- case ARM64::STRDui:
- case ARM64::STURSi:
- case ARM64::STURDi:
+ case AArch64::STRSui:
+ case AArch64::STRDui:
+ case AArch64::STURSi:
+ case AArch64::STURDi:
return true;
}
}
-bool ARM64StorePairSuppress::runOnMachineFunction(MachineFunction &mf) {
+bool AArch64StorePairSuppress::runOnMachineFunction(MachineFunction &mf) {
MF = &mf;
- TII = static_cast<const ARM64InstrInfo *>(MF->getTarget().getInstrInfo());
+ TII = static_cast<const AArch64InstrInfo *>(MF->getTarget().getInstrInfo());
TRI = MF->getTarget().getRegisterInfo();
MRI = &MF->getRegInfo();
const TargetSubtargetInfo &ST =
Copied: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64Subtarget.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64Subtarget.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64Subtarget.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64Subtarget.cpp - ARM64 Subtarget Information --------*- C++ -*-===//
+//===-- AArch64Subtarget.cpp - AArch64 Subtarget Information ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ARM64 specific subclass of TargetSubtarget.
+// This file implements the AArch64 specific subclass of TargetSubtarget.
//
//===----------------------------------------------------------------------===//
-#include "ARM64InstrInfo.h"
-#include "ARM64Subtarget.h"
+#include "AArch64InstrInfo.h"
+#include "AArch64Subtarget.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/IR/GlobalValue.h"
@@ -20,22 +20,23 @@
using namespace llvm;
-#define DEBUG_TYPE "arm64-subtarget"
+#define DEBUG_TYPE "aarch64-subtarget"
#define GET_SUBTARGETINFO_CTOR
#define GET_SUBTARGETINFO_TARGET_DESC
-#include "ARM64GenSubtargetInfo.inc"
+#include "AArch64GenSubtargetInfo.inc"
static cl::opt<bool>
-EnableEarlyIfConvert("arm64-early-ifcvt", cl::desc("Enable the early if "
+EnableEarlyIfConvert("aarch64-early-ifcvt", cl::desc("Enable the early if "
"converter pass"), cl::init(true), cl::Hidden);
-ARM64Subtarget::ARM64Subtarget(const std::string &TT, const std::string &CPU,
- const std::string &FS, bool LittleEndian)
- : ARM64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
+AArch64Subtarget::AArch64Subtarget(const std::string &TT,
+ const std::string &CPU,
+ const std::string &FS, bool LittleEndian)
+ : AArch64GenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others),
HasFPARMv8(false), HasNEON(false), HasCrypto(false), HasCRC(false),
- HasZeroCycleRegMove(false), HasZeroCycleZeroing(false),
- CPUString(CPU), TargetTriple(TT), IsLittleEndian(LittleEndian) {
+ HasZeroCycleRegMove(false), HasZeroCycleZeroing(false), CPUString(CPU),
+ TargetTriple(TT), IsLittleEndian(LittleEndian) {
// Determine default and user-specified characteristics
if (CPUString.empty())
@@ -47,7 +48,7 @@ ARM64Subtarget::ARM64Subtarget(const std
/// ClassifyGlobalReference - Find the target operand flags that describe
/// how a global value should be referenced for the current subtarget.
unsigned char
-ARM64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
+AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
const TargetMachine &TM) const {
// Determine whether this is a reference to a definition or a declaration.
@@ -60,13 +61,13 @@ ARM64Subtarget::ClassifyGlobalReference(
// MachO large model always goes via a GOT, simply to get a single 8-byte
// absolute relocation on all global addresses.
if (TM.getCodeModel() == CodeModel::Large && isTargetMachO())
- return ARM64II::MO_GOT;
+ return AArch64II::MO_GOT;
// The small code mode's direct accesses use ADRP, which cannot necessarily
// produce the value 0 (if the code is above 4GB). Therefore they must use the
// GOT.
if (TM.getCodeModel() == CodeModel::Small && GV->isWeakForLinker() && isDecl)
- return ARM64II::MO_GOT;
+ return AArch64II::MO_GOT;
// If symbol visibility is hidden, the extra load is not needed if
// the symbol is definitely defined in the current translation unit.
@@ -78,14 +79,14 @@ ARM64Subtarget::ClassifyGlobalReference(
// defined could end up in unexpected places. Use a GOT.
if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) {
if (isTargetMachO())
- return (isDecl || GV->isWeakForLinker()) ? ARM64II::MO_GOT
- : ARM64II::MO_NO_FLAG;
+ return (isDecl || GV->isWeakForLinker()) ? AArch64II::MO_GOT
+ : AArch64II::MO_NO_FLAG;
else
// No need to go through the GOT for local symbols on ELF.
- return GV->hasLocalLinkage() ? ARM64II::MO_NO_FLAG : ARM64II::MO_GOT;
+ return GV->hasLocalLinkage() ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT;
}
- return ARM64II::MO_NO_FLAG;
+ return AArch64II::MO_NO_FLAG;
}
/// This function returns the name of a function which has an interface
@@ -93,7 +94,7 @@ ARM64Subtarget::ClassifyGlobalReference(
/// the current subtarget and it is considered prefereable over
/// memset with zero passed as the second argument. Otherwise it
/// returns null.
-const char *ARM64Subtarget::getBZeroEntry() const {
+const char *AArch64Subtarget::getBZeroEntry() const {
// Prefer bzero on Darwin only.
if(isTargetDarwin())
return "bzero";
@@ -101,7 +102,7 @@ const char *ARM64Subtarget::getBZeroEntr
return nullptr;
}
-void ARM64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
+void AArch64Subtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
MachineInstr *begin, MachineInstr *end,
unsigned NumRegionInstrs) const {
// LNT run (at least on Cyclone) showed reasonably significant gains for
@@ -110,6 +111,6 @@ void ARM64Subtarget::overrideSchedPolicy
Policy.OnlyBottomUp = false;
}
-bool ARM64Subtarget::enableEarlyIfConversion() const {
+bool AArch64Subtarget::enableEarlyIfConversion() const {
return EnableEarlyIfConvert;
}
Copied: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64Subtarget.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?p2=llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h&p1=llvm/trunk/lib/Target/ARM64/ARM64Subtarget.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64Subtarget.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//=====---- ARM64Subtarget.h - Define Subtarget for the ARM64 -*- C++ -*--====//
+//===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,25 +7,25 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares the ARM64 specific subclass of TargetSubtarget.
+// This file declares the AArch64 specific subclass of TargetSubtarget.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64SUBTARGET_H
-#define ARM64SUBTARGET_H
+#ifndef AArch64SUBTARGET_H
+#define AArch64SUBTARGET_H
#include "llvm/Target/TargetSubtargetInfo.h"
-#include "ARM64RegisterInfo.h"
+#include "AArch64RegisterInfo.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
-#include "ARM64GenSubtargetInfo.inc"
+#include "AArch64GenSubtargetInfo.inc"
namespace llvm {
class GlobalValue;
class StringRef;
-class ARM64Subtarget : public ARM64GenSubtargetInfo {
+class AArch64Subtarget : public AArch64GenSubtargetInfo {
protected:
enum ARMProcFamilyEnum {Others, CortexA53, CortexA57, Cyclone};
@@ -55,7 +55,7 @@ protected:
public:
/// This constructor initializes the data members to match that
/// of the specified triple.
- ARM64Subtarget(const std::string &TT, const std::string &CPU,
+ AArch64Subtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, bool LittleEndian);
bool enableMachineScheduler() const override { return true; }
@@ -107,4 +107,4 @@ public:
};
} // End llvm namespace
-#endif // ARM64SUBTARGET_H
+#endif // AArch64SUBTARGET_H
Copied: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64TargetMachine.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64TargetMachine.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64TargetMachine.cpp - Define TargetMachine for ARM64 -----------===//
+//===-- AArch64TargetMachine.cpp - Define TargetMachine for AArch64 -------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64.h"
-#include "ARM64TargetMachine.h"
+#include "AArch64.h"
+#include "AArch64TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
@@ -21,28 +21,28 @@
using namespace llvm;
static cl::opt<bool>
-EnableCCMP("arm64-ccmp", cl::desc("Enable the CCMP formation pass"),
+EnableCCMP("aarch64-ccmp", cl::desc("Enable the CCMP formation pass"),
cl::init(true), cl::Hidden);
static cl::opt<bool>
-EnableStPairSuppress("arm64-stp-suppress", cl::desc("Suppress STP for ARM64"),
+EnableStPairSuppress("aarch64-stp-suppress", cl::desc("Suppress STP for AArch64"),
cl::init(true), cl::Hidden);
static cl::opt<bool>
-EnableAdvSIMDScalar("arm64-simd-scalar", cl::desc("Enable use of AdvSIMD scalar"
+EnableAdvSIMDScalar("aarch64-simd-scalar", cl::desc("Enable use of AdvSIMD scalar"
" integer instructions"), cl::init(false), cl::Hidden);
static cl::opt<bool>
-EnablePromoteConstant("arm64-promote-const", cl::desc("Enable the promote "
+EnablePromoteConstant("aarch64-promote-const", cl::desc("Enable the promote "
"constant pass"), cl::init(true), cl::Hidden);
static cl::opt<bool>
-EnableCollectLOH("arm64-collect-loh", cl::desc("Enable the pass that emits the"
+EnableCollectLOH("aarch64-collect-loh", cl::desc("Enable the pass that emits the"
" linker optimization hints (LOH)"), cl::init(true),
cl::Hidden);
static cl::opt<bool>
-EnableDeadRegisterElimination("arm64-dead-def-elimination", cl::Hidden,
+EnableDeadRegisterElimination("aarch64-dead-def-elimination", cl::Hidden,
cl::desc("Enable the pass that removes dead"
" definitons and replaces stores to"
" them with stores to the zero"
@@ -50,67 +50,67 @@ EnableDeadRegisterElimination("arm64-dea
cl::init(true));
static cl::opt<bool>
-EnableLoadStoreOpt("arm64-load-store-opt", cl::desc("Enable the load/store pair"
+EnableLoadStoreOpt("aarch64-load-store-opt", cl::desc("Enable the load/store pair"
" optimization pass"), cl::init(true), cl::Hidden);
-extern "C" void LLVMInitializeARM64Target() {
+extern "C" void LLVMInitializeAArch64Target() {
// Register the target.
- RegisterTargetMachine<ARM64leTargetMachine> X(TheARM64leTarget);
- RegisterTargetMachine<ARM64beTargetMachine> Y(TheARM64beTarget);
+ RegisterTargetMachine<AArch64leTargetMachine> X(TheAArch64leTarget);
+ RegisterTargetMachine<AArch64beTargetMachine> Y(TheAArch64beTarget);
- RegisterTargetMachine<ARM64leTargetMachine> Z(TheAArch64leTarget);
- RegisterTargetMachine<ARM64beTargetMachine> W(TheAArch64beTarget);
+ RegisterTargetMachine<AArch64leTargetMachine> Z(TheARM64leTarget);
+ RegisterTargetMachine<AArch64beTargetMachine> W(TheARM64beTarget);
}
-/// TargetMachine ctor - Create an ARM64 architecture model.
+/// TargetMachine ctor - Create an AArch64 architecture model.
///
-ARM64TargetMachine::ARM64TargetMachine(const Target &T, StringRef TT,
- StringRef CPU, StringRef FS,
- const TargetOptions &Options,
- Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL,
- bool LittleEndian)
+AArch64TargetMachine::AArch64TargetMachine(const Target &T, StringRef TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL,
+ bool LittleEndian)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, LittleEndian),
- // This nested ternary is horrible, but DL needs to be properly initialized
+ // This nested ternary is horrible, but DL needs to be properly
+ // initialized
// before TLInfo is constructed.
- DL(Subtarget.isTargetMachO() ?
- "e-m:o-i64:64-i128:128-n32:64-S128" :
- (LittleEndian ?
- "e-m:e-i64:64-i128:128-n32:64-S128" :
- "E-m:e-i64:64-i128:128-n32:64-S128")),
+ DL(Subtarget.isTargetMachO()
+ ? "e-m:o-i64:64-i128:128-n32:64-S128"
+ : (LittleEndian ? "e-m:e-i64:64-i128:128-n32:64-S128"
+ : "E-m:e-i64:64-i128:128-n32:64-S128")),
InstrInfo(Subtarget), TLInfo(*this), FrameLowering(*this, Subtarget),
TSInfo(*this) {
initAsmInfo();
}
-void ARM64leTargetMachine::anchor() { }
+void AArch64leTargetMachine::anchor() { }
-ARM64leTargetMachine::
-ARM64leTargetMachine(const Target &T, StringRef TT,
+AArch64leTargetMachine::
+AArch64leTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
- : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
+ : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
-void ARM64beTargetMachine::anchor() { }
+void AArch64beTargetMachine::anchor() { }
-ARM64beTargetMachine::
-ARM64beTargetMachine(const Target &T, StringRef TT,
+AArch64beTargetMachine::
+AArch64beTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
- : ARM64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
+ : AArch64TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
namespace {
-/// ARM64 Code Generator Pass Configuration Options.
-class ARM64PassConfig : public TargetPassConfig {
+/// AArch64 Code Generator Pass Configuration Options.
+class AArch64PassConfig : public TargetPassConfig {
public:
- ARM64PassConfig(ARM64TargetMachine *TM, PassManagerBase &PM)
+ AArch64PassConfig(AArch64TargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
- ARM64TargetMachine &getARM64TargetMachine() const {
- return getTM<ARM64TargetMachine>();
+ AArch64TargetMachine &getAArch64TargetMachine() const {
+ return getTM<AArch64TargetMachine>();
}
bool addPreISel() override;
@@ -123,28 +123,28 @@ public:
};
} // namespace
-void ARM64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
- // Add first the target-independent BasicTTI pass, then our ARM64 pass. This
- // allows the ARM64 pass to delegate to the target independent layer when
+void AArch64TargetMachine::addAnalysisPasses(PassManagerBase &PM) {
+ // Add first the target-independent BasicTTI pass, then our AArch64 pass. This
+ // allows the AArch64 pass to delegate to the target independent layer when
// appropriate.
PM.add(createBasicTargetTransformInfoPass(this));
- PM.add(createARM64TargetTransformInfoPass(this));
+ PM.add(createAArch64TargetTransformInfoPass(this));
}
-TargetPassConfig *ARM64TargetMachine::createPassConfig(PassManagerBase &PM) {
- return new ARM64PassConfig(this, PM);
+TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new AArch64PassConfig(this, PM);
}
// Pass Pipeline Configuration
-bool ARM64PassConfig::addPreISel() {
+bool AArch64PassConfig::addPreISel() {
// Run promote constant before global merge, so that the promoted constants
// get a chance to be merged
if (TM->getOptLevel() != CodeGenOpt::None && EnablePromoteConstant)
- addPass(createARM64PromoteConstantPass());
+ addPass(createAArch64PromoteConstantPass());
if (TM->getOptLevel() != CodeGenOpt::None)
addPass(createGlobalMergePass(TM));
if (TM->getOptLevel() != CodeGenOpt::None)
- addPass(createARM64AddressTypePromotionPass());
+ addPass(createAArch64AddressTypePromotionPass());
// Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
// ourselves.
@@ -153,56 +153,56 @@ bool ARM64PassConfig::addPreISel() {
return false;
}
-bool ARM64PassConfig::addInstSelector() {
- addPass(createARM64ISelDag(getARM64TargetMachine(), getOptLevel()));
+bool AArch64PassConfig::addInstSelector() {
+ addPass(createAArch64ISelDag(getAArch64TargetMachine(), getOptLevel()));
// For ELF, cleanup any local-dynamic TLS accesses (i.e. combine as many
// references to _TLS_MODULE_BASE_ as possible.
- if (TM->getSubtarget<ARM64Subtarget>().isTargetELF() &&
+ if (TM->getSubtarget<AArch64Subtarget>().isTargetELF() &&
getOptLevel() != CodeGenOpt::None)
- addPass(createARM64CleanupLocalDynamicTLSPass());
+ addPass(createAArch64CleanupLocalDynamicTLSPass());
return false;
}
-bool ARM64PassConfig::addILPOpts() {
+bool AArch64PassConfig::addILPOpts() {
if (EnableCCMP)
- addPass(createARM64ConditionalCompares());
+ addPass(createAArch64ConditionalCompares());
addPass(&EarlyIfConverterID);
if (EnableStPairSuppress)
- addPass(createARM64StorePairSuppressPass());
+ addPass(createAArch64StorePairSuppressPass());
return true;
}
-bool ARM64PassConfig::addPreRegAlloc() {
+bool AArch64PassConfig::addPreRegAlloc() {
// Use AdvSIMD scalar instructions whenever profitable.
if (TM->getOptLevel() != CodeGenOpt::None && EnableAdvSIMDScalar)
- addPass(createARM64AdvSIMDScalar());
+ addPass(createAArch64AdvSIMDScalar());
return true;
}
-bool ARM64PassConfig::addPostRegAlloc() {
+bool AArch64PassConfig::addPostRegAlloc() {
// Change dead register definitions to refer to the zero register.
if (TM->getOptLevel() != CodeGenOpt::None && EnableDeadRegisterElimination)
- addPass(createARM64DeadRegisterDefinitions());
+ addPass(createAArch64DeadRegisterDefinitions());
return true;
}
-bool ARM64PassConfig::addPreSched2() {
+bool AArch64PassConfig::addPreSched2() {
// Expand some pseudo instructions to allow proper scheduling.
- addPass(createARM64ExpandPseudoPass());
+ addPass(createAArch64ExpandPseudoPass());
// Use load/store pair instructions when possible.
if (TM->getOptLevel() != CodeGenOpt::None && EnableLoadStoreOpt)
- addPass(createARM64LoadStoreOptimizationPass());
+ addPass(createAArch64LoadStoreOptimizationPass());
return true;
}
-bool ARM64PassConfig::addPreEmitPass() {
+bool AArch64PassConfig::addPreEmitPass() {
// Relax conditional branch instructions if they're otherwise out of
// range of their destination.
- addPass(createARM64BranchRelaxation());
+ addPass(createAArch64BranchRelaxation());
if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH &&
- TM->getSubtarget<ARM64Subtarget>().isTargetMachO())
- addPass(createARM64CollectLOHPass());
+ TM->getSubtarget<AArch64Subtarget>().isTargetMachO())
+ addPass(createAArch64CollectLOHPass());
return true;
}
Added: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h (added)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h Sat May 24 07:50:23 2014
@@ -0,0 +1,94 @@
+//==-- AArch64TargetMachine.h - Define TargetMachine for AArch64 -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the AArch64 specific subclass of TargetMachine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef AArch64TARGETMACHINE_H
+#define AArch64TARGETMACHINE_H
+
+#include "AArch64InstrInfo.h"
+#include "AArch64ISelLowering.h"
+#include "AArch64Subtarget.h"
+#include "AArch64FrameLowering.h"
+#include "AArch64SelectionDAGInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+
+class AArch64TargetMachine : public LLVMTargetMachine {
+protected:
+ AArch64Subtarget Subtarget;
+
+private:
+ const DataLayout DL;
+ AArch64InstrInfo InstrInfo;
+ AArch64TargetLowering TLInfo;
+ AArch64FrameLowering FrameLowering;
+ AArch64SelectionDAGInfo TSInfo;
+
+public:
+ AArch64TargetMachine(const Target &T, StringRef TT, StringRef CPU,
+ StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL, bool IsLittleEndian);
+
+ const AArch64Subtarget *getSubtargetImpl() const override {
+ return &Subtarget;
+ }
+ const AArch64TargetLowering *getTargetLowering() const override {
+ return &TLInfo;
+ }
+ const DataLayout *getDataLayout() const override { return &DL; }
+ const AArch64FrameLowering *getFrameLowering() const override {
+ return &FrameLowering;
+ }
+ const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
+ const AArch64RegisterInfo *getRegisterInfo() const override {
+ return &InstrInfo.getRegisterInfo();
+ }
+ const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
+ return &TSInfo;
+ }
+
+ // Pass Pipeline Configuration
+ TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+
+ /// \brief Register AArch64 analysis passes with a pass manager.
+ void addAnalysisPasses(PassManagerBase &PM) override;
+};
+
+// AArch64leTargetMachine - AArch64 little endian target machine.
+//
+class AArch64leTargetMachine : public AArch64TargetMachine {
+ virtual void anchor();
+public:
+ AArch64leTargetMachine(const Target &T, StringRef TT, StringRef CPU,
+ StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL);
+};
+
+// AArch64beTargetMachine - AArch64 big endian target machine.
+//
+class AArch64beTargetMachine : public AArch64TargetMachine {
+ virtual void anchor();
+public:
+ AArch64beTargetMachine(const Target &T, StringRef TT, StringRef CPU,
+ StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL);
+};
+
+} // end namespace llvm
+
+#endif
Copied: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64TargetObjectFile.cpp - ARM64 Object Info ---------------------===//
+//===-- AArch64TargetObjectFile.cpp - AArch64 Object Info -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64TargetObjectFile.h"
-#include "ARM64TargetMachine.h"
+#include "AArch64TargetObjectFile.h"
+#include "AArch64TargetMachine.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -17,13 +17,13 @@
using namespace llvm;
using namespace dwarf;
-void ARM64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
+void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
+ const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
InitializeELF(TM.Options.UseInitArray);
}
-const MCExpr *ARM64_MachoTargetObjectFile::getTTypeGlobalReference(
+const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(
const GlobalValue *GV, unsigned Encoding, Mangler &Mang,
const TargetMachine &TM, MachineModuleInfo *MMI,
MCStreamer &Streamer) const {
@@ -45,7 +45,7 @@ const MCExpr *ARM64_MachoTargetObjectFil
GV, Encoding, Mang, TM, MMI, Streamer);
}
-MCSymbol *ARM64_MachoTargetObjectFile::getCFIPersonalitySymbol(
+MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol(
const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM,
MachineModuleInfo *MMI) const {
return TM.getSymbol(GV, Mang);
Copied: llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h (from r209576, llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h?p2=llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h&p1=llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64TargetObjectFile.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetObjectFile.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64TargetObjectFile.h - ARM64 Object Info -*- C++ -------------*-===//
+//===-- AArch64TargetObjectFile.h - AArch64 Object Info -*- C++ ---------*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,22 +7,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ARM64_TARGETOBJECTFILE_H
-#define LLVM_TARGET_ARM64_TARGETOBJECTFILE_H
+#ifndef LLVM_TARGET_AArch64_TARGETOBJECTFILE_H
+#define LLVM_TARGET_AArch64_TARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
namespace llvm {
-class ARM64TargetMachine;
+class AArch64TargetMachine;
/// This implementation is used for AArch64 ELF targets (Linux in particular).
-class ARM64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
+class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
};
-/// ARM64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
-class ARM64_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
+/// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
+class AArch64_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
unsigned Encoding, Mangler &Mang,
Copied: llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64TargetTransformInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64TargetTransformInfo.cpp - ARM64 specific TTI pass ------------===//
+//===-- AArch64TargetTransformInfo.cpp - AArch64 specific TTI pass --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,15 +8,15 @@
//===----------------------------------------------------------------------===//
/// \file
/// This file implements a TargetTransformInfo analysis pass specific to the
-/// ARM64 target machine. It uses the target's detailed information to provide
+/// AArch64 target machine. It uses the target's detailed information to provide
/// more precise answers to certain TTI queries, while letting the target
/// independent and default TTI implementations handle the rest.
///
//===----------------------------------------------------------------------===//
-#include "ARM64.h"
-#include "ARM64TargetMachine.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
+#include "AArch64.h"
+#include "AArch64TargetMachine.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/CostTable.h"
@@ -24,35 +24,35 @@
#include <algorithm>
using namespace llvm;
-#define DEBUG_TYPE "arm64tti"
+#define DEBUG_TYPE "aarch64tti"
// Declare the pass initialization routine locally as target-specific passes
// don't have a target-wide initialization entry point, and so we rely on the
// pass constructor initialization.
namespace llvm {
-void initializeARM64TTIPass(PassRegistry &);
+void initializeAArch64TTIPass(PassRegistry &);
}
namespace {
-class ARM64TTI final : public ImmutablePass, public TargetTransformInfo {
- const ARM64TargetMachine *TM;
- const ARM64Subtarget *ST;
- const ARM64TargetLowering *TLI;
+class AArch64TTI final : public ImmutablePass, public TargetTransformInfo {
+ const AArch64TargetMachine *TM;
+ const AArch64Subtarget *ST;
+ const AArch64TargetLowering *TLI;
/// Estimate the overhead of scalarizing an instruction. Insert and Extract
/// are set if the result needs to be inserted and/or extracted from vectors.
unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
public:
- ARM64TTI() : ImmutablePass(ID), TM(nullptr), ST(nullptr), TLI(nullptr) {
+ AArch64TTI() : ImmutablePass(ID), TM(nullptr), ST(nullptr), TLI(nullptr) {
llvm_unreachable("This pass cannot be directly constructed");
}
- ARM64TTI(const ARM64TargetMachine *TM)
+ AArch64TTI(const AArch64TargetMachine *TM)
: ImmutablePass(ID), TM(TM), ST(TM->getSubtargetImpl()),
TLI(TM->getTargetLowering()) {
- initializeARM64TTIPass(*PassRegistry::getPassRegistry());
+ initializeAArch64TTIPass(*PassRegistry::getPassRegistry());
}
void initializePass() override { pushTTIStack(this); }
@@ -129,21 +129,21 @@ public:
} // end anonymous namespace
-INITIALIZE_AG_PASS(ARM64TTI, TargetTransformInfo, "arm64tti",
- "ARM64 Target Transform Info", true, true, false)
-char ARM64TTI::ID = 0;
+INITIALIZE_AG_PASS(AArch64TTI, TargetTransformInfo, "aarch64tti",
+ "AArch64 Target Transform Info", true, true, false)
+char AArch64TTI::ID = 0;
ImmutablePass *
-llvm::createARM64TargetTransformInfoPass(const ARM64TargetMachine *TM) {
- return new ARM64TTI(TM);
+llvm::createAArch64TargetTransformInfoPass(const AArch64TargetMachine *TM) {
+ return new AArch64TTI(TM);
}
/// \brief Calculate the cost of materializing a 64-bit value. This helper
/// method might only calculate a fraction of a larger immediate. Therefore it
/// is valid to return a cost of ZERO.
-unsigned ARM64TTI::getIntImmCost(int64_t Val) const {
+unsigned AArch64TTI::getIntImmCost(int64_t Val) const {
// Check if the immediate can be encoded within an instruction.
- if (Val == 0 || ARM64_AM::isLogicalImmediate(Val, 64))
+ if (Val == 0 || AArch64_AM::isLogicalImmediate(Val, 64))
return 0;
if (Val < 0)
@@ -155,7 +155,7 @@ unsigned ARM64TTI::getIntImmCost(int64_t
}
/// \brief Calculate the cost of materializing the given constant.
-unsigned ARM64TTI::getIntImmCost(const APInt &Imm, Type *Ty) const {
+unsigned AArch64TTI::getIntImmCost(const APInt &Imm, Type *Ty) const {
assert(Ty->isIntegerTy());
unsigned BitSize = Ty->getPrimitiveSizeInBits();
@@ -179,7 +179,7 @@ unsigned ARM64TTI::getIntImmCost(const A
return std::max(1U, Cost);
}
-unsigned ARM64TTI::getIntImmCost(unsigned Opcode, unsigned Idx,
+unsigned AArch64TTI::getIntImmCost(unsigned Opcode, unsigned Idx,
const APInt &Imm, Type *Ty) const {
assert(Ty->isIntegerTy());
@@ -237,14 +237,14 @@ unsigned ARM64TTI::getIntImmCost(unsigne
if (Idx == ImmIdx) {
unsigned NumConstants = (BitSize + 63) / 64;
- unsigned Cost = ARM64TTI::getIntImmCost(Imm, Ty);
+ unsigned Cost = AArch64TTI::getIntImmCost(Imm, Ty);
return (Cost <= NumConstants * TCC_Basic)
? static_cast<unsigned>(TCC_Free) : Cost;
}
- return ARM64TTI::getIntImmCost(Imm, Ty);
+ return AArch64TTI::getIntImmCost(Imm, Ty);
}
-unsigned ARM64TTI::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
+unsigned AArch64TTI::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
const APInt &Imm, Type *Ty) const {
assert(Ty->isIntegerTy());
@@ -265,7 +265,7 @@ unsigned ARM64TTI::getIntImmCost(Intrins
case Intrinsic::umul_with_overflow:
if (Idx == 1) {
unsigned NumConstants = (BitSize + 63) / 64;
- unsigned Cost = ARM64TTI::getIntImmCost(Imm, Ty);
+ unsigned Cost = AArch64TTI::getIntImmCost(Imm, Ty);
return (Cost <= NumConstants * TCC_Basic)
? static_cast<unsigned>(TCC_Free) : Cost;
}
@@ -280,18 +280,19 @@ unsigned ARM64TTI::getIntImmCost(Intrins
return TCC_Free;
break;
}
- return ARM64TTI::getIntImmCost(Imm, Ty);
+ return AArch64TTI::getIntImmCost(Imm, Ty);
}
-ARM64TTI::PopcntSupportKind ARM64TTI::getPopcntSupport(unsigned TyWidth) const {
+AArch64TTI::PopcntSupportKind
+AArch64TTI::getPopcntSupport(unsigned TyWidth) const {
assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
if (TyWidth == 32 || TyWidth == 64)
return PSK_FastHardware;
- // TODO: ARM64TargetLowering::LowerCTPOP() supports 128bit popcount.
+ // TODO: AArch64TargetLowering::LowerCTPOP() supports 128bit popcount.
return PSK_Software;
}
-unsigned ARM64TTI::getCastInstrCost(unsigned Opcode, Type *Dst,
+unsigned AArch64TTI::getCastInstrCost(unsigned Opcode, Type *Dst,
Type *Src) const {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
@@ -338,7 +339,7 @@ unsigned ARM64TTI::getCastInstrCost(unsi
return TargetTransformInfo::getCastInstrCost(Opcode, Dst, Src);
}
-unsigned ARM64TTI::getVectorInstrCost(unsigned Opcode, Type *Val,
+unsigned AArch64TTI::getVectorInstrCost(unsigned Opcode, Type *Val,
unsigned Index) const {
assert(Val->isVectorTy() && "This must be a vector type");
@@ -363,7 +364,7 @@ unsigned ARM64TTI::getVectorInstrCost(un
return 2;
}
-unsigned ARM64TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
+unsigned AArch64TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
OperandValueKind Opd1Info,
OperandValueKind Opd2Info) const {
// Legalize the type.
@@ -386,7 +387,7 @@ unsigned ARM64TTI::getArithmeticInstrCos
}
}
-unsigned ARM64TTI::getAddressComputationCost(Type *Ty, bool IsComplex) const {
+unsigned AArch64TTI::getAddressComputationCost(Type *Ty, bool IsComplex) const {
// Address computations in vectorized code with non-consecutive addresses will
// likely result in more instructions compared to scalar code where the
// computation can more often be merged into the index mode. The resulting
@@ -401,7 +402,7 @@ unsigned ARM64TTI::getAddressComputation
return 1;
}
-unsigned ARM64TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+unsigned AArch64TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
Type *CondTy) const {
int ISD = TLI->InstructionOpcodeToISD(Opcode);
@@ -432,7 +433,7 @@ unsigned ARM64TTI::getCmpSelInstrCost(un
return TargetTransformInfo::getCmpSelInstrCost(Opcode, ValTy, CondTy);
}
-unsigned ARM64TTI::getMemoryOpCost(unsigned Opcode, Type *Src,
+unsigned AArch64TTI::getMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) const {
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Src);
Copied: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (from r209576, llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp?p2=llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp&p1=llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64AsmParser.cpp - Parse ARM64 assembly to MCInst instructions --===//
+//==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
//
// The LLVM Compiler Infrastructure
//
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "MCTargetDesc/ARM64MCExpr.h"
-#include "Utils/ARM64BaseInfo.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
@@ -35,9 +35,9 @@ using namespace llvm;
namespace {
-class ARM64Operand;
+class AArch64Operand;
-class ARM64AsmParser : public MCTargetAsmParser {
+class AArch64AsmParser : public MCTargetAsmParser {
public:
typedef SmallVectorImpl<MCParsedAsmOperand *> OperandVector;
@@ -52,7 +52,7 @@ private:
SMLoc getLoc() const { return Parser.getTok().getLoc(); }
bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
- ARM64CC::CondCode parseCondCodeString(StringRef Cond);
+ AArch64CC::CondCode parseCondCodeString(StringRef Cond);
bool parseCondCode(OperandVector &Operands, bool invertCondCode);
int tryParseRegister();
int tryMatchVectorRegister(StringRef &Kind, bool expected);
@@ -80,7 +80,7 @@ private:
/// {
#define GET_ASSEMBLER_HEADER
-#include "ARM64GenAsmMatcher.inc"
+#include "AArch64GenAsmMatcher.inc"
/// }
@@ -98,12 +98,12 @@ private:
bool tryParseVectorRegister(OperandVector &Operands);
public:
- enum ARM64MatchResultTy {
+ enum AArch64MatchResultTy {
Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
#define GET_OPERAND_DIAGNOSTIC_TYPES
-#include "ARM64GenAsmMatcher.inc"
+#include "AArch64GenAsmMatcher.inc"
};
- ARM64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
+ AArch64AsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
const MCInstrInfo &MII,
const MCTargetOptions &Options)
: MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
@@ -121,7 +121,7 @@ public:
unsigned Kind) override;
static bool classifySymbolRef(const MCExpr *Expr,
- ARM64MCExpr::VariantKind &ELFRefKind,
+ AArch64MCExpr::VariantKind &ELFRefKind,
MCSymbolRefExpr::VariantKind &DarwinRefKind,
int64_t &Addend);
};
@@ -129,9 +129,9 @@ public:
namespace {
-/// ARM64Operand - Instances of this class represent a parsed ARM64 machine
+/// AArch64Operand - Instances of this class represent a parsed AArch64 machine
/// instruction.
-class ARM64Operand : public MCParsedAsmOperand {
+class AArch64Operand : public MCParsedAsmOperand {
private:
enum KindTy {
k_Immediate,
@@ -183,7 +183,7 @@ private:
};
struct CondCodeOp {
- ARM64CC::CondCode Code;
+ AArch64CC::CondCode Code;
};
struct FPImmOp {
@@ -211,7 +211,7 @@ private:
};
struct ShiftExtendOp {
- ARM64_AM::ShiftExtendType Type;
+ AArch64_AM::ShiftExtendType Type;
unsigned Amount;
bool HasExplicitAmount;
};
@@ -240,11 +240,11 @@ private:
// the add<>Operands() calls.
MCContext &Ctx;
- ARM64Operand(KindTy K, MCContext &_Ctx)
+ AArch64Operand(KindTy K, MCContext &_Ctx)
: MCParsedAsmOperand(), Kind(K), Ctx(_Ctx) {}
public:
- ARM64Operand(const ARM64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
+ AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
Kind = o.Kind;
StartLoc = o.StartLoc;
EndLoc = o.EndLoc;
@@ -321,7 +321,7 @@ public:
return ShiftedImm.ShiftAmount;
}
- ARM64CC::CondCode getCondCode() const {
+ AArch64CC::CondCode getCondCode() const {
assert(Kind == k_CondCode && "Invalid access!");
return CondCode.Code;
}
@@ -376,7 +376,7 @@ public:
return Prefetch.Val;
}
- ARM64_AM::ShiftExtendType getShiftExtendType() const {
+ AArch64_AM::ShiftExtendType getShiftExtendType() const {
assert(Kind == k_ShiftExtend && "Invalid access!");
return ShiftExtend.Type;
}
@@ -431,10 +431,10 @@ public:
}
bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
- ARM64MCExpr::VariantKind ELFRefKind;
+ AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
- if (!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
+ if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
Addend)) {
// If we don't understand the expression, assume the best and
// let the fixup and relocation code deal with it.
@@ -442,14 +442,14 @@ public:
}
if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
- ELFRefKind == ARM64MCExpr::VK_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_GOT_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12_NC ||
- ELFRefKind == ARM64MCExpr::VK_TPREL_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_TPREL_LO12_NC ||
- ELFRefKind == ARM64MCExpr::VK_GOTTPREL_LO12_NC ||
- ELFRefKind == ARM64MCExpr::VK_TLSDESC_LO12) {
+ ELFRefKind == AArch64MCExpr::VK_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
+ ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
+ ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
+ ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) {
// Note that we don't range-check the addend. It's adjusted modulo page
// size when converted, so there is no "out of range" condition when using
// @pageoff.
@@ -607,7 +607,7 @@ public:
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
- return ARM64_AM::isLogicalImmediate(MCE->getValue(), 32);
+ return AArch64_AM::isLogicalImmediate(MCE->getValue(), 32);
}
bool isLogicalImm64() const {
if (!isImm())
@@ -615,7 +615,7 @@ public:
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
- return ARM64_AM::isLogicalImmediate(MCE->getValue(), 64);
+ return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
}
bool isShiftedImm() const { return Kind == k_ShiftedImm; }
bool isAddSubImm() const {
@@ -634,22 +634,22 @@ public:
Expr = getImm();
}
- ARM64MCExpr::VariantKind ELFRefKind;
+ AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
- if (ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind,
+ if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
DarwinRefKind, Addend)) {
return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
|| DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
|| (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
- || ELFRefKind == ARM64MCExpr::VK_LO12
- || ELFRefKind == ARM64MCExpr::VK_DTPREL_HI12
- || ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12
- || ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12_NC
- || ELFRefKind == ARM64MCExpr::VK_TPREL_HI12
- || ELFRefKind == ARM64MCExpr::VK_TPREL_LO12
- || ELFRefKind == ARM64MCExpr::VK_TPREL_LO12_NC
- || ELFRefKind == ARM64MCExpr::VK_TLSDESC_LO12;
+ || ELFRefKind == AArch64MCExpr::VK_LO12
+ || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
+ || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
+ || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
+ || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
+ || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
+ || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
+ || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12;
}
// Otherwise it should be a real immediate in range:
@@ -663,7 +663,7 @@ public:
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
- return ARM64_AM::isAdvSIMDModImmType10(MCE->getValue());
+ return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
}
bool isBranchTarget26() const {
if (!isImm())
@@ -699,15 +699,16 @@ public:
return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
}
- bool isMovWSymbol(ArrayRef<ARM64MCExpr::VariantKind> AllowedModifiers) const {
+ bool
+ isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
if (!isImm())
return false;
- ARM64MCExpr::VariantKind ELFRefKind;
+ AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
- if (!ARM64AsmParser::classifySymbolRef(getImm(), ELFRefKind, DarwinRefKind,
- Addend)) {
+ if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
+ DarwinRefKind, Addend)) {
return false;
}
if (DarwinRefKind != MCSymbolRefExpr::VK_None)
@@ -722,57 +723,56 @@ public:
}
bool isMovZSymbolG3() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G3 };
+ static AArch64MCExpr::VariantKind Variants[] = { AArch64MCExpr::VK_ABS_G3 };
return isMovWSymbol(Variants);
}
bool isMovZSymbolG2() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G2,
- ARM64MCExpr::VK_ABS_G2_S,
- ARM64MCExpr::VK_TPREL_G2,
- ARM64MCExpr::VK_DTPREL_G2 };
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
+ AArch64MCExpr::VK_TPREL_G2, AArch64MCExpr::VK_DTPREL_G2};
return isMovWSymbol(Variants);
}
bool isMovZSymbolG1() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G1,
- ARM64MCExpr::VK_ABS_G1_S,
- ARM64MCExpr::VK_GOTTPREL_G1,
- ARM64MCExpr::VK_TPREL_G1,
- ARM64MCExpr::VK_DTPREL_G1, };
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
+ AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
+ AArch64MCExpr::VK_DTPREL_G1,
+ };
return isMovWSymbol(Variants);
}
bool isMovZSymbolG0() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G0,
- ARM64MCExpr::VK_ABS_G0_S,
- ARM64MCExpr::VK_TPREL_G0,
- ARM64MCExpr::VK_DTPREL_G0 };
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
+ AArch64MCExpr::VK_TPREL_G0, AArch64MCExpr::VK_DTPREL_G0};
return isMovWSymbol(Variants);
}
bool isMovKSymbolG3() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G3 };
+ static AArch64MCExpr::VariantKind Variants[] = { AArch64MCExpr::VK_ABS_G3 };
return isMovWSymbol(Variants);
}
bool isMovKSymbolG2() const {
- static ARM64MCExpr::VariantKind Variants[] = { ARM64MCExpr::VK_ABS_G2_NC };
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G2_NC};
return isMovWSymbol(Variants);
}
bool isMovKSymbolG1() const {
- static ARM64MCExpr::VariantKind Variants[] = {
- ARM64MCExpr::VK_ABS_G1_NC, ARM64MCExpr::VK_TPREL_G1_NC,
- ARM64MCExpr::VK_DTPREL_G1_NC
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G1_NC, AArch64MCExpr::VK_TPREL_G1_NC,
+ AArch64MCExpr::VK_DTPREL_G1_NC
};
return isMovWSymbol(Variants);
}
bool isMovKSymbolG0() const {
- static ARM64MCExpr::VariantKind Variants[] = {
- ARM64MCExpr::VK_ABS_G0_NC, ARM64MCExpr::VK_GOTTPREL_G0_NC,
- ARM64MCExpr::VK_TPREL_G0_NC, ARM64MCExpr::VK_DTPREL_G0_NC
+ static AArch64MCExpr::VariantKind Variants[] = {
+ AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
+ AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC
};
return isMovWSymbol(Variants);
}
@@ -822,7 +822,7 @@ public:
if (!isSysReg()) return false;
bool IsKnownRegister;
- auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
+ auto Mapper = AArch64SysReg::MRSMapper(getSysRegFeatureBits());
Mapper.fromString(getSysReg(), IsKnownRegister);
return IsKnownRegister;
@@ -831,7 +831,7 @@ public:
if (!isSysReg()) return false;
bool IsKnownRegister;
- auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
+ auto Mapper = AArch64SysReg::MSRMapper(getSysRegFeatureBits());
Mapper.fromString(getSysReg(), IsKnownRegister);
return IsKnownRegister;
@@ -840,7 +840,7 @@ public:
if (!isSysReg()) return false;
bool IsKnownRegister;
- ARM64PState::PStateMapper().fromString(getSysReg(), IsKnownRegister);
+ AArch64PState::PStateMapper().fromString(getSysReg(), IsKnownRegister);
return IsKnownRegister;
}
@@ -848,16 +848,17 @@ public:
bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
bool isVectorRegLo() const {
return Kind == k_Register && Reg.isVector &&
- ARM64MCRegisterClasses[ARM64::FPR128_loRegClassID].contains(Reg.RegNum);
+ AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
+ Reg.RegNum);
}
bool isGPR32as64() const {
return Kind == k_Register && !Reg.isVector &&
- ARM64MCRegisterClasses[ARM64::GPR64RegClassID].contains(Reg.RegNum);
+ AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
}
bool isGPR64sp0() const {
return Kind == k_Register && !Reg.isVector &&
- ARM64MCRegisterClasses[ARM64::GPR64spRegClassID].contains(Reg.RegNum);
+ AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
}
/// Is this a vector list with the type implicit (presumably attached to the
@@ -904,20 +905,21 @@ public:
if (!isShiftExtend())
return false;
- ARM64_AM::ShiftExtendType ST = getShiftExtendType();
- return (ST == ARM64_AM::LSL || ST == ARM64_AM::LSR || ST == ARM64_AM::ASR ||
- ST == ARM64_AM::ROR || ST == ARM64_AM::MSL);
+ AArch64_AM::ShiftExtendType ST = getShiftExtendType();
+ return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
+ ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
+ ST == AArch64_AM::MSL);
}
bool isExtend() const {
if (!isShiftExtend())
return false;
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- return (ET == ARM64_AM::UXTB || ET == ARM64_AM::SXTB ||
- ET == ARM64_AM::UXTH || ET == ARM64_AM::SXTH ||
- ET == ARM64_AM::UXTW || ET == ARM64_AM::SXTW ||
- ET == ARM64_AM::UXTX || ET == ARM64_AM::SXTX ||
- ET == ARM64_AM::LSL) &&
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
+ ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
+ ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
+ ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
+ ET == AArch64_AM::LSL) &&
getShiftExtendAmount() <= 4;
}
@@ -925,22 +927,23 @@ public:
if (!isExtend())
return false;
// UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- return ET != ARM64_AM::UXTX && ET != ARM64_AM::SXTX;
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX;
}
bool isExtendLSL64() const {
if (!isExtend())
return false;
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- return (ET == ARM64_AM::UXTX || ET == ARM64_AM::SXTX || ET == ARM64_AM::LSL) &&
- getShiftExtendAmount() <= 4;
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
+ ET == AArch64_AM::LSL) &&
+ getShiftExtendAmount() <= 4;
}
template<int Width> bool isMemXExtend() const {
if (!isExtend())
return false;
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- return (ET == ARM64_AM::LSL || ET == ARM64_AM::SXTX) &&
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
(getShiftExtendAmount() == Log2_32(Width / 8) ||
getShiftExtendAmount() == 0);
}
@@ -948,8 +951,8 @@ public:
template<int Width> bool isMemWExtend() const {
if (!isExtend())
return false;
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- return (ET == ARM64_AM::UXTW || ET == ARM64_AM::SXTW) &&
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
(getShiftExtendAmount() == Log2_32(Width / 8) ||
getShiftExtendAmount() == 0);
}
@@ -960,9 +963,9 @@ public:
return false;
// An arithmetic shifter is LSL, LSR, or ASR.
- ARM64_AM::ShiftExtendType ST = getShiftExtendType();
- return (ST == ARM64_AM::LSL || ST == ARM64_AM::LSR ||
- ST == ARM64_AM::ASR) && getShiftExtendAmount() < width;
+ AArch64_AM::ShiftExtendType ST = getShiftExtendType();
+ return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
+ ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
}
template <unsigned width>
@@ -971,9 +974,9 @@ public:
return false;
// A logical shifter is LSL, LSR, ASR or ROR.
- ARM64_AM::ShiftExtendType ST = getShiftExtendType();
- return (ST == ARM64_AM::LSL || ST == ARM64_AM::LSR || ST == ARM64_AM::ASR ||
- ST == ARM64_AM::ROR) &&
+ AArch64_AM::ShiftExtendType ST = getShiftExtendType();
+ return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
+ ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
getShiftExtendAmount() < width;
}
@@ -982,8 +985,8 @@ public:
return false;
// A MOVi shifter is LSL of 0, 16, 32, or 48.
- ARM64_AM::ShiftExtendType ST = getShiftExtendType();
- if (ST != ARM64_AM::LSL)
+ AArch64_AM::ShiftExtendType ST = getShiftExtendType();
+ if (ST != AArch64_AM::LSL)
return false;
uint64_t Val = getShiftExtendAmount();
return (Val == 0 || Val == 16);
@@ -994,8 +997,8 @@ public:
return false;
// A MOVi shifter is LSL of 0 or 16.
- ARM64_AM::ShiftExtendType ST = getShiftExtendType();
- if (ST != ARM64_AM::LSL)
+ AArch64_AM::ShiftExtendType ST = getShiftExtendType();
+ if (ST != AArch64_AM::LSL)
return false;
uint64_t Val = getShiftExtendAmount();
return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
@@ -1007,7 +1010,7 @@ public:
// A logical vector shifter is a left shift by 0, 8, 16, or 24.
unsigned Shift = getShiftExtendAmount();
- return getShiftExtendType() == ARM64_AM::LSL &&
+ return getShiftExtendType() == AArch64_AM::LSL &&
(Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
}
@@ -1017,7 +1020,8 @@ public:
// A logical vector shifter is a left shift by 0 or 8.
unsigned Shift = getShiftExtendAmount();
- return getShiftExtendType() == ARM64_AM::LSL && (Shift == 0 || Shift == 8);
+ return getShiftExtendType() == AArch64_AM::LSL &&
+ (Shift == 0 || Shift == 8);
}
bool isMoveVecShifter() const {
@@ -1026,7 +1030,8 @@ public:
// A logical vector shifter is a left shift by 8 or 16.
unsigned Shift = getShiftExtendAmount();
- return getShiftExtendType() == ARM64_AM::MSL && (Shift == 8 || Shift == 16);
+ return getShiftExtendType() == AArch64_AM::MSL &&
+ (Shift == 8 || Shift == 16);
}
// Fallback unscaled operands are for aliases of LDR/STR that fall back
@@ -1088,10 +1093,11 @@ public:
void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- assert(ARM64MCRegisterClasses[ARM64::GPR64RegClassID].contains(getReg()));
+ assert(
+ AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
const MCRegisterInfo *RI = Ctx.getRegisterInfo();
- uint32_t Reg = RI->getRegClass(ARM64::GPR32RegClassID).getRegister(
+ uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
RI->getEncodingValue(getReg()));
Inst.addOperand(MCOperand::CreateReg(Reg));
@@ -1099,13 +1105,15 @@ public:
void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- assert(ARM64MCRegisterClasses[ARM64::FPR128RegClassID].contains(getReg()));
- Inst.addOperand(MCOperand::CreateReg(ARM64::D0 + getReg() - ARM64::Q0));
+ assert(
+ AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
+ Inst.addOperand(MCOperand::CreateReg(AArch64::D0 + getReg() - AArch64::Q0));
}
void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- assert(ARM64MCRegisterClasses[ARM64::FPR128RegClassID].contains(getReg()));
+ assert(
+ AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
Inst.addOperand(MCOperand::CreateReg(getReg()));
}
@@ -1117,23 +1125,23 @@ public:
template <unsigned NumRegs>
void addVectorList64Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- static unsigned FirstRegs[] = { ARM64::D0, ARM64::D0_D1,
- ARM64::D0_D1_D2, ARM64::D0_D1_D2_D3 };
+ static unsigned FirstRegs[] = { AArch64::D0, AArch64::D0_D1,
+ AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 };
unsigned FirstReg = FirstRegs[NumRegs - 1];
Inst.addOperand(
- MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
+ MCOperand::CreateReg(FirstReg + getVectorListStart() - AArch64::Q0));
}
template <unsigned NumRegs>
void addVectorList128Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- static unsigned FirstRegs[] = { ARM64::Q0, ARM64::Q0_Q1,
- ARM64::Q0_Q1_Q2, ARM64::Q0_Q1_Q2_Q3 };
+ static unsigned FirstRegs[] = { AArch64::Q0, AArch64::Q0_Q1,
+ AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 };
unsigned FirstReg = FirstRegs[NumRegs - 1];
Inst.addOperand(
- MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
+ MCOperand::CreateReg(FirstReg + getVectorListStart() - AArch64::Q0));
}
void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
@@ -1340,7 +1348,7 @@ public:
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
assert(MCE && "Invalid logical immediate operand!");
- uint64_t encoding = ARM64_AM::encodeLogicalImmediate(MCE->getValue(), 32);
+ uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 32);
Inst.addOperand(MCOperand::CreateImm(encoding));
}
@@ -1348,7 +1356,7 @@ public:
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
assert(MCE && "Invalid logical immediate operand!");
- uint64_t encoding = ARM64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
+ uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
Inst.addOperand(MCOperand::CreateImm(encoding));
}
@@ -1356,7 +1364,7 @@ public:
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
assert(MCE && "Invalid immediate operand!");
- uint64_t encoding = ARM64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
+ uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
Inst.addOperand(MCOperand::CreateImm(encoding));
}
@@ -1416,7 +1424,7 @@ public:
assert(N == 1 && "Invalid number of operands!");
bool Valid;
- auto Mapper = ARM64SysReg::MRSMapper(getSysRegFeatureBits());
+ auto Mapper = AArch64SysReg::MRSMapper(getSysRegFeatureBits());
uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
Inst.addOperand(MCOperand::CreateImm(Bits));
@@ -1426,7 +1434,7 @@ public:
assert(N == 1 && "Invalid number of operands!");
bool Valid;
- auto Mapper = ARM64SysReg::MSRMapper(getSysRegFeatureBits());
+ auto Mapper = AArch64SysReg::MSRMapper(getSysRegFeatureBits());
uint32_t Bits = Mapper.fromString(getSysReg(), Valid);
Inst.addOperand(MCOperand::CreateImm(Bits));
@@ -1436,7 +1444,8 @@ public:
assert(N == 1 && "Invalid number of operands!");
bool Valid;
- uint32_t Bits = ARM64PState::PStateMapper().fromString(getSysReg(), Valid);
+ uint32_t Bits =
+ AArch64PState::PStateMapper().fromString(getSysReg(), Valid);
Inst.addOperand(MCOperand::CreateImm(Bits));
}
@@ -1454,30 +1463,30 @@ public:
void addShifterOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
unsigned Imm =
- ARM64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
+ AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
Inst.addOperand(MCOperand::CreateImm(Imm));
}
void addExtendOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- if (ET == ARM64_AM::LSL) ET = ARM64_AM::UXTW;
- unsigned Imm = ARM64_AM::getArithExtendImm(ET, getShiftExtendAmount());
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
+ unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
Inst.addOperand(MCOperand::CreateImm(Imm));
}
void addExtend64Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- if (ET == ARM64_AM::LSL) ET = ARM64_AM::UXTX;
- unsigned Imm = ARM64_AM::getArithExtendImm(ET, getShiftExtendAmount());
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
+ unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
Inst.addOperand(MCOperand::CreateImm(Imm));
}
void addMemExtendOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- bool IsSigned = ET == ARM64_AM::SXTW || ET == ARM64_AM::SXTX;
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
Inst.addOperand(MCOperand::CreateImm(IsSigned));
Inst.addOperand(MCOperand::CreateImm(getShiftExtendAmount() != 0));
}
@@ -1488,8 +1497,8 @@ public:
// than its size.
void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- ARM64_AM::ShiftExtendType ET = getShiftExtendType();
- bool IsSigned = ET == ARM64_AM::SXTW || ET == ARM64_AM::SXTX;
+ AArch64_AM::ShiftExtendType ET = getShiftExtendType();
+ bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
Inst.addOperand(MCOperand::CreateImm(IsSigned));
Inst.addOperand(MCOperand::CreateImm(hasShiftExtendAmount()));
}
@@ -1514,9 +1523,9 @@ public:
void print(raw_ostream &OS) const override;
- static ARM64Operand *CreateToken(StringRef Str, bool IsSuffix, SMLoc S,
+ static AArch64Operand *CreateToken(StringRef Str, bool IsSuffix, SMLoc S,
MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_Token, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_Token, Ctx);
Op->Tok.Data = Str.data();
Op->Tok.Length = Str.size();
Op->Tok.IsSuffix = IsSuffix;
@@ -1525,9 +1534,9 @@ public:
return Op;
}
- static ARM64Operand *CreateReg(unsigned RegNum, bool isVector, SMLoc S,
+ static AArch64Operand *CreateReg(unsigned RegNum, bool isVector, SMLoc S,
SMLoc E, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_Register, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_Register, Ctx);
Op->Reg.RegNum = RegNum;
Op->Reg.isVector = isVector;
Op->StartLoc = S;
@@ -1535,10 +1544,10 @@ public:
return Op;
}
- static ARM64Operand *CreateVectorList(unsigned RegNum, unsigned Count,
+ static AArch64Operand *CreateVectorList(unsigned RegNum, unsigned Count,
unsigned NumElements, char ElementKind,
SMLoc S, SMLoc E, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_VectorList, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_VectorList, Ctx);
Op->VectorList.RegNum = RegNum;
Op->VectorList.Count = Count;
Op->VectorList.NumElements = NumElements;
@@ -1548,27 +1557,28 @@ public:
return Op;
}
- static ARM64Operand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
+ static AArch64Operand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_VectorIndex, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_VectorIndex, Ctx);
Op->VectorIndex.Val = Idx;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
- static ARM64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
+ static AArch64Operand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_Immediate, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_Immediate, Ctx);
Op->Imm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
- static ARM64Operand *CreateShiftedImm(const MCExpr *Val, unsigned ShiftAmount,
- SMLoc S, SMLoc E, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_ShiftedImm, Ctx);
+ static AArch64Operand *CreateShiftedImm(const MCExpr *Val,
+ unsigned ShiftAmount, SMLoc S,
+ SMLoc E, MCContext &Ctx) {
+ AArch64Operand *Op = new AArch64Operand(k_ShiftedImm, Ctx);
Op->ShiftedImm .Val = Val;
Op->ShiftedImm.ShiftAmount = ShiftAmount;
Op->StartLoc = S;
@@ -1576,34 +1586,34 @@ public:
return Op;
}
- static ARM64Operand *CreateCondCode(ARM64CC::CondCode Code, SMLoc S, SMLoc E,
- MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_CondCode, Ctx);
+ static AArch64Operand *CreateCondCode(AArch64CC::CondCode Code, SMLoc S,
+ SMLoc E, MCContext &Ctx) {
+ AArch64Operand *Op = new AArch64Operand(k_CondCode, Ctx);
Op->CondCode.Code = Code;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
- static ARM64Operand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_FPImm, Ctx);
+ static AArch64Operand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
+ AArch64Operand *Op = new AArch64Operand(k_FPImm, Ctx);
Op->FPImm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
}
- static ARM64Operand *CreateBarrier(unsigned Val, SMLoc S, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_Barrier, Ctx);
+ static AArch64Operand *CreateBarrier(unsigned Val, SMLoc S, MCContext &Ctx) {
+ AArch64Operand *Op = new AArch64Operand(k_Barrier, Ctx);
Op->Barrier.Val = Val;
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
}
- static ARM64Operand *CreateSysReg(StringRef Str, SMLoc S,
+ static AArch64Operand *CreateSysReg(StringRef Str, SMLoc S,
uint64_t FeatureBits, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_SysReg, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_SysReg, Ctx);
Op->SysReg.Data = Str.data();
Op->SysReg.Length = Str.size();
Op->SysReg.FeatureBits = FeatureBits;
@@ -1612,27 +1622,27 @@ public:
return Op;
}
- static ARM64Operand *CreateSysCR(unsigned Val, SMLoc S, SMLoc E,
+ static AArch64Operand *CreateSysCR(unsigned Val, SMLoc S, SMLoc E,
MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_SysCR, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_SysCR, Ctx);
Op->SysCRImm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
- static ARM64Operand *CreatePrefetch(unsigned Val, SMLoc S, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_Prefetch, Ctx);
+ static AArch64Operand *CreatePrefetch(unsigned Val, SMLoc S, MCContext &Ctx) {
+ AArch64Operand *Op = new AArch64Operand(k_Prefetch, Ctx);
Op->Prefetch.Val = Val;
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
}
- static ARM64Operand *CreateShiftExtend(ARM64_AM::ShiftExtendType ShOp,
+ static AArch64Operand *CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp,
unsigned Val, bool HasExplicitAmount,
SMLoc S, SMLoc E, MCContext &Ctx) {
- ARM64Operand *Op = new ARM64Operand(k_ShiftExtend, Ctx);
+ AArch64Operand *Op = new AArch64Operand(k_ShiftExtend, Ctx);
Op->ShiftExtend.Type = ShOp;
Op->ShiftExtend.Amount = Val;
Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
@@ -1644,15 +1654,15 @@ public:
} // end anonymous namespace.
-void ARM64Operand::print(raw_ostream &OS) const {
+void AArch64Operand::print(raw_ostream &OS) const {
switch (Kind) {
case k_FPImm:
- OS << "<fpimm " << getFPImm() << "(" << ARM64_AM::getFPImmFloat(getFPImm())
- << ") >";
+ OS << "<fpimm " << getFPImm() << "("
+ << AArch64_AM::getFPImmFloat(getFPImm()) << ") >";
break;
case k_Barrier: {
bool Valid;
- StringRef Name = ARM64DB::DBarrierMapper().toString(getBarrier(), Valid);
+ StringRef Name = AArch64DB::DBarrierMapper().toString(getBarrier(), Valid);
if (Valid)
OS << "<barrier " << Name << ">";
else
@@ -1666,7 +1676,7 @@ void ARM64Operand::print(raw_ostream &OS
unsigned Shift = getShiftedImmShift();
OS << "<shiftedimm ";
getShiftedImmVal()->print(OS);
- OS << ", lsl #" << ARM64_AM::getShiftValue(Shift) << ">";
+ OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
break;
}
case k_CondCode:
@@ -1697,7 +1707,7 @@ void ARM64Operand::print(raw_ostream &OS
break;
case k_Prefetch: {
bool Valid;
- StringRef Name = ARM64PRFM::PRFMMapper().toString(getPrefetch(), Valid);
+ StringRef Name = AArch64PRFM::PRFMMapper().toString(getPrefetch(), Valid);
if (Valid)
OS << "<prfop " << Name << ">";
else
@@ -1705,7 +1715,7 @@ void ARM64Operand::print(raw_ostream &OS
break;
}
case k_ShiftExtend: {
- OS << "<" << ARM64_AM::getShiftExtendName(getShiftExtendType()) << " #"
+ OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
<< getShiftExtendAmount();
if (!hasShiftExtendAmount())
OS << "<imp>";
@@ -1724,38 +1734,38 @@ static unsigned MatchRegisterName(String
static unsigned matchVectorRegName(StringRef Name) {
return StringSwitch<unsigned>(Name)
- .Case("v0", ARM64::Q0)
- .Case("v1", ARM64::Q1)
- .Case("v2", ARM64::Q2)
- .Case("v3", ARM64::Q3)
- .Case("v4", ARM64::Q4)
- .Case("v5", ARM64::Q5)
- .Case("v6", ARM64::Q6)
- .Case("v7", ARM64::Q7)
- .Case("v8", ARM64::Q8)
- .Case("v9", ARM64::Q9)
- .Case("v10", ARM64::Q10)
- .Case("v11", ARM64::Q11)
- .Case("v12", ARM64::Q12)
- .Case("v13", ARM64::Q13)
- .Case("v14", ARM64::Q14)
- .Case("v15", ARM64::Q15)
- .Case("v16", ARM64::Q16)
- .Case("v17", ARM64::Q17)
- .Case("v18", ARM64::Q18)
- .Case("v19", ARM64::Q19)
- .Case("v20", ARM64::Q20)
- .Case("v21", ARM64::Q21)
- .Case("v22", ARM64::Q22)
- .Case("v23", ARM64::Q23)
- .Case("v24", ARM64::Q24)
- .Case("v25", ARM64::Q25)
- .Case("v26", ARM64::Q26)
- .Case("v27", ARM64::Q27)
- .Case("v28", ARM64::Q28)
- .Case("v29", ARM64::Q29)
- .Case("v30", ARM64::Q30)
- .Case("v31", ARM64::Q31)
+ .Case("v0", AArch64::Q0)
+ .Case("v1", AArch64::Q1)
+ .Case("v2", AArch64::Q2)
+ .Case("v3", AArch64::Q3)
+ .Case("v4", AArch64::Q4)
+ .Case("v5", AArch64::Q5)
+ .Case("v6", AArch64::Q6)
+ .Case("v7", AArch64::Q7)
+ .Case("v8", AArch64::Q8)
+ .Case("v9", AArch64::Q9)
+ .Case("v10", AArch64::Q10)
+ .Case("v11", AArch64::Q11)
+ .Case("v12", AArch64::Q12)
+ .Case("v13", AArch64::Q13)
+ .Case("v14", AArch64::Q14)
+ .Case("v15", AArch64::Q15)
+ .Case("v16", AArch64::Q16)
+ .Case("v17", AArch64::Q17)
+ .Case("v18", AArch64::Q18)
+ .Case("v19", AArch64::Q19)
+ .Case("v20", AArch64::Q20)
+ .Case("v21", AArch64::Q21)
+ .Case("v22", AArch64::Q22)
+ .Case("v23", AArch64::Q23)
+ .Case("v24", AArch64::Q24)
+ .Case("v25", AArch64::Q25)
+ .Case("v26", AArch64::Q26)
+ .Case("v27", AArch64::Q27)
+ .Case("v28", AArch64::Q28)
+ .Case("v29", AArch64::Q29)
+ .Case("v30", AArch64::Q30)
+ .Case("v31", AArch64::Q31)
.Default(0);
}
@@ -1798,8 +1808,8 @@ static void parseValidVectorKind(StringR
}
}
-bool ARM64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
- SMLoc &EndLoc) {
+bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
+ SMLoc &EndLoc) {
StartLoc = getLoc();
RegNo = tryParseRegister();
EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
@@ -1809,7 +1819,7 @@ bool ARM64AsmParser::ParseRegister(unsig
/// tryParseRegister - Try to parse a register name. The token must be an
/// Identifier when called, and if it is a register name the token is eaten and
/// the register is added to the operand list.
-int ARM64AsmParser::tryParseRegister() {
+int AArch64AsmParser::tryParseRegister() {
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
@@ -1818,10 +1828,10 @@ int ARM64AsmParser::tryParseRegister() {
// Also handle a few aliases of registers.
if (RegNum == 0)
RegNum = StringSwitch<unsigned>(lowerCase)
- .Case("fp", ARM64::FP)
- .Case("lr", ARM64::LR)
- .Case("x31", ARM64::XZR)
- .Case("w31", ARM64::WZR)
+ .Case("fp", AArch64::FP)
+ .Case("lr", AArch64::LR)
+ .Case("x31", AArch64::XZR)
+ .Case("w31", AArch64::WZR)
.Default(0);
if (RegNum == 0)
@@ -1833,7 +1843,7 @@ int ARM64AsmParser::tryParseRegister() {
/// tryMatchVectorRegister - Try to parse a vector register name with optional
/// kind specifier. If it is a register specifier, eat the token and return it.
-int ARM64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
+int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
if (Parser.getTok().isNot(AsmToken::Identifier)) {
TokError("vector register expected");
return -1;
@@ -1863,8 +1873,8 @@ int ARM64AsmParser::tryMatchVectorRegist
}
/// tryParseSysCROperand - Try to parse a system instruction CR operand name.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
SMLoc S = getLoc();
if (Parser.getTok().isNot(AsmToken::Identifier)) {
@@ -1886,13 +1896,14 @@ ARM64AsmParser::tryParseSysCROperand(Ope
}
Parser.Lex(); // Eat identifier token.
- Operands.push_back(ARM64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
+ Operands.push_back(
+ AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
return MatchOperand_Success;
}
/// tryParsePrefetch - Try to parse a prefetch operand.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParsePrefetch(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
SMLoc S = getLoc();
const AsmToken &Tok = Parser.getTok();
// Either an identifier for named values or a 5-bit immediate.
@@ -1915,7 +1926,7 @@ ARM64AsmParser::tryParsePrefetch(Operand
return MatchOperand_ParseFail;
}
- Operands.push_back(ARM64Operand::CreatePrefetch(prfop, S, getContext()));
+ Operands.push_back(AArch64Operand::CreatePrefetch(prfop, S, getContext()));
return MatchOperand_Success;
}
@@ -1925,21 +1936,21 @@ ARM64AsmParser::tryParsePrefetch(Operand
}
bool Valid;
- unsigned prfop = ARM64PRFM::PRFMMapper().fromString(Tok.getString(), Valid);
+ unsigned prfop = AArch64PRFM::PRFMMapper().fromString(Tok.getString(), Valid);
if (!Valid) {
TokError("pre-fetch hint expected");
return MatchOperand_ParseFail;
}
Parser.Lex(); // Eat identifier token.
- Operands.push_back(ARM64Operand::CreatePrefetch(prfop, S, getContext()));
+ Operands.push_back(AArch64Operand::CreatePrefetch(prfop, S, getContext()));
return MatchOperand_Success;
}
/// tryParseAdrpLabel - Parse and validate a source label for the ADRP
/// instruction.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
SMLoc S = getLoc();
const MCExpr *Expr;
@@ -1950,15 +1961,16 @@ ARM64AsmParser::tryParseAdrpLabel(Operan
if (parseSymbolicImmVal(Expr))
return MatchOperand_ParseFail;
- ARM64MCExpr::VariantKind ELFRefKind;
+ AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
- ELFRefKind == ARM64MCExpr::VK_INVALID) {
+ ELFRefKind == AArch64MCExpr::VK_INVALID) {
// No modifier was specified at all; this is the syntax for an ELF basic
// ADRP relocation (unfortunately).
- Expr = ARM64MCExpr::Create(Expr, ARM64MCExpr::VK_ABS_PAGE, getContext());
+ Expr =
+ AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
} else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
Addend != 0) {
@@ -1967,9 +1979,9 @@ ARM64AsmParser::tryParseAdrpLabel(Operan
} else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
- ELFRefKind != ARM64MCExpr::VK_GOT_PAGE &&
- ELFRefKind != ARM64MCExpr::VK_GOTTPREL_PAGE &&
- ELFRefKind != ARM64MCExpr::VK_TLSDESC_PAGE) {
+ ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
+ ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
+ ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
// The operand must be an @page or @gotpage qualified symbolref.
Error(S, "page or gotpage label reference expected");
return MatchOperand_ParseFail;
@@ -1980,15 +1992,15 @@ ARM64AsmParser::tryParseAdrpLabel(Operan
// addend is a raw value here. The linker will adjust it to only reference the
// page.
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
return MatchOperand_Success;
}
/// tryParseAdrLabel - Parse and validate a source label for the ADR
/// instruction.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
SMLoc S = getLoc();
const MCExpr *Expr;
@@ -2000,14 +2012,14 @@ ARM64AsmParser::tryParseAdrLabel(Operand
return MatchOperand_ParseFail;
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
return MatchOperand_Success;
}
/// tryParseFPImm - A floating point immediate expression operand.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseFPImm(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
SMLoc S = getLoc();
bool Hash = false;
@@ -2028,7 +2040,7 @@ ARM64AsmParser::tryParseFPImm(OperandVec
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
// If we had a '-' in front, toggle the sign bit.
IntVal ^= (uint64_t)isNegative << 63;
- int Val = ARM64_AM::getFP64Imm(APInt(64, IntVal));
+ int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
Parser.Lex(); // Eat the token.
// Check for out of range values. As an exception, we let Zero through,
// as we handle that special case in post-processing before matching in
@@ -2037,7 +2049,7 @@ ARM64AsmParser::tryParseFPImm(OperandVec
TokError("expected compatible register or floating-point constant");
return MatchOperand_ParseFail;
}
- Operands.push_back(ARM64Operand::CreateFPImm(Val, S, getContext()));
+ Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
return MatchOperand_Success;
}
if (Tok.is(AsmToken::Integer)) {
@@ -2053,10 +2065,10 @@ ARM64AsmParser::tryParseFPImm(OperandVec
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
// If we had a '-' in front, toggle the sign bit.
IntVal ^= (uint64_t)isNegative << 63;
- Val = ARM64_AM::getFP64Imm(APInt(64, IntVal));
+ Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
}
Parser.Lex(); // Eat the token.
- Operands.push_back(ARM64Operand::CreateFPImm(Val, S, getContext()));
+ Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
return MatchOperand_Success;
}
@@ -2068,8 +2080,8 @@ ARM64AsmParser::tryParseFPImm(OperandVec
}
/// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
SMLoc S = getLoc();
if (Parser.getTok().is(AsmToken::Hash))
@@ -2092,8 +2104,8 @@ ARM64AsmParser::tryParseAddSubImm(Operan
}
}
SMLoc E = Parser.getTok().getLoc();
- Operands.push_back(ARM64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
+ getContext()));
return MatchOperand_Success;
}
@@ -2128,81 +2140,81 @@ ARM64AsmParser::tryParseAddSubImm(Operan
Parser.Lex(); // Eat the number
SMLoc E = Parser.getTok().getLoc();
- Operands.push_back(ARM64Operand::CreateShiftedImm(Imm, ShiftAmount,
- S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
+ S, E, getContext()));
return MatchOperand_Success;
}
/// parseCondCodeString - Parse a Condition Code string.
-ARM64CC::CondCode ARM64AsmParser::parseCondCodeString(StringRef Cond) {
- ARM64CC::CondCode CC = StringSwitch<ARM64CC::CondCode>(Cond.lower())
- .Case("eq", ARM64CC::EQ)
- .Case("ne", ARM64CC::NE)
- .Case("cs", ARM64CC::HS)
- .Case("hs", ARM64CC::HS)
- .Case("cc", ARM64CC::LO)
- .Case("lo", ARM64CC::LO)
- .Case("mi", ARM64CC::MI)
- .Case("pl", ARM64CC::PL)
- .Case("vs", ARM64CC::VS)
- .Case("vc", ARM64CC::VC)
- .Case("hi", ARM64CC::HI)
- .Case("ls", ARM64CC::LS)
- .Case("ge", ARM64CC::GE)
- .Case("lt", ARM64CC::LT)
- .Case("gt", ARM64CC::GT)
- .Case("le", ARM64CC::LE)
- .Case("al", ARM64CC::AL)
- .Case("nv", ARM64CC::NV)
- .Default(ARM64CC::Invalid);
+AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
+ AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
+ .Case("eq", AArch64CC::EQ)
+ .Case("ne", AArch64CC::NE)
+ .Case("cs", AArch64CC::HS)
+ .Case("hs", AArch64CC::HS)
+ .Case("cc", AArch64CC::LO)
+ .Case("lo", AArch64CC::LO)
+ .Case("mi", AArch64CC::MI)
+ .Case("pl", AArch64CC::PL)
+ .Case("vs", AArch64CC::VS)
+ .Case("vc", AArch64CC::VC)
+ .Case("hi", AArch64CC::HI)
+ .Case("ls", AArch64CC::LS)
+ .Case("ge", AArch64CC::GE)
+ .Case("lt", AArch64CC::LT)
+ .Case("gt", AArch64CC::GT)
+ .Case("le", AArch64CC::LE)
+ .Case("al", AArch64CC::AL)
+ .Case("nv", AArch64CC::NV)
+ .Default(AArch64CC::Invalid);
return CC;
}
/// parseCondCode - Parse a Condition Code operand.
-bool ARM64AsmParser::parseCondCode(OperandVector &Operands,
- bool invertCondCode) {
+bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
+ bool invertCondCode) {
SMLoc S = getLoc();
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
StringRef Cond = Tok.getString();
- ARM64CC::CondCode CC = parseCondCodeString(Cond);
- if (CC == ARM64CC::Invalid)
+ AArch64CC::CondCode CC = parseCondCodeString(Cond);
+ if (CC == AArch64CC::Invalid)
return TokError("invalid condition code");
Parser.Lex(); // Eat identifier token.
if (invertCondCode)
- CC = ARM64CC::getInvertedCondCode(ARM64CC::CondCode(CC));
+ CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
Operands.push_back(
- ARM64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
+ AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
return false;
}
/// tryParseOptionalShift - Some operands take an optional shift argument. Parse
/// them if present.
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
const AsmToken &Tok = Parser.getTok();
std::string LowerID = Tok.getString().lower();
- ARM64_AM::ShiftExtendType ShOp =
- StringSwitch<ARM64_AM::ShiftExtendType>(LowerID)
- .Case("lsl", ARM64_AM::LSL)
- .Case("lsr", ARM64_AM::LSR)
- .Case("asr", ARM64_AM::ASR)
- .Case("ror", ARM64_AM::ROR)
- .Case("msl", ARM64_AM::MSL)
- .Case("uxtb", ARM64_AM::UXTB)
- .Case("uxth", ARM64_AM::UXTH)
- .Case("uxtw", ARM64_AM::UXTW)
- .Case("uxtx", ARM64_AM::UXTX)
- .Case("sxtb", ARM64_AM::SXTB)
- .Case("sxth", ARM64_AM::SXTH)
- .Case("sxtw", ARM64_AM::SXTW)
- .Case("sxtx", ARM64_AM::SXTX)
- .Default(ARM64_AM::InvalidShiftExtend);
+ AArch64_AM::ShiftExtendType ShOp =
+ StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
+ .Case("lsl", AArch64_AM::LSL)
+ .Case("lsr", AArch64_AM::LSR)
+ .Case("asr", AArch64_AM::ASR)
+ .Case("ror", AArch64_AM::ROR)
+ .Case("msl", AArch64_AM::MSL)
+ .Case("uxtb", AArch64_AM::UXTB)
+ .Case("uxth", AArch64_AM::UXTH)
+ .Case("uxtw", AArch64_AM::UXTW)
+ .Case("uxtx", AArch64_AM::UXTX)
+ .Case("sxtb", AArch64_AM::SXTB)
+ .Case("sxth", AArch64_AM::SXTH)
+ .Case("sxtw", AArch64_AM::SXTW)
+ .Case("sxtx", AArch64_AM::SXTX)
+ .Default(AArch64_AM::InvalidShiftExtend);
- if (ShOp == ARM64_AM::InvalidShiftExtend)
+ if (ShOp == AArch64_AM::InvalidShiftExtend)
return MatchOperand_NoMatch;
SMLoc S = Tok.getLoc();
@@ -2210,9 +2222,9 @@ ARM64AsmParser::tryParseOptionalShiftExt
bool Hash = getLexer().is(AsmToken::Hash);
if (!Hash && getLexer().isNot(AsmToken::Integer)) {
- if (ShOp == ARM64_AM::LSL || ShOp == ARM64_AM::LSR ||
- ShOp == ARM64_AM::ASR || ShOp == ARM64_AM::ROR ||
- ShOp == ARM64_AM::MSL) {
+ if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
+ ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
+ ShOp == AArch64_AM::MSL) {
// We expect a number here.
TokError("expected #imm after shift specifier");
return MatchOperand_ParseFail;
@@ -2221,7 +2233,7 @@ ARM64AsmParser::tryParseOptionalShiftExt
// "extend" type operatoins don't need an immediate, #0 is implicit.
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
Operands.push_back(
- ARM64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
+ AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
return MatchOperand_Success;
}
@@ -2246,21 +2258,21 @@ ARM64AsmParser::tryParseOptionalShiftExt
}
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateShiftExtend(ShOp, MCE->getValue(),
- true, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateShiftExtend(
+ ShOp, MCE->getValue(), true, S, E, getContext()));
return MatchOperand_Success;
}
/// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
/// the SYS instruction. Parse them specially so that we create a SYS MCInst.
-bool ARM64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
+bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands) {
if (Name.find('.') != StringRef::npos)
return TokError("invalid operand");
Mnemonic = Name;
Operands.push_back(
- ARM64Operand::CreateToken("sys", false, NameLoc, getContext()));
+ AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
const AsmToken &Tok = Parser.getTok();
StringRef Op = Tok.getString();
@@ -2272,14 +2284,14 @@ bool ARM64AsmParser::parseSysAlias(Strin
do { \
Expr = MCConstantExpr::Create(op1, getContext()); \
Operands.push_back( \
- ARM64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
+ AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
Operands.push_back( \
- ARM64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
+ AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
Operands.push_back( \
- ARM64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
+ AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
Expr = MCConstantExpr::Create(op2, getContext()); \
Operands.push_back( \
- ARM64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
+ AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
} while (0)
if (Mnemonic == "ic") {
@@ -2498,8 +2510,8 @@ bool ARM64AsmParser::parseSysAlias(Strin
return false;
}
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
const AsmToken &Tok = Parser.getTok();
// Can be either a #imm style literal or an option name
@@ -2522,7 +2534,7 @@ ARM64AsmParser::tryParseBarrierOperand(O
return MatchOperand_ParseFail;
}
Operands.push_back(
- ARM64Operand::CreateBarrier(MCE->getValue(), ExprLoc, getContext()));
+ AArch64Operand::CreateBarrier(MCE->getValue(), ExprLoc, getContext()));
return MatchOperand_Success;
}
@@ -2532,32 +2544,33 @@ ARM64AsmParser::tryParseBarrierOperand(O
}
bool Valid;
- unsigned Opt = ARM64DB::DBarrierMapper().fromString(Tok.getString(), Valid);
+ unsigned Opt = AArch64DB::DBarrierMapper().fromString(Tok.getString(), Valid);
if (!Valid) {
TokError("invalid barrier option name");
return MatchOperand_ParseFail;
}
// The only valid named option for ISB is 'sy'
- if (Mnemonic == "isb" && Opt != ARM64DB::SY) {
+ if (Mnemonic == "isb" && Opt != AArch64DB::SY) {
TokError("'sy' or #imm operand expected");
return MatchOperand_ParseFail;
}
- Operands.push_back(ARM64Operand::CreateBarrier(Opt, getLoc(), getContext()));
+ Operands.push_back(
+ AArch64Operand::CreateBarrier(Opt, getLoc(), getContext()));
Parser.Lex(); // Consume the option
return MatchOperand_Success;
}
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseSysReg(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return MatchOperand_NoMatch;
- Operands.push_back(ARM64Operand::CreateSysReg(Tok.getString(), getLoc(),
+ Operands.push_back(AArch64Operand::CreateSysReg(Tok.getString(), getLoc(),
STI.getFeatureBits(), getContext()));
Parser.Lex(); // Eat identifier
@@ -2565,7 +2578,7 @@ ARM64AsmParser::tryParseSysReg(OperandVe
}
/// tryParseVectorRegister - Parse a vector register operand.
-bool ARM64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
+bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
if (Parser.getTok().isNot(AsmToken::Identifier))
return true;
@@ -2576,11 +2589,12 @@ bool ARM64AsmParser::tryParseVectorRegis
if (Reg == -1)
return true;
Operands.push_back(
- ARM64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
+ AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
// If there was an explicit qualifier, that goes on as a literal text
// operand.
if (!Kind.empty())
- Operands.push_back(ARM64Operand::CreateToken(Kind, false, S, getContext()));
+ Operands.push_back(
+ AArch64Operand::CreateToken(Kind, false, S, getContext()));
// If there is an index specifier following the register, parse that too.
if (Parser.getTok().is(AsmToken::LBrac)) {
@@ -2604,15 +2618,15 @@ bool ARM64AsmParser::tryParseVectorRegis
Parser.Lex(); // Eat right bracket token.
- Operands.push_back(ARM64Operand::CreateVectorIndex(MCE->getValue(), SIdx, E,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
+ E, getContext()));
}
return false;
}
/// parseRegister - Parse a non-vector register operand.
-bool ARM64AsmParser::parseRegister(OperandVector &Operands) {
+bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
SMLoc S = getLoc();
// Try for a vector register.
if (!tryParseVectorRegister(Operands))
@@ -2623,7 +2637,7 @@ bool ARM64AsmParser::parseRegister(Opera
if (Reg == -1)
return true;
Operands.push_back(
- ARM64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
+ AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
// A small number of instructions (FMOVXDhighr, for example) have "[1]"
// as a string token in the instruction itself.
@@ -2640,11 +2654,11 @@ bool ARM64AsmParser::parseRegister(Opera
SMLoc RBracS = getLoc();
Parser.Lex();
Operands.push_back(
- ARM64Operand::CreateToken("[", false, LBracS, getContext()));
+ AArch64Operand::CreateToken("[", false, LBracS, getContext()));
Operands.push_back(
- ARM64Operand::CreateToken("1", false, IntS, getContext()));
+ AArch64Operand::CreateToken("1", false, IntS, getContext()));
Operands.push_back(
- ARM64Operand::CreateToken("]", false, RBracS, getContext()));
+ AArch64Operand::CreateToken("]", false, RBracS, getContext()));
return false;
}
}
@@ -2654,9 +2668,9 @@ bool ARM64AsmParser::parseRegister(Opera
return false;
}
-bool ARM64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
+bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
bool HasELFModifier = false;
- ARM64MCExpr::VariantKind RefKind;
+ AArch64MCExpr::VariantKind RefKind;
if (Parser.getTok().is(AsmToken::Colon)) {
Parser.Lex(); // Eat ':"
@@ -2669,45 +2683,45 @@ bool ARM64AsmParser::parseSymbolicImmVal
}
std::string LowerCase = Parser.getTok().getIdentifier().lower();
- RefKind = StringSwitch<ARM64MCExpr::VariantKind>(LowerCase)
- .Case("lo12", ARM64MCExpr::VK_LO12)
- .Case("abs_g3", ARM64MCExpr::VK_ABS_G3)
- .Case("abs_g2", ARM64MCExpr::VK_ABS_G2)
- .Case("abs_g2_s", ARM64MCExpr::VK_ABS_G2_S)
- .Case("abs_g2_nc", ARM64MCExpr::VK_ABS_G2_NC)
- .Case("abs_g1", ARM64MCExpr::VK_ABS_G1)
- .Case("abs_g1_s", ARM64MCExpr::VK_ABS_G1_S)
- .Case("abs_g1_nc", ARM64MCExpr::VK_ABS_G1_NC)
- .Case("abs_g0", ARM64MCExpr::VK_ABS_G0)
- .Case("abs_g0_s", ARM64MCExpr::VK_ABS_G0_S)
- .Case("abs_g0_nc", ARM64MCExpr::VK_ABS_G0_NC)
- .Case("dtprel_g2", ARM64MCExpr::VK_DTPREL_G2)
- .Case("dtprel_g1", ARM64MCExpr::VK_DTPREL_G1)
- .Case("dtprel_g1_nc", ARM64MCExpr::VK_DTPREL_G1_NC)
- .Case("dtprel_g0", ARM64MCExpr::VK_DTPREL_G0)
- .Case("dtprel_g0_nc", ARM64MCExpr::VK_DTPREL_G0_NC)
- .Case("dtprel_hi12", ARM64MCExpr::VK_DTPREL_HI12)
- .Case("dtprel_lo12", ARM64MCExpr::VK_DTPREL_LO12)
- .Case("dtprel_lo12_nc", ARM64MCExpr::VK_DTPREL_LO12_NC)
- .Case("tprel_g2", ARM64MCExpr::VK_TPREL_G2)
- .Case("tprel_g1", ARM64MCExpr::VK_TPREL_G1)
- .Case("tprel_g1_nc", ARM64MCExpr::VK_TPREL_G1_NC)
- .Case("tprel_g0", ARM64MCExpr::VK_TPREL_G0)
- .Case("tprel_g0_nc", ARM64MCExpr::VK_TPREL_G0_NC)
- .Case("tprel_hi12", ARM64MCExpr::VK_TPREL_HI12)
- .Case("tprel_lo12", ARM64MCExpr::VK_TPREL_LO12)
- .Case("tprel_lo12_nc", ARM64MCExpr::VK_TPREL_LO12_NC)
- .Case("tlsdesc_lo12", ARM64MCExpr::VK_TLSDESC_LO12)
- .Case("got", ARM64MCExpr::VK_GOT_PAGE)
- .Case("got_lo12", ARM64MCExpr::VK_GOT_LO12)
- .Case("gottprel", ARM64MCExpr::VK_GOTTPREL_PAGE)
- .Case("gottprel_lo12", ARM64MCExpr::VK_GOTTPREL_LO12_NC)
- .Case("gottprel_g1", ARM64MCExpr::VK_GOTTPREL_G1)
- .Case("gottprel_g0_nc", ARM64MCExpr::VK_GOTTPREL_G0_NC)
- .Case("tlsdesc", ARM64MCExpr::VK_TLSDESC_PAGE)
- .Default(ARM64MCExpr::VK_INVALID);
+ RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
+ .Case("lo12", AArch64MCExpr::VK_LO12)
+ .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
+ .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
+ .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
+ .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
+ .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
+ .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
+ .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
+ .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
+ .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
+ .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
+ .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
+ .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
+ .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
+ .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
+ .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
+ .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
+ .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
+ .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
+ .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
+ .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
+ .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
+ .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
+ .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
+ .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
+ .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
+ .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
+ .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
+ .Case("got", AArch64MCExpr::VK_GOT_PAGE)
+ .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
+ .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
+ .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
+ .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
+ .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
+ .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
+ .Default(AArch64MCExpr::VK_INVALID);
- if (RefKind == ARM64MCExpr::VK_INVALID) {
+ if (RefKind == AArch64MCExpr::VK_INVALID) {
Error(Parser.getTok().getLoc(),
"expect relocation specifier in operand after ':'");
return true;
@@ -2726,13 +2740,13 @@ bool ARM64AsmParser::parseSymbolicImmVal
return true;
if (HasELFModifier)
- ImmVal = ARM64MCExpr::Create(ImmVal, RefKind, getContext());
+ ImmVal = AArch64MCExpr::Create(ImmVal, RefKind, getContext());
return false;
}
/// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
-bool ARM64AsmParser::parseVectorList(OperandVector &Operands) {
+bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket");
SMLoc S = getLoc();
Parser.Lex(); // Eat left bracket token.
@@ -2798,7 +2812,7 @@ bool ARM64AsmParser::parseVectorList(Ope
if (!Kind.empty())
parseValidVectorKind(Kind, NumElements, ElementKind);
- Operands.push_back(ARM64Operand::CreateVectorList(
+ Operands.push_back(AArch64Operand::CreateVectorList(
FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
// If there is an index specifier following the list, parse that too.
@@ -2823,14 +2837,14 @@ bool ARM64AsmParser::parseVectorList(Ope
Parser.Lex(); // Eat right bracket token.
- Operands.push_back(ARM64Operand::CreateVectorIndex(MCE->getValue(), SIdx, E,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
+ E, getContext()));
}
return false;
}
-ARM64AsmParser::OperandMatchResultTy
-ARM64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
+AArch64AsmParser::OperandMatchResultTy
+AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
const AsmToken &Tok = Parser.getTok();
if (!Tok.is(AsmToken::Identifier))
return MatchOperand_NoMatch;
@@ -2839,14 +2853,15 @@ ARM64AsmParser::tryParseGPR64sp0Operand(
MCContext &Ctx = getContext();
const MCRegisterInfo *RI = Ctx.getRegisterInfo();
- if (!RI->getRegClass(ARM64::GPR64spRegClassID).contains(RegNum))
+ if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
return MatchOperand_NoMatch;
SMLoc S = getLoc();
Parser.Lex(); // Eat register
if (Parser.getTok().isNot(AsmToken::Comma)) {
- Operands.push_back(ARM64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
+ Operands.push_back(
+ AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
return MatchOperand_Success;
}
Parser.Lex(); // Eat comma.
@@ -2866,13 +2881,14 @@ ARM64AsmParser::tryParseGPR64sp0Operand(
return MatchOperand_ParseFail;
}
- Operands.push_back(ARM64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
+ Operands.push_back(
+ AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
return MatchOperand_Success;
}
/// parseOperand - Parse a arm instruction operand. For now this parses the
/// operand regardless of the mnemonic.
-bool ARM64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
+bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
bool invertCondCode) {
// Check if the current operand has a custom associated parser, if so, try to
// custom parse the operand, or fallback to the general approach.
@@ -2895,13 +2911,13 @@ bool ARM64AsmParser::parseOperand(Operan
return Error(S, "invalid operand");
SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateImm(Expr, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
return false;
}
case AsmToken::LBrac: {
SMLoc Loc = Parser.getTok().getLoc();
- Operands.push_back(ARM64Operand::CreateToken("[", false, Loc,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
+ getContext()));
Parser.Lex(); // Eat '['
// There's no comma after a '[', so we can parse the next operand
@@ -2933,7 +2949,7 @@ bool ARM64AsmParser::parseOperand(Operan
return true;
E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateImm(IdVal, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
return false;
}
case AsmToken::Integer:
@@ -2970,9 +2986,9 @@ bool ARM64AsmParser::parseOperand(Operan
Parser.Lex(); // Eat the token.
Operands.push_back(
- ARM64Operand::CreateToken("#0", false, S, getContext()));
+ AArch64Operand::CreateToken("#0", false, S, getContext()));
Operands.push_back(
- ARM64Operand::CreateToken(".0", false, S, getContext()));
+ AArch64Operand::CreateToken(".0", false, S, getContext()));
return false;
}
@@ -2981,17 +2997,17 @@ bool ARM64AsmParser::parseOperand(Operan
return true;
E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
- Operands.push_back(ARM64Operand::CreateImm(ImmVal, S, E, getContext()));
+ Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
return false;
}
}
}
-/// ParseInstruction - Parse an ARM64 instruction mnemonic followed by its
+/// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
/// operands.
-bool ARM64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
- StringRef Name, SMLoc NameLoc,
- OperandVector &Operands) {
+bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
+ StringRef Name, SMLoc NameLoc,
+ OperandVector &Operands) {
Name = StringSwitch<StringRef>(Name.lower())
.Case("beq", "b.eq")
.Case("bne", "b.ne")
@@ -3026,7 +3042,7 @@ bool ARM64AsmParser::ParseInstruction(Pa
}
Operands.push_back(
- ARM64Operand::CreateToken(Head, false, NameLoc, getContext()));
+ AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
Mnemonic = Head;
// Handle condition codes for a branch mnemonic
@@ -3037,13 +3053,13 @@ bool ARM64AsmParser::ParseInstruction(Pa
SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
(Head.data() - Name.data()));
- ARM64CC::CondCode CC = parseCondCodeString(Head);
- if (CC == ARM64CC::Invalid)
+ AArch64CC::CondCode CC = parseCondCodeString(Head);
+ if (CC == AArch64CC::Invalid)
return Error(SuffixLoc, "invalid condition code");
Operands.push_back(
- ARM64Operand::CreateToken(".", true, SuffixLoc, getContext()));
+ AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
Operands.push_back(
- ARM64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
+ AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
}
// Add the remaining tokens in the mnemonic.
@@ -3054,7 +3070,7 @@ bool ARM64AsmParser::ParseInstruction(Pa
SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
(Head.data() - Name.data()) + 1);
Operands.push_back(
- ARM64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
+ AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
}
// Conditional compare instructions have a Condition Code operand, which needs
@@ -3105,15 +3121,15 @@ bool ARM64AsmParser::ParseInstruction(Pa
// in the given context!
if (Parser.getTok().is(AsmToken::RBrac)) {
SMLoc Loc = Parser.getTok().getLoc();
- Operands.push_back(ARM64Operand::CreateToken("]", false, Loc,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateToken("]", false, Loc,
+ getContext()));
Parser.Lex();
}
if (Parser.getTok().is(AsmToken::Exclaim)) {
SMLoc Loc = Parser.getTok().getLoc();
- Operands.push_back(ARM64Operand::CreateToken("!", false, Loc,
- getContext()));
+ Operands.push_back(AArch64Operand::CreateToken("!", false, Loc,
+ getContext()));
Parser.Lex();
}
@@ -3134,18 +3150,18 @@ bool ARM64AsmParser::ParseInstruction(Pa
// FIXME: This entire function is a giant hack to provide us with decent
// operand range validation/diagnostics until TableGen/MC can be extended
// to support autogeneration of this kind of validation.
-bool ARM64AsmParser::validateInstruction(MCInst &Inst,
+bool AArch64AsmParser::validateInstruction(MCInst &Inst,
SmallVectorImpl<SMLoc> &Loc) {
const MCRegisterInfo *RI = getContext().getRegisterInfo();
// Check for indexed addressing modes w/ the base register being the
// same as a destination/source register or pair load where
// the Rt == Rt2. All of those are undefined behaviour.
switch (Inst.getOpcode()) {
- case ARM64::LDPSWpre:
- case ARM64::LDPWpost:
- case ARM64::LDPWpre:
- case ARM64::LDPXpost:
- case ARM64::LDPXpre: {
+ case AArch64::LDPSWpre:
+ case AArch64::LDPWpost:
+ case AArch64::LDPWpre:
+ case AArch64::LDPXpost:
+ case AArch64::LDPXpre: {
unsigned Rt = Inst.getOperand(1).getReg();
unsigned Rt2 = Inst.getOperand(2).getReg();
unsigned Rn = Inst.getOperand(3).getReg();
@@ -3157,41 +3173,41 @@ bool ARM64AsmParser::validateInstruction
"is also a destination");
// FALLTHROUGH
}
- case ARM64::LDPDi:
- case ARM64::LDPQi:
- case ARM64::LDPSi:
- case ARM64::LDPSWi:
- case ARM64::LDPWi:
- case ARM64::LDPXi: {
+ case AArch64::LDPDi:
+ case AArch64::LDPQi:
+ case AArch64::LDPSi:
+ case AArch64::LDPSWi:
+ case AArch64::LDPWi:
+ case AArch64::LDPXi: {
unsigned Rt = Inst.getOperand(0).getReg();
unsigned Rt2 = Inst.getOperand(1).getReg();
if (Rt == Rt2)
return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
break;
}
- case ARM64::LDPDpost:
- case ARM64::LDPDpre:
- case ARM64::LDPQpost:
- case ARM64::LDPQpre:
- case ARM64::LDPSpost:
- case ARM64::LDPSpre:
- case ARM64::LDPSWpost: {
+ case AArch64::LDPDpost:
+ case AArch64::LDPDpre:
+ case AArch64::LDPQpost:
+ case AArch64::LDPQpre:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSpre:
+ case AArch64::LDPSWpost: {
unsigned Rt = Inst.getOperand(1).getReg();
unsigned Rt2 = Inst.getOperand(2).getReg();
if (Rt == Rt2)
return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
break;
}
- case ARM64::STPDpost:
- case ARM64::STPDpre:
- case ARM64::STPQpost:
- case ARM64::STPQpre:
- case ARM64::STPSpost:
- case ARM64::STPSpre:
- case ARM64::STPWpost:
- case ARM64::STPWpre:
- case ARM64::STPXpost:
- case ARM64::STPXpre: {
+ case AArch64::STPDpost:
+ case AArch64::STPDpre:
+ case AArch64::STPQpost:
+ case AArch64::STPQpre:
+ case AArch64::STPSpost:
+ case AArch64::STPSpre:
+ case AArch64::STPWpost:
+ case AArch64::STPWpre:
+ case AArch64::STPXpost:
+ case AArch64::STPXpre: {
unsigned Rt = Inst.getOperand(1).getReg();
unsigned Rt2 = Inst.getOperand(2).getReg();
unsigned Rn = Inst.getOperand(3).getReg();
@@ -3203,28 +3219,28 @@ bool ARM64AsmParser::validateInstruction
"is also a source");
break;
}
- case ARM64::LDRBBpre:
- case ARM64::LDRBpre:
- case ARM64::LDRHHpre:
- case ARM64::LDRHpre:
- case ARM64::LDRSBWpre:
- case ARM64::LDRSBXpre:
- case ARM64::LDRSHWpre:
- case ARM64::LDRSHXpre:
- case ARM64::LDRSWpre:
- case ARM64::LDRWpre:
- case ARM64::LDRXpre:
- case ARM64::LDRBBpost:
- case ARM64::LDRBpost:
- case ARM64::LDRHHpost:
- case ARM64::LDRHpost:
- case ARM64::LDRSBWpost:
- case ARM64::LDRSBXpost:
- case ARM64::LDRSHWpost:
- case ARM64::LDRSHXpost:
- case ARM64::LDRSWpost:
- case ARM64::LDRWpost:
- case ARM64::LDRXpost: {
+ case AArch64::LDRBBpre:
+ case AArch64::LDRBpre:
+ case AArch64::LDRHHpre:
+ case AArch64::LDRHpre:
+ case AArch64::LDRSBWpre:
+ case AArch64::LDRSBXpre:
+ case AArch64::LDRSHWpre:
+ case AArch64::LDRSHXpre:
+ case AArch64::LDRSWpre:
+ case AArch64::LDRWpre:
+ case AArch64::LDRXpre:
+ case AArch64::LDRBBpost:
+ case AArch64::LDRBpost:
+ case AArch64::LDRHHpost:
+ case AArch64::LDRHpost:
+ case AArch64::LDRSBWpost:
+ case AArch64::LDRSBXpost:
+ case AArch64::LDRSHWpost:
+ case AArch64::LDRSHXpost:
+ case AArch64::LDRSWpost:
+ case AArch64::LDRWpost:
+ case AArch64::LDRXpost: {
unsigned Rt = Inst.getOperand(1).getReg();
unsigned Rn = Inst.getOperand(2).getReg();
if (RI->isSubRegisterEq(Rn, Rt))
@@ -3232,18 +3248,18 @@ bool ARM64AsmParser::validateInstruction
"is also a source");
break;
}
- case ARM64::STRBBpost:
- case ARM64::STRBpost:
- case ARM64::STRHHpost:
- case ARM64::STRHpost:
- case ARM64::STRWpost:
- case ARM64::STRXpost:
- case ARM64::STRBBpre:
- case ARM64::STRBpre:
- case ARM64::STRHHpre:
- case ARM64::STRHpre:
- case ARM64::STRWpre:
- case ARM64::STRXpre: {
+ case AArch64::STRBBpost:
+ case AArch64::STRBpost:
+ case AArch64::STRHHpost:
+ case AArch64::STRHpost:
+ case AArch64::STRWpost:
+ case AArch64::STRXpost:
+ case AArch64::STRBBpre:
+ case AArch64::STRBpre:
+ case AArch64::STRHHpre:
+ case AArch64::STRHpre:
+ case AArch64::STRWpre:
+ case AArch64::STRXpre: {
unsigned Rt = Inst.getOperand(1).getReg();
unsigned Rn = Inst.getOperand(2).getReg();
if (RI->isSubRegisterEq(Rn, Rt))
@@ -3257,19 +3273,19 @@ bool ARM64AsmParser::validateInstruction
// in the instructions being checked and this keeps the nested conditionals
// to a minimum.
switch (Inst.getOpcode()) {
- case ARM64::ADDSWri:
- case ARM64::ADDSXri:
- case ARM64::ADDWri:
- case ARM64::ADDXri:
- case ARM64::SUBSWri:
- case ARM64::SUBSXri:
- case ARM64::SUBWri:
- case ARM64::SUBXri: {
+ case AArch64::ADDSWri:
+ case AArch64::ADDSXri:
+ case AArch64::ADDWri:
+ case AArch64::ADDXri:
+ case AArch64::SUBSWri:
+ case AArch64::SUBSXri:
+ case AArch64::SUBWri:
+ case AArch64::SUBXri: {
// Annoyingly we can't do this in the isAddSubImm predicate, so there is
// some slight duplication here.
if (Inst.getOperand(2).isExpr()) {
const MCExpr *Expr = Inst.getOperand(2).getExpr();
- ARM64MCExpr::VariantKind ELFRefKind;
+ AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
@@ -3279,20 +3295,20 @@ bool ARM64AsmParser::validateInstruction
// Only allow these with ADDXri.
if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
- Inst.getOpcode() == ARM64::ADDXri)
+ Inst.getOpcode() == AArch64::ADDXri)
return false;
// Only allow these with ADDXri/ADDWri
- if ((ELFRefKind == ARM64MCExpr::VK_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_DTPREL_HI12 ||
- ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_DTPREL_LO12_NC ||
- ELFRefKind == ARM64MCExpr::VK_TPREL_HI12 ||
- ELFRefKind == ARM64MCExpr::VK_TPREL_LO12 ||
- ELFRefKind == ARM64MCExpr::VK_TPREL_LO12_NC ||
- ELFRefKind == ARM64MCExpr::VK_TLSDESC_LO12) &&
- (Inst.getOpcode() == ARM64::ADDXri ||
- Inst.getOpcode() == ARM64::ADDWri))
+ if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
+ ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
+ ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
+ ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
+ ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
+ ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
+ (Inst.getOpcode() == AArch64::ADDXri ||
+ Inst.getOpcode() == AArch64::ADDWri))
return false;
// Don't allow expressions in the immediate field otherwise
@@ -3305,7 +3321,7 @@ bool ARM64AsmParser::validateInstruction
}
}
-bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
+bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
switch (ErrCode) {
case Match_MissingFeature:
return Error(Loc,
@@ -3434,28 +3450,28 @@ bool ARM64AsmParser::showMatchError(SMLo
static const char *getSubtargetFeatureName(unsigned Val);
-bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
- OperandVector &Operands,
- MCStreamer &Out,
- unsigned &ErrorInfo,
- bool MatchingInlineAsm) {
+bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+ OperandVector &Operands,
+ MCStreamer &Out,
+ unsigned &ErrorInfo,
+ bool MatchingInlineAsm) {
assert(!Operands.empty() && "Unexpect empty operand list!");
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[0]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[0]);
assert(Op->isToken() && "Leading operand should always be a mnemonic!");
StringRef Tok = Op->getToken();
unsigned NumOperands = Operands.size();
if (NumOperands == 4 && Tok == "lsl") {
- ARM64Operand *Op2 = static_cast<ARM64Operand *>(Operands[2]);
- ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
+ AArch64Operand *Op2 = static_cast<AArch64Operand *>(Operands[2]);
+ AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
if (Op2->isReg() && Op3->isImm()) {
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
if (Op3CE) {
uint64_t Op3Val = Op3CE->getValue();
uint64_t NewOp3Val = 0;
uint64_t NewOp4Val = 0;
- if (ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(
+ if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
Op2->getReg())) {
NewOp3Val = (32 - Op3Val) & 0x1f;
NewOp4Val = 31 - Op3Val;
@@ -3467,11 +3483,11 @@ bool ARM64AsmParser::MatchAndEmitInstruc
const MCExpr *NewOp3 = MCConstantExpr::Create(NewOp3Val, getContext());
const MCExpr *NewOp4 = MCConstantExpr::Create(NewOp4Val, getContext());
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"ubfm", false, Op->getStartLoc(), getContext());
- Operands[3] = ARM64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
- Op3->getEndLoc(), getContext());
- Operands.push_back(ARM64Operand::CreateImm(
+ Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
+ Op3->getEndLoc(), getContext());
+ Operands.push_back(AArch64Operand::CreateImm(
NewOp4, Op3->getStartLoc(), Op3->getEndLoc(), getContext()));
delete Op3;
delete Op;
@@ -3481,9 +3497,9 @@ bool ARM64AsmParser::MatchAndEmitInstruc
// FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
// UBFIZ -> UBFM aliases.
if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
- ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
- ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
- ARM64Operand *Op4 = static_cast<ARM64Operand *>(Operands[4]);
+ AArch64Operand *Op1 = static_cast<AArch64Operand *>(Operands[1]);
+ AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
+ AArch64Operand *Op4 = static_cast<AArch64Operand *>(Operands[4]);
if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
@@ -3494,7 +3510,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
uint64_t Op4Val = Op4CE->getValue();
uint64_t RegWidth = 0;
- if (ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
Op1->getReg()))
RegWidth = 64;
else
@@ -3508,7 +3524,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
"expected integer in range [1, 32]");
uint64_t NewOp3Val = 0;
- if (ARM64MCRegisterClasses[ARM64::GPR32allRegClassID].contains(
+ if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
Op1->getReg()))
NewOp3Val = (32 - Op3Val) & 0x1f;
else
@@ -3524,18 +3540,18 @@ bool ARM64AsmParser::MatchAndEmitInstruc
MCConstantExpr::Create(NewOp3Val, getContext());
const MCExpr *NewOp4 =
MCConstantExpr::Create(NewOp4Val, getContext());
- Operands[3] = ARM64Operand::CreateImm(NewOp3, Op3->getStartLoc(),
- Op3->getEndLoc(), getContext());
- Operands[4] = ARM64Operand::CreateImm(NewOp4, Op4->getStartLoc(),
- Op4->getEndLoc(), getContext());
+ Operands[3] = AArch64Operand::CreateImm(
+ NewOp3, Op3->getStartLoc(), Op3->getEndLoc(), getContext());
+ Operands[4] = AArch64Operand::CreateImm(
+ NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
if (Tok == "bfi")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"bfm", false, Op->getStartLoc(), getContext());
else if (Tok == "sbfiz")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"sbfm", false, Op->getStartLoc(), getContext());
else if (Tok == "ubfiz")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"ubfm", false, Op->getStartLoc(), getContext());
else
llvm_unreachable("No valid mnemonic for alias?");
@@ -3550,9 +3566,9 @@ bool ARM64AsmParser::MatchAndEmitInstruc
// UBFX -> UBFM aliases.
} else if (NumOperands == 5 &&
(Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
- ARM64Operand *Op1 = static_cast<ARM64Operand *>(Operands[1]);
- ARM64Operand *Op3 = static_cast<ARM64Operand *>(Operands[3]);
- ARM64Operand *Op4 = static_cast<ARM64Operand *>(Operands[4]);
+ AArch64Operand *Op1 = static_cast<AArch64Operand *>(Operands[1]);
+ AArch64Operand *Op3 = static_cast<AArch64Operand *>(Operands[3]);
+ AArch64Operand *Op4 = static_cast<AArch64Operand *>(Operands[4]);
if (Op1->isReg() && Op3->isImm() && Op4->isImm()) {
const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3->getImm());
@@ -3563,7 +3579,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
uint64_t Op4Val = Op4CE->getValue();
uint64_t RegWidth = 0;
- if (ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
Op1->getReg()))
RegWidth = 64;
else
@@ -3584,16 +3600,16 @@ bool ARM64AsmParser::MatchAndEmitInstruc
const MCExpr *NewOp4 =
MCConstantExpr::Create(NewOp4Val, getContext());
- Operands[4] = ARM64Operand::CreateImm(
+ Operands[4] = AArch64Operand::CreateImm(
NewOp4, Op4->getStartLoc(), Op4->getEndLoc(), getContext());
if (Tok == "bfxil")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"bfm", false, Op->getStartLoc(), getContext());
else if (Tok == "sbfx")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"sbfm", false, Op->getStartLoc(), getContext());
else if (Tok == "ubfx")
- Operands[0] = ARM64Operand::CreateToken(
+ Operands[0] = AArch64Operand::CreateToken(
"ubfm", false, Op->getStartLoc(), getContext());
else
llvm_unreachable("No valid mnemonic for alias?");
@@ -3610,44 +3626,44 @@ bool ARM64AsmParser::MatchAndEmitInstruc
if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
// The source register can be Wn here, but the matcher expects a
// GPR64. Twiddle it here if necessary.
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[2]);
if (Op->isReg()) {
unsigned Reg = getXRegFromWReg(Op->getReg());
- Operands[2] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(),
- Op->getEndLoc(), getContext());
+ Operands[2] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
+ Op->getEndLoc(), getContext());
delete Op;
}
}
// FIXME: Likewise for sxt[bh] with a Xd dst operand
else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
if (Op->isReg() &&
- ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
Op->getReg())) {
// The source register can be Wn here, but the matcher expects a
// GPR64. Twiddle it here if necessary.
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[2]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[2]);
if (Op->isReg()) {
unsigned Reg = getXRegFromWReg(Op->getReg());
- Operands[2] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(),
- Op->getEndLoc(), getContext());
+ Operands[2] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
+ Op->getEndLoc(), getContext());
delete Op;
}
}
}
// FIXME: Likewise for uxt[bh] with a Xd dst operand
else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
if (Op->isReg() &&
- ARM64MCRegisterClasses[ARM64::GPR64allRegClassID].contains(
+ AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
Op->getReg())) {
// The source register can be Wn here, but the matcher expects a
// GPR32. Twiddle it here if necessary.
- ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[1]);
+ AArch64Operand *Op = static_cast<AArch64Operand *>(Operands[1]);
if (Op->isReg()) {
unsigned Reg = getWRegFromXReg(Op->getReg());
- Operands[1] = ARM64Operand::CreateReg(Reg, false, Op->getStartLoc(),
- Op->getEndLoc(), getContext());
+ Operands[1] = AArch64Operand::CreateReg(Reg, false, Op->getStartLoc(),
+ Op->getEndLoc(), getContext());
delete Op;
}
}
@@ -3655,16 +3671,17 @@ bool ARM64AsmParser::MatchAndEmitInstruc
// Yet another horrible hack to handle FMOV Rd, #0.0 using [WX]ZR.
if (NumOperands == 3 && Tok == "fmov") {
- ARM64Operand *RegOp = static_cast<ARM64Operand *>(Operands[1]);
- ARM64Operand *ImmOp = static_cast<ARM64Operand *>(Operands[2]);
+ AArch64Operand *RegOp = static_cast<AArch64Operand *>(Operands[1]);
+ AArch64Operand *ImmOp = static_cast<AArch64Operand *>(Operands[2]);
if (RegOp->isReg() && ImmOp->isFPImm() &&
ImmOp->getFPImm() == (unsigned)-1) {
- unsigned zreg = ARM64MCRegisterClasses[ARM64::FPR32RegClassID].contains(
- RegOp->getReg())
- ? ARM64::WZR
- : ARM64::XZR;
- Operands[2] = ARM64Operand::CreateReg(zreg, false, Op->getStartLoc(),
- Op->getEndLoc(), getContext());
+ unsigned zreg =
+ AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
+ RegOp->getReg())
+ ? AArch64::WZR
+ : AArch64::XZR;
+ Operands[2] = AArch64Operand::CreateReg(zreg, false, Op->getStartLoc(),
+ Op->getEndLoc(), getContext());
delete ImmOp;
}
}
@@ -3718,14 +3735,14 @@ bool ARM64AsmParser::MatchAndEmitInstruc
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction");
- ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc();
+ ErrorLoc = ((AArch64Operand *)Operands[ErrorInfo])->getStartLoc();
if (ErrorLoc == SMLoc())
ErrorLoc = IDLoc;
}
// If the match failed on a suffix token operand, tweak the diagnostic
// accordingly.
- if (((ARM64Operand *)Operands[ErrorInfo])->isToken() &&
- ((ARM64Operand *)Operands[ErrorInfo])->isTokenSuffix())
+ if (((AArch64Operand *)Operands[ErrorInfo])->isToken() &&
+ ((AArch64Operand *)Operands[ErrorInfo])->isTokenSuffix())
MatchResult = Match_InvalidSuffix;
return showMatchError(ErrorLoc, MatchResult);
@@ -3779,7 +3796,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
case Match_MRS: {
// Any time we get here, there's nothing fancy to do. Just get the
// operand SMLoc and display the diagnostic.
- SMLoc ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc();
+ SMLoc ErrorLoc = ((AArch64Operand *)Operands[ErrorInfo])->getStartLoc();
if (ErrorLoc == SMLoc())
ErrorLoc = IDLoc;
return showMatchError(ErrorLoc, MatchResult);
@@ -3791,7 +3808,7 @@ bool ARM64AsmParser::MatchAndEmitInstruc
}
/// ParseDirective parses the arm specific directives
-bool ARM64AsmParser::ParseDirective(AsmToken DirectiveID) {
+bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getIdentifier();
SMLoc Loc = DirectiveID.getLoc();
if (IDVal == ".hword")
@@ -3808,7 +3825,7 @@ bool ARM64AsmParser::ParseDirective(AsmT
/// parseDirectiveWord
/// ::= .word [ expression (, expression)* ]
-bool ARM64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
+bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
@@ -3833,17 +3850,17 @@ bool ARM64AsmParser::parseDirectiveWord(
// parseDirectiveTLSDescCall:
// ::= .tlsdesccall symbol
-bool ARM64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
+bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return Error(L, "expected symbol after directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, getContext());
- Expr = ARM64MCExpr::Create(Expr, ARM64MCExpr::VK_TLSDESC, getContext());
+ Expr = AArch64MCExpr::Create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
MCInst Inst;
- Inst.setOpcode(ARM64::TLSDESCCALL);
+ Inst.setOpcode(AArch64::TLSDESCCALL);
Inst.addOperand(MCOperand::CreateExpr(Expr));
getParser().getStreamer().EmitInstruction(Inst, STI);
@@ -3852,7 +3869,7 @@ bool ARM64AsmParser::parseDirectiveTLSDe
/// ::= .loh <lohName | lohId> label1, ..., labelN
/// The number of arguments depends on the loh identifier.
-bool ARM64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
+bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
if (IDVal != MCLOHDirectiveName())
return true;
MCLOHType Kind;
@@ -3904,15 +3921,15 @@ bool ARM64AsmParser::parseDirectiveLOH(S
}
bool
-ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
- ARM64MCExpr::VariantKind &ELFRefKind,
- MCSymbolRefExpr::VariantKind &DarwinRefKind,
- int64_t &Addend) {
- ELFRefKind = ARM64MCExpr::VK_INVALID;
+AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
+ AArch64MCExpr::VariantKind &ELFRefKind,
+ MCSymbolRefExpr::VariantKind &DarwinRefKind,
+ int64_t &Addend) {
+ ELFRefKind = AArch64MCExpr::VK_INVALID;
DarwinRefKind = MCSymbolRefExpr::VK_None;
Addend = 0;
- if (const ARM64MCExpr *AE = dyn_cast<ARM64MCExpr>(Expr)) {
+ if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
ELFRefKind = AE->getKind();
Expr = AE->getSubExpr();
}
@@ -3949,29 +3966,29 @@ ARM64AsmParser::classifySymbolRef(const
// It's some symbol reference + a constant addend, but really
// shouldn't use both Darwin and ELF syntax.
- return ELFRefKind == ARM64MCExpr::VK_INVALID ||
+ return ELFRefKind == AArch64MCExpr::VK_INVALID ||
DarwinRefKind == MCSymbolRefExpr::VK_None;
}
/// Force static initialization.
-extern "C" void LLVMInitializeARM64AsmParser() {
- RegisterMCAsmParser<ARM64AsmParser> X(TheARM64leTarget);
- RegisterMCAsmParser<ARM64AsmParser> Y(TheARM64beTarget);
+extern "C" void LLVMInitializeAArch64AsmParser() {
+ RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64leTarget);
+ RegisterMCAsmParser<AArch64AsmParser> Y(TheAArch64beTarget);
- RegisterMCAsmParser<ARM64AsmParser> Z(TheAArch64leTarget);
- RegisterMCAsmParser<ARM64AsmParser> W(TheAArch64beTarget);
+ RegisterMCAsmParser<AArch64AsmParser> Z(TheARM64leTarget);
+ RegisterMCAsmParser<AArch64AsmParser> W(TheARM64beTarget);
}
#define GET_REGISTER_MATCHER
#define GET_SUBTARGET_FEATURE_NAME
#define GET_MATCHER_IMPLEMENTATION
-#include "ARM64GenAsmMatcher.inc"
+#include "AArch64GenAsmMatcher.inc"
// Define this matcher function after the auto-generated include so we
// have the match class enum definitions.
-unsigned ARM64AsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
- unsigned Kind) {
- ARM64Operand *Op = static_cast<ARM64Operand *>(AsmOp);
+unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp,
+ unsigned Kind) {
+ AArch64Operand *Op = static_cast<AArch64Operand *>(AsmOp);
// If the kind is a token for a literal immediate, check if our asm
// operand matches. This is for InstAliases which have a fixed-value
// immediate in the syntax.
Copied: llvm/trunk/lib/Target/AArch64/AsmParser/CMakeLists.txt (from r209576, llvm/trunk/lib/Target/ARM64/AsmParser/CMakeLists.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/CMakeLists.txt?p2=llvm/trunk/lib/Target/AArch64/AsmParser/CMakeLists.txt&p1=llvm/trunk/lib/Target/ARM64/AsmParser/CMakeLists.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -1,6 +1,6 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-add_llvm_library(LLVMARM64AsmParser
- ARM64AsmParser.cpp
+add_llvm_library(LLVMAArch64AsmParser
+ AArch64AsmParser.cpp
)
Copied: llvm/trunk/lib/Target/AArch64/AsmParser/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/AsmParser/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/AsmParser/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/AsmParser/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/AsmParser/LLVMBuild.txt ---------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/AsmParser/LLVMBuild.txt ---------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,7 +17,7 @@
[component_0]
type = Library
-name = ARM64AsmParser
-parent = ARM64
-required_libraries = ARM64Desc ARM64Info ARM64Utils MC MCParser Support
-add_to_library_groups = ARM64
+name = AArch64AsmParser
+parent = AArch64
+required_libraries = AArch64Desc AArch64Info AArch64Utils MC MCParser Support
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/AsmParser/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/AsmParser/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/Makefile?p2=llvm/trunk/lib/Target/AArch64/AsmParser/Makefile&p1=llvm/trunk/lib/Target/ARM64/AsmParser/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM/AsmParser/Makefile -------------------*- Makefile -*-===##
+##===- lib/Target/AArch64/AsmParser/Makefile ---------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64AsmParser
+LIBRARYNAME = LLVMAArch64AsmParser
# Hack: we need to include 'main' ARM target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
Added: llvm/trunk/lib/Target/AArch64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/CMakeLists.txt?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/AArch64/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -0,0 +1,51 @@
+set(LLVM_TARGET_DEFINITIONS AArch64.td)
+
+tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM AArch64GenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM AArch64GenMCCodeEmitter.inc -gen-emitter -mc-emitter)
+tablegen(LLVM AArch64GenMCPseudoLowering.inc -gen-pseudo-lowering)
+tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
+tablegen(LLVM AArch64GenAsmMatcher.inc -gen-asm-matcher)
+tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
+tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
+tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
+tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget)
+tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
+add_public_tablegen_target(AArch64CommonTableGen)
+
+add_llvm_target(AArch64CodeGen
+ AArch64AddressTypePromotion.cpp
+ AArch64AdvSIMDScalarPass.cpp
+ AArch64AsmPrinter.cpp
+ AArch64BranchRelaxation.cpp
+ AArch64CleanupLocalDynamicTLSPass.cpp
+ AArch64CollectLOH.cpp
+ AArch64ConditionalCompares.cpp
+ AArch64DeadRegisterDefinitionsPass.cpp
+ AArch64ExpandPseudoInsts.cpp
+ AArch64FastISel.cpp
+ AArch64FrameLowering.cpp
+ AArch64ISelDAGToDAG.cpp
+ AArch64ISelLowering.cpp
+ AArch64InstrInfo.cpp
+ AArch64LoadStoreOptimizer.cpp
+ AArch64MCInstLower.cpp
+ AArch64PromoteConstant.cpp
+ AArch64RegisterInfo.cpp
+ AArch64SelectionDAGInfo.cpp
+ AArch64StorePairSuppress.cpp
+ AArch64Subtarget.cpp
+ AArch64TargetMachine.cpp
+ AArch64TargetObjectFile.cpp
+ AArch64TargetTransformInfo.cpp
+)
+
+add_dependencies(LLVMAArch64CodeGen intrinsics_gen)
+
+add_subdirectory(TargetInfo)
+add_subdirectory(AsmParser)
+add_subdirectory(Disassembler)
+add_subdirectory(InstPrinter)
+add_subdirectory(MCTargetDesc)
+add_subdirectory(Utils)
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp?p2=llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp&p1=llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64Disassembler.cpp - Disassembler for ARM64 -----------*- C++ -*-===//
+//===- AArch64Disassembler.cpp - Disassembler for AArch64 -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,11 +10,11 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64Disassembler.h"
-#include "ARM64ExternalSymbolizer.h"
-#include "ARM64Subtarget.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "Utils/ARM64BaseInfo.h"
+#include "AArch64Disassembler.h"
+#include "AArch64ExternalSymbolizer.h"
+#include "AArch64Subtarget.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/Support/Debug.h"
@@ -24,7 +24,7 @@
using namespace llvm;
-#define DEBUG_TYPE "arm64-disassembler"
+#define DEBUG_TYPE "aarch64-disassembler"
// Pull DecodeStatus and its enum values into the global namespace.
typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
@@ -186,20 +186,20 @@ static bool Check(DecodeStatus &Out, Dec
llvm_unreachable("Invalid DecodeStatus!");
}
-#include "ARM64GenDisassemblerTables.inc"
-#include "ARM64GenInstrInfo.inc"
+#include "AArch64GenDisassemblerTables.inc"
+#include "AArch64GenInstrInfo.inc"
#define Success llvm::MCDisassembler::Success
#define Fail llvm::MCDisassembler::Fail
#define SoftFail llvm::MCDisassembler::SoftFail
-static MCDisassembler *createARM64Disassembler(const Target &T,
+static MCDisassembler *createAArch64Disassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
- return new ARM64Disassembler(STI, Ctx);
+ return new AArch64Disassembler(STI, Ctx);
}
-DecodeStatus ARM64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
+DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
const MemoryObject &Region,
uint64_t Address,
raw_ostream &os,
@@ -223,43 +223,44 @@ DecodeStatus ARM64Disassembler::getInstr
}
static MCSymbolizer *
-createARM64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+createAArch64ExternalSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp,
void *DisInfo, MCContext *Ctx,
MCRelocationInfo *RelInfo) {
- return new llvm::ARM64ExternalSymbolizer(
+ return new llvm::AArch64ExternalSymbolizer(
*Ctx,
std::unique_ptr<MCRelocationInfo>(RelInfo),
GetOpInfo, SymbolLookUp, DisInfo);
}
-extern "C" void LLVMInitializeARM64Disassembler() {
- TargetRegistry::RegisterMCDisassembler(TheARM64leTarget,
- createARM64Disassembler);
- TargetRegistry::RegisterMCDisassembler(TheARM64beTarget,
- createARM64Disassembler);
- TargetRegistry::RegisterMCSymbolizer(TheARM64leTarget,
- createARM64ExternalSymbolizer);
- TargetRegistry::RegisterMCSymbolizer(TheARM64beTarget,
- createARM64ExternalSymbolizer);
-
+extern "C" void LLVMInitializeAArch64Disassembler() {
TargetRegistry::RegisterMCDisassembler(TheAArch64leTarget,
- createARM64Disassembler);
+ createAArch64Disassembler);
TargetRegistry::RegisterMCDisassembler(TheAArch64beTarget,
- createARM64Disassembler);
+ createAArch64Disassembler);
TargetRegistry::RegisterMCSymbolizer(TheAArch64leTarget,
- createARM64ExternalSymbolizer);
+ createAArch64ExternalSymbolizer);
TargetRegistry::RegisterMCSymbolizer(TheAArch64beTarget,
- createARM64ExternalSymbolizer);
+ createAArch64ExternalSymbolizer);
+
+ TargetRegistry::RegisterMCDisassembler(TheARM64leTarget,
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCDisassembler(TheARM64beTarget,
+ createAArch64Disassembler);
+ TargetRegistry::RegisterMCSymbolizer(TheARM64leTarget,
+ createAArch64ExternalSymbolizer);
+ TargetRegistry::RegisterMCSymbolizer(TheARM64beTarget,
+ createAArch64ExternalSymbolizer);
}
static const unsigned FPR128DecoderTable[] = {
- ARM64::Q0, ARM64::Q1, ARM64::Q2, ARM64::Q3, ARM64::Q4, ARM64::Q5,
- ARM64::Q6, ARM64::Q7, ARM64::Q8, ARM64::Q9, ARM64::Q10, ARM64::Q11,
- ARM64::Q12, ARM64::Q13, ARM64::Q14, ARM64::Q15, ARM64::Q16, ARM64::Q17,
- ARM64::Q18, ARM64::Q19, ARM64::Q20, ARM64::Q21, ARM64::Q22, ARM64::Q23,
- ARM64::Q24, ARM64::Q25, ARM64::Q26, ARM64::Q27, ARM64::Q28, ARM64::Q29,
- ARM64::Q30, ARM64::Q31
+ AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
+ AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
+ AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
+ AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
+ AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
+ AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
+ AArch64::Q30, AArch64::Q31
};
static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -282,12 +283,13 @@ static DecodeStatus DecodeFPR128_loRegis
}
static const unsigned FPR64DecoderTable[] = {
- ARM64::D0, ARM64::D1, ARM64::D2, ARM64::D3, ARM64::D4, ARM64::D5,
- ARM64::D6, ARM64::D7, ARM64::D8, ARM64::D9, ARM64::D10, ARM64::D11,
- ARM64::D12, ARM64::D13, ARM64::D14, ARM64::D15, ARM64::D16, ARM64::D17,
- ARM64::D18, ARM64::D19, ARM64::D20, ARM64::D21, ARM64::D22, ARM64::D23,
- ARM64::D24, ARM64::D25, ARM64::D26, ARM64::D27, ARM64::D28, ARM64::D29,
- ARM64::D30, ARM64::D31
+ AArch64::D0, AArch64::D1, AArch64::D2, AArch64::D3, AArch64::D4,
+ AArch64::D5, AArch64::D6, AArch64::D7, AArch64::D8, AArch64::D9,
+ AArch64::D10, AArch64::D11, AArch64::D12, AArch64::D13, AArch64::D14,
+ AArch64::D15, AArch64::D16, AArch64::D17, AArch64::D18, AArch64::D19,
+ AArch64::D20, AArch64::D21, AArch64::D22, AArch64::D23, AArch64::D24,
+ AArch64::D25, AArch64::D26, AArch64::D27, AArch64::D28, AArch64::D29,
+ AArch64::D30, AArch64::D31
};
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -302,12 +304,13 @@ static DecodeStatus DecodeFPR64RegisterC
}
static const unsigned FPR32DecoderTable[] = {
- ARM64::S0, ARM64::S1, ARM64::S2, ARM64::S3, ARM64::S4, ARM64::S5,
- ARM64::S6, ARM64::S7, ARM64::S8, ARM64::S9, ARM64::S10, ARM64::S11,
- ARM64::S12, ARM64::S13, ARM64::S14, ARM64::S15, ARM64::S16, ARM64::S17,
- ARM64::S18, ARM64::S19, ARM64::S20, ARM64::S21, ARM64::S22, ARM64::S23,
- ARM64::S24, ARM64::S25, ARM64::S26, ARM64::S27, ARM64::S28, ARM64::S29,
- ARM64::S30, ARM64::S31
+ AArch64::S0, AArch64::S1, AArch64::S2, AArch64::S3, AArch64::S4,
+ AArch64::S5, AArch64::S6, AArch64::S7, AArch64::S8, AArch64::S9,
+ AArch64::S10, AArch64::S11, AArch64::S12, AArch64::S13, AArch64::S14,
+ AArch64::S15, AArch64::S16, AArch64::S17, AArch64::S18, AArch64::S19,
+ AArch64::S20, AArch64::S21, AArch64::S22, AArch64::S23, AArch64::S24,
+ AArch64::S25, AArch64::S26, AArch64::S27, AArch64::S28, AArch64::S29,
+ AArch64::S30, AArch64::S31
};
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -322,12 +325,13 @@ static DecodeStatus DecodeFPR32RegisterC
}
static const unsigned FPR16DecoderTable[] = {
- ARM64::H0, ARM64::H1, ARM64::H2, ARM64::H3, ARM64::H4, ARM64::H5,
- ARM64::H6, ARM64::H7, ARM64::H8, ARM64::H9, ARM64::H10, ARM64::H11,
- ARM64::H12, ARM64::H13, ARM64::H14, ARM64::H15, ARM64::H16, ARM64::H17,
- ARM64::H18, ARM64::H19, ARM64::H20, ARM64::H21, ARM64::H22, ARM64::H23,
- ARM64::H24, ARM64::H25, ARM64::H26, ARM64::H27, ARM64::H28, ARM64::H29,
- ARM64::H30, ARM64::H31
+ AArch64::H0, AArch64::H1, AArch64::H2, AArch64::H3, AArch64::H4,
+ AArch64::H5, AArch64::H6, AArch64::H7, AArch64::H8, AArch64::H9,
+ AArch64::H10, AArch64::H11, AArch64::H12, AArch64::H13, AArch64::H14,
+ AArch64::H15, AArch64::H16, AArch64::H17, AArch64::H18, AArch64::H19,
+ AArch64::H20, AArch64::H21, AArch64::H22, AArch64::H23, AArch64::H24,
+ AArch64::H25, AArch64::H26, AArch64::H27, AArch64::H28, AArch64::H29,
+ AArch64::H30, AArch64::H31
};
static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -342,12 +346,13 @@ static DecodeStatus DecodeFPR16RegisterC
}
static const unsigned FPR8DecoderTable[] = {
- ARM64::B0, ARM64::B1, ARM64::B2, ARM64::B3, ARM64::B4, ARM64::B5,
- ARM64::B6, ARM64::B7, ARM64::B8, ARM64::B9, ARM64::B10, ARM64::B11,
- ARM64::B12, ARM64::B13, ARM64::B14, ARM64::B15, ARM64::B16, ARM64::B17,
- ARM64::B18, ARM64::B19, ARM64::B20, ARM64::B21, ARM64::B22, ARM64::B23,
- ARM64::B24, ARM64::B25, ARM64::B26, ARM64::B27, ARM64::B28, ARM64::B29,
- ARM64::B30, ARM64::B31
+ AArch64::B0, AArch64::B1, AArch64::B2, AArch64::B3, AArch64::B4,
+ AArch64::B5, AArch64::B6, AArch64::B7, AArch64::B8, AArch64::B9,
+ AArch64::B10, AArch64::B11, AArch64::B12, AArch64::B13, AArch64::B14,
+ AArch64::B15, AArch64::B16, AArch64::B17, AArch64::B18, AArch64::B19,
+ AArch64::B20, AArch64::B21, AArch64::B22, AArch64::B23, AArch64::B24,
+ AArch64::B25, AArch64::B26, AArch64::B27, AArch64::B28, AArch64::B29,
+ AArch64::B30, AArch64::B31
};
static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -362,12 +367,13 @@ static DecodeStatus DecodeFPR8RegisterCl
}
static const unsigned GPR64DecoderTable[] = {
- ARM64::X0, ARM64::X1, ARM64::X2, ARM64::X3, ARM64::X4, ARM64::X5,
- ARM64::X6, ARM64::X7, ARM64::X8, ARM64::X9, ARM64::X10, ARM64::X11,
- ARM64::X12, ARM64::X13, ARM64::X14, ARM64::X15, ARM64::X16, ARM64::X17,
- ARM64::X18, ARM64::X19, ARM64::X20, ARM64::X21, ARM64::X22, ARM64::X23,
- ARM64::X24, ARM64::X25, ARM64::X26, ARM64::X27, ARM64::X28, ARM64::FP,
- ARM64::LR, ARM64::XZR
+ AArch64::X0, AArch64::X1, AArch64::X2, AArch64::X3, AArch64::X4,
+ AArch64::X5, AArch64::X6, AArch64::X7, AArch64::X8, AArch64::X9,
+ AArch64::X10, AArch64::X11, AArch64::X12, AArch64::X13, AArch64::X14,
+ AArch64::X15, AArch64::X16, AArch64::X17, AArch64::X18, AArch64::X19,
+ AArch64::X20, AArch64::X21, AArch64::X22, AArch64::X23, AArch64::X24,
+ AArch64::X25, AArch64::X26, AArch64::X27, AArch64::X28, AArch64::FP,
+ AArch64::LR, AArch64::XZR
};
static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -387,19 +393,20 @@ static DecodeStatus DecodeGPR64spRegiste
if (RegNo > 31)
return Fail;
unsigned Register = GPR64DecoderTable[RegNo];
- if (Register == ARM64::XZR)
- Register = ARM64::SP;
+ if (Register == AArch64::XZR)
+ Register = AArch64::SP;
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned GPR32DecoderTable[] = {
- ARM64::W0, ARM64::W1, ARM64::W2, ARM64::W3, ARM64::W4, ARM64::W5,
- ARM64::W6, ARM64::W7, ARM64::W8, ARM64::W9, ARM64::W10, ARM64::W11,
- ARM64::W12, ARM64::W13, ARM64::W14, ARM64::W15, ARM64::W16, ARM64::W17,
- ARM64::W18, ARM64::W19, ARM64::W20, ARM64::W21, ARM64::W22, ARM64::W23,
- ARM64::W24, ARM64::W25, ARM64::W26, ARM64::W27, ARM64::W28, ARM64::W29,
- ARM64::W30, ARM64::WZR
+ AArch64::W0, AArch64::W1, AArch64::W2, AArch64::W3, AArch64::W4,
+ AArch64::W5, AArch64::W6, AArch64::W7, AArch64::W8, AArch64::W9,
+ AArch64::W10, AArch64::W11, AArch64::W12, AArch64::W13, AArch64::W14,
+ AArch64::W15, AArch64::W16, AArch64::W17, AArch64::W18, AArch64::W19,
+ AArch64::W20, AArch64::W21, AArch64::W22, AArch64::W23, AArch64::W24,
+ AArch64::W25, AArch64::W26, AArch64::W27, AArch64::W28, AArch64::W29,
+ AArch64::W30, AArch64::WZR
};
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
@@ -420,19 +427,20 @@ static DecodeStatus DecodeGPR32spRegiste
return Fail;
unsigned Register = GPR32DecoderTable[RegNo];
- if (Register == ARM64::WZR)
- Register = ARM64::WSP;
+ if (Register == AArch64::WZR)
+ Register = AArch64::WSP;
Inst.addOperand(MCOperand::CreateReg(Register));
return Success;
}
static const unsigned VectorDecoderTable[] = {
- ARM64::Q0, ARM64::Q1, ARM64::Q2, ARM64::Q3, ARM64::Q4, ARM64::Q5,
- ARM64::Q6, ARM64::Q7, ARM64::Q8, ARM64::Q9, ARM64::Q10, ARM64::Q11,
- ARM64::Q12, ARM64::Q13, ARM64::Q14, ARM64::Q15, ARM64::Q16, ARM64::Q17,
- ARM64::Q18, ARM64::Q19, ARM64::Q20, ARM64::Q21, ARM64::Q22, ARM64::Q23,
- ARM64::Q24, ARM64::Q25, ARM64::Q26, ARM64::Q27, ARM64::Q28, ARM64::Q29,
- ARM64::Q30, ARM64::Q31
+ AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
+ AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
+ AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
+ AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
+ AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
+ AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
+ AArch64::Q30, AArch64::Q31
};
static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -447,14 +455,14 @@ static DecodeStatus DecodeVectorRegister
}
static const unsigned QQDecoderTable[] = {
- ARM64::Q0_Q1, ARM64::Q1_Q2, ARM64::Q2_Q3, ARM64::Q3_Q4,
- ARM64::Q4_Q5, ARM64::Q5_Q6, ARM64::Q6_Q7, ARM64::Q7_Q8,
- ARM64::Q8_Q9, ARM64::Q9_Q10, ARM64::Q10_Q11, ARM64::Q11_Q12,
- ARM64::Q12_Q13, ARM64::Q13_Q14, ARM64::Q14_Q15, ARM64::Q15_Q16,
- ARM64::Q16_Q17, ARM64::Q17_Q18, ARM64::Q18_Q19, ARM64::Q19_Q20,
- ARM64::Q20_Q21, ARM64::Q21_Q22, ARM64::Q22_Q23, ARM64::Q23_Q24,
- ARM64::Q24_Q25, ARM64::Q25_Q26, ARM64::Q26_Q27, ARM64::Q27_Q28,
- ARM64::Q28_Q29, ARM64::Q29_Q30, ARM64::Q30_Q31, ARM64::Q31_Q0
+ AArch64::Q0_Q1, AArch64::Q1_Q2, AArch64::Q2_Q3, AArch64::Q3_Q4,
+ AArch64::Q4_Q5, AArch64::Q5_Q6, AArch64::Q6_Q7, AArch64::Q7_Q8,
+ AArch64::Q8_Q9, AArch64::Q9_Q10, AArch64::Q10_Q11, AArch64::Q11_Q12,
+ AArch64::Q12_Q13, AArch64::Q13_Q14, AArch64::Q14_Q15, AArch64::Q15_Q16,
+ AArch64::Q16_Q17, AArch64::Q17_Q18, AArch64::Q18_Q19, AArch64::Q19_Q20,
+ AArch64::Q20_Q21, AArch64::Q21_Q22, AArch64::Q22_Q23, AArch64::Q23_Q24,
+ AArch64::Q24_Q25, AArch64::Q25_Q26, AArch64::Q26_Q27, AArch64::Q27_Q28,
+ AArch64::Q28_Q29, AArch64::Q29_Q30, AArch64::Q30_Q31, AArch64::Q31_Q0
};
static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -467,17 +475,17 @@ static DecodeStatus DecodeQQRegisterClas
}
static const unsigned QQQDecoderTable[] = {
- ARM64::Q0_Q1_Q2, ARM64::Q1_Q2_Q3, ARM64::Q2_Q3_Q4,
- ARM64::Q3_Q4_Q5, ARM64::Q4_Q5_Q6, ARM64::Q5_Q6_Q7,
- ARM64::Q6_Q7_Q8, ARM64::Q7_Q8_Q9, ARM64::Q8_Q9_Q10,
- ARM64::Q9_Q10_Q11, ARM64::Q10_Q11_Q12, ARM64::Q11_Q12_Q13,
- ARM64::Q12_Q13_Q14, ARM64::Q13_Q14_Q15, ARM64::Q14_Q15_Q16,
- ARM64::Q15_Q16_Q17, ARM64::Q16_Q17_Q18, ARM64::Q17_Q18_Q19,
- ARM64::Q18_Q19_Q20, ARM64::Q19_Q20_Q21, ARM64::Q20_Q21_Q22,
- ARM64::Q21_Q22_Q23, ARM64::Q22_Q23_Q24, ARM64::Q23_Q24_Q25,
- ARM64::Q24_Q25_Q26, ARM64::Q25_Q26_Q27, ARM64::Q26_Q27_Q28,
- ARM64::Q27_Q28_Q29, ARM64::Q28_Q29_Q30, ARM64::Q29_Q30_Q31,
- ARM64::Q30_Q31_Q0, ARM64::Q31_Q0_Q1
+ AArch64::Q0_Q1_Q2, AArch64::Q1_Q2_Q3, AArch64::Q2_Q3_Q4,
+ AArch64::Q3_Q4_Q5, AArch64::Q4_Q5_Q6, AArch64::Q5_Q6_Q7,
+ AArch64::Q6_Q7_Q8, AArch64::Q7_Q8_Q9, AArch64::Q8_Q9_Q10,
+ AArch64::Q9_Q10_Q11, AArch64::Q10_Q11_Q12, AArch64::Q11_Q12_Q13,
+ AArch64::Q12_Q13_Q14, AArch64::Q13_Q14_Q15, AArch64::Q14_Q15_Q16,
+ AArch64::Q15_Q16_Q17, AArch64::Q16_Q17_Q18, AArch64::Q17_Q18_Q19,
+ AArch64::Q18_Q19_Q20, AArch64::Q19_Q20_Q21, AArch64::Q20_Q21_Q22,
+ AArch64::Q21_Q22_Q23, AArch64::Q22_Q23_Q24, AArch64::Q23_Q24_Q25,
+ AArch64::Q24_Q25_Q26, AArch64::Q25_Q26_Q27, AArch64::Q26_Q27_Q28,
+ AArch64::Q27_Q28_Q29, AArch64::Q28_Q29_Q30, AArch64::Q29_Q30_Q31,
+ AArch64::Q30_Q31_Q0, AArch64::Q31_Q0_Q1
};
static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -490,17 +498,17 @@ static DecodeStatus DecodeQQQRegisterCla
}
static const unsigned QQQQDecoderTable[] = {
- ARM64::Q0_Q1_Q2_Q3, ARM64::Q1_Q2_Q3_Q4, ARM64::Q2_Q3_Q4_Q5,
- ARM64::Q3_Q4_Q5_Q6, ARM64::Q4_Q5_Q6_Q7, ARM64::Q5_Q6_Q7_Q8,
- ARM64::Q6_Q7_Q8_Q9, ARM64::Q7_Q8_Q9_Q10, ARM64::Q8_Q9_Q10_Q11,
- ARM64::Q9_Q10_Q11_Q12, ARM64::Q10_Q11_Q12_Q13, ARM64::Q11_Q12_Q13_Q14,
- ARM64::Q12_Q13_Q14_Q15, ARM64::Q13_Q14_Q15_Q16, ARM64::Q14_Q15_Q16_Q17,
- ARM64::Q15_Q16_Q17_Q18, ARM64::Q16_Q17_Q18_Q19, ARM64::Q17_Q18_Q19_Q20,
- ARM64::Q18_Q19_Q20_Q21, ARM64::Q19_Q20_Q21_Q22, ARM64::Q20_Q21_Q22_Q23,
- ARM64::Q21_Q22_Q23_Q24, ARM64::Q22_Q23_Q24_Q25, ARM64::Q23_Q24_Q25_Q26,
- ARM64::Q24_Q25_Q26_Q27, ARM64::Q25_Q26_Q27_Q28, ARM64::Q26_Q27_Q28_Q29,
- ARM64::Q27_Q28_Q29_Q30, ARM64::Q28_Q29_Q30_Q31, ARM64::Q29_Q30_Q31_Q0,
- ARM64::Q30_Q31_Q0_Q1, ARM64::Q31_Q0_Q1_Q2
+ AArch64::Q0_Q1_Q2_Q3, AArch64::Q1_Q2_Q3_Q4, AArch64::Q2_Q3_Q4_Q5,
+ AArch64::Q3_Q4_Q5_Q6, AArch64::Q4_Q5_Q6_Q7, AArch64::Q5_Q6_Q7_Q8,
+ AArch64::Q6_Q7_Q8_Q9, AArch64::Q7_Q8_Q9_Q10, AArch64::Q8_Q9_Q10_Q11,
+ AArch64::Q9_Q10_Q11_Q12, AArch64::Q10_Q11_Q12_Q13, AArch64::Q11_Q12_Q13_Q14,
+ AArch64::Q12_Q13_Q14_Q15, AArch64::Q13_Q14_Q15_Q16, AArch64::Q14_Q15_Q16_Q17,
+ AArch64::Q15_Q16_Q17_Q18, AArch64::Q16_Q17_Q18_Q19, AArch64::Q17_Q18_Q19_Q20,
+ AArch64::Q18_Q19_Q20_Q21, AArch64::Q19_Q20_Q21_Q22, AArch64::Q20_Q21_Q22_Q23,
+ AArch64::Q21_Q22_Q23_Q24, AArch64::Q22_Q23_Q24_Q25, AArch64::Q23_Q24_Q25_Q26,
+ AArch64::Q24_Q25_Q26_Q27, AArch64::Q25_Q26_Q27_Q28, AArch64::Q26_Q27_Q28_Q29,
+ AArch64::Q27_Q28_Q29_Q30, AArch64::Q28_Q29_Q30_Q31, AArch64::Q29_Q30_Q31_Q0,
+ AArch64::Q30_Q31_Q0_Q1, AArch64::Q31_Q0_Q1_Q2
};
static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -514,14 +522,14 @@ static DecodeStatus DecodeQQQQRegisterCl
}
static const unsigned DDDecoderTable[] = {
- ARM64::D0_D1, ARM64::D1_D2, ARM64::D2_D3, ARM64::D3_D4,
- ARM64::D4_D5, ARM64::D5_D6, ARM64::D6_D7, ARM64::D7_D8,
- ARM64::D8_D9, ARM64::D9_D10, ARM64::D10_D11, ARM64::D11_D12,
- ARM64::D12_D13, ARM64::D13_D14, ARM64::D14_D15, ARM64::D15_D16,
- ARM64::D16_D17, ARM64::D17_D18, ARM64::D18_D19, ARM64::D19_D20,
- ARM64::D20_D21, ARM64::D21_D22, ARM64::D22_D23, ARM64::D23_D24,
- ARM64::D24_D25, ARM64::D25_D26, ARM64::D26_D27, ARM64::D27_D28,
- ARM64::D28_D29, ARM64::D29_D30, ARM64::D30_D31, ARM64::D31_D0
+ AArch64::D0_D1, AArch64::D1_D2, AArch64::D2_D3, AArch64::D3_D4,
+ AArch64::D4_D5, AArch64::D5_D6, AArch64::D6_D7, AArch64::D7_D8,
+ AArch64::D8_D9, AArch64::D9_D10, AArch64::D10_D11, AArch64::D11_D12,
+ AArch64::D12_D13, AArch64::D13_D14, AArch64::D14_D15, AArch64::D15_D16,
+ AArch64::D16_D17, AArch64::D17_D18, AArch64::D18_D19, AArch64::D19_D20,
+ AArch64::D20_D21, AArch64::D21_D22, AArch64::D22_D23, AArch64::D23_D24,
+ AArch64::D24_D25, AArch64::D25_D26, AArch64::D26_D27, AArch64::D27_D28,
+ AArch64::D28_D29, AArch64::D29_D30, AArch64::D30_D31, AArch64::D31_D0
};
static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -534,17 +542,17 @@ static DecodeStatus DecodeDDRegisterClas
}
static const unsigned DDDDecoderTable[] = {
- ARM64::D0_D1_D2, ARM64::D1_D2_D3, ARM64::D2_D3_D4,
- ARM64::D3_D4_D5, ARM64::D4_D5_D6, ARM64::D5_D6_D7,
- ARM64::D6_D7_D8, ARM64::D7_D8_D9, ARM64::D8_D9_D10,
- ARM64::D9_D10_D11, ARM64::D10_D11_D12, ARM64::D11_D12_D13,
- ARM64::D12_D13_D14, ARM64::D13_D14_D15, ARM64::D14_D15_D16,
- ARM64::D15_D16_D17, ARM64::D16_D17_D18, ARM64::D17_D18_D19,
- ARM64::D18_D19_D20, ARM64::D19_D20_D21, ARM64::D20_D21_D22,
- ARM64::D21_D22_D23, ARM64::D22_D23_D24, ARM64::D23_D24_D25,
- ARM64::D24_D25_D26, ARM64::D25_D26_D27, ARM64::D26_D27_D28,
- ARM64::D27_D28_D29, ARM64::D28_D29_D30, ARM64::D29_D30_D31,
- ARM64::D30_D31_D0, ARM64::D31_D0_D1
+ AArch64::D0_D1_D2, AArch64::D1_D2_D3, AArch64::D2_D3_D4,
+ AArch64::D3_D4_D5, AArch64::D4_D5_D6, AArch64::D5_D6_D7,
+ AArch64::D6_D7_D8, AArch64::D7_D8_D9, AArch64::D8_D9_D10,
+ AArch64::D9_D10_D11, AArch64::D10_D11_D12, AArch64::D11_D12_D13,
+ AArch64::D12_D13_D14, AArch64::D13_D14_D15, AArch64::D14_D15_D16,
+ AArch64::D15_D16_D17, AArch64::D16_D17_D18, AArch64::D17_D18_D19,
+ AArch64::D18_D19_D20, AArch64::D19_D20_D21, AArch64::D20_D21_D22,
+ AArch64::D21_D22_D23, AArch64::D22_D23_D24, AArch64::D23_D24_D25,
+ AArch64::D24_D25_D26, AArch64::D25_D26_D27, AArch64::D26_D27_D28,
+ AArch64::D27_D28_D29, AArch64::D28_D29_D30, AArch64::D29_D30_D31,
+ AArch64::D30_D31_D0, AArch64::D31_D0_D1
};
static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -557,17 +565,17 @@ static DecodeStatus DecodeDDDRegisterCla
}
static const unsigned DDDDDecoderTable[] = {
- ARM64::D0_D1_D2_D3, ARM64::D1_D2_D3_D4, ARM64::D2_D3_D4_D5,
- ARM64::D3_D4_D5_D6, ARM64::D4_D5_D6_D7, ARM64::D5_D6_D7_D8,
- ARM64::D6_D7_D8_D9, ARM64::D7_D8_D9_D10, ARM64::D8_D9_D10_D11,
- ARM64::D9_D10_D11_D12, ARM64::D10_D11_D12_D13, ARM64::D11_D12_D13_D14,
- ARM64::D12_D13_D14_D15, ARM64::D13_D14_D15_D16, ARM64::D14_D15_D16_D17,
- ARM64::D15_D16_D17_D18, ARM64::D16_D17_D18_D19, ARM64::D17_D18_D19_D20,
- ARM64::D18_D19_D20_D21, ARM64::D19_D20_D21_D22, ARM64::D20_D21_D22_D23,
- ARM64::D21_D22_D23_D24, ARM64::D22_D23_D24_D25, ARM64::D23_D24_D25_D26,
- ARM64::D24_D25_D26_D27, ARM64::D25_D26_D27_D28, ARM64::D26_D27_D28_D29,
- ARM64::D27_D28_D29_D30, ARM64::D28_D29_D30_D31, ARM64::D29_D30_D31_D0,
- ARM64::D30_D31_D0_D1, ARM64::D31_D0_D1_D2
+ AArch64::D0_D1_D2_D3, AArch64::D1_D2_D3_D4, AArch64::D2_D3_D4_D5,
+ AArch64::D3_D4_D5_D6, AArch64::D4_D5_D6_D7, AArch64::D5_D6_D7_D8,
+ AArch64::D6_D7_D8_D9, AArch64::D7_D8_D9_D10, AArch64::D8_D9_D10_D11,
+ AArch64::D9_D10_D11_D12, AArch64::D10_D11_D12_D13, AArch64::D11_D12_D13_D14,
+ AArch64::D12_D13_D14_D15, AArch64::D13_D14_D15_D16, AArch64::D14_D15_D16_D17,
+ AArch64::D15_D16_D17_D18, AArch64::D16_D17_D18_D19, AArch64::D17_D18_D19_D20,
+ AArch64::D18_D19_D20_D21, AArch64::D19_D20_D21_D22, AArch64::D20_D21_D22_D23,
+ AArch64::D21_D22_D23_D24, AArch64::D22_D23_D24_D25, AArch64::D23_D24_D25_D26,
+ AArch64::D24_D25_D26_D27, AArch64::D25_D26_D27_D28, AArch64::D26_D27_D28_D29,
+ AArch64::D27_D28_D29_D30, AArch64::D28_D29_D30_D31, AArch64::D29_D30_D31_D0,
+ AArch64::D30_D31_D0_D1, AArch64::D31_D0_D1_D2
};
static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
@@ -599,15 +607,15 @@ static DecodeStatus DecodeFixedPointScal
static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder) {
int64_t ImmVal = Imm;
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
// Sign-extend 19-bit immediate.
if (ImmVal & (1 << (19 - 1)))
ImmVal |= ~((1LL << 19) - 1);
if (!Dis->tryAddingSymbolicOperand(Inst, ImmVal << 2, Addr,
- Inst.getOpcode() != ARM64::LDRXl, 0, 4))
+ Inst.getOpcode() != AArch64::LDRXl, 0, 4))
Inst.addOperand(MCOperand::CreateImm(ImmVal));
return Success;
}
@@ -622,15 +630,16 @@ static DecodeStatus DecodeMemExtend(llvm
static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
bool ValidNamed;
- (void)ARM64SysReg::MRSMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
+ (void)AArch64SysReg::MRSMapper(STI.getFeatureBits())
+ .toString(Imm, ValidNamed);
return ValidNamed ? Success : Fail;
}
@@ -638,15 +647,16 @@ static DecodeStatus DecodeMRSSystemRegis
static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
uint64_t Address,
const void *Decoder) {
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
const MCSubtargetInfo &STI = Dis->getSubtargetInfo();
Imm |= 0x8000;
Inst.addOperand(MCOperand::CreateImm(Imm));
bool ValidNamed;
- (void)ARM64SysReg::MSRMapper(STI.getFeatureBits()).toString(Imm, ValidNamed);
+ (void)AArch64SysReg::MSRMapper(STI.getFeatureBits())
+ .toString(Imm, ValidNamed);
return ValidNamed ? Success : Fail;
}
@@ -756,22 +766,22 @@ static DecodeStatus DecodeThreeAddrSRegI
switch (Inst.getOpcode()) {
default:
return Fail;
- case ARM64::ADDWrs:
- case ARM64::ADDSWrs:
- case ARM64::SUBWrs:
- case ARM64::SUBSWrs:
+ case AArch64::ADDWrs:
+ case AArch64::ADDSWrs:
+ case AArch64::SUBWrs:
+ case AArch64::SUBSWrs:
// if shift == '11' then ReservedValue()
if (shiftHi == 0x3)
return Fail;
// Deliberate fallthrough
- case ARM64::ANDWrs:
- case ARM64::ANDSWrs:
- case ARM64::BICWrs:
- case ARM64::BICSWrs:
- case ARM64::ORRWrs:
- case ARM64::ORNWrs:
- case ARM64::EORWrs:
- case ARM64::EONWrs: {
+ case AArch64::ANDWrs:
+ case AArch64::ANDSWrs:
+ case AArch64::BICWrs:
+ case AArch64::BICSWrs:
+ case AArch64::ORRWrs:
+ case AArch64::ORNWrs:
+ case AArch64::EORWrs:
+ case AArch64::EONWrs: {
// if sf == '0' and imm6<5> == '1' then ReservedValue()
if (shiftLo >> 5 == 1)
return Fail;
@@ -780,22 +790,22 @@ static DecodeStatus DecodeThreeAddrSRegI
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
}
- case ARM64::ADDXrs:
- case ARM64::ADDSXrs:
- case ARM64::SUBXrs:
- case ARM64::SUBSXrs:
+ case AArch64::ADDXrs:
+ case AArch64::ADDSXrs:
+ case AArch64::SUBXrs:
+ case AArch64::SUBSXrs:
// if shift == '11' then ReservedValue()
if (shiftHi == 0x3)
return Fail;
// Deliberate fallthrough
- case ARM64::ANDXrs:
- case ARM64::ANDSXrs:
- case ARM64::BICXrs:
- case ARM64::BICSXrs:
- case ARM64::ORRXrs:
- case ARM64::ORNXrs:
- case ARM64::EORXrs:
- case ARM64::EONXrs:
+ case AArch64::ANDXrs:
+ case AArch64::ANDSXrs:
+ case AArch64::BICXrs:
+ case AArch64::BICSXrs:
+ case AArch64::ORRXrs:
+ case AArch64::ORNXrs:
+ case AArch64::EORXrs:
+ case AArch64::EONXrs:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
@@ -816,21 +826,22 @@ static DecodeStatus DecodeMoveImmInstruc
switch (Inst.getOpcode()) {
default:
return Fail;
- case ARM64::MOVZWi:
- case ARM64::MOVNWi:
- case ARM64::MOVKWi:
+ case AArch64::MOVZWi:
+ case AArch64::MOVNWi:
+ case AArch64::MOVKWi:
if (shift & (1U << 5))
return Fail;
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
break;
- case ARM64::MOVZXi:
- case ARM64::MOVNXi:
- case ARM64::MOVKXi:
+ case AArch64::MOVZXi:
+ case AArch64::MOVNXi:
+ case AArch64::MOVKXi:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
break;
}
- if (Inst.getOpcode() == ARM64::MOVKWi || Inst.getOpcode() == ARM64::MOVKXi)
+ if (Inst.getOpcode() == AArch64::MOVKWi ||
+ Inst.getOpcode() == AArch64::MOVKXi)
Inst.addOperand(Inst.getOperand(0));
Inst.addOperand(MCOperand::CreateImm(imm));
@@ -844,51 +855,51 @@ static DecodeStatus DecodeUnsignedLdStIn
unsigned Rt = fieldFromInstruction(insn, 0, 5);
unsigned Rn = fieldFromInstruction(insn, 5, 5);
unsigned offset = fieldFromInstruction(insn, 10, 12);
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
switch (Inst.getOpcode()) {
default:
return Fail;
- case ARM64::PRFMui:
+ case AArch64::PRFMui:
// Rt is an immediate in prefetch.
Inst.addOperand(MCOperand::CreateImm(Rt));
break;
- case ARM64::STRBBui:
- case ARM64::LDRBBui:
- case ARM64::LDRSBWui:
- case ARM64::STRHHui:
- case ARM64::LDRHHui:
- case ARM64::LDRSHWui:
- case ARM64::STRWui:
- case ARM64::LDRWui:
+ case AArch64::STRBBui:
+ case AArch64::LDRBBui:
+ case AArch64::LDRSBWui:
+ case AArch64::STRHHui:
+ case AArch64::LDRHHui:
+ case AArch64::LDRSHWui:
+ case AArch64::STRWui:
+ case AArch64::LDRWui:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRSBXui:
- case ARM64::LDRSHXui:
- case ARM64::LDRSWui:
- case ARM64::STRXui:
- case ARM64::LDRXui:
+ case AArch64::LDRSBXui:
+ case AArch64::LDRSHXui:
+ case AArch64::LDRSWui:
+ case AArch64::STRXui:
+ case AArch64::LDRXui:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRQui:
- case ARM64::STRQui:
+ case AArch64::LDRQui:
+ case AArch64::STRQui:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRDui:
- case ARM64::STRDui:
+ case AArch64::LDRDui:
+ case AArch64::STRDui:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRSui:
- case ARM64::STRSui:
+ case AArch64::LDRSui:
+ case AArch64::STRSui:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRHui:
- case ARM64::STRHui:
+ case AArch64::LDRHui:
+ case AArch64::STRHui:
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDRBui:
- case ARM64::STRBui:
+ case AArch64::LDRBui:
+ case AArch64::STRBui:
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break;
}
@@ -915,52 +926,52 @@ static DecodeStatus DecodeSignedLdStInst
switch (Inst.getOpcode()) {
default:
break;
- case ARM64::LDRSBWpre:
- case ARM64::LDRSHWpre:
- case ARM64::STRBBpre:
- case ARM64::LDRBBpre:
- case ARM64::STRHHpre:
- case ARM64::LDRHHpre:
- case ARM64::STRWpre:
- case ARM64::LDRWpre:
- case ARM64::LDRSBWpost:
- case ARM64::LDRSHWpost:
- case ARM64::STRBBpost:
- case ARM64::LDRBBpost:
- case ARM64::STRHHpost:
- case ARM64::LDRHHpost:
- case ARM64::STRWpost:
- case ARM64::LDRWpost:
- case ARM64::LDRSBXpre:
- case ARM64::LDRSHXpre:
- case ARM64::STRXpre:
- case ARM64::LDRSWpre:
- case ARM64::LDRXpre:
- case ARM64::LDRSBXpost:
- case ARM64::LDRSHXpost:
- case ARM64::STRXpost:
- case ARM64::LDRSWpost:
- case ARM64::LDRXpost:
- case ARM64::LDRQpre:
- case ARM64::STRQpre:
- case ARM64::LDRQpost:
- case ARM64::STRQpost:
- case ARM64::LDRDpre:
- case ARM64::STRDpre:
- case ARM64::LDRDpost:
- case ARM64::STRDpost:
- case ARM64::LDRSpre:
- case ARM64::STRSpre:
- case ARM64::LDRSpost:
- case ARM64::STRSpost:
- case ARM64::LDRHpre:
- case ARM64::STRHpre:
- case ARM64::LDRHpost:
- case ARM64::STRHpost:
- case ARM64::LDRBpre:
- case ARM64::STRBpre:
- case ARM64::LDRBpost:
- case ARM64::STRBpost:
+ case AArch64::LDRSBWpre:
+ case AArch64::LDRSHWpre:
+ case AArch64::STRBBpre:
+ case AArch64::LDRBBpre:
+ case AArch64::STRHHpre:
+ case AArch64::LDRHHpre:
+ case AArch64::STRWpre:
+ case AArch64::LDRWpre:
+ case AArch64::LDRSBWpost:
+ case AArch64::LDRSHWpost:
+ case AArch64::STRBBpost:
+ case AArch64::LDRBBpost:
+ case AArch64::STRHHpost:
+ case AArch64::LDRHHpost:
+ case AArch64::STRWpost:
+ case AArch64::LDRWpost:
+ case AArch64::LDRSBXpre:
+ case AArch64::LDRSHXpre:
+ case AArch64::STRXpre:
+ case AArch64::LDRSWpre:
+ case AArch64::LDRXpre:
+ case AArch64::LDRSBXpost:
+ case AArch64::LDRSHXpost:
+ case AArch64::STRXpost:
+ case AArch64::LDRSWpost:
+ case AArch64::LDRXpost:
+ case AArch64::LDRQpre:
+ case AArch64::STRQpre:
+ case AArch64::LDRQpost:
+ case AArch64::STRQpost:
+ case AArch64::LDRDpre:
+ case AArch64::STRDpre:
+ case AArch64::LDRDpost:
+ case AArch64::STRDpost:
+ case AArch64::LDRSpre:
+ case AArch64::STRSpre:
+ case AArch64::LDRSpost:
+ case AArch64::STRSpost:
+ case AArch64::LDRHpre:
+ case AArch64::STRHpre:
+ case AArch64::LDRHpost:
+ case AArch64::STRHpost:
+ case AArch64::LDRBpre:
+ case AArch64::STRBpre:
+ case AArch64::LDRBpost:
+ case AArch64::STRBpost:
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
break;
}
@@ -968,104 +979,104 @@ static DecodeStatus DecodeSignedLdStInst
switch (Inst.getOpcode()) {
default:
return Fail;
- case ARM64::PRFUMi:
+ case AArch64::PRFUMi:
// Rt is an immediate in prefetch.
Inst.addOperand(MCOperand::CreateImm(Rt));
break;
- case ARM64::STURBBi:
- case ARM64::LDURBBi:
- case ARM64::LDURSBWi:
- case ARM64::STURHHi:
- case ARM64::LDURHHi:
- case ARM64::LDURSHWi:
- case ARM64::STURWi:
- case ARM64::LDURWi:
- case ARM64::LDTRSBWi:
- case ARM64::LDTRSHWi:
- case ARM64::STTRWi:
- case ARM64::LDTRWi:
- case ARM64::STTRHi:
- case ARM64::LDTRHi:
- case ARM64::LDTRBi:
- case ARM64::STTRBi:
- case ARM64::LDRSBWpre:
- case ARM64::LDRSHWpre:
- case ARM64::STRBBpre:
- case ARM64::LDRBBpre:
- case ARM64::STRHHpre:
- case ARM64::LDRHHpre:
- case ARM64::STRWpre:
- case ARM64::LDRWpre:
- case ARM64::LDRSBWpost:
- case ARM64::LDRSHWpost:
- case ARM64::STRBBpost:
- case ARM64::LDRBBpost:
- case ARM64::STRHHpost:
- case ARM64::LDRHHpost:
- case ARM64::STRWpost:
- case ARM64::LDRWpost:
+ case AArch64::STURBBi:
+ case AArch64::LDURBBi:
+ case AArch64::LDURSBWi:
+ case AArch64::STURHHi:
+ case AArch64::LDURHHi:
+ case AArch64::LDURSHWi:
+ case AArch64::STURWi:
+ case AArch64::LDURWi:
+ case AArch64::LDTRSBWi:
+ case AArch64::LDTRSHWi:
+ case AArch64::STTRWi:
+ case AArch64::LDTRWi:
+ case AArch64::STTRHi:
+ case AArch64::LDTRHi:
+ case AArch64::LDTRBi:
+ case AArch64::STTRBi:
+ case AArch64::LDRSBWpre:
+ case AArch64::LDRSHWpre:
+ case AArch64::STRBBpre:
+ case AArch64::LDRBBpre:
+ case AArch64::STRHHpre:
+ case AArch64::LDRHHpre:
+ case AArch64::STRWpre:
+ case AArch64::LDRWpre:
+ case AArch64::LDRSBWpost:
+ case AArch64::LDRSHWpost:
+ case AArch64::STRBBpost:
+ case AArch64::LDRBBpost:
+ case AArch64::STRHHpost:
+ case AArch64::LDRHHpost:
+ case AArch64::STRWpost:
+ case AArch64::LDRWpost:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURSBXi:
- case ARM64::LDURSHXi:
- case ARM64::LDURSWi:
- case ARM64::STURXi:
- case ARM64::LDURXi:
- case ARM64::LDTRSBXi:
- case ARM64::LDTRSHXi:
- case ARM64::LDTRSWi:
- case ARM64::STTRXi:
- case ARM64::LDTRXi:
- case ARM64::LDRSBXpre:
- case ARM64::LDRSHXpre:
- case ARM64::STRXpre:
- case ARM64::LDRSWpre:
- case ARM64::LDRXpre:
- case ARM64::LDRSBXpost:
- case ARM64::LDRSHXpost:
- case ARM64::STRXpost:
- case ARM64::LDRSWpost:
- case ARM64::LDRXpost:
+ case AArch64::LDURSBXi:
+ case AArch64::LDURSHXi:
+ case AArch64::LDURSWi:
+ case AArch64::STURXi:
+ case AArch64::LDURXi:
+ case AArch64::LDTRSBXi:
+ case AArch64::LDTRSHXi:
+ case AArch64::LDTRSWi:
+ case AArch64::STTRXi:
+ case AArch64::LDTRXi:
+ case AArch64::LDRSBXpre:
+ case AArch64::LDRSHXpre:
+ case AArch64::STRXpre:
+ case AArch64::LDRSWpre:
+ case AArch64::LDRXpre:
+ case AArch64::LDRSBXpost:
+ case AArch64::LDRSHXpost:
+ case AArch64::STRXpost:
+ case AArch64::LDRSWpost:
+ case AArch64::LDRXpost:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURQi:
- case ARM64::STURQi:
- case ARM64::LDRQpre:
- case ARM64::STRQpre:
- case ARM64::LDRQpost:
- case ARM64::STRQpost:
+ case AArch64::LDURQi:
+ case AArch64::STURQi:
+ case AArch64::LDRQpre:
+ case AArch64::STRQpre:
+ case AArch64::LDRQpost:
+ case AArch64::STRQpost:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURDi:
- case ARM64::STURDi:
- case ARM64::LDRDpre:
- case ARM64::STRDpre:
- case ARM64::LDRDpost:
- case ARM64::STRDpost:
+ case AArch64::LDURDi:
+ case AArch64::STURDi:
+ case AArch64::LDRDpre:
+ case AArch64::STRDpre:
+ case AArch64::LDRDpost:
+ case AArch64::STRDpost:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURSi:
- case ARM64::STURSi:
- case ARM64::LDRSpre:
- case ARM64::STRSpre:
- case ARM64::LDRSpost:
- case ARM64::STRSpost:
+ case AArch64::LDURSi:
+ case AArch64::STURSi:
+ case AArch64::LDRSpre:
+ case AArch64::STRSpre:
+ case AArch64::LDRSpost:
+ case AArch64::STRSpost:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURHi:
- case ARM64::STURHi:
- case ARM64::LDRHpre:
- case ARM64::STRHpre:
- case ARM64::LDRHpost:
- case ARM64::STRHpost:
+ case AArch64::LDURHi:
+ case AArch64::STURHi:
+ case AArch64::LDRHpre:
+ case AArch64::STRHpre:
+ case AArch64::LDRHpost:
+ case AArch64::STRHpost:
DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::LDURBi:
- case ARM64::STURBi:
- case ARM64::LDRBpre:
- case ARM64::STRBpre:
- case ARM64::LDRBpost:
- case ARM64::STRBpost:
+ case AArch64::LDURBi:
+ case AArch64::STURBi:
+ case AArch64::LDRBpre:
+ case AArch64::STRBpre:
+ case AArch64::LDRBpost:
+ case AArch64::STRBpost:
DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
break;
}
@@ -1096,53 +1107,53 @@ static DecodeStatus DecodeExclusiveLdStI
switch (Opcode) {
default:
return Fail;
- case ARM64::STLXRW:
- case ARM64::STLXRB:
- case ARM64::STLXRH:
- case ARM64::STXRW:
- case ARM64::STXRB:
- case ARM64::STXRH:
+ case AArch64::STLXRW:
+ case AArch64::STLXRB:
+ case AArch64::STLXRH:
+ case AArch64::STXRW:
+ case AArch64::STXRB:
+ case AArch64::STXRH:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
- case ARM64::LDARW:
- case ARM64::LDARB:
- case ARM64::LDARH:
- case ARM64::LDAXRW:
- case ARM64::LDAXRB:
- case ARM64::LDAXRH:
- case ARM64::LDXRW:
- case ARM64::LDXRB:
- case ARM64::LDXRH:
- case ARM64::STLRW:
- case ARM64::STLRB:
- case ARM64::STLRH:
+ case AArch64::LDARW:
+ case AArch64::LDARB:
+ case AArch64::LDARH:
+ case AArch64::LDAXRW:
+ case AArch64::LDAXRB:
+ case AArch64::LDAXRH:
+ case AArch64::LDXRW:
+ case AArch64::LDXRB:
+ case AArch64::LDXRH:
+ case AArch64::STLRW:
+ case AArch64::STLRB:
+ case AArch64::STLRH:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::STLXRX:
- case ARM64::STXRX:
+ case AArch64::STLXRX:
+ case AArch64::STXRX:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
- case ARM64::LDARX:
- case ARM64::LDAXRX:
- case ARM64::LDXRX:
- case ARM64::STLRX:
+ case AArch64::LDARX:
+ case AArch64::LDAXRX:
+ case AArch64::LDXRX:
+ case AArch64::STLRX:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
break;
- case ARM64::STLXPW:
- case ARM64::STXPW:
+ case AArch64::STLXPW:
+ case AArch64::STXPW:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
- case ARM64::LDAXPW:
- case ARM64::LDXPW:
+ case AArch64::LDAXPW:
+ case AArch64::LDXPW:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
- case ARM64::STLXPX:
- case ARM64::STXPX:
+ case AArch64::STLXPX:
+ case AArch64::STXPX:
DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
// FALLTHROUGH
- case ARM64::LDAXPX:
- case ARM64::LDXPX:
+ case AArch64::LDAXPX:
+ case AArch64::LDXPX:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
@@ -1151,8 +1162,8 @@ static DecodeStatus DecodeExclusiveLdStI
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
// You shouldn't load to the same register twice in an instruction...
- if ((Opcode == ARM64::LDAXPW || Opcode == ARM64::LDXPW ||
- Opcode == ARM64::LDAXPX || Opcode == ARM64::LDXPX) &&
+ if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
+ Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
Rt == Rt2)
return SoftFail;
@@ -1180,28 +1191,28 @@ static DecodeStatus DecodePairLdStInstru
switch (Opcode) {
default:
break;
- case ARM64::LDPXpost:
- case ARM64::STPXpost:
- case ARM64::LDPSWpost:
- case ARM64::LDPXpre:
- case ARM64::STPXpre:
- case ARM64::LDPSWpre:
- case ARM64::LDPWpost:
- case ARM64::STPWpost:
- case ARM64::LDPWpre:
- case ARM64::STPWpre:
- case ARM64::LDPQpost:
- case ARM64::STPQpost:
- case ARM64::LDPQpre:
- case ARM64::STPQpre:
- case ARM64::LDPDpost:
- case ARM64::STPDpost:
- case ARM64::LDPDpre:
- case ARM64::STPDpre:
- case ARM64::LDPSpost:
- case ARM64::STPSpost:
- case ARM64::LDPSpre:
- case ARM64::STPSpre:
+ case AArch64::LDPXpost:
+ case AArch64::STPXpost:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPXpre:
+ case AArch64::STPXpre:
+ case AArch64::LDPSWpre:
+ case AArch64::LDPWpost:
+ case AArch64::STPWpost:
+ case AArch64::LDPWpre:
+ case AArch64::STPWpre:
+ case AArch64::LDPQpost:
+ case AArch64::STPQpost:
+ case AArch64::LDPQpre:
+ case AArch64::STPQpre:
+ case AArch64::LDPDpost:
+ case AArch64::STPDpost:
+ case AArch64::LDPDpre:
+ case AArch64::STPDpre:
+ case AArch64::LDPSpost:
+ case AArch64::STPSpost:
+ case AArch64::LDPSpre:
+ case AArch64::STPSpre:
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
break;
}
@@ -1209,65 +1220,65 @@ static DecodeStatus DecodePairLdStInstru
switch (Opcode) {
default:
return Fail;
- case ARM64::LDPXpost:
- case ARM64::STPXpost:
- case ARM64::LDPSWpost:
- case ARM64::LDPXpre:
- case ARM64::STPXpre:
- case ARM64::LDPSWpre:
+ case AArch64::LDPXpost:
+ case AArch64::STPXpost:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPXpre:
+ case AArch64::STPXpre:
+ case AArch64::LDPSWpre:
NeedsDisjointWritebackTransfer = true;
// Fallthrough
- case ARM64::LDNPXi:
- case ARM64::STNPXi:
- case ARM64::LDPXi:
- case ARM64::STPXi:
- case ARM64::LDPSWi:
+ case AArch64::LDNPXi:
+ case AArch64::STNPXi:
+ case AArch64::LDPXi:
+ case AArch64::STPXi:
+ case AArch64::LDPSWi:
DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
- case ARM64::LDPWpost:
- case ARM64::STPWpost:
- case ARM64::LDPWpre:
- case ARM64::STPWpre:
+ case AArch64::LDPWpost:
+ case AArch64::STPWpost:
+ case AArch64::LDPWpre:
+ case AArch64::STPWpre:
NeedsDisjointWritebackTransfer = true;
// Fallthrough
- case ARM64::LDNPWi:
- case ARM64::STNPWi:
- case ARM64::LDPWi:
- case ARM64::STPWi:
+ case AArch64::LDNPWi:
+ case AArch64::STNPWi:
+ case AArch64::LDPWi:
+ case AArch64::STPWi:
DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
- case ARM64::LDNPQi:
- case ARM64::STNPQi:
- case ARM64::LDPQpost:
- case ARM64::STPQpost:
- case ARM64::LDPQi:
- case ARM64::STPQi:
- case ARM64::LDPQpre:
- case ARM64::STPQpre:
+ case AArch64::LDNPQi:
+ case AArch64::STNPQi:
+ case AArch64::LDPQpost:
+ case AArch64::STPQpost:
+ case AArch64::LDPQi:
+ case AArch64::STPQi:
+ case AArch64::LDPQpre:
+ case AArch64::STPQpre:
DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
break;
- case ARM64::LDNPDi:
- case ARM64::STNPDi:
- case ARM64::LDPDpost:
- case ARM64::STPDpost:
- case ARM64::LDPDi:
- case ARM64::STPDi:
- case ARM64::LDPDpre:
- case ARM64::STPDpre:
+ case AArch64::LDNPDi:
+ case AArch64::STNPDi:
+ case AArch64::LDPDpost:
+ case AArch64::STPDpost:
+ case AArch64::LDPDi:
+ case AArch64::STPDi:
+ case AArch64::LDPDpre:
+ case AArch64::STPDpre:
DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
break;
- case ARM64::LDNPSi:
- case ARM64::STNPSi:
- case ARM64::LDPSpost:
- case ARM64::STPSpost:
- case ARM64::LDPSi:
- case ARM64::STPSi:
- case ARM64::LDPSpre:
- case ARM64::STPSpre:
+ case AArch64::LDNPSi:
+ case AArch64::STNPSi:
+ case AArch64::LDPSpost:
+ case AArch64::STPSpost:
+ case AArch64::LDPSi:
+ case AArch64::STPSi:
+ case AArch64::LDPSpre:
+ case AArch64::STPSpre:
DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
break;
@@ -1303,38 +1314,38 @@ static DecodeStatus DecodeAddSubERegInst
switch (Inst.getOpcode()) {
default:
return Fail;
- case ARM64::ADDWrx:
- case ARM64::SUBWrx:
+ case AArch64::ADDWrx:
+ case AArch64::SUBWrx:
DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
- case ARM64::ADDSWrx:
- case ARM64::SUBSWrx:
+ case AArch64::ADDSWrx:
+ case AArch64::SUBSWrx:
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
- case ARM64::ADDXrx:
- case ARM64::SUBXrx:
+ case AArch64::ADDXrx:
+ case AArch64::SUBXrx:
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
- case ARM64::ADDSXrx:
- case ARM64::SUBSXrx:
+ case AArch64::ADDSXrx:
+ case AArch64::SUBSXrx:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
break;
- case ARM64::ADDXrx64:
- case ARM64::SUBXrx64:
+ case AArch64::ADDXrx64:
+ case AArch64::SUBXrx64:
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
break;
- case ARM64::SUBSXrx64:
- case ARM64::ADDSXrx64:
+ case AArch64::SUBSXrx64:
+ case AArch64::ADDSXrx64:
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
@@ -1354,22 +1365,22 @@ static DecodeStatus DecodeLogicalImmInst
unsigned imm;
if (Datasize) {
- if (Inst.getOpcode() == ARM64::ANDSXri)
+ if (Inst.getOpcode() == AArch64::ANDSXri)
DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
imm = fieldFromInstruction(insn, 10, 13);
- if (!ARM64_AM::isValidDecodeLogicalImmediate(imm, 64))
+ if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
return Fail;
} else {
- if (Inst.getOpcode() == ARM64::ANDSWri)
+ if (Inst.getOpcode() == AArch64::ANDSWri)
DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
imm = fieldFromInstruction(insn, 10, 12);
- if (!ARM64_AM::isValidDecodeLogicalImmediate(imm, 32))
+ if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
return Fail;
}
Inst.addOperand(MCOperand::CreateImm(imm));
@@ -1384,7 +1395,7 @@ static DecodeStatus DecodeModImmInstruct
unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
imm |= fieldFromInstruction(insn, 5, 5);
- if (Inst.getOpcode() == ARM64::MOVID)
+ if (Inst.getOpcode() == AArch64::MOVID)
DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
else
DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
@@ -1394,20 +1405,20 @@ static DecodeStatus DecodeModImmInstruct
switch (Inst.getOpcode()) {
default:
break;
- case ARM64::MOVIv4i16:
- case ARM64::MOVIv8i16:
- case ARM64::MVNIv4i16:
- case ARM64::MVNIv8i16:
- case ARM64::MOVIv2i32:
- case ARM64::MOVIv4i32:
- case ARM64::MVNIv2i32:
- case ARM64::MVNIv4i32:
+ case AArch64::MOVIv4i16:
+ case AArch64::MOVIv8i16:
+ case AArch64::MVNIv4i16:
+ case AArch64::MVNIv8i16:
+ case AArch64::MOVIv2i32:
+ case AArch64::MOVIv4i32:
+ case AArch64::MVNIv2i32:
+ case AArch64::MVNIv4i32:
Inst.addOperand(MCOperand::CreateImm((cmode & 6) << 2));
break;
- case ARM64::MOVIv2s_msl:
- case ARM64::MOVIv4s_msl:
- case ARM64::MVNIv2s_msl:
- case ARM64::MVNIv4s_msl:
+ case AArch64::MOVIv2s_msl:
+ case AArch64::MOVIv4s_msl:
+ case AArch64::MVNIv2s_msl:
+ case AArch64::MVNIv4s_msl:
Inst.addOperand(MCOperand::CreateImm(cmode & 1 ? 0x110 : 0x108));
break;
}
@@ -1438,8 +1449,8 @@ static DecodeStatus DecodeAdrInstruction
unsigned Rd = fieldFromInstruction(insn, 0, 5);
int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
imm |= fieldFromInstruction(insn, 29, 2);
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
// Sign-extend the 21-bit immediate.
if (imm & (1 << (21 - 1)))
@@ -1462,8 +1473,8 @@ static DecodeStatus DecodeBaseAddSubImm(
unsigned ShifterVal = (Imm >> 12) & 3;
unsigned ImmVal = Imm & 0xFFF;
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
if (ShifterVal != 0 && ShifterVal != 1)
return Fail;
@@ -1492,8 +1503,8 @@ static DecodeStatus DecodeUnconditionalB
uint64_t Addr,
const void *Decoder) {
int64_t imm = fieldFromInstruction(insn, 0, 26);
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
// Sign-extend the 26-bit immediate.
if (imm & (1 << (26 - 1)))
@@ -1518,7 +1529,7 @@ static DecodeStatus DecodeSystemPStateIn
Inst.addOperand(MCOperand::CreateImm(crm));
bool ValidNamed;
- (void)ARM64PState::PStateMapper().toString(pstate_field, ValidNamed);
+ (void)AArch64PState::PStateMapper().toString(pstate_field, ValidNamed);
return ValidNamed ? Success : Fail;
}
@@ -1529,8 +1540,8 @@ static DecodeStatus DecodeTestAndBranch(
uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
bit |= fieldFromInstruction(insn, 19, 5);
int64_t dst = fieldFromInstruction(insn, 5, 14);
- const ARM64Disassembler *Dis =
- static_cast<const ARM64Disassembler *>(Decoder);
+ const AArch64Disassembler *Dis =
+ static_cast<const AArch64Disassembler *>(Decoder);
// Sign-extend 14-bit immediate.
if (dst & (1 << (14 - 1)))
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.h (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.h?p2=llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.h&p1=llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/ARM64Disassembler.h (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64Disassembler.h - Disassembler for ARM64 -------------*- C++ -*-===//
+//===- AArch64Disassembler.h - Disassembler for AArch64 ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64DISASSEMBLER_H
-#define ARM64DISASSEMBLER_H
+#ifndef AArch64DISASSEMBLER_H
+#define AArch64DISASSEMBLER_H
#include "llvm/MC/MCDisassembler.h"
@@ -21,12 +21,12 @@ class MCInst;
class MemoryObject;
class raw_ostream;
-class ARM64Disassembler : public MCDisassembler {
+class AArch64Disassembler : public MCDisassembler {
public:
- ARM64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
+ AArch64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
: MCDisassembler(STI, Ctx) {}
- ~ARM64Disassembler() {}
+ ~AArch64Disassembler() {}
/// getInstruction - See MCDisassembler.
MCDisassembler::DecodeStatus
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp?p2=llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp&p1=llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64ExternalSymbolizer.cpp - Symbolizer for ARM64 -------*- C++ -*-===//
+//===- AArch64ExternalSymbolizer.cpp - Symbolizer for AArch64 ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64ExternalSymbolizer.h"
-#include "ARM64Subtarget.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "Utils/ARM64BaseInfo.h"
+#include "AArch64ExternalSymbolizer.h"
+#include "AArch64Subtarget.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
@@ -19,7 +19,7 @@
using namespace llvm;
-#define DEBUG_TYPE "arm64-disassembler"
+#define DEBUG_TYPE "aarch64-disassembler"
static MCSymbolRefExpr::VariantKind
getVariant(uint64_t LLVMDisassembler_VariantKind) {
@@ -58,14 +58,9 @@ getVariant(uint64_t LLVMDisassembler_Var
/// a symbol look up is done to see it is returns a specific reference type
/// to add to the comment stream. This function returns Success if it adds
/// an operand to the MCInst and Fail otherwise.
-bool ARM64ExternalSymbolizer::tryAddingSymbolicOperand(
- MCInst &MI,
- raw_ostream &CommentStream,
- int64_t Value,
- uint64_t Address,
- bool IsBranch,
- uint64_t Offset,
- uint64_t InstSize) {
+bool AArch64ExternalSymbolizer::tryAddingSymbolicOperand(
+ MCInst &MI, raw_ostream &CommentStream, int64_t Value, uint64_t Address,
+ bool IsBranch, uint64_t Offset, uint64_t InstSize) {
// FIXME: This method shares a lot of code with
// MCExternalSymbolizer::tryAddingSymbolicOperand. It may be possible
// refactor the MCExternalSymbolizer interface to allow more of this
@@ -94,7 +89,7 @@ bool ARM64ExternalSymbolizer::tryAddingS
else if (ReferenceType ==
LLVMDisassembler_ReferenceType_Out_Objc_Message)
CommentStream << "Objc message: " << ReferenceName;
- } else if (MI.getOpcode() == ARM64::ADRP) {
+ } else if (MI.getOpcode() == AArch64::ADRP) {
ReferenceType = LLVMDisassembler_ReferenceType_In_ARM64_ADRP;
// otool expects the fully encoded ADRP instruction to be passed in as
// the value here, so reconstruct it:
@@ -107,19 +102,19 @@ bool ARM64ExternalSymbolizer::tryAddingS
&ReferenceName);
CommentStream << format("0x%llx",
0xfffffffffffff000LL & (Address + Value));
- } else if (MI.getOpcode() == ARM64::ADDXri ||
- MI.getOpcode() == ARM64::LDRXui ||
- MI.getOpcode() == ARM64::LDRXl ||
- MI.getOpcode() == ARM64::ADR) {
- if (MI.getOpcode() == ARM64::ADDXri)
+ } else if (MI.getOpcode() == AArch64::ADDXri ||
+ MI.getOpcode() == AArch64::LDRXui ||
+ MI.getOpcode() == AArch64::LDRXl ||
+ MI.getOpcode() == AArch64::ADR) {
+ if (MI.getOpcode() == AArch64::ADDXri)
ReferenceType = LLVMDisassembler_ReferenceType_In_ARM64_ADDXri;
- else if (MI.getOpcode() == ARM64::LDRXui)
+ else if (MI.getOpcode() == AArch64::LDRXui)
ReferenceType = LLVMDisassembler_ReferenceType_In_ARM64_LDRXui;
- if (MI.getOpcode() == ARM64::LDRXl) {
+ if (MI.getOpcode() == AArch64::LDRXl) {
ReferenceType = LLVMDisassembler_ReferenceType_In_ARM64_LDRXl;
SymbolLookUp(DisInfo, Address + Value, &ReferenceType, Address,
&ReferenceName);
- } else if (MI.getOpcode() == ARM64::ADR) {
+ } else if (MI.getOpcode() == AArch64::ADR) {
ReferenceType = LLVMDisassembler_ReferenceType_In_ARM64_ADR;
SymbolLookUp(DisInfo, Address + Value, &ReferenceType, Address,
&ReferenceName);
@@ -128,7 +123,7 @@ bool ARM64ExternalSymbolizer::tryAddingS
// otool expects the fully encoded ADD/LDR instruction to be passed in
// as the value here, so reconstruct it:
unsigned EncodedInst =
- MI.getOpcode() == ARM64::ADDXri ? 0x91000000: 0xF9400000;
+ MI.getOpcode() == AArch64::ADDXri ? 0x91000000: 0xF9400000;
EncodedInst |= Value << 10; // imm12 [+ shift:2 for ADD]
EncodedInst |=
MCRI.getEncodingValue(MI.getOperand(1).getReg()) << 5; // Rn
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.h (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.h?p2=llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.h&p1=llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/ARM64ExternalSymbolizer.h (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64ExternalSymbolizer.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64ExternalSymbolizer.h - Symbolizer for ARM64 ---------*- C++ -*-===//
+//===- AArch64ExternalSymbolizer.h - Symbolizer for AArch64 -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,25 +7,26 @@
//
//===----------------------------------------------------------------------===//
//
-// Symbolize ARM64 assembly code during disassembly using callbacks.
+// Symbolize AArch64 assembly code during disassembly using callbacks.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64EXTERNALSYMBOLIZER_H
-#define ARM64EXTERNALSYMBOLIZER_H
+#ifndef AArch64EXTERNALSYMBOLIZER_H
+#define AArch64EXTERNALSYMBOLIZER_H
#include "llvm/MC/MCExternalSymbolizer.h"
namespace llvm {
-class ARM64ExternalSymbolizer : public MCExternalSymbolizer {
+class AArch64ExternalSymbolizer : public MCExternalSymbolizer {
public:
- ARM64ExternalSymbolizer(MCContext &Ctx,
- std::unique_ptr<MCRelocationInfo> RelInfo,
- LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo)
- : MCExternalSymbolizer(Ctx, std::move(RelInfo), GetOpInfo, SymbolLookUp,
- DisInfo) {}
+ AArch64ExternalSymbolizer(MCContext &Ctx,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
+ LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp,
+ void *DisInfo)
+ : MCExternalSymbolizer(Ctx, std::move(RelInfo), GetOpInfo, SymbolLookUp,
+ DisInfo) {}
bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream,
int64_t Value, uint64_t Address, bool IsBranch,
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/CMakeLists.txt (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/CMakeLists.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/CMakeLists.txt?p2=llvm/trunk/lib/Target/AArch64/Disassembler/CMakeLists.txt&p1=llvm/trunk/lib/Target/ARM64/Disassembler/CMakeLists.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -1,8 +1,8 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
-add_llvm_library(LLVMARM64Disassembler
- ARM64Disassembler.cpp
- ARM64ExternalSymbolizer.cpp
+add_llvm_library(LLVMAArch64Disassembler
+ AArch64Disassembler.cpp
+ AArch64ExternalSymbolizer.cpp
)
# workaround for hanging compilation on MSVC8, 9 and 10
#if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
@@ -11,4 +11,4 @@ add_llvm_library(LLVMARM64Disassembler
# PROPERTY COMPILE_FLAGS "/Od"
# )
#endif()
-add_dependencies(LLVMARM64Disassembler ARM64CommonTableGen)
+add_dependencies(LLVMAArch64Disassembler AArch64CommonTableGen)
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/Disassembler/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/Disassembler/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,7 +17,7 @@
[component_0]
type = Library
-name = ARM64Disassembler
-parent = ARM64
-required_libraries = ARM64Info ARM64Utils MC Support
-add_to_library_groups = ARM64
+name = AArch64Disassembler
+parent = AArch64
+required_libraries = AArch64Info AArch64Utils MC Support
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/Disassembler/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/Disassembler/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/Makefile?p2=llvm/trunk/lib/Target/AArch64/Disassembler/Makefile&p1=llvm/trunk/lib/Target/ARM64/Disassembler/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Disassembler/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM64/Disassembler/Makefile --------------*- Makefile -*-===##
+##===- lib/Target/AArch64/Disassembler/Makefile ------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64Disassembler
+LIBRARYNAME = LLVMAArch64Disassembler
# Hack: we need to include 'main' arm target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
Added: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp (added)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp Sat May 24 07:50:23 2014
@@ -0,0 +1,1316 @@
+//==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints an AArch64 MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AArch64InstPrinter.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "Utils/AArch64BaseInfo.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "asm-printer"
+
+#define GET_INSTRUCTION_NAME
+#define PRINT_ALIAS_INSTR
+#include "AArch64GenAsmWriter.inc"
+#define GET_INSTRUCTION_NAME
+#define PRINT_ALIAS_INSTR
+#include "AArch64GenAsmWriter1.inc"
+
+AArch64InstPrinter::AArch64InstPrinter(const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI)
+ : MCInstPrinter(MAI, MII, MRI) {
+ // Initialize the set of available features.
+ setAvailableFeatures(STI.getFeatureBits());
+}
+
+AArch64AppleInstPrinter::AArch64AppleInstPrinter(const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI)
+ : AArch64InstPrinter(MAI, MII, MRI, STI) {}
+
+void AArch64InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
+ // This is for .cfi directives.
+ OS << getRegisterName(RegNo);
+}
+
+void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
+ StringRef Annot) {
+ // Check for special encodings and print the canonical alias instead.
+
+ unsigned Opcode = MI->getOpcode();
+
+ if (Opcode == AArch64::SYSxt)
+ if (printSysAlias(MI, O)) {
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ // SBFM/UBFM should print to a nicer aliased form if possible.
+ if (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri ||
+ Opcode == AArch64::UBFMXri || Opcode == AArch64::UBFMWri) {
+ const MCOperand &Op0 = MI->getOperand(0);
+ const MCOperand &Op1 = MI->getOperand(1);
+ const MCOperand &Op2 = MI->getOperand(2);
+ const MCOperand &Op3 = MI->getOperand(3);
+
+ bool IsSigned = (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri);
+ bool Is64Bit = (Opcode == AArch64::SBFMXri || Opcode == AArch64::UBFMXri);
+ if (Op2.isImm() && Op2.getImm() == 0 && Op3.isImm()) {
+ const char *AsmMnemonic = nullptr;
+
+ switch (Op3.getImm()) {
+ default:
+ break;
+ case 7:
+ if (IsSigned)
+ AsmMnemonic = "sxtb";
+ else if (!Is64Bit)
+ AsmMnemonic = "uxtb";
+ break;
+ case 15:
+ if (IsSigned)
+ AsmMnemonic = "sxth";
+ else if (!Is64Bit)
+ AsmMnemonic = "uxth";
+ break;
+ case 31:
+ // *xtw is only valid for signed 64-bit operations.
+ if (Is64Bit && IsSigned)
+ AsmMnemonic = "sxtw";
+ break;
+ }
+
+ if (AsmMnemonic) {
+ O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg())
+ << ", " << getRegisterName(getWRegFromXReg(Op1.getReg()));
+ printAnnotation(O, Annot);
+ return;
+ }
+ }
+
+ // All immediate shifts are aliases, implemented using the Bitfield
+ // instruction. In all cases the immediate shift amount shift must be in
+ // the range 0 to (reg.size -1).
+ if (Op2.isImm() && Op3.isImm()) {
+ const char *AsmMnemonic = nullptr;
+ int shift = 0;
+ int64_t immr = Op2.getImm();
+ int64_t imms = Op3.getImm();
+ if (Opcode == AArch64::UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {
+ AsmMnemonic = "lsl";
+ shift = 31 - imms;
+ } else if (Opcode == AArch64::UBFMXri && imms != 0x3f &&
+ ((imms + 1 == immr))) {
+ AsmMnemonic = "lsl";
+ shift = 63 - imms;
+ } else if (Opcode == AArch64::UBFMWri && imms == 0x1f) {
+ AsmMnemonic = "lsr";
+ shift = immr;
+ } else if (Opcode == AArch64::UBFMXri && imms == 0x3f) {
+ AsmMnemonic = "lsr";
+ shift = immr;
+ } else if (Opcode == AArch64::SBFMWri && imms == 0x1f) {
+ AsmMnemonic = "asr";
+ shift = immr;
+ } else if (Opcode == AArch64::SBFMXri && imms == 0x3f) {
+ AsmMnemonic = "asr";
+ shift = immr;
+ }
+ if (AsmMnemonic) {
+ O << '\t' << AsmMnemonic << '\t' << getRegisterName(Op0.getReg())
+ << ", " << getRegisterName(Op1.getReg()) << ", #" << shift;
+ printAnnotation(O, Annot);
+ return;
+ }
+ }
+
+ // SBFIZ/UBFIZ aliases
+ if (Op2.getImm() > Op3.getImm()) {
+ O << '\t' << (IsSigned ? "sbfiz" : "ubfiz") << '\t'
+ << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg())
+ << ", #" << (Is64Bit ? 64 : 32) - Op2.getImm() << ", #" << Op3.getImm() + 1;
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ // Otherwise SBFX/UBFX is the preferred form
+ O << '\t' << (IsSigned ? "sbfx" : "ubfx") << '\t'
+ << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg())
+ << ", #" << Op2.getImm() << ", #" << Op3.getImm() - Op2.getImm() + 1;
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ if (Opcode == AArch64::BFMXri || Opcode == AArch64::BFMWri) {
+ const MCOperand &Op0 = MI->getOperand(0); // Op1 == Op0
+ const MCOperand &Op2 = MI->getOperand(2);
+ int ImmR = MI->getOperand(3).getImm();
+ int ImmS = MI->getOperand(4).getImm();
+
+ // BFI alias
+ if (ImmS < ImmR) {
+ int BitWidth = Opcode == AArch64::BFMXri ? 64 : 32;
+ int LSB = (BitWidth - ImmR) % BitWidth;
+ int Width = ImmS + 1;
+ O << "\tbfi\t" << getRegisterName(Op0.getReg()) << ", "
+ << getRegisterName(Op2.getReg()) << ", #" << LSB << ", #" << Width;
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ int LSB = ImmR;
+ int Width = ImmS - ImmR + 1;
+ // Otherwise BFXIL the preferred form
+ O << "\tbfxil\t"
+ << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op2.getReg())
+ << ", #" << LSB << ", #" << Width;
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ // Symbolic operands for MOVZ, MOVN and MOVK already imply a shift
+ // (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be
+ // printed.
+ if ((Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi ||
+ Opcode == AArch64::MOVNXi || Opcode == AArch64::MOVNWi) &&
+ MI->getOperand(1).isExpr()) {
+ if (Opcode == AArch64::MOVZXi || Opcode == AArch64::MOVZWi)
+ O << "\tmovz\t";
+ else
+ O << "\tmovn\t";
+
+ O << getRegisterName(MI->getOperand(0).getReg()) << ", #"
+ << *MI->getOperand(1).getExpr();
+ return;
+ }
+
+ if ((Opcode == AArch64::MOVKXi || Opcode == AArch64::MOVKWi) &&
+ MI->getOperand(2).isExpr()) {
+ O << "\tmovk\t" << getRegisterName(MI->getOperand(0).getReg()) << ", #"
+ << *MI->getOperand(2).getExpr();
+ return;
+ }
+
+ if (!printAliasInstr(MI, O))
+ printInstruction(MI, O);
+
+ printAnnotation(O, Annot);
+}
+
+static bool isTblTbxInstruction(unsigned Opcode, StringRef &Layout,
+ bool &IsTbx) {
+ switch (Opcode) {
+ case AArch64::TBXv8i8One:
+ case AArch64::TBXv8i8Two:
+ case AArch64::TBXv8i8Three:
+ case AArch64::TBXv8i8Four:
+ IsTbx = true;
+ Layout = ".8b";
+ return true;
+ case AArch64::TBLv8i8One:
+ case AArch64::TBLv8i8Two:
+ case AArch64::TBLv8i8Three:
+ case AArch64::TBLv8i8Four:
+ IsTbx = false;
+ Layout = ".8b";
+ return true;
+ case AArch64::TBXv16i8One:
+ case AArch64::TBXv16i8Two:
+ case AArch64::TBXv16i8Three:
+ case AArch64::TBXv16i8Four:
+ IsTbx = true;
+ Layout = ".16b";
+ return true;
+ case AArch64::TBLv16i8One:
+ case AArch64::TBLv16i8Two:
+ case AArch64::TBLv16i8Three:
+ case AArch64::TBLv16i8Four:
+ IsTbx = false;
+ Layout = ".16b";
+ return true;
+ default:
+ return false;
+ }
+}
+
+struct LdStNInstrDesc {
+ unsigned Opcode;
+ const char *Mnemonic;
+ const char *Layout;
+ int ListOperand;
+ bool HasLane;
+ int NaturalOffset;
+};
+
+static LdStNInstrDesc LdStNInstInfo[] = {
+ { AArch64::LD1i8, "ld1", ".b", 1, true, 0 },
+ { AArch64::LD1i16, "ld1", ".h", 1, true, 0 },
+ { AArch64::LD1i32, "ld1", ".s", 1, true, 0 },
+ { AArch64::LD1i64, "ld1", ".d", 1, true, 0 },
+ { AArch64::LD1i8_POST, "ld1", ".b", 2, true, 1 },
+ { AArch64::LD1i16_POST, "ld1", ".h", 2, true, 2 },
+ { AArch64::LD1i32_POST, "ld1", ".s", 2, true, 4 },
+ { AArch64::LD1i64_POST, "ld1", ".d", 2, true, 8 },
+ { AArch64::LD1Rv16b, "ld1r", ".16b", 0, false, 0 },
+ { AArch64::LD1Rv8h, "ld1r", ".8h", 0, false, 0 },
+ { AArch64::LD1Rv4s, "ld1r", ".4s", 0, false, 0 },
+ { AArch64::LD1Rv2d, "ld1r", ".2d", 0, false, 0 },
+ { AArch64::LD1Rv8b, "ld1r", ".8b", 0, false, 0 },
+ { AArch64::LD1Rv4h, "ld1r", ".4h", 0, false, 0 },
+ { AArch64::LD1Rv2s, "ld1r", ".2s", 0, false, 0 },
+ { AArch64::LD1Rv1d, "ld1r", ".1d", 0, false, 0 },
+ { AArch64::LD1Rv16b_POST, "ld1r", ".16b", 1, false, 1 },
+ { AArch64::LD1Rv8h_POST, "ld1r", ".8h", 1, false, 2 },
+ { AArch64::LD1Rv4s_POST, "ld1r", ".4s", 1, false, 4 },
+ { AArch64::LD1Rv2d_POST, "ld1r", ".2d", 1, false, 8 },
+ { AArch64::LD1Rv8b_POST, "ld1r", ".8b", 1, false, 1 },
+ { AArch64::LD1Rv4h_POST, "ld1r", ".4h", 1, false, 2 },
+ { AArch64::LD1Rv2s_POST, "ld1r", ".2s", 1, false, 4 },
+ { AArch64::LD1Rv1d_POST, "ld1r", ".1d", 1, false, 8 },
+ { AArch64::LD1Onev16b, "ld1", ".16b", 0, false, 0 },
+ { AArch64::LD1Onev8h, "ld1", ".8h", 0, false, 0 },
+ { AArch64::LD1Onev4s, "ld1", ".4s", 0, false, 0 },
+ { AArch64::LD1Onev2d, "ld1", ".2d", 0, false, 0 },
+ { AArch64::LD1Onev8b, "ld1", ".8b", 0, false, 0 },
+ { AArch64::LD1Onev4h, "ld1", ".4h", 0, false, 0 },
+ { AArch64::LD1Onev2s, "ld1", ".2s", 0, false, 0 },
+ { AArch64::LD1Onev1d, "ld1", ".1d", 0, false, 0 },
+ { AArch64::LD1Onev16b_POST, "ld1", ".16b", 1, false, 16 },
+ { AArch64::LD1Onev8h_POST, "ld1", ".8h", 1, false, 16 },
+ { AArch64::LD1Onev4s_POST, "ld1", ".4s", 1, false, 16 },
+ { AArch64::LD1Onev2d_POST, "ld1", ".2d", 1, false, 16 },
+ { AArch64::LD1Onev8b_POST, "ld1", ".8b", 1, false, 8 },
+ { AArch64::LD1Onev4h_POST, "ld1", ".4h", 1, false, 8 },
+ { AArch64::LD1Onev2s_POST, "ld1", ".2s", 1, false, 8 },
+ { AArch64::LD1Onev1d_POST, "ld1", ".1d", 1, false, 8 },
+ { AArch64::LD1Twov16b, "ld1", ".16b", 0, false, 0 },
+ { AArch64::LD1Twov8h, "ld1", ".8h", 0, false, 0 },
+ { AArch64::LD1Twov4s, "ld1", ".4s", 0, false, 0 },
+ { AArch64::LD1Twov2d, "ld1", ".2d", 0, false, 0 },
+ { AArch64::LD1Twov8b, "ld1", ".8b", 0, false, 0 },
+ { AArch64::LD1Twov4h, "ld1", ".4h", 0, false, 0 },
+ { AArch64::LD1Twov2s, "ld1", ".2s", 0, false, 0 },
+ { AArch64::LD1Twov1d, "ld1", ".1d", 0, false, 0 },
+ { AArch64::LD1Twov16b_POST, "ld1", ".16b", 1, false, 32 },
+ { AArch64::LD1Twov8h_POST, "ld1", ".8h", 1, false, 32 },
+ { AArch64::LD1Twov4s_POST, "ld1", ".4s", 1, false, 32 },
+ { AArch64::LD1Twov2d_POST, "ld1", ".2d", 1, false, 32 },
+ { AArch64::LD1Twov8b_POST, "ld1", ".8b", 1, false, 16 },
+ { AArch64::LD1Twov4h_POST, "ld1", ".4h", 1, false, 16 },
+ { AArch64::LD1Twov2s_POST, "ld1", ".2s", 1, false, 16 },
+ { AArch64::LD1Twov1d_POST, "ld1", ".1d", 1, false, 16 },
+ { AArch64::LD1Threev16b, "ld1", ".16b", 0, false, 0 },
+ { AArch64::LD1Threev8h, "ld1", ".8h", 0, false, 0 },
+ { AArch64::LD1Threev4s, "ld1", ".4s", 0, false, 0 },
+ { AArch64::LD1Threev2d, "ld1", ".2d", 0, false, 0 },
+ { AArch64::LD1Threev8b, "ld1", ".8b", 0, false, 0 },
+ { AArch64::LD1Threev4h, "ld1", ".4h", 0, false, 0 },
+ { AArch64::LD1Threev2s, "ld1", ".2s", 0, false, 0 },
+ { AArch64::LD1Threev1d, "ld1", ".1d", 0, false, 0 },
+ { AArch64::LD1Threev16b_POST, "ld1", ".16b", 1, false, 48 },
+ { AArch64::LD1Threev8h_POST, "ld1", ".8h", 1, false, 48 },
+ { AArch64::LD1Threev4s_POST, "ld1", ".4s", 1, false, 48 },
+ { AArch64::LD1Threev2d_POST, "ld1", ".2d", 1, false, 48 },
+ { AArch64::LD1Threev8b_POST, "ld1", ".8b", 1, false, 24 },
+ { AArch64::LD1Threev4h_POST, "ld1", ".4h", 1, false, 24 },
+ { AArch64::LD1Threev2s_POST, "ld1", ".2s", 1, false, 24 },
+ { AArch64::LD1Threev1d_POST, "ld1", ".1d", 1, false, 24 },
+ { AArch64::LD1Fourv16b, "ld1", ".16b", 0, false, 0 },
+ { AArch64::LD1Fourv8h, "ld1", ".8h", 0, false, 0 },
+ { AArch64::LD1Fourv4s, "ld1", ".4s", 0, false, 0 },
+ { AArch64::LD1Fourv2d, "ld1", ".2d", 0, false, 0 },
+ { AArch64::LD1Fourv8b, "ld1", ".8b", 0, false, 0 },
+ { AArch64::LD1Fourv4h, "ld1", ".4h", 0, false, 0 },
+ { AArch64::LD1Fourv2s, "ld1", ".2s", 0, false, 0 },
+ { AArch64::LD1Fourv1d, "ld1", ".1d", 0, false, 0 },
+ { AArch64::LD1Fourv16b_POST, "ld1", ".16b", 1, false, 64 },
+ { AArch64::LD1Fourv8h_POST, "ld1", ".8h", 1, false, 64 },
+ { AArch64::LD1Fourv4s_POST, "ld1", ".4s", 1, false, 64 },
+ { AArch64::LD1Fourv2d_POST, "ld1", ".2d", 1, false, 64 },
+ { AArch64::LD1Fourv8b_POST, "ld1", ".8b", 1, false, 32 },
+ { AArch64::LD1Fourv4h_POST, "ld1", ".4h", 1, false, 32 },
+ { AArch64::LD1Fourv2s_POST, "ld1", ".2s", 1, false, 32 },
+ { AArch64::LD1Fourv1d_POST, "ld1", ".1d", 1, false, 32 },
+ { AArch64::LD2i8, "ld2", ".b", 1, true, 0 },
+ { AArch64::LD2i16, "ld2", ".h", 1, true, 0 },
+ { AArch64::LD2i32, "ld2", ".s", 1, true, 0 },
+ { AArch64::LD2i64, "ld2", ".d", 1, true, 0 },
+ { AArch64::LD2i8_POST, "ld2", ".b", 2, true, 2 },
+ { AArch64::LD2i16_POST, "ld2", ".h", 2, true, 4 },
+ { AArch64::LD2i32_POST, "ld2", ".s", 2, true, 8 },
+ { AArch64::LD2i64_POST, "ld2", ".d", 2, true, 16 },
+ { AArch64::LD2Rv16b, "ld2r", ".16b", 0, false, 0 },
+ { AArch64::LD2Rv8h, "ld2r", ".8h", 0, false, 0 },
+ { AArch64::LD2Rv4s, "ld2r", ".4s", 0, false, 0 },
+ { AArch64::LD2Rv2d, "ld2r", ".2d", 0, false, 0 },
+ { AArch64::LD2Rv8b, "ld2r", ".8b", 0, false, 0 },
+ { AArch64::LD2Rv4h, "ld2r", ".4h", 0, false, 0 },
+ { AArch64::LD2Rv2s, "ld2r", ".2s", 0, false, 0 },
+ { AArch64::LD2Rv1d, "ld2r", ".1d", 0, false, 0 },
+ { AArch64::LD2Rv16b_POST, "ld2r", ".16b", 1, false, 2 },
+ { AArch64::LD2Rv8h_POST, "ld2r", ".8h", 1, false, 4 },
+ { AArch64::LD2Rv4s_POST, "ld2r", ".4s", 1, false, 8 },
+ { AArch64::LD2Rv2d_POST, "ld2r", ".2d", 1, false, 16 },
+ { AArch64::LD2Rv8b_POST, "ld2r", ".8b", 1, false, 2 },
+ { AArch64::LD2Rv4h_POST, "ld2r", ".4h", 1, false, 4 },
+ { AArch64::LD2Rv2s_POST, "ld2r", ".2s", 1, false, 8 },
+ { AArch64::LD2Rv1d_POST, "ld2r", ".1d", 1, false, 16 },
+ { AArch64::LD2Twov16b, "ld2", ".16b", 0, false, 0 },
+ { AArch64::LD2Twov8h, "ld2", ".8h", 0, false, 0 },
+ { AArch64::LD2Twov4s, "ld2", ".4s", 0, false, 0 },
+ { AArch64::LD2Twov2d, "ld2", ".2d", 0, false, 0 },
+ { AArch64::LD2Twov8b, "ld2", ".8b", 0, false, 0 },
+ { AArch64::LD2Twov4h, "ld2", ".4h", 0, false, 0 },
+ { AArch64::LD2Twov2s, "ld2", ".2s", 0, false, 0 },
+ { AArch64::LD2Twov16b_POST, "ld2", ".16b", 1, false, 32 },
+ { AArch64::LD2Twov8h_POST, "ld2", ".8h", 1, false, 32 },
+ { AArch64::LD2Twov4s_POST, "ld2", ".4s", 1, false, 32 },
+ { AArch64::LD2Twov2d_POST, "ld2", ".2d", 1, false, 32 },
+ { AArch64::LD2Twov8b_POST, "ld2", ".8b", 1, false, 16 },
+ { AArch64::LD2Twov4h_POST, "ld2", ".4h", 1, false, 16 },
+ { AArch64::LD2Twov2s_POST, "ld2", ".2s", 1, false, 16 },
+ { AArch64::LD3i8, "ld3", ".b", 1, true, 0 },
+ { AArch64::LD3i16, "ld3", ".h", 1, true, 0 },
+ { AArch64::LD3i32, "ld3", ".s", 1, true, 0 },
+ { AArch64::LD3i64, "ld3", ".d", 1, true, 0 },
+ { AArch64::LD3i8_POST, "ld3", ".b", 2, true, 3 },
+ { AArch64::LD3i16_POST, "ld3", ".h", 2, true, 6 },
+ { AArch64::LD3i32_POST, "ld3", ".s", 2, true, 12 },
+ { AArch64::LD3i64_POST, "ld3", ".d", 2, true, 24 },
+ { AArch64::LD3Rv16b, "ld3r", ".16b", 0, false, 0 },
+ { AArch64::LD3Rv8h, "ld3r", ".8h", 0, false, 0 },
+ { AArch64::LD3Rv4s, "ld3r", ".4s", 0, false, 0 },
+ { AArch64::LD3Rv2d, "ld3r", ".2d", 0, false, 0 },
+ { AArch64::LD3Rv8b, "ld3r", ".8b", 0, false, 0 },
+ { AArch64::LD3Rv4h, "ld3r", ".4h", 0, false, 0 },
+ { AArch64::LD3Rv2s, "ld3r", ".2s", 0, false, 0 },
+ { AArch64::LD3Rv1d, "ld3r", ".1d", 0, false, 0 },
+ { AArch64::LD3Rv16b_POST, "ld3r", ".16b", 1, false, 3 },
+ { AArch64::LD3Rv8h_POST, "ld3r", ".8h", 1, false, 6 },
+ { AArch64::LD3Rv4s_POST, "ld3r", ".4s", 1, false, 12 },
+ { AArch64::LD3Rv2d_POST, "ld3r", ".2d", 1, false, 24 },
+ { AArch64::LD3Rv8b_POST, "ld3r", ".8b", 1, false, 3 },
+ { AArch64::LD3Rv4h_POST, "ld3r", ".4h", 1, false, 6 },
+ { AArch64::LD3Rv2s_POST, "ld3r", ".2s", 1, false, 12 },
+ { AArch64::LD3Rv1d_POST, "ld3r", ".1d", 1, false, 24 },
+ { AArch64::LD3Threev16b, "ld3", ".16b", 0, false, 0 },
+ { AArch64::LD3Threev8h, "ld3", ".8h", 0, false, 0 },
+ { AArch64::LD3Threev4s, "ld3", ".4s", 0, false, 0 },
+ { AArch64::LD3Threev2d, "ld3", ".2d", 0, false, 0 },
+ { AArch64::LD3Threev8b, "ld3", ".8b", 0, false, 0 },
+ { AArch64::LD3Threev4h, "ld3", ".4h", 0, false, 0 },
+ { AArch64::LD3Threev2s, "ld3", ".2s", 0, false, 0 },
+ { AArch64::LD3Threev16b_POST, "ld3", ".16b", 1, false, 48 },
+ { AArch64::LD3Threev8h_POST, "ld3", ".8h", 1, false, 48 },
+ { AArch64::LD3Threev4s_POST, "ld3", ".4s", 1, false, 48 },
+ { AArch64::LD3Threev2d_POST, "ld3", ".2d", 1, false, 48 },
+ { AArch64::LD3Threev8b_POST, "ld3", ".8b", 1, false, 24 },
+ { AArch64::LD3Threev4h_POST, "ld3", ".4h", 1, false, 24 },
+ { AArch64::LD3Threev2s_POST, "ld3", ".2s", 1, false, 24 },
+ { AArch64::LD4i8, "ld4", ".b", 1, true, 0 },
+ { AArch64::LD4i16, "ld4", ".h", 1, true, 0 },
+ { AArch64::LD4i32, "ld4", ".s", 1, true, 0 },
+ { AArch64::LD4i64, "ld4", ".d", 1, true, 0 },
+ { AArch64::LD4i8_POST, "ld4", ".b", 2, true, 4 },
+ { AArch64::LD4i16_POST, "ld4", ".h", 2, true, 8 },
+ { AArch64::LD4i32_POST, "ld4", ".s", 2, true, 16 },
+ { AArch64::LD4i64_POST, "ld4", ".d", 2, true, 32 },
+ { AArch64::LD4Rv16b, "ld4r", ".16b", 0, false, 0 },
+ { AArch64::LD4Rv8h, "ld4r", ".8h", 0, false, 0 },
+ { AArch64::LD4Rv4s, "ld4r", ".4s", 0, false, 0 },
+ { AArch64::LD4Rv2d, "ld4r", ".2d", 0, false, 0 },
+ { AArch64::LD4Rv8b, "ld4r", ".8b", 0, false, 0 },
+ { AArch64::LD4Rv4h, "ld4r", ".4h", 0, false, 0 },
+ { AArch64::LD4Rv2s, "ld4r", ".2s", 0, false, 0 },
+ { AArch64::LD4Rv1d, "ld4r", ".1d", 0, false, 0 },
+ { AArch64::LD4Rv16b_POST, "ld4r", ".16b", 1, false, 4 },
+ { AArch64::LD4Rv8h_POST, "ld4r", ".8h", 1, false, 8 },
+ { AArch64::LD4Rv4s_POST, "ld4r", ".4s", 1, false, 16 },
+ { AArch64::LD4Rv2d_POST, "ld4r", ".2d", 1, false, 32 },
+ { AArch64::LD4Rv8b_POST, "ld4r", ".8b", 1, false, 4 },
+ { AArch64::LD4Rv4h_POST, "ld4r", ".4h", 1, false, 8 },
+ { AArch64::LD4Rv2s_POST, "ld4r", ".2s", 1, false, 16 },
+ { AArch64::LD4Rv1d_POST, "ld4r", ".1d", 1, false, 32 },
+ { AArch64::LD4Fourv16b, "ld4", ".16b", 0, false, 0 },
+ { AArch64::LD4Fourv8h, "ld4", ".8h", 0, false, 0 },
+ { AArch64::LD4Fourv4s, "ld4", ".4s", 0, false, 0 },
+ { AArch64::LD4Fourv2d, "ld4", ".2d", 0, false, 0 },
+ { AArch64::LD4Fourv8b, "ld4", ".8b", 0, false, 0 },
+ { AArch64::LD4Fourv4h, "ld4", ".4h", 0, false, 0 },
+ { AArch64::LD4Fourv2s, "ld4", ".2s", 0, false, 0 },
+ { AArch64::LD4Fourv16b_POST, "ld4", ".16b", 1, false, 64 },
+ { AArch64::LD4Fourv8h_POST, "ld4", ".8h", 1, false, 64 },
+ { AArch64::LD4Fourv4s_POST, "ld4", ".4s", 1, false, 64 },
+ { AArch64::LD4Fourv2d_POST, "ld4", ".2d", 1, false, 64 },
+ { AArch64::LD4Fourv8b_POST, "ld4", ".8b", 1, false, 32 },
+ { AArch64::LD4Fourv4h_POST, "ld4", ".4h", 1, false, 32 },
+ { AArch64::LD4Fourv2s_POST, "ld4", ".2s", 1, false, 32 },
+ { AArch64::ST1i8, "st1", ".b", 0, true, 0 },
+ { AArch64::ST1i16, "st1", ".h", 0, true, 0 },
+ { AArch64::ST1i32, "st1", ".s", 0, true, 0 },
+ { AArch64::ST1i64, "st1", ".d", 0, true, 0 },
+ { AArch64::ST1i8_POST, "st1", ".b", 1, true, 1 },
+ { AArch64::ST1i16_POST, "st1", ".h", 1, true, 2 },
+ { AArch64::ST1i32_POST, "st1", ".s", 1, true, 4 },
+ { AArch64::ST1i64_POST, "st1", ".d", 1, true, 8 },
+ { AArch64::ST1Onev16b, "st1", ".16b", 0, false, 0 },
+ { AArch64::ST1Onev8h, "st1", ".8h", 0, false, 0 },
+ { AArch64::ST1Onev4s, "st1", ".4s", 0, false, 0 },
+ { AArch64::ST1Onev2d, "st1", ".2d", 0, false, 0 },
+ { AArch64::ST1Onev8b, "st1", ".8b", 0, false, 0 },
+ { AArch64::ST1Onev4h, "st1", ".4h", 0, false, 0 },
+ { AArch64::ST1Onev2s, "st1", ".2s", 0, false, 0 },
+ { AArch64::ST1Onev1d, "st1", ".1d", 0, false, 0 },
+ { AArch64::ST1Onev16b_POST, "st1", ".16b", 1, false, 16 },
+ { AArch64::ST1Onev8h_POST, "st1", ".8h", 1, false, 16 },
+ { AArch64::ST1Onev4s_POST, "st1", ".4s", 1, false, 16 },
+ { AArch64::ST1Onev2d_POST, "st1", ".2d", 1, false, 16 },
+ { AArch64::ST1Onev8b_POST, "st1", ".8b", 1, false, 8 },
+ { AArch64::ST1Onev4h_POST, "st1", ".4h", 1, false, 8 },
+ { AArch64::ST1Onev2s_POST, "st1", ".2s", 1, false, 8 },
+ { AArch64::ST1Onev1d_POST, "st1", ".1d", 1, false, 8 },
+ { AArch64::ST1Twov16b, "st1", ".16b", 0, false, 0 },
+ { AArch64::ST1Twov8h, "st1", ".8h", 0, false, 0 },
+ { AArch64::ST1Twov4s, "st1", ".4s", 0, false, 0 },
+ { AArch64::ST1Twov2d, "st1", ".2d", 0, false, 0 },
+ { AArch64::ST1Twov8b, "st1", ".8b", 0, false, 0 },
+ { AArch64::ST1Twov4h, "st1", ".4h", 0, false, 0 },
+ { AArch64::ST1Twov2s, "st1", ".2s", 0, false, 0 },
+ { AArch64::ST1Twov1d, "st1", ".1d", 0, false, 0 },
+ { AArch64::ST1Twov16b_POST, "st1", ".16b", 1, false, 32 },
+ { AArch64::ST1Twov8h_POST, "st1", ".8h", 1, false, 32 },
+ { AArch64::ST1Twov4s_POST, "st1", ".4s", 1, false, 32 },
+ { AArch64::ST1Twov2d_POST, "st1", ".2d", 1, false, 32 },
+ { AArch64::ST1Twov8b_POST, "st1", ".8b", 1, false, 16 },
+ { AArch64::ST1Twov4h_POST, "st1", ".4h", 1, false, 16 },
+ { AArch64::ST1Twov2s_POST, "st1", ".2s", 1, false, 16 },
+ { AArch64::ST1Twov1d_POST, "st1", ".1d", 1, false, 16 },
+ { AArch64::ST1Threev16b, "st1", ".16b", 0, false, 0 },
+ { AArch64::ST1Threev8h, "st1", ".8h", 0, false, 0 },
+ { AArch64::ST1Threev4s, "st1", ".4s", 0, false, 0 },
+ { AArch64::ST1Threev2d, "st1", ".2d", 0, false, 0 },
+ { AArch64::ST1Threev8b, "st1", ".8b", 0, false, 0 },
+ { AArch64::ST1Threev4h, "st1", ".4h", 0, false, 0 },
+ { AArch64::ST1Threev2s, "st1", ".2s", 0, false, 0 },
+ { AArch64::ST1Threev1d, "st1", ".1d", 0, false, 0 },
+ { AArch64::ST1Threev16b_POST, "st1", ".16b", 1, false, 48 },
+ { AArch64::ST1Threev8h_POST, "st1", ".8h", 1, false, 48 },
+ { AArch64::ST1Threev4s_POST, "st1", ".4s", 1, false, 48 },
+ { AArch64::ST1Threev2d_POST, "st1", ".2d", 1, false, 48 },
+ { AArch64::ST1Threev8b_POST, "st1", ".8b", 1, false, 24 },
+ { AArch64::ST1Threev4h_POST, "st1", ".4h", 1, false, 24 },
+ { AArch64::ST1Threev2s_POST, "st1", ".2s", 1, false, 24 },
+ { AArch64::ST1Threev1d_POST, "st1", ".1d", 1, false, 24 },
+ { AArch64::ST1Fourv16b, "st1", ".16b", 0, false, 0 },
+ { AArch64::ST1Fourv8h, "st1", ".8h", 0, false, 0 },
+ { AArch64::ST1Fourv4s, "st1", ".4s", 0, false, 0 },
+ { AArch64::ST1Fourv2d, "st1", ".2d", 0, false, 0 },
+ { AArch64::ST1Fourv8b, "st1", ".8b", 0, false, 0 },
+ { AArch64::ST1Fourv4h, "st1", ".4h", 0, false, 0 },
+ { AArch64::ST1Fourv2s, "st1", ".2s", 0, false, 0 },
+ { AArch64::ST1Fourv1d, "st1", ".1d", 0, false, 0 },
+ { AArch64::ST1Fourv16b_POST, "st1", ".16b", 1, false, 64 },
+ { AArch64::ST1Fourv8h_POST, "st1", ".8h", 1, false, 64 },
+ { AArch64::ST1Fourv4s_POST, "st1", ".4s", 1, false, 64 },
+ { AArch64::ST1Fourv2d_POST, "st1", ".2d", 1, false, 64 },
+ { AArch64::ST1Fourv8b_POST, "st1", ".8b", 1, false, 32 },
+ { AArch64::ST1Fourv4h_POST, "st1", ".4h", 1, false, 32 },
+ { AArch64::ST1Fourv2s_POST, "st1", ".2s", 1, false, 32 },
+ { AArch64::ST1Fourv1d_POST, "st1", ".1d", 1, false, 32 },
+ { AArch64::ST2i8, "st2", ".b", 0, true, 0 },
+ { AArch64::ST2i16, "st2", ".h", 0, true, 0 },
+ { AArch64::ST2i32, "st2", ".s", 0, true, 0 },
+ { AArch64::ST2i64, "st2", ".d", 0, true, 0 },
+ { AArch64::ST2i8_POST, "st2", ".b", 1, true, 2 },
+ { AArch64::ST2i16_POST, "st2", ".h", 1, true, 4 },
+ { AArch64::ST2i32_POST, "st2", ".s", 1, true, 8 },
+ { AArch64::ST2i64_POST, "st2", ".d", 1, true, 16 },
+ { AArch64::ST2Twov16b, "st2", ".16b", 0, false, 0 },
+ { AArch64::ST2Twov8h, "st2", ".8h", 0, false, 0 },
+ { AArch64::ST2Twov4s, "st2", ".4s", 0, false, 0 },
+ { AArch64::ST2Twov2d, "st2", ".2d", 0, false, 0 },
+ { AArch64::ST2Twov8b, "st2", ".8b", 0, false, 0 },
+ { AArch64::ST2Twov4h, "st2", ".4h", 0, false, 0 },
+ { AArch64::ST2Twov2s, "st2", ".2s", 0, false, 0 },
+ { AArch64::ST2Twov16b_POST, "st2", ".16b", 1, false, 32 },
+ { AArch64::ST2Twov8h_POST, "st2", ".8h", 1, false, 32 },
+ { AArch64::ST2Twov4s_POST, "st2", ".4s", 1, false, 32 },
+ { AArch64::ST2Twov2d_POST, "st2", ".2d", 1, false, 32 },
+ { AArch64::ST2Twov8b_POST, "st2", ".8b", 1, false, 16 },
+ { AArch64::ST2Twov4h_POST, "st2", ".4h", 1, false, 16 },
+ { AArch64::ST2Twov2s_POST, "st2", ".2s", 1, false, 16 },
+ { AArch64::ST3i8, "st3", ".b", 0, true, 0 },
+ { AArch64::ST3i16, "st3", ".h", 0, true, 0 },
+ { AArch64::ST3i32, "st3", ".s", 0, true, 0 },
+ { AArch64::ST3i64, "st3", ".d", 0, true, 0 },
+ { AArch64::ST3i8_POST, "st3", ".b", 1, true, 3 },
+ { AArch64::ST3i16_POST, "st3", ".h", 1, true, 6 },
+ { AArch64::ST3i32_POST, "st3", ".s", 1, true, 12 },
+ { AArch64::ST3i64_POST, "st3", ".d", 1, true, 24 },
+ { AArch64::ST3Threev16b, "st3", ".16b", 0, false, 0 },
+ { AArch64::ST3Threev8h, "st3", ".8h", 0, false, 0 },
+ { AArch64::ST3Threev4s, "st3", ".4s", 0, false, 0 },
+ { AArch64::ST3Threev2d, "st3", ".2d", 0, false, 0 },
+ { AArch64::ST3Threev8b, "st3", ".8b", 0, false, 0 },
+ { AArch64::ST3Threev4h, "st3", ".4h", 0, false, 0 },
+ { AArch64::ST3Threev2s, "st3", ".2s", 0, false, 0 },
+ { AArch64::ST3Threev16b_POST, "st3", ".16b", 1, false, 48 },
+ { AArch64::ST3Threev8h_POST, "st3", ".8h", 1, false, 48 },
+ { AArch64::ST3Threev4s_POST, "st3", ".4s", 1, false, 48 },
+ { AArch64::ST3Threev2d_POST, "st3", ".2d", 1, false, 48 },
+ { AArch64::ST3Threev8b_POST, "st3", ".8b", 1, false, 24 },
+ { AArch64::ST3Threev4h_POST, "st3", ".4h", 1, false, 24 },
+ { AArch64::ST3Threev2s_POST, "st3", ".2s", 1, false, 24 },
+ { AArch64::ST4i8, "st4", ".b", 0, true, 0 },
+ { AArch64::ST4i16, "st4", ".h", 0, true, 0 },
+ { AArch64::ST4i32, "st4", ".s", 0, true, 0 },
+ { AArch64::ST4i64, "st4", ".d", 0, true, 0 },
+ { AArch64::ST4i8_POST, "st4", ".b", 1, true, 4 },
+ { AArch64::ST4i16_POST, "st4", ".h", 1, true, 8 },
+ { AArch64::ST4i32_POST, "st4", ".s", 1, true, 16 },
+ { AArch64::ST4i64_POST, "st4", ".d", 1, true, 32 },
+ { AArch64::ST4Fourv16b, "st4", ".16b", 0, false, 0 },
+ { AArch64::ST4Fourv8h, "st4", ".8h", 0, false, 0 },
+ { AArch64::ST4Fourv4s, "st4", ".4s", 0, false, 0 },
+ { AArch64::ST4Fourv2d, "st4", ".2d", 0, false, 0 },
+ { AArch64::ST4Fourv8b, "st4", ".8b", 0, false, 0 },
+ { AArch64::ST4Fourv4h, "st4", ".4h", 0, false, 0 },
+ { AArch64::ST4Fourv2s, "st4", ".2s", 0, false, 0 },
+ { AArch64::ST4Fourv16b_POST, "st4", ".16b", 1, false, 64 },
+ { AArch64::ST4Fourv8h_POST, "st4", ".8h", 1, false, 64 },
+ { AArch64::ST4Fourv4s_POST, "st4", ".4s", 1, false, 64 },
+ { AArch64::ST4Fourv2d_POST, "st4", ".2d", 1, false, 64 },
+ { AArch64::ST4Fourv8b_POST, "st4", ".8b", 1, false, 32 },
+ { AArch64::ST4Fourv4h_POST, "st4", ".4h", 1, false, 32 },
+ { AArch64::ST4Fourv2s_POST, "st4", ".2s", 1, false, 32 },
+};
+
+static LdStNInstrDesc *getLdStNInstrDesc(unsigned Opcode) {
+ unsigned Idx;
+ for (Idx = 0; Idx != array_lengthof(LdStNInstInfo); ++Idx)
+ if (LdStNInstInfo[Idx].Opcode == Opcode)
+ return &LdStNInstInfo[Idx];
+
+ return nullptr;
+}
+
+void AArch64AppleInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
+ StringRef Annot) {
+ unsigned Opcode = MI->getOpcode();
+ StringRef Layout, Mnemonic;
+
+ bool IsTbx;
+ if (isTblTbxInstruction(MI->getOpcode(), Layout, IsTbx)) {
+ O << "\t" << (IsTbx ? "tbx" : "tbl") << Layout << '\t'
+ << getRegisterName(MI->getOperand(0).getReg(), AArch64::vreg) << ", ";
+
+ unsigned ListOpNum = IsTbx ? 2 : 1;
+ printVectorList(MI, ListOpNum, O, "");
+
+ O << ", "
+ << getRegisterName(MI->getOperand(ListOpNum + 1).getReg(), AArch64::vreg);
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ if (LdStNInstrDesc *LdStDesc = getLdStNInstrDesc(Opcode)) {
+ O << "\t" << LdStDesc->Mnemonic << LdStDesc->Layout << '\t';
+
+ // Now onto the operands: first a vector list with possible lane
+ // specifier. E.g. { v0 }[2]
+ int OpNum = LdStDesc->ListOperand;
+ printVectorList(MI, OpNum++, O, "");
+
+ if (LdStDesc->HasLane)
+ O << '[' << MI->getOperand(OpNum++).getImm() << ']';
+
+ // Next the address: [xN]
+ unsigned AddrReg = MI->getOperand(OpNum++).getReg();
+ O << ", [" << getRegisterName(AddrReg) << ']';
+
+ // Finally, there might be a post-indexed offset.
+ if (LdStDesc->NaturalOffset != 0) {
+ unsigned Reg = MI->getOperand(OpNum++).getReg();
+ if (Reg != AArch64::XZR)
+ O << ", " << getRegisterName(Reg);
+ else {
+ assert(LdStDesc->NaturalOffset && "no offset on post-inc instruction?");
+ O << ", #" << LdStDesc->NaturalOffset;
+ }
+ }
+
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ AArch64InstPrinter::printInst(MI, O, Annot);
+}
+
+bool AArch64InstPrinter::printSysAlias(const MCInst *MI, raw_ostream &O) {
+#ifndef NDEBUG
+ unsigned Opcode = MI->getOpcode();
+ assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!");
+#endif
+
+ const char *Asm = nullptr;
+ const MCOperand &Op1 = MI->getOperand(0);
+ const MCOperand &Cn = MI->getOperand(1);
+ const MCOperand &Cm = MI->getOperand(2);
+ const MCOperand &Op2 = MI->getOperand(3);
+
+ unsigned Op1Val = Op1.getImm();
+ unsigned CnVal = Cn.getImm();
+ unsigned CmVal = Cm.getImm();
+ unsigned Op2Val = Op2.getImm();
+
+ if (CnVal == 7) {
+ switch (CmVal) {
+ default:
+ break;
+
+ // IC aliases
+ case 1:
+ if (Op1Val == 0 && Op2Val == 0)
+ Asm = "ic\tialluis";
+ break;
+ case 5:
+ if (Op1Val == 0 && Op2Val == 0)
+ Asm = "ic\tiallu";
+ else if (Op1Val == 3 && Op2Val == 1)
+ Asm = "ic\tivau";
+ break;
+
+ // DC aliases
+ case 4:
+ if (Op1Val == 3 && Op2Val == 1)
+ Asm = "dc\tzva";
+ break;
+ case 6:
+ if (Op1Val == 0 && Op2Val == 1)
+ Asm = "dc\tivac";
+ if (Op1Val == 0 && Op2Val == 2)
+ Asm = "dc\tisw";
+ break;
+ case 10:
+ if (Op1Val == 3 && Op2Val == 1)
+ Asm = "dc\tcvac";
+ else if (Op1Val == 0 && Op2Val == 2)
+ Asm = "dc\tcsw";
+ break;
+ case 11:
+ if (Op1Val == 3 && Op2Val == 1)
+ Asm = "dc\tcvau";
+ break;
+ case 14:
+ if (Op1Val == 3 && Op2Val == 1)
+ Asm = "dc\tcivac";
+ else if (Op1Val == 0 && Op2Val == 2)
+ Asm = "dc\tcisw";
+ break;
+
+ // AT aliases
+ case 8:
+ switch (Op1Val) {
+ default:
+ break;
+ case 0:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "at\ts1e1r"; break;
+ case 1: Asm = "at\ts1e1w"; break;
+ case 2: Asm = "at\ts1e0r"; break;
+ case 3: Asm = "at\ts1e0w"; break;
+ }
+ break;
+ case 4:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "at\ts1e2r"; break;
+ case 1: Asm = "at\ts1e2w"; break;
+ case 4: Asm = "at\ts12e1r"; break;
+ case 5: Asm = "at\ts12e1w"; break;
+ case 6: Asm = "at\ts12e0r"; break;
+ case 7: Asm = "at\ts12e0w"; break;
+ }
+ break;
+ case 6:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "at\ts1e3r"; break;
+ case 1: Asm = "at\ts1e3w"; break;
+ }
+ break;
+ }
+ break;
+ }
+ } else if (CnVal == 8) {
+ // TLBI aliases
+ switch (CmVal) {
+ default:
+ break;
+ case 3:
+ switch (Op1Val) {
+ default:
+ break;
+ case 0:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\tvmalle1is"; break;
+ case 1: Asm = "tlbi\tvae1is"; break;
+ case 2: Asm = "tlbi\taside1is"; break;
+ case 3: Asm = "tlbi\tvaae1is"; break;
+ case 5: Asm = "tlbi\tvale1is"; break;
+ case 7: Asm = "tlbi\tvaale1is"; break;
+ }
+ break;
+ case 4:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\talle2is"; break;
+ case 1: Asm = "tlbi\tvae2is"; break;
+ case 4: Asm = "tlbi\talle1is"; break;
+ case 5: Asm = "tlbi\tvale2is"; break;
+ case 6: Asm = "tlbi\tvmalls12e1is"; break;
+ }
+ break;
+ case 6:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\talle3is"; break;
+ case 1: Asm = "tlbi\tvae3is"; break;
+ case 5: Asm = "tlbi\tvale3is"; break;
+ }
+ break;
+ }
+ break;
+ case 0:
+ switch (Op1Val) {
+ default:
+ break;
+ case 4:
+ switch (Op2Val) {
+ default:
+ break;
+ case 1: Asm = "tlbi\tipas2e1is"; break;
+ case 5: Asm = "tlbi\tipas2le1is"; break;
+ }
+ break;
+ }
+ break;
+ case 4:
+ switch (Op1Val) {
+ default:
+ break;
+ case 4:
+ switch (Op2Val) {
+ default:
+ break;
+ case 1: Asm = "tlbi\tipas2e1"; break;
+ case 5: Asm = "tlbi\tipas2le1"; break;
+ }
+ break;
+ }
+ break;
+ case 7:
+ switch (Op1Val) {
+ default:
+ break;
+ case 0:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\tvmalle1"; break;
+ case 1: Asm = "tlbi\tvae1"; break;
+ case 2: Asm = "tlbi\taside1"; break;
+ case 3: Asm = "tlbi\tvaae1"; break;
+ case 5: Asm = "tlbi\tvale1"; break;
+ case 7: Asm = "tlbi\tvaale1"; break;
+ }
+ break;
+ case 4:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\talle2"; break;
+ case 1: Asm = "tlbi\tvae2"; break;
+ case 4: Asm = "tlbi\talle1"; break;
+ case 5: Asm = "tlbi\tvale2"; break;
+ case 6: Asm = "tlbi\tvmalls12e1"; break;
+ }
+ break;
+ case 6:
+ switch (Op2Val) {
+ default:
+ break;
+ case 0: Asm = "tlbi\talle3"; break;
+ case 1: Asm = "tlbi\tvae3"; break;
+ case 5: Asm = "tlbi\tvale3"; break;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ if (Asm) {
+ unsigned Reg = MI->getOperand(4).getReg();
+
+ O << '\t' << Asm;
+ if (StringRef(Asm).lower().find("all") == StringRef::npos)
+ O << ", " << getRegisterName(Reg);
+ }
+
+ return Asm != nullptr;
+}
+
+void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isReg()) {
+ unsigned Reg = Op.getReg();
+ O << getRegisterName(Reg);
+ } else if (Op.isImm()) {
+ O << '#' << Op.getImm();
+ } else {
+ assert(Op.isExpr() && "unknown operand kind in printOperand");
+ O << *Op.getExpr();
+ }
+}
+
+void AArch64InstPrinter::printHexImm(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ O << format("#%#llx", Op.getImm());
+}
+
+void AArch64InstPrinter::printPostIncOperand(const MCInst *MI, unsigned OpNo,
+ unsigned Imm, raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isReg()) {
+ unsigned Reg = Op.getReg();
+ if (Reg == AArch64::XZR)
+ O << "#" << Imm;
+ else
+ O << getRegisterName(Reg);
+ } else
+ assert(0 && "unknown operand kind in printPostIncOperand64");
+}
+
+void AArch64InstPrinter::printVRegOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ assert(Op.isReg() && "Non-register vreg operand!");
+ unsigned Reg = Op.getReg();
+ O << getRegisterName(Reg, AArch64::vreg);
+}
+
+void AArch64InstPrinter::printSysCROperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ assert(Op.isImm() && "System instruction C[nm] operands must be immediates!");
+ O << "c" << Op.getImm();
+}
+
+void AArch64InstPrinter::printAddSubImm(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNum);
+ if (MO.isImm()) {
+ unsigned Val = (MO.getImm() & 0xfff);
+ assert(Val == MO.getImm() && "Add/sub immediate out of range!");
+ unsigned Shift =
+ AArch64_AM::getShiftValue(MI->getOperand(OpNum + 1).getImm());
+ O << '#' << Val;
+ if (Shift != 0)
+ printShifter(MI, OpNum + 1, O);
+
+ if (CommentStream)
+ *CommentStream << '=' << (Val << Shift) << '\n';
+ } else {
+ assert(MO.isExpr() && "Unexpected operand type!");
+ O << *MO.getExpr();
+ printShifter(MI, OpNum + 1, O);
+ }
+}
+
+void AArch64InstPrinter::printLogicalImm32(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ uint64_t Val = MI->getOperand(OpNum).getImm();
+ O << "#0x";
+ O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 32));
+}
+
+void AArch64InstPrinter::printLogicalImm64(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ uint64_t Val = MI->getOperand(OpNum).getImm();
+ O << "#0x";
+ O.write_hex(AArch64_AM::decodeLogicalImmediate(Val, 64));
+}
+
+void AArch64InstPrinter::printShifter(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNum).getImm();
+ // LSL #0 should not be printed.
+ if (AArch64_AM::getShiftType(Val) == AArch64_AM::LSL &&
+ AArch64_AM::getShiftValue(Val) == 0)
+ return;
+ O << ", " << AArch64_AM::getShiftExtendName(AArch64_AM::getShiftType(Val))
+ << " #" << AArch64_AM::getShiftValue(Val);
+}
+
+void AArch64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ O << getRegisterName(MI->getOperand(OpNum).getReg());
+ printShifter(MI, OpNum + 1, O);
+}
+
+void AArch64InstPrinter::printExtendedRegister(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ O << getRegisterName(MI->getOperand(OpNum).getReg());
+ printArithExtend(MI, OpNum + 1, O);
+}
+
+void AArch64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNum).getImm();
+ AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getArithExtendType(Val);
+ unsigned ShiftVal = AArch64_AM::getArithShiftValue(Val);
+
+ // If the destination or first source register operand is [W]SP, print
+ // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
+ // all.
+ if (ExtType == AArch64_AM::UXTW || ExtType == AArch64_AM::UXTX) {
+ unsigned Dest = MI->getOperand(0).getReg();
+ unsigned Src1 = MI->getOperand(1).getReg();
+ if ( ((Dest == AArch64::SP || Src1 == AArch64::SP) &&
+ ExtType == AArch64_AM::UXTX) ||
+ ((Dest == AArch64::WSP || Src1 == AArch64::WSP) &&
+ ExtType == AArch64_AM::UXTW) ) {
+ if (ShiftVal != 0)
+ O << ", lsl #" << ShiftVal;
+ return;
+ }
+ }
+ O << ", " << AArch64_AM::getShiftExtendName(ExtType);
+ if (ShiftVal != 0)
+ O << " #" << ShiftVal;
+}
+
+void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O, char SrcRegKind,
+ unsigned Width) {
+ unsigned SignExtend = MI->getOperand(OpNum).getImm();
+ unsigned DoShift = MI->getOperand(OpNum + 1).getImm();
+
+ // sxtw, sxtx, uxtw or lsl (== uxtx)
+ bool IsLSL = !SignExtend && SrcRegKind == 'x';
+ if (IsLSL)
+ O << "lsl";
+ else
+ O << (SignExtend ? 's' : 'u') << "xt" << SrcRegKind;
+
+ if (DoShift || IsLSL)
+ O << " #" << Log2_32(Width / 8);
+}
+
+void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm();
+ O << AArch64CC::getCondCodeName(CC);
+}
+
+void AArch64InstPrinter::printInverseCondCode(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(OpNum).getImm();
+ O << AArch64CC::getCondCodeName(AArch64CC::getInvertedCondCode(CC));
+}
+
+void AArch64InstPrinter::printAMNoIndex(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()) << ']';
+}
+
+template<int Scale>
+void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ O << '#' << Scale * MI->getOperand(OpNum).getImm();
+}
+
+void AArch64InstPrinter::printUImm12Offset(const MCInst *MI, unsigned OpNum,
+ unsigned Scale, raw_ostream &O) {
+ const MCOperand MO = MI->getOperand(OpNum);
+ if (MO.isImm()) {
+ O << "#" << (MO.getImm() * Scale);
+ } else {
+ assert(MO.isExpr() && "Unexpected operand type!");
+ O << *MO.getExpr();
+ }
+}
+
+void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum,
+ unsigned Scale, raw_ostream &O) {
+ const MCOperand MO1 = MI->getOperand(OpNum + 1);
+ O << '[' << getRegisterName(MI->getOperand(OpNum).getReg());
+ if (MO1.isImm()) {
+ O << ", #" << (MO1.getImm() * Scale);
+ } else {
+ assert(MO1.isExpr() && "Unexpected operand type!");
+ O << ", " << *MO1.getExpr();
+ }
+ O << ']';
+}
+
+void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ unsigned prfop = MI->getOperand(OpNum).getImm();
+ bool Valid;
+ StringRef Name = AArch64PRFM::PRFMMapper().toString(prfop, Valid);
+ if (Valid)
+ O << Name;
+ else
+ O << '#' << prfop;
+}
+
+void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNum);
+ float FPImm =
+ MO.isFPImm() ? MO.getFPImm() : AArch64_AM::getFPImmFloat(MO.getImm());
+
+ // 8 decimal places are enough to perfectly represent permitted floats.
+ O << format("#%.8f", FPImm);
+}
+
+static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) {
+ while (Stride--) {
+ switch (Reg) {
+ default:
+ assert(0 && "Vector register expected!");
+ case AArch64::Q0: Reg = AArch64::Q1; break;
+ case AArch64::Q1: Reg = AArch64::Q2; break;
+ case AArch64::Q2: Reg = AArch64::Q3; break;
+ case AArch64::Q3: Reg = AArch64::Q4; break;
+ case AArch64::Q4: Reg = AArch64::Q5; break;
+ case AArch64::Q5: Reg = AArch64::Q6; break;
+ case AArch64::Q6: Reg = AArch64::Q7; break;
+ case AArch64::Q7: Reg = AArch64::Q8; break;
+ case AArch64::Q8: Reg = AArch64::Q9; break;
+ case AArch64::Q9: Reg = AArch64::Q10; break;
+ case AArch64::Q10: Reg = AArch64::Q11; break;
+ case AArch64::Q11: Reg = AArch64::Q12; break;
+ case AArch64::Q12: Reg = AArch64::Q13; break;
+ case AArch64::Q13: Reg = AArch64::Q14; break;
+ case AArch64::Q14: Reg = AArch64::Q15; break;
+ case AArch64::Q15: Reg = AArch64::Q16; break;
+ case AArch64::Q16: Reg = AArch64::Q17; break;
+ case AArch64::Q17: Reg = AArch64::Q18; break;
+ case AArch64::Q18: Reg = AArch64::Q19; break;
+ case AArch64::Q19: Reg = AArch64::Q20; break;
+ case AArch64::Q20: Reg = AArch64::Q21; break;
+ case AArch64::Q21: Reg = AArch64::Q22; break;
+ case AArch64::Q22: Reg = AArch64::Q23; break;
+ case AArch64::Q23: Reg = AArch64::Q24; break;
+ case AArch64::Q24: Reg = AArch64::Q25; break;
+ case AArch64::Q25: Reg = AArch64::Q26; break;
+ case AArch64::Q26: Reg = AArch64::Q27; break;
+ case AArch64::Q27: Reg = AArch64::Q28; break;
+ case AArch64::Q28: Reg = AArch64::Q29; break;
+ case AArch64::Q29: Reg = AArch64::Q30; break;
+ case AArch64::Q30: Reg = AArch64::Q31; break;
+ // Vector lists can wrap around.
+ case AArch64::Q31:
+ Reg = AArch64::Q0;
+ break;
+ }
+ }
+ return Reg;
+}
+
+void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O,
+ StringRef LayoutSuffix) {
+ unsigned Reg = MI->getOperand(OpNum).getReg();
+
+ O << "{ ";
+
+ // Work out how many registers there are in the list (if there is an actual
+ // list).
+ unsigned NumRegs = 1;
+ if (MRI.getRegClass(AArch64::DDRegClassID).contains(Reg) ||
+ MRI.getRegClass(AArch64::QQRegClassID).contains(Reg))
+ NumRegs = 2;
+ else if (MRI.getRegClass(AArch64::DDDRegClassID).contains(Reg) ||
+ MRI.getRegClass(AArch64::QQQRegClassID).contains(Reg))
+ NumRegs = 3;
+ else if (MRI.getRegClass(AArch64::DDDDRegClassID).contains(Reg) ||
+ MRI.getRegClass(AArch64::QQQQRegClassID).contains(Reg))
+ NumRegs = 4;
+
+ // Now forget about the list and find out what the first register is.
+ if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::dsub0))
+ Reg = FirstReg;
+ else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::qsub0))
+ Reg = FirstReg;
+
+ // If it's a D-reg, we need to promote it to the equivalent Q-reg before
+ // printing (otherwise getRegisterName fails).
+ if (MRI.getRegClass(AArch64::FPR64RegClassID).contains(Reg)) {
+ const MCRegisterClass &FPR128RC =
+ MRI.getRegClass(AArch64::FPR128RegClassID);
+ Reg = MRI.getMatchingSuperReg(Reg, AArch64::dsub, &FPR128RC);
+ }
+
+ for (unsigned i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg)) {
+ O << getRegisterName(Reg, AArch64::vreg) << LayoutSuffix;
+ if (i + 1 != NumRegs)
+ O << ", ";
+ }
+
+ O << " }";
+}
+
+void AArch64InstPrinter::printImplicitlyTypedVectorList(const MCInst *MI,
+ unsigned OpNum,
+ raw_ostream &O) {
+ printVectorList(MI, OpNum, O, "");
+}
+
+template <unsigned NumLanes, char LaneKind>
+void AArch64InstPrinter::printTypedVectorList(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ std::string Suffix(".");
+ if (NumLanes)
+ Suffix += itostr(NumLanes) + LaneKind;
+ else
+ Suffix += LaneKind;
+
+ printVectorList(MI, OpNum, O, Suffix);
+}
+
+void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ O << "[" << MI->getOperand(OpNum).getImm() << "]";
+}
+
+void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNum);
+
+ // If the label has already been resolved to an immediate offset (say, when
+ // we're running the disassembler), just print the immediate.
+ if (Op.isImm()) {
+ O << "#" << (Op.getImm() << 2);
+ return;
+ }
+
+ // If the branch target is simply an address then print it in hex.
+ const MCConstantExpr *BranchTarget =
+ dyn_cast<MCConstantExpr>(MI->getOperand(OpNum).getExpr());
+ int64_t Address;
+ if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) {
+ O << "0x";
+ O.write_hex(Address);
+ } else {
+ // Otherwise, just print the expression.
+ O << *MI->getOperand(OpNum).getExpr();
+ }
+}
+
+void AArch64InstPrinter::printAdrpLabel(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &Op = MI->getOperand(OpNum);
+
+ // If the label has already been resolved to an immediate offset (say, when
+ // we're running the disassembler), just print the immediate.
+ if (Op.isImm()) {
+ O << "#" << (Op.getImm() << 12);
+ return;
+ }
+
+ // Otherwise, just print the expression.
+ O << *MI->getOperand(OpNum).getExpr();
+}
+
+void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNo).getImm();
+ unsigned Opcode = MI->getOpcode();
+
+ bool Valid;
+ StringRef Name;
+ if (Opcode == AArch64::ISB)
+ Name = AArch64ISB::ISBMapper().toString(Val, Valid);
+ else
+ Name = AArch64DB::DBarrierMapper().toString(Val, Valid);
+ if (Valid)
+ O << Name;
+ else
+ O << "#" << Val;
+}
+
+void AArch64InstPrinter::printMRSSystemRegister(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNo).getImm();
+
+ bool Valid;
+ auto Mapper = AArch64SysReg::MRSMapper(getAvailableFeatures());
+ std::string Name = Mapper.toString(Val, Valid);
+
+ if (Valid)
+ O << StringRef(Name).upper();
+}
+
+void AArch64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNo).getImm();
+
+ bool Valid;
+ auto Mapper = AArch64SysReg::MSRMapper(getAvailableFeatures());
+ std::string Name = Mapper.toString(Val, Valid);
+
+ if (Valid)
+ O << StringRef(Name).upper();
+}
+
+void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Val = MI->getOperand(OpNo).getImm();
+
+ bool Valid;
+ StringRef Name = AArch64PState::PStateMapper().toString(Val, Valid);
+ if (Valid)
+ O << StringRef(Name.str()).upper();
+ else
+ O << "#" << Val;
+}
+
+void AArch64InstPrinter::printSIMDType10Operand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned RawVal = MI->getOperand(OpNo).getImm();
+ uint64_t Val = AArch64_AM::decodeAdvSIMDModImmType10(RawVal);
+ O << format("#%#016llx", Val);
+}
Copied: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h (from r209576, llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h?p2=llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h&p1=llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64InstPrinter.h - Convert ARM64 MCInst to assembly syntax ------===//
+//===-- AArch64InstPrinter.h - Convert AArch64 MCInst to assembly syntax --===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This class prints an ARM64 MCInst to a .s file.
+// This class prints an AArch64 MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64INSTPRINTER_H
-#define ARM64INSTPRINTER_H
+#ifndef AArch64INSTPRINTER_H
+#define AArch64INSTPRINTER_H
-#include "MCTargetDesc/ARM64MCTargetDesc.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -23,10 +23,10 @@ namespace llvm {
class MCOperand;
-class ARM64InstPrinter : public MCInstPrinter {
+class AArch64InstPrinter : public MCInstPrinter {
public:
- ARM64InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
- const MCRegisterInfo &MRI, const MCSubtargetInfo &STI);
+ AArch64InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI, const MCSubtargetInfo &STI);
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override;
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
@@ -40,7 +40,7 @@ public:
return getRegisterName(RegNo);
}
static const char *getRegisterName(unsigned RegNo,
- unsigned AltIdx = ARM64::NoRegAltName);
+ unsigned AltIdx = AArch64::NoRegAltName);
protected:
bool printSysAlias(const MCInst *MI, raw_ostream &O);
@@ -118,9 +118,9 @@ protected:
void printSIMDType10Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
};
-class ARM64AppleInstPrinter : public ARM64InstPrinter {
+class AArch64AppleInstPrinter : public AArch64InstPrinter {
public:
- ARM64AppleInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ AArch64AppleInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI, const MCSubtargetInfo &STI);
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override;
@@ -133,7 +133,7 @@ public:
return getRegisterName(RegNo);
}
static const char *getRegisterName(unsigned RegNo,
- unsigned AltIdx = ARM64::NoRegAltName);
+ unsigned AltIdx = AArch64::NoRegAltName);
};
}
Added: llvm/trunk/lib/Target/AArch64/InstPrinter/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/CMakeLists.txt?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/InstPrinter/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -0,0 +1,7 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMAArch64AsmPrinter
+ AArch64InstPrinter.cpp
+ )
+
+add_dependencies(LLVMAArch64AsmPrinter AArch64CommonTableGen)
Copied: llvm/trunk/lib/Target/AArch64/InstPrinter/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/InstPrinter/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/InstPrinter/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/InstPrinter/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/InstPrinter/LLVMBuild.txt -------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/InstPrinter/LLVMBuild.txt -------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,8 +17,8 @@
[component_0]
type = Library
-name = ARM64AsmPrinter
-parent = ARM64
-required_libraries = ARM64Utils MC Support
-add_to_library_groups = ARM64
+name = AArch64AsmPrinter
+parent = AArch64
+required_libraries = AArch64Utils MC Support
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/InstPrinter/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/InstPrinter/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/InstPrinter/Makefile?p2=llvm/trunk/lib/Target/AArch64/InstPrinter/Makefile&p1=llvm/trunk/lib/Target/ARM64/InstPrinter/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/InstPrinter/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/InstPrinter/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM64/AsmPrinter/Makefile ----------------*- Makefile -*-===##
+##===- lib/Target/AArch64/AsmPrinter/Makefile --------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64AsmPrinter
+LIBRARYNAME = LLVMAArch64AsmPrinter
# Hack: we need to include 'main' arm target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
Copied: llvm/trunk/lib/Target/AArch64/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/LLVMBuild.txt -------------------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/LLVMBuild.txt -------------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -20,7 +20,7 @@ subdirectories = AsmParser Disassembler
[component_0]
type = TargetGroup
-name = ARM64
+name = AArch64
parent = Target
has_asmparser = 1
has_asmprinter = 1
@@ -29,7 +29,7 @@ has_jit = 1
[component_1]
type = Library
-name = ARM64CodeGen
-parent = ARM64
-required_libraries = ARM64AsmPrinter ARM64Desc ARM64Info ARM64Utils Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target
-add_to_library_groups = ARM64
+name = AArch64CodeGen
+parent = AArch64
+required_libraries = AArch64AsmPrinter AArch64Desc AArch64Info AArch64Utils Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AddressingModes.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AddressingModes.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AddressingModes.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- ARM64AddressingModes.h - ARM64 Addressing Modes ----------*- C++ -*-===//
+//===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the ARM64 addressing mode implementation stuff.
+// This file contains the AArch64 addressing mode implementation stuff.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ARM64_ARM64ADDRESSINGMODES_H
-#define LLVM_TARGET_ARM64_ARM64ADDRESSINGMODES_H
+#ifndef LLVM_TARGET_AArch64_AArch64ADDRESSINGMODES_H
+#define LLVM_TARGET_AArch64_AArch64ADDRESSINGMODES_H
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
@@ -22,8 +22,8 @@
namespace llvm {
-/// ARM64_AM - ARM64 Addressing Mode Stuff
-namespace ARM64_AM {
+/// AArch64_AM - AArch64 Addressing Mode Stuff
+namespace AArch64_AM {
//===----------------------------------------------------------------------===//
// Shifts
@@ -49,35 +49,35 @@ enum ShiftExtendType {
};
/// getShiftName - Get the string encoding for the shift type.
-static inline const char *getShiftExtendName(ARM64_AM::ShiftExtendType ST) {
+static inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) {
switch (ST) {
default: assert(false && "unhandled shift type!");
- case ARM64_AM::LSL: return "lsl";
- case ARM64_AM::LSR: return "lsr";
- case ARM64_AM::ASR: return "asr";
- case ARM64_AM::ROR: return "ror";
- case ARM64_AM::MSL: return "msl";
- case ARM64_AM::UXTB: return "uxtb";
- case ARM64_AM::UXTH: return "uxth";
- case ARM64_AM::UXTW: return "uxtw";
- case ARM64_AM::UXTX: return "uxtx";
- case ARM64_AM::SXTB: return "sxtb";
- case ARM64_AM::SXTH: return "sxth";
- case ARM64_AM::SXTW: return "sxtw";
- case ARM64_AM::SXTX: return "sxtx";
+ case AArch64_AM::LSL: return "lsl";
+ case AArch64_AM::LSR: return "lsr";
+ case AArch64_AM::ASR: return "asr";
+ case AArch64_AM::ROR: return "ror";
+ case AArch64_AM::MSL: return "msl";
+ case AArch64_AM::UXTB: return "uxtb";
+ case AArch64_AM::UXTH: return "uxth";
+ case AArch64_AM::UXTW: return "uxtw";
+ case AArch64_AM::UXTX: return "uxtx";
+ case AArch64_AM::SXTB: return "sxtb";
+ case AArch64_AM::SXTH: return "sxth";
+ case AArch64_AM::SXTW: return "sxtw";
+ case AArch64_AM::SXTX: return "sxtx";
}
return nullptr;
}
/// getShiftType - Extract the shift type.
-static inline ARM64_AM::ShiftExtendType getShiftType(unsigned Imm) {
+static inline AArch64_AM::ShiftExtendType getShiftType(unsigned Imm) {
switch ((Imm >> 6) & 0x7) {
- default: return ARM64_AM::InvalidShiftExtend;
- case 0: return ARM64_AM::LSL;
- case 1: return ARM64_AM::LSR;
- case 2: return ARM64_AM::ASR;
- case 3: return ARM64_AM::ROR;
- case 4: return ARM64_AM::MSL;
+ default: return AArch64_AM::InvalidShiftExtend;
+ case 0: return AArch64_AM::LSL;
+ case 1: return AArch64_AM::LSR;
+ case 2: return AArch64_AM::ASR;
+ case 3: return AArch64_AM::ROR;
+ case 4: return AArch64_AM::MSL;
}
}
@@ -95,17 +95,17 @@ static inline unsigned getShiftValue(uns
/// 100 ==> msl
/// {8-6} = shifter
/// {5-0} = imm
-static inline unsigned getShifterImm(ARM64_AM::ShiftExtendType ST,
+static inline unsigned getShifterImm(AArch64_AM::ShiftExtendType ST,
unsigned Imm) {
assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!");
unsigned STEnc = 0;
switch (ST) {
default: llvm_unreachable("Invalid shift requested");
- case ARM64_AM::LSL: STEnc = 0; break;
- case ARM64_AM::LSR: STEnc = 1; break;
- case ARM64_AM::ASR: STEnc = 2; break;
- case ARM64_AM::ROR: STEnc = 3; break;
- case ARM64_AM::MSL: STEnc = 4; break;
+ case AArch64_AM::LSL: STEnc = 0; break;
+ case AArch64_AM::LSR: STEnc = 1; break;
+ case AArch64_AM::ASR: STEnc = 2; break;
+ case AArch64_AM::ROR: STEnc = 3; break;
+ case AArch64_AM::MSL: STEnc = 4; break;
}
return (STEnc << 6) | (Imm & 0x3f);
}
@@ -120,22 +120,22 @@ static inline unsigned getArithShiftValu
}
/// getExtendType - Extract the extend type for operands of arithmetic ops.
-static inline ARM64_AM::ShiftExtendType getExtendType(unsigned Imm) {
+static inline AArch64_AM::ShiftExtendType getExtendType(unsigned Imm) {
assert((Imm & 0x7) == Imm && "invalid immediate!");
switch (Imm) {
default: llvm_unreachable("Compiler bug!");
- case 0: return ARM64_AM::UXTB;
- case 1: return ARM64_AM::UXTH;
- case 2: return ARM64_AM::UXTW;
- case 3: return ARM64_AM::UXTX;
- case 4: return ARM64_AM::SXTB;
- case 5: return ARM64_AM::SXTH;
- case 6: return ARM64_AM::SXTW;
- case 7: return ARM64_AM::SXTX;
+ case 0: return AArch64_AM::UXTB;
+ case 1: return AArch64_AM::UXTH;
+ case 2: return AArch64_AM::UXTW;
+ case 3: return AArch64_AM::UXTX;
+ case 4: return AArch64_AM::SXTB;
+ case 5: return AArch64_AM::SXTH;
+ case 6: return AArch64_AM::SXTW;
+ case 7: return AArch64_AM::SXTX;
}
}
-static inline ARM64_AM::ShiftExtendType getArithExtendType(unsigned Imm) {
+static inline AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm) {
return getExtendType((Imm >> 3) & 0x7);
}
@@ -148,17 +148,17 @@ static inline ARM64_AM::ShiftExtendType
/// 101 ==> sxth
/// 110 ==> sxtw
/// 111 ==> sxtx
-inline unsigned getExtendEncoding(ARM64_AM::ShiftExtendType ET) {
+inline unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET) {
switch (ET) {
default: llvm_unreachable("Invalid extend type requested");
- case ARM64_AM::UXTB: return 0; break;
- case ARM64_AM::UXTH: return 1; break;
- case ARM64_AM::UXTW: return 2; break;
- case ARM64_AM::UXTX: return 3; break;
- case ARM64_AM::SXTB: return 4; break;
- case ARM64_AM::SXTH: return 5; break;
- case ARM64_AM::SXTW: return 6; break;
- case ARM64_AM::SXTX: return 7; break;
+ case AArch64_AM::UXTB: return 0; break;
+ case AArch64_AM::UXTH: return 1; break;
+ case AArch64_AM::UXTW: return 2; break;
+ case AArch64_AM::UXTX: return 3; break;
+ case AArch64_AM::SXTB: return 4; break;
+ case AArch64_AM::SXTH: return 5; break;
+ case AArch64_AM::SXTW: return 6; break;
+ case AArch64_AM::SXTX: return 7; break;
}
}
@@ -167,7 +167,7 @@ inline unsigned getExtendEncoding(ARM64_
/// imm: 3-bit extend amount
/// {5-3} = shifter
/// {2-0} = imm3
-static inline unsigned getArithExtendImm(ARM64_AM::ShiftExtendType ET,
+static inline unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET,
unsigned Imm) {
assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!");
return (getExtendEncoding(ET) << 3) | (Imm & 0x7);
@@ -181,7 +181,7 @@ static inline bool getMemDoShift(unsigne
/// getExtendType - Extract the extend type for the offset operand of
/// loads/stores.
-static inline ARM64_AM::ShiftExtendType getMemExtendType(unsigned Imm) {
+static inline AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm) {
return getExtendType((Imm >> 1) & 0x7);
}
@@ -197,7 +197,7 @@ static inline ARM64_AM::ShiftExtendType
/// 111 ==> sxtx
/// {3-1} = shifter
/// {0} = doshift
-static inline unsigned getMemExtendImm(ARM64_AM::ShiftExtendType ET,
+static inline unsigned getMemExtendImm(AArch64_AM::ShiftExtendType ET,
bool DoShift) {
return (getExtendEncoding(ET) << 1) | unsigned(DoShift);
}
@@ -731,7 +731,7 @@ static inline uint64_t decodeAdvSIMDModI
return (EncVal << 32) | EncVal;
}
-} // end namespace ARM64_AM
+} // end namespace AArch64_AM
} // end namespace llvm
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64AsmBackend.cpp - ARM64 Assembler Backend ---------------------===//
+//===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64.h"
-#include "ARM64RegisterInfo.h"
-#include "MCTargetDesc/ARM64FixupKinds.h"
+#include "AArch64.h"
+#include "AArch64RegisterInfo.h"
+#include "MCTargetDesc/AArch64FixupKinds.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCDirectives.h"
@@ -23,38 +23,38 @@ using namespace llvm;
namespace {
-class ARM64AsmBackend : public MCAsmBackend {
+class AArch64AsmBackend : public MCAsmBackend {
static const unsigned PCRelFlagVal =
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits | MCFixupKindInfo::FKF_IsPCRel;
public:
- ARM64AsmBackend(const Target &T) : MCAsmBackend() {}
+ AArch64AsmBackend(const Target &T) : MCAsmBackend() {}
unsigned getNumFixupKinds() const override {
- return ARM64::NumTargetFixupKinds;
+ return AArch64::NumTargetFixupKinds;
}
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
- const static MCFixupKindInfo Infos[ARM64::NumTargetFixupKinds] = {
+ const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
// This table *must* be in the order that the fixup_* kinds are defined in
- // ARM64FixupKinds.h.
+ // AArch64FixupKinds.h.
//
// Name Offset (bits) Size (bits) Flags
- { "fixup_arm64_pcrel_adr_imm21", 0, 32, PCRelFlagVal },
- { "fixup_arm64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal },
- { "fixup_arm64_add_imm12", 10, 12, 0 },
- { "fixup_arm64_ldst_imm12_scale1", 10, 12, 0 },
- { "fixup_arm64_ldst_imm12_scale2", 10, 12, 0 },
- { "fixup_arm64_ldst_imm12_scale4", 10, 12, 0 },
- { "fixup_arm64_ldst_imm12_scale8", 10, 12, 0 },
- { "fixup_arm64_ldst_imm12_scale16", 10, 12, 0 },
- { "fixup_arm64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal },
- { "fixup_arm64_movw", 5, 16, 0 },
- { "fixup_arm64_pcrel_branch14", 5, 14, PCRelFlagVal },
- { "fixup_arm64_pcrel_branch19", 5, 19, PCRelFlagVal },
- { "fixup_arm64_pcrel_branch26", 0, 26, PCRelFlagVal },
- { "fixup_arm64_pcrel_call26", 0, 26, PCRelFlagVal },
- { "fixup_arm64_tlsdesc_call", 0, 0, 0 }
+ { "fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal },
+ { "fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal },
+ { "fixup_aarch64_add_imm12", 10, 12, 0 },
+ { "fixup_aarch64_ldst_imm12_scale1", 10, 12, 0 },
+ { "fixup_aarch64_ldst_imm12_scale2", 10, 12, 0 },
+ { "fixup_aarch64_ldst_imm12_scale4", 10, 12, 0 },
+ { "fixup_aarch64_ldst_imm12_scale8", 10, 12, 0 },
+ { "fixup_aarch64_ldst_imm12_scale16", 10, 12, 0 },
+ { "fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal },
+ { "fixup_aarch64_movw", 5, 16, 0 },
+ { "fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal },
+ { "fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal },
+ { "fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal },
+ { "fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal },
+ { "fixup_aarch64_tlsdesc_call", 0, 0, 0 }
};
if (Kind < FirstTargetFixupKind)
@@ -88,31 +88,31 @@ static unsigned getFixupKindNumBytes(uns
default:
assert(0 && "Unknown fixup kind!");
- case ARM64::fixup_arm64_tlsdesc_call:
+ case AArch64::fixup_aarch64_tlsdesc_call:
return 0;
case FK_Data_1:
return 1;
case FK_Data_2:
- case ARM64::fixup_arm64_movw:
+ case AArch64::fixup_aarch64_movw:
return 2;
- case ARM64::fixup_arm64_pcrel_branch14:
- case ARM64::fixup_arm64_add_imm12:
- case ARM64::fixup_arm64_ldst_imm12_scale1:
- case ARM64::fixup_arm64_ldst_imm12_scale2:
- case ARM64::fixup_arm64_ldst_imm12_scale4:
- case ARM64::fixup_arm64_ldst_imm12_scale8:
- case ARM64::fixup_arm64_ldst_imm12_scale16:
- case ARM64::fixup_arm64_ldr_pcrel_imm19:
- case ARM64::fixup_arm64_pcrel_branch19:
+ case AArch64::fixup_aarch64_pcrel_branch14:
+ case AArch64::fixup_aarch64_add_imm12:
+ case AArch64::fixup_aarch64_ldst_imm12_scale1:
+ case AArch64::fixup_aarch64_ldst_imm12_scale2:
+ case AArch64::fixup_aarch64_ldst_imm12_scale4:
+ case AArch64::fixup_aarch64_ldst_imm12_scale8:
+ case AArch64::fixup_aarch64_ldst_imm12_scale16:
+ case AArch64::fixup_aarch64_ldr_pcrel_imm19:
+ case AArch64::fixup_aarch64_pcrel_branch19:
return 3;
- case ARM64::fixup_arm64_pcrel_adr_imm21:
- case ARM64::fixup_arm64_pcrel_adrp_imm21:
- case ARM64::fixup_arm64_pcrel_branch26:
- case ARM64::fixup_arm64_pcrel_call26:
+ case AArch64::fixup_aarch64_pcrel_adr_imm21:
+ case AArch64::fixup_aarch64_pcrel_adrp_imm21:
+ case AArch64::fixup_aarch64_pcrel_branch26:
+ case AArch64::fixup_aarch64_pcrel_call26:
case FK_Data_4:
return 4;
@@ -132,49 +132,49 @@ static uint64_t adjustFixupValue(unsigne
switch (Kind) {
default:
assert(false && "Unknown fixup kind!");
- case ARM64::fixup_arm64_pcrel_adr_imm21:
+ case AArch64::fixup_aarch64_pcrel_adr_imm21:
if (SignedValue > 2097151 || SignedValue < -2097152)
report_fatal_error("fixup value out of range");
return AdrImmBits(Value & 0x1fffffULL);
- case ARM64::fixup_arm64_pcrel_adrp_imm21:
+ case AArch64::fixup_aarch64_pcrel_adrp_imm21:
return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
- case ARM64::fixup_arm64_ldr_pcrel_imm19:
- case ARM64::fixup_arm64_pcrel_branch19:
+ case AArch64::fixup_aarch64_ldr_pcrel_imm19:
+ case AArch64::fixup_aarch64_pcrel_branch19:
// Signed 21-bit immediate
if (SignedValue > 2097151 || SignedValue < -2097152)
report_fatal_error("fixup value out of range");
// Low two bits are not encoded.
return (Value >> 2) & 0x7ffff;
- case ARM64::fixup_arm64_add_imm12:
- case ARM64::fixup_arm64_ldst_imm12_scale1:
+ case AArch64::fixup_aarch64_add_imm12:
+ case AArch64::fixup_aarch64_ldst_imm12_scale1:
// Unsigned 12-bit immediate
if (Value >= 0x1000)
report_fatal_error("invalid imm12 fixup value");
return Value;
- case ARM64::fixup_arm64_ldst_imm12_scale2:
+ case AArch64::fixup_aarch64_ldst_imm12_scale2:
// Unsigned 12-bit immediate which gets multiplied by 2
if (Value & 1 || Value >= 0x2000)
report_fatal_error("invalid imm12 fixup value");
return Value >> 1;
- case ARM64::fixup_arm64_ldst_imm12_scale4:
+ case AArch64::fixup_aarch64_ldst_imm12_scale4:
// Unsigned 12-bit immediate which gets multiplied by 4
if (Value & 3 || Value >= 0x4000)
report_fatal_error("invalid imm12 fixup value");
return Value >> 2;
- case ARM64::fixup_arm64_ldst_imm12_scale8:
+ case AArch64::fixup_aarch64_ldst_imm12_scale8:
// Unsigned 12-bit immediate which gets multiplied by 8
if (Value & 7 || Value >= 0x8000)
report_fatal_error("invalid imm12 fixup value");
return Value >> 3;
- case ARM64::fixup_arm64_ldst_imm12_scale16:
+ case AArch64::fixup_aarch64_ldst_imm12_scale16:
// Unsigned 12-bit immediate which gets multiplied by 16
if (Value & 15 || Value >= 0x10000)
report_fatal_error("invalid imm12 fixup value");
return Value >> 4;
- case ARM64::fixup_arm64_movw:
+ case AArch64::fixup_aarch64_movw:
report_fatal_error("no resolvable MOVZ/MOVK fixups supported yet");
return Value;
- case ARM64::fixup_arm64_pcrel_branch14:
+ case AArch64::fixup_aarch64_pcrel_branch14:
// Signed 16-bit immediate
if (SignedValue > 32767 || SignedValue < -32768)
report_fatal_error("fixup value out of range");
@@ -182,8 +182,8 @@ static uint64_t adjustFixupValue(unsigne
if (Value & 0x3)
report_fatal_error("fixup not sufficiently aligned");
return (Value >> 2) & 0x3fff;
- case ARM64::fixup_arm64_pcrel_branch26:
- case ARM64::fixup_arm64_pcrel_call26:
+ case AArch64::fixup_aarch64_pcrel_branch26:
+ case AArch64::fixup_aarch64_pcrel_call26:
// Signed 28-bit immediate
if (SignedValue > 134217727 || SignedValue < -134217728)
report_fatal_error("fixup value out of range");
@@ -199,9 +199,9 @@ static uint64_t adjustFixupValue(unsigne
}
}
-void ARM64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
- unsigned DataSize, uint64_t Value,
- bool IsPCRel) const {
+void AArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
+ unsigned DataSize, uint64_t Value,
+ bool IsPCRel) const {
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
if (!Value)
return; // Doesn't change encoding.
@@ -221,25 +221,27 @@ void ARM64AsmBackend::applyFixup(const M
Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
}
-bool ARM64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
+bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
return false;
}
-bool ARM64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
- const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const {
- // FIXME: This isn't correct for ARM64. Just moving the "generic" logic
+bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const {
+ // FIXME: This isn't correct for AArch64. Just moving the "generic" logic
// into the targets for now.
//
// Relax if the value is too big for a (signed) i8.
return int64_t(Value) != int64_t(int8_t(Value));
}
-void ARM64AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
- assert(false && "ARM64AsmBackend::relaxInstruction() unimplemented");
+void AArch64AsmBackend::relaxInstruction(const MCInst &Inst,
+ MCInst &Res) const {
+ assert(false && "AArch64AsmBackend::relaxInstruction() unimplemented");
}
-bool ARM64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
@@ -263,14 +265,14 @@ namespace CU {
enum CompactUnwindEncodings {
/// \brief A "frameless" leaf function, where no non-volatile registers are
/// saved. The return remains in LR throughout the function.
- UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
+ UNWIND_AArch64_MODE_FRAMELESS = 0x02000000,
/// \brief No compact unwind encoding available. Instead the low 23-bits of
/// the compact unwind encoding is the offset of the DWARF FDE in the
/// __eh_frame section. This mode is never used in object files. It is only
/// generated by the linker in final linked images, which have only DWARF info
/// for a function.
- UNWIND_ARM64_MODE_DWARF = 0x03000000,
+ UNWIND_AArch64_MODE_DWARF = 0x03000000,
/// \brief This is a standard arm64 prologue where FP/LR are immediately
/// pushed on the stack, then SP is copied to FP. If there are any
@@ -278,40 +280,40 @@ enum CompactUnwindEncodings {
/// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
/// five X pairs and four D pairs can be saved, but the memory layout must be
/// in register number order.
- UNWIND_ARM64_MODE_FRAME = 0x04000000,
+ UNWIND_AArch64_MODE_FRAME = 0x04000000,
/// \brief Frame register pair encodings.
- UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
- UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
- UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
- UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
- UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
- UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
- UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
- UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
- UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
+ UNWIND_AArch64_FRAME_X19_X20_PAIR = 0x00000001,
+ UNWIND_AArch64_FRAME_X21_X22_PAIR = 0x00000002,
+ UNWIND_AArch64_FRAME_X23_X24_PAIR = 0x00000004,
+ UNWIND_AArch64_FRAME_X25_X26_PAIR = 0x00000008,
+ UNWIND_AArch64_FRAME_X27_X28_PAIR = 0x00000010,
+ UNWIND_AArch64_FRAME_D8_D9_PAIR = 0x00000100,
+ UNWIND_AArch64_FRAME_D10_D11_PAIR = 0x00000200,
+ UNWIND_AArch64_FRAME_D12_D13_PAIR = 0x00000400,
+ UNWIND_AArch64_FRAME_D14_D15_PAIR = 0x00000800
};
} // end CU namespace
// FIXME: This should be in a separate file.
-class DarwinARM64AsmBackend : public ARM64AsmBackend {
+class DarwinAArch64AsmBackend : public AArch64AsmBackend {
const MCRegisterInfo &MRI;
/// \brief Encode compact unwind stack adjustment for frameless functions.
- /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
+ /// See UNWIND_AArch64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
/// The stack size always needs to be 16 byte aligned.
uint32_t encodeStackAdjustment(uint32_t StackSize) const {
return (StackSize / 16) << 12;
}
public:
- DarwinARM64AsmBackend(const Target &T, const MCRegisterInfo &MRI)
- : ARM64AsmBackend(T), MRI(MRI) {}
+ DarwinAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI)
+ : AArch64AsmBackend(T), MRI(MRI) {}
MCObjectWriter *createObjectWriter(raw_ostream &OS) const override {
- return createARM64MachObjectWriter(OS, MachO::CPU_TYPE_ARM64,
- MachO::CPU_SUBTYPE_ARM64_ALL);
+ return createAArch64MachObjectWriter(OS, MachO::CPU_TYPE_ARM64,
+ MachO::CPU_SUBTYPE_ARM64_ALL);
}
bool doesSectionRequireSymbols(const MCSection &Section) const override {
@@ -354,7 +356,7 @@ public:
uint32_t generateCompactUnwindEncoding(
ArrayRef<MCCFIInstruction> Instrs) const override {
if (Instrs.empty())
- return CU::UNWIND_ARM64_MODE_FRAMELESS;
+ return CU::UNWIND_AArch64_MODE_FRAMELESS;
bool HasFP = false;
unsigned StackSize = 0;
@@ -366,11 +368,11 @@ public:
switch (Inst.getOperation()) {
default:
// Cannot handle this directive: bail out.
- return CU::UNWIND_ARM64_MODE_DWARF;
+ return CU::UNWIND_AArch64_MODE_DWARF;
case MCCFIInstruction::OpDefCfa: {
// Defines a frame pointer.
assert(getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true)) ==
- ARM64::FP &&
+ AArch64::FP &&
"Invalid frame pointer!");
assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
@@ -387,11 +389,11 @@ public:
LRReg = getXRegFromWReg(LRReg);
FPReg = getXRegFromWReg(FPReg);
- assert(LRReg == ARM64::LR && FPReg == ARM64::FP &&
+ assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
"Pushing invalid registers for frame!");
// Indicate that the function has a frame.
- CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAME;
HasFP = true;
break;
}
@@ -405,11 +407,11 @@ public:
// `.cfi_offset' instructions with the appropriate registers specified.
unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true);
if (i + 1 == e)
- return CU::UNWIND_ARM64_MODE_DWARF;
+ return CU::UNWIND_AArch64_MODE_DWARF;
const MCCFIInstruction &Inst2 = Instrs[++i];
if (Inst2.getOperation() != MCCFIInstruction::OpOffset)
- return CU::UNWIND_ARM64_MODE_DWARF;
+ return CU::UNWIND_AArch64_MODE_DWARF;
unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true);
// N.B. The encodings must be in register number order, and the X
@@ -423,21 +425,21 @@ public:
Reg1 = getXRegFromWReg(Reg1);
Reg2 = getXRegFromWReg(Reg2);
- if (Reg1 == ARM64::X19 && Reg2 == ARM64::X20 &&
+ if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
(CompactUnwindEncoding & 0xF1E) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
- else if (Reg1 == ARM64::X21 && Reg2 == ARM64::X22 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X19_X20_PAIR;
+ else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
(CompactUnwindEncoding & 0xF1C) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
- else if (Reg1 == ARM64::X23 && Reg2 == ARM64::X24 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X21_X22_PAIR;
+ else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
(CompactUnwindEncoding & 0xF18) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
- else if (Reg1 == ARM64::X25 && Reg2 == ARM64::X26 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X23_X24_PAIR;
+ else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
(CompactUnwindEncoding & 0xF10) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
- else if (Reg1 == ARM64::X27 && Reg2 == ARM64::X28 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X25_X26_PAIR;
+ else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
(CompactUnwindEncoding & 0xF00) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X27_X28_PAIR;
else {
Reg1 = getDRegFromBReg(Reg1);
Reg2 = getDRegFromBReg(Reg2);
@@ -446,20 +448,20 @@ public:
// D10/D11 pair = 0x00000200,
// D12/D13 pair = 0x00000400,
// D14/D15 pair = 0x00000800
- if (Reg1 == ARM64::D8 && Reg2 == ARM64::D9 &&
+ if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
(CompactUnwindEncoding & 0xE00) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
- else if (Reg1 == ARM64::D10 && Reg2 == ARM64::D11 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D8_D9_PAIR;
+ else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
(CompactUnwindEncoding & 0xC00) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
- else if (Reg1 == ARM64::D12 && Reg2 == ARM64::D13 &&
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D10_D11_PAIR;
+ else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
(CompactUnwindEncoding & 0x800) == 0)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
- else if (Reg1 == ARM64::D14 && Reg2 == ARM64::D15)
- CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D12_D13_PAIR;
+ else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D14_D15_PAIR;
else
// A pair was pushed which we cannot handle.
- return CU::UNWIND_ARM64_MODE_DWARF;
+ return CU::UNWIND_AArch64_MODE_DWARF;
}
break;
@@ -471,9 +473,9 @@ public:
// With compact unwind info we can only represent stack adjustments of up
// to 65520 bytes.
if (StackSize > 65520)
- return CU::UNWIND_ARM64_MODE_DWARF;
+ return CU::UNWIND_AArch64_MODE_DWARF;
- CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
+ CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAMELESS;
CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
}
@@ -485,16 +487,16 @@ public:
namespace {
-class ELFARM64AsmBackend : public ARM64AsmBackend {
+class ELFAArch64AsmBackend : public AArch64AsmBackend {
public:
uint8_t OSABI;
bool IsLittleEndian;
- ELFARM64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian)
- : ARM64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {}
+ ELFAArch64AsmBackend(const Target &T, uint8_t OSABI, bool IsLittleEndian)
+ : AArch64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {}
MCObjectWriter *createObjectWriter(raw_ostream &OS) const override {
- return createARM64ELFObjectWriter(OS, OSABI, IsLittleEndian);
+ return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian);
}
void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
@@ -506,12 +508,10 @@ public:
uint64_t Value, bool IsPCRel) const override;
};
-void ELFARM64AsmBackend::processFixupValue(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFixup &Fixup,
- const MCFragment *DF,
- const MCValue &Target,
- uint64_t &Value, bool &IsResolved) {
+void ELFAArch64AsmBackend::processFixupValue(
+ const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup,
+ const MCFragment *DF, const MCValue &Target, uint64_t &Value,
+ bool &IsResolved) {
// The ADRP instruction adds some multiple of 0x1000 to the current PC &
// ~0xfff. This means that the required offset to reach a symbol can vary by
// up to one step depending on where the ADRP is in memory. For example:
@@ -524,13 +524,13 @@ void ELFARM64AsmBackend::processFixupVal
// same page as the ADRP and the instruction should encode 0x0. Assuming the
// section isn't 0x1000-aligned, we therefore need to delegate this decision
// to the linker -- a relocation!
- if ((uint32_t)Fixup.getKind() == ARM64::fixup_arm64_pcrel_adrp_imm21)
+ if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
IsResolved = false;
}
-void ELFARM64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
- unsigned DataSize, uint64_t Value,
- bool IsPCRel) const {
+void ELFAArch64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
+ unsigned DataSize, uint64_t Value,
+ bool IsPCRel) const {
// store fixups in .eh_frame section in big endian order
if (!IsLittleEndian && Fixup.getKind() == FK_Data_4) {
const MCSection *Sec = Fixup.getValue()->FindAssociatedSection();
@@ -538,27 +538,29 @@ void ELFARM64AsmBackend::applyFixup(cons
if (SecELF->getSectionName() == ".eh_frame")
Value = ByteSwap_32(unsigned(Value));
}
- ARM64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel);
+ AArch64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel);
}
}
-MCAsmBackend *llvm::createARM64leAsmBackend(const Target &T,
+MCAsmBackend *llvm::createAArch64leAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
StringRef TT, StringRef CPU) {
Triple TheTriple(TT);
if (TheTriple.isOSDarwin())
- return new DarwinARM64AsmBackend(T, MRI);
+ return new DarwinAArch64AsmBackend(T, MRI);
assert(TheTriple.isOSBinFormatELF() && "Expect either MachO or ELF target");
- return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/true);
+ return new ELFAArch64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/true);
}
-MCAsmBackend *llvm::createARM64beAsmBackend(const Target &T,
+MCAsmBackend *llvm::createAArch64beAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
StringRef TT, StringRef CPU) {
Triple TheTriple(TT);
- assert(TheTriple.isOSBinFormatELF() && "Big endian is only supported for ELF targets!");
- return new ELFARM64AsmBackend(T, TheTriple.getOS(), /*IsLittleEndian=*/false);
+ assert(TheTriple.isOSBinFormatELF() &&
+ "Big endian is only supported for ELF targets!");
+ return new ELFAArch64AsmBackend(T, TheTriple.getOS(),
+ /*IsLittleEndian=*/false);
}
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64ELFObjectWriter.cpp - ARM64 ELF Writer -----------------------===//
+//===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,9 +12,9 @@
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/ARM64FixupKinds.h"
-#include "MCTargetDesc/ARM64MCExpr.h"
-#include "MCTargetDesc/ARM64MCTargetDesc.h"
+#include "MCTargetDesc/AArch64FixupKinds.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
@@ -22,11 +22,11 @@
using namespace llvm;
namespace {
-class ARM64ELFObjectWriter : public MCELFObjectTargetWriter {
+class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
public:
- ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
+ AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
- virtual ~ARM64ELFObjectWriter();
+ virtual ~AArch64ELFObjectWriter();
protected:
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
@@ -36,19 +36,20 @@ private:
};
}
-ARM64ELFObjectWriter::ARM64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian)
+AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI,
+ bool IsLittleEndian)
: MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
/*HasRelocationAddend*/ true) {}
-ARM64ELFObjectWriter::~ARM64ELFObjectWriter() {}
+AArch64ELFObjectWriter::~AArch64ELFObjectWriter() {}
-unsigned ARM64ELFObjectWriter::GetRelocType(const MCValue &Target,
+unsigned AArch64ELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- ARM64MCExpr::VariantKind RefKind =
- static_cast<ARM64MCExpr::VariantKind>(Target.getRefKind());
- ARM64MCExpr::VariantKind SymLoc = ARM64MCExpr::getSymbolLoc(RefKind);
- bool IsNC = ARM64MCExpr::isNotChecked(RefKind);
+ AArch64MCExpr::VariantKind RefKind =
+ static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
+ AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
+ bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
@@ -66,30 +67,30 @@ unsigned ARM64ELFObjectWriter::GetRelocT
return ELF::R_AARCH64_PREL32;
case FK_Data_8:
return ELF::R_AARCH64_PREL64;
- case ARM64::fixup_arm64_pcrel_adr_imm21:
- assert(SymLoc == ARM64MCExpr::VK_NONE && "unexpected ADR relocation");
+ case AArch64::fixup_aarch64_pcrel_adr_imm21:
+ assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation");
return ELF::R_AARCH64_ADR_PREL_LO21;
- case ARM64::fixup_arm64_pcrel_adrp_imm21:
- if (SymLoc == ARM64MCExpr::VK_ABS && !IsNC)
+ case AArch64::fixup_aarch64_pcrel_adrp_imm21:
+ if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
return ELF::R_AARCH64_ADR_PREL_PG_HI21;
- if (SymLoc == ARM64MCExpr::VK_GOT && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
return ELF::R_AARCH64_ADR_GOT_PAGE;
- if (SymLoc == ARM64MCExpr::VK_GOTTPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
return ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21;
- if (SymLoc == ARM64MCExpr::VK_TLSDESC && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
return ELF::R_AARCH64_TLSDESC_ADR_PAGE;
llvm_unreachable("invalid symbol kind for ADRP relocation");
- case ARM64::fixup_arm64_pcrel_branch26:
+ case AArch64::fixup_aarch64_pcrel_branch26:
return ELF::R_AARCH64_JUMP26;
- case ARM64::fixup_arm64_pcrel_call26:
+ case AArch64::fixup_aarch64_pcrel_call26:
return ELF::R_AARCH64_CALL26;
- case ARM64::fixup_arm64_ldr_pcrel_imm19:
- if (SymLoc == ARM64MCExpr::VK_GOTTPREL)
+ case AArch64::fixup_aarch64_ldr_pcrel_imm19:
+ if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
return ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19;
return ELF::R_AARCH64_LD_PREL_LO19;
- case ARM64::fixup_arm64_pcrel_branch14:
+ case AArch64::fixup_aarch64_pcrel_branch14:
return ELF::R_AARCH64_TSTBR14;
- case ARM64::fixup_arm64_pcrel_branch19:
+ case AArch64::fixup_aarch64_pcrel_branch19:
return ELF::R_AARCH64_CONDBR19;
default:
llvm_unreachable("Unsupported pc-relative fixup kind");
@@ -102,142 +103,142 @@ unsigned ARM64ELFObjectWriter::GetRelocT
return ELF::R_AARCH64_ABS32;
case FK_Data_8:
return ELF::R_AARCH64_ABS64;
- case ARM64::fixup_arm64_add_imm12:
- if (RefKind == ARM64MCExpr::VK_DTPREL_HI12)
+ case AArch64::fixup_aarch64_add_imm12:
+ if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
return ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12;
- if (RefKind == ARM64MCExpr::VK_TPREL_HI12)
+ if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
return ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12;
- if (RefKind == ARM64MCExpr::VK_DTPREL_LO12_NC)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC;
- if (RefKind == ARM64MCExpr::VK_DTPREL_LO12)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12;
- if (RefKind == ARM64MCExpr::VK_TPREL_LO12_NC)
+ if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC;
- if (RefKind == ARM64MCExpr::VK_TPREL_LO12)
+ if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12;
- if (RefKind == ARM64MCExpr::VK_TLSDESC_LO12)
+ if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
return ELF::R_AARCH64_TLSDESC_ADD_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_ADD_ABS_LO12_NC;
report_fatal_error("invalid fixup for add (uimm12) instruction");
return 0;
- case ARM64::fixup_arm64_ldst_imm12_scale1:
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ case AArch64::fixup_aarch64_ldst_imm12_scale1:
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_LDST8_ABS_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_TPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_TPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC;
report_fatal_error("invalid fixup for 8-bit load/store instruction");
return 0;
- case ARM64::fixup_arm64_ldst_imm12_scale2:
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ case AArch64::fixup_aarch64_ldst_imm12_scale2:
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_LDST16_ABS_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_TPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_TPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC;
report_fatal_error("invalid fixup for 16-bit load/store instruction");
return 0;
- case ARM64::fixup_arm64_ldst_imm12_scale4:
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ case AArch64::fixup_aarch64_ldst_imm12_scale4:
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_LDST32_ABS_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_TPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_TPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC;
report_fatal_error("invalid fixup for 32-bit load/store instruction");
return 0;
- case ARM64::fixup_arm64_ldst_imm12_scale8:
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ case AArch64::fixup_aarch64_ldst_imm12_scale8:
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_LDST64_ABS_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_GOT && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_GOT && IsNC)
return ELF::R_AARCH64_LD64_GOT_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_DTPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_TPREL && !IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12;
- if (SymLoc == ARM64MCExpr::VK_TPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_GOTTPREL && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC)
return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
- if (SymLoc == ARM64MCExpr::VK_TLSDESC && IsNC)
+ if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC)
return ELF::R_AARCH64_TLSDESC_LD64_LO12_NC;
report_fatal_error("invalid fixup for 64-bit load/store instruction");
return 0;
- case ARM64::fixup_arm64_ldst_imm12_scale16:
- if (SymLoc == ARM64MCExpr::VK_ABS && IsNC)
+ case AArch64::fixup_aarch64_ldst_imm12_scale16:
+ if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
return ELF::R_AARCH64_LDST128_ABS_LO12_NC;
report_fatal_error("invalid fixup for 128-bit load/store instruction");
return 0;
- case ARM64::fixup_arm64_movw:
- if (RefKind == ARM64MCExpr::VK_ABS_G3)
+ case AArch64::fixup_aarch64_movw:
+ if (RefKind == AArch64MCExpr::VK_ABS_G3)
return ELF::R_AARCH64_MOVW_UABS_G3;
- if (RefKind == ARM64MCExpr::VK_ABS_G2)
+ if (RefKind == AArch64MCExpr::VK_ABS_G2)
return ELF::R_AARCH64_MOVW_UABS_G2;
- if (RefKind == ARM64MCExpr::VK_ABS_G2_S)
+ if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
return ELF::R_AARCH64_MOVW_SABS_G2;
- if (RefKind == ARM64MCExpr::VK_ABS_G2_NC)
+ if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
return ELF::R_AARCH64_MOVW_UABS_G2_NC;
- if (RefKind == ARM64MCExpr::VK_ABS_G1)
+ if (RefKind == AArch64MCExpr::VK_ABS_G1)
return ELF::R_AARCH64_MOVW_UABS_G1;
- if (RefKind == ARM64MCExpr::VK_ABS_G1_S)
+ if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
return ELF::R_AARCH64_MOVW_SABS_G1;
- if (RefKind == ARM64MCExpr::VK_ABS_G1_NC)
+ if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
return ELF::R_AARCH64_MOVW_UABS_G1_NC;
- if (RefKind == ARM64MCExpr::VK_ABS_G0)
+ if (RefKind == AArch64MCExpr::VK_ABS_G0)
return ELF::R_AARCH64_MOVW_UABS_G0;
- if (RefKind == ARM64MCExpr::VK_ABS_G0_S)
+ if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
return ELF::R_AARCH64_MOVW_SABS_G0;
- if (RefKind == ARM64MCExpr::VK_ABS_G0_NC)
+ if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
return ELF::R_AARCH64_MOVW_UABS_G0_NC;
- if (RefKind == ARM64MCExpr::VK_DTPREL_G2)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
- if (RefKind == ARM64MCExpr::VK_DTPREL_G1)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1;
- if (RefKind == ARM64MCExpr::VK_DTPREL_G1_NC)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
- if (RefKind == ARM64MCExpr::VK_DTPREL_G0)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0;
- if (RefKind == ARM64MCExpr::VK_DTPREL_G0_NC)
+ if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC;
- if (RefKind == ARM64MCExpr::VK_TPREL_G2)
+ if (RefKind == AArch64MCExpr::VK_TPREL_G2)
return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
- if (RefKind == ARM64MCExpr::VK_TPREL_G1)
+ if (RefKind == AArch64MCExpr::VK_TPREL_G1)
return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1;
- if (RefKind == ARM64MCExpr::VK_TPREL_G1_NC)
+ if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
- if (RefKind == ARM64MCExpr::VK_TPREL_G0)
+ if (RefKind == AArch64MCExpr::VK_TPREL_G0)
return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0;
- if (RefKind == ARM64MCExpr::VK_TPREL_G0_NC)
+ if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC;
- if (RefKind == ARM64MCExpr::VK_GOTTPREL_G1)
+ if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
- if (RefKind == ARM64MCExpr::VK_GOTTPREL_G0_NC)
+ if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
report_fatal_error("invalid fixup for movz/movk instruction");
return 0;
- case ARM64::fixup_arm64_tlsdesc_call:
+ case AArch64::fixup_aarch64_tlsdesc_call:
return ELF::R_AARCH64_TLSDESC_CALL;
default:
llvm_unreachable("Unknown ELF relocation type");
@@ -247,9 +248,10 @@ unsigned ARM64ELFObjectWriter::GetRelocT
llvm_unreachable("Unimplemented fixup -> relocation");
}
-MCObjectWriter *llvm::createARM64ELFObjectWriter(raw_ostream &OS,
+MCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_ostream &OS,
uint8_t OSABI,
bool IsLittleEndian) {
- MCELFObjectTargetWriter *MOTW = new ARM64ELFObjectWriter(OSABI, IsLittleEndian);
+ MCELFObjectTargetWriter *MOTW =
+ new AArch64ELFObjectWriter(OSABI, IsLittleEndian);
return createELFObjectWriter(MOTW, OS, IsLittleEndian);
}
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===- lib/MC/ARM64ELFStreamer.cpp - ELF Object Output for ARM64 ----------===//
+//===- lib/MC/AArch64ELFStreamer.cpp - ELF Object Output for AArch64 ------===//
//
// The LLVM Compiler Infrastructure
//
@@ -53,14 +53,14 @@ namespace {
///
/// As a result this system is orthogonal to the DataRegion infrastructure used
/// by MachO. Beware!
-class ARM64ELFStreamer : public MCELFStreamer {
+class AArch64ELFStreamer : public MCELFStreamer {
public:
- ARM64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCELFStreamer(Context, TAB, OS, Emitter), MappingSymbolCounter(0),
LastEMS(EMS_None) {}
- ~ARM64ELFStreamer() {}
+ ~AArch64ELFStreamer() {}
void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) override {
@@ -83,7 +83,7 @@ public:
}
/// This is one of the functions used to emit data into an ELF section, so the
- /// ARM64 streamer overrides it to add the appropriate mapping symbol ($d)
+ /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d)
/// if necessary.
void EmitBytes(StringRef Data) override {
EmitDataMappingSymbol();
@@ -91,7 +91,7 @@ public:
}
/// This is one of the functions used to emit data into an ELF section, so the
- /// ARM64 streamer overrides it to add the appropriate mapping symbol ($d)
+ /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d)
/// if necessary.
void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) override {
@@ -147,10 +147,10 @@ private:
}
namespace llvm {
-MCELFStreamer *createARM64ELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll, bool NoExecStack) {
- ARM64ELFStreamer *S = new ARM64ELFStreamer(Context, TAB, OS, Emitter);
+MCELFStreamer *createAArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ bool RelaxAll, bool NoExecStack) {
+ AArch64ELFStreamer *S = new AArch64ELFStreamer(Context, TAB, OS, Emitter);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
if (NoExecStack)
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.h (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.h?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.h&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64ELFStreamer.h - ELF Streamer for ARM64 -------------*- C++ -*-===//
+//===-- AArch64ELFStreamer.h - ELF Streamer for AArch64 ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements ELF streamer information for the ARM64 backend.
+// This file implements ELF streamer information for the AArch64 backend.
//
//===----------------------------------------------------------------------===//
@@ -18,9 +18,9 @@
namespace llvm {
-MCELFStreamer *createARM64ELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll, bool NoExecStack);
+MCELFStreamer *createAArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ bool RelaxAll, bool NoExecStack);
}
-#endif // ARM64_ELF_STREAMER_H
+#endif // AArch64_ELF_STREAMER_H
Added: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h (added)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h Sat May 24 07:50:23 2014
@@ -0,0 +1,76 @@
+//===-- AArch64FixupKinds.h - AArch64 Specific Fixup Entries ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_AArch64FIXUPKINDS_H
+#define LLVM_AArch64FIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace AArch64 {
+
+enum Fixups {
+ // fixup_aarch64_pcrel_adr_imm21 - A 21-bit pc-relative immediate inserted into
+ // an ADR instruction.
+ fixup_aarch64_pcrel_adr_imm21 = FirstTargetFixupKind,
+
+ // fixup_aarch64_pcrel_adrp_imm21 - A 21-bit pc-relative immediate inserted into
+ // an ADRP instruction.
+ fixup_aarch64_pcrel_adrp_imm21,
+
+ // fixup_aarch64_imm12 - 12-bit fixup for add/sub instructions.
+ // No alignment adjustment. All value bits are encoded.
+ fixup_aarch64_add_imm12,
+
+ // fixup_aarch64_ldst_imm12_* - unsigned 12-bit fixups for load and
+ // store instructions.
+ fixup_aarch64_ldst_imm12_scale1,
+ fixup_aarch64_ldst_imm12_scale2,
+ fixup_aarch64_ldst_imm12_scale4,
+ fixup_aarch64_ldst_imm12_scale8,
+ fixup_aarch64_ldst_imm12_scale16,
+
+ // fixup_aarch64_ldr_pcrel_imm19 - The high 19 bits of a 21-bit pc-relative
+ // immediate. Same encoding as fixup_aarch64_pcrel_adrhi, except this is used by
+ // pc-relative loads and generates relocations directly when necessary.
+ fixup_aarch64_ldr_pcrel_imm19,
+
+ // FIXME: comment
+ fixup_aarch64_movw,
+
+ // fixup_aarch64_pcrel_imm14 - The high 14 bits of a 21-bit pc-relative
+ // immediate.
+ fixup_aarch64_pcrel_branch14,
+
+ // fixup_aarch64_pcrel_branch19 - The high 19 bits of a 21-bit pc-relative
+ // immediate. Same encoding as fixup_aarch64_pcrel_adrhi, except this is use by
+ // b.cc and generates relocations directly when necessary.
+ fixup_aarch64_pcrel_branch19,
+
+ // fixup_aarch64_pcrel_branch26 - The high 26 bits of a 28-bit pc-relative
+ // immediate.
+ fixup_aarch64_pcrel_branch26,
+
+ // fixup_aarch64_pcrel_call26 - The high 26 bits of a 28-bit pc-relative
+ // immediate. Distinguished from branch26 only on ELF.
+ fixup_aarch64_pcrel_call26,
+
+ // fixup_aarch64_tlsdesc_call - zero-space placeholder for the ELF
+ // R_AARCH64_TLSDESC_CALL relocation.
+ fixup_aarch64_tlsdesc_call,
+
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+
+} // end namespace AArch64
+} // end namespace llvm
+
+#endif
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64MCAsmInfo.cpp - ARM64 asm properties -----------------------===//
+//===-- AArch64MCAsmInfo.cpp - AArch64 asm properties ---------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the declarations of the ARM64MCAsmInfo properties.
+// This file contains the declarations of the AArch64MCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
-#include "ARM64MCAsmInfo.h"
+#include "AArch64MCAsmInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCContext.h"
@@ -26,13 +26,13 @@ enum AsmWriterVariantTy {
};
static cl::opt<AsmWriterVariantTy> AsmWriterVariant(
- "arm64-neon-syntax", cl::init(Default),
- cl::desc("Choose style of NEON code to emit from ARM64 backend:"),
+ "aarch64-neon-syntax", cl::init(Default),
+ cl::desc("Choose style of NEON code to emit from AArch64 backend:"),
cl::values(clEnumValN(Generic, "generic", "Emit generic NEON assembly"),
clEnumValN(Apple, "apple", "Emit Apple-style NEON assembly"),
clEnumValEnd));
-ARM64MCAsmInfoDarwin::ARM64MCAsmInfoDarwin() {
+AArch64MCAsmInfoDarwin::AArch64MCAsmInfoDarwin() {
// We prefer NEON instructions to be printed in the short form.
AssemblerDialect = AsmWriterVariant == Default ? 1 : AsmWriterVariant;
@@ -49,7 +49,7 @@ ARM64MCAsmInfoDarwin::ARM64MCAsmInfoDarw
ExceptionsType = ExceptionHandling::DwarfCFI;
}
-const MCExpr *ARM64MCAsmInfoDarwin::getExprForPersonalitySymbol(
+const MCExpr *AArch64MCAsmInfoDarwin::getExprForPersonalitySymbol(
const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const {
// On Darwin, we can reference dwarf symbols with foo at GOT-., which
// is an indirect pc-relative reference. The default implementation
@@ -64,9 +64,9 @@ const MCExpr *ARM64MCAsmInfoDarwin::getE
return MCBinaryExpr::CreateSub(Res, PC, Context);
}
-ARM64MCAsmInfoELF::ARM64MCAsmInfoELF(StringRef TT) {
+AArch64MCAsmInfoELF::AArch64MCAsmInfoELF(StringRef TT) {
Triple T(TT);
- if (T.getArch() == Triple::arm64_be)
+ if (T.getArch() == Triple::arm64_be || T.getArch() == Triple::aarch64_be)
IsLittleEndian = false;
// We prefer NEON instructions to be printed in the short form.
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCAsmInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//=====-- ARM64MCAsmInfo.h - ARM64 asm properties -----------*- C++ -*--====//
+//=====-- AArch64MCAsmInfo.h - AArch64 asm properties ---------*- C++ -*--====//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains the declaration of the ARM64MCAsmInfo class.
+// This file contains the declaration of the AArch64MCAsmInfo class.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64TARGETASMINFO_H
-#define ARM64TARGETASMINFO_H
+#ifndef AArch64TARGETASMINFO_H
+#define AArch64TARGETASMINFO_H
#include "llvm/MC/MCAsmInfoDarwin.h"
@@ -20,15 +20,15 @@ namespace llvm {
class Target;
class StringRef;
class MCStreamer;
-struct ARM64MCAsmInfoDarwin : public MCAsmInfoDarwin {
- explicit ARM64MCAsmInfoDarwin();
+struct AArch64MCAsmInfoDarwin : public MCAsmInfoDarwin {
+ explicit AArch64MCAsmInfoDarwin();
const MCExpr *
getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding,
MCStreamer &Streamer) const override;
};
-struct ARM64MCAsmInfoELF : public MCAsmInfo {
- explicit ARM64MCAsmInfoELF(StringRef TT);
+struct AArch64MCAsmInfoELF : public MCAsmInfo {
+ explicit AArch64MCAsmInfoELF(StringRef TT);
};
} // namespace llvm
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64/ARM64MCCodeEmitter.cpp - Convert ARM64 code to machine code -===//
+//=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 code to machine code-=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the ARM64MCCodeEmitter class.
+// This file implements the AArch64MCCodeEmitter class.
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "MCTargetDesc/ARM64FixupKinds.h"
-#include "MCTargetDesc/ARM64MCExpr.h"
-#include "Utils/ARM64BaseInfo.h"
+#include "MCTargetDesc/AArch64AddressingModes.h"
+#include "MCTargetDesc/AArch64FixupKinds.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
+#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
@@ -32,17 +32,17 @@ STATISTIC(MCNumFixups, "Number of MC fix
namespace {
-class ARM64MCCodeEmitter : public MCCodeEmitter {
+class AArch64MCCodeEmitter : public MCCodeEmitter {
MCContext &Ctx;
- ARM64MCCodeEmitter(const ARM64MCCodeEmitter &); // DO NOT IMPLEMENT
- void operator=(const ARM64MCCodeEmitter &); // DO NOT IMPLEMENT
+ AArch64MCCodeEmitter(const AArch64MCCodeEmitter &); // DO NOT IMPLEMENT
+ void operator=(const AArch64MCCodeEmitter &); // DO NOT IMPLEMENT
public:
- ARM64MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
+ AArch64MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
MCContext &ctx)
: Ctx(ctx) {}
- ~ARM64MCCodeEmitter() {}
+ ~AArch64MCCodeEmitter() {}
// getBinaryCodeForInstr - TableGen'erated function for getting the
// binary encoding for an instruction.
@@ -203,19 +203,19 @@ public:
} // end anonymous namespace
-MCCodeEmitter *llvm::createARM64MCCodeEmitter(const MCInstrInfo &MCII,
- const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI,
- MCContext &Ctx) {
- return new ARM64MCCodeEmitter(MCII, STI, Ctx);
+MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) {
+ return new AArch64MCCodeEmitter(MCII, STI, Ctx);
}
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned
-ARM64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
if (MO.isReg())
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
else {
@@ -228,9 +228,9 @@ ARM64MCCodeEmitter::getMachineOpValue(co
}
template<unsigned FixupKind> uint32_t
-ARM64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getLdStUImm12OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
uint32_t ImmVal = 0;
@@ -249,9 +249,9 @@ ARM64MCCodeEmitter::getLdStUImm12OpValue
/// getAdrLabelOpValue - Return encoding info for 21-bit immediate ADR label
/// target.
uint32_t
-ARM64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
// If the destination is an immediate, we have nothing to do.
@@ -260,9 +260,9 @@ ARM64MCCodeEmitter::getAdrLabelOpValue(c
assert(MO.isExpr() && "Unexpected target type!");
const MCExpr *Expr = MO.getExpr();
- MCFixupKind Kind = MI.getOpcode() == ARM64::ADR
- ? MCFixupKind(ARM64::fixup_arm64_pcrel_adr_imm21)
- : MCFixupKind(ARM64::fixup_arm64_pcrel_adrp_imm21);
+ MCFixupKind Kind = MI.getOpcode() == AArch64::ADR
+ ? MCFixupKind(AArch64::fixup_aarch64_pcrel_adr_imm21)
+ : MCFixupKind(AArch64::fixup_aarch64_pcrel_adrp_imm21);
Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
MCNumFixups += 1;
@@ -275,15 +275,15 @@ ARM64MCCodeEmitter::getAdrLabelOpValue(c
/// the 2-bit shift field. The shift field is stored in bits 13-14 of the
/// return value.
uint32_t
-ARM64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
// Suboperands are [imm, shifter].
const MCOperand &MO = MI.getOperand(OpIdx);
const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
- assert(ARM64_AM::getShiftType(MO1.getImm()) == ARM64_AM::LSL &&
+ assert(AArch64_AM::getShiftType(MO1.getImm()) == AArch64_AM::LSL &&
"unexpected shift type for add/sub immediate");
- unsigned ShiftVal = ARM64_AM::getShiftValue(MO1.getImm());
+ unsigned ShiftVal = AArch64_AM::getShiftValue(MO1.getImm());
assert((ShiftVal == 0 || ShiftVal == 12) &&
"unexpected shift value for add/sub immediate");
if (MO.isImm())
@@ -292,7 +292,7 @@ ARM64MCCodeEmitter::getAddSubImmOpValue(
const MCExpr *Expr = MO.getExpr();
// Encode the 12 bits of the fixup.
- MCFixupKind Kind = MCFixupKind(ARM64::fixup_arm64_add_imm12);
+ MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_add_imm12);
Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
++MCNumFixups;
@@ -302,7 +302,7 @@ ARM64MCCodeEmitter::getAddSubImmOpValue(
/// getCondBranchTargetOpValue - Return the encoded value for a conditional
/// branch target.
-uint32_t ARM64MCCodeEmitter::getCondBranchTargetOpValue(
+uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
@@ -312,7 +312,7 @@ uint32_t ARM64MCCodeEmitter::getCondBran
return MO.getImm();
assert(MO.isExpr() && "Unexpected target type!");
- MCFixupKind Kind = MCFixupKind(ARM64::fixup_arm64_pcrel_branch19);
+ MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch19);
Fixups.push_back(MCFixup::Create(0, MO.getExpr(), Kind, MI.getLoc()));
++MCNumFixups;
@@ -324,9 +324,9 @@ uint32_t ARM64MCCodeEmitter::getCondBran
/// getLoadLiteralOpValue - Return the encoded value for a load-literal
/// pc-relative address.
uint32_t
-ARM64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getLoadLiteralOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
// If the destination is an immediate, we have nothing to do.
@@ -334,7 +334,7 @@ ARM64MCCodeEmitter::getLoadLiteralOpValu
return MO.getImm();
assert(MO.isExpr() && "Unexpected target type!");
- MCFixupKind Kind = MCFixupKind(ARM64::fixup_arm64_ldr_pcrel_imm19);
+ MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_ldr_pcrel_imm19);
Fixups.push_back(MCFixup::Create(0, MO.getExpr(), Kind, MI.getLoc()));
++MCNumFixups;
@@ -344,18 +344,18 @@ ARM64MCCodeEmitter::getLoadLiteralOpValu
}
uint32_t
-ARM64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getMemExtendOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
unsigned SignExtend = MI.getOperand(OpIdx).getImm();
unsigned DoShift = MI.getOperand(OpIdx + 1).getImm();
return (SignExtend << 1) | DoShift;
}
uint32_t
-ARM64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
if (MO.isImm())
@@ -363,7 +363,7 @@ ARM64MCCodeEmitter::getMoveWideImmOpValu
assert(MO.isExpr() && "Unexpected movz/movk immediate");
Fixups.push_back(MCFixup::Create(
- 0, MO.getExpr(), MCFixupKind(ARM64::fixup_arm64_movw), MI.getLoc()));
+ 0, MO.getExpr(), MCFixupKind(AArch64::fixup_aarch64_movw), MI.getLoc()));
++MCNumFixups;
@@ -372,7 +372,7 @@ ARM64MCCodeEmitter::getMoveWideImmOpValu
/// getTestBranchTargetOpValue - Return the encoded value for a test-bit-and-
/// branch target.
-uint32_t ARM64MCCodeEmitter::getTestBranchTargetOpValue(
+uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
@@ -382,7 +382,7 @@ uint32_t ARM64MCCodeEmitter::getTestBran
return MO.getImm();
assert(MO.isExpr() && "Unexpected ADR target type!");
- MCFixupKind Kind = MCFixupKind(ARM64::fixup_arm64_pcrel_branch14);
+ MCFixupKind Kind = MCFixupKind(AArch64::fixup_aarch64_pcrel_branch14);
Fixups.push_back(MCFixup::Create(0, MO.getExpr(), Kind, MI.getLoc()));
++MCNumFixups;
@@ -394,9 +394,9 @@ uint32_t ARM64MCCodeEmitter::getTestBran
/// getBranchTargetOpValue - Return the encoded value for an unconditional
/// branch target.
uint32_t
-ARM64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
// If the destination is an immediate, we have nothing to do.
@@ -404,9 +404,9 @@ ARM64MCCodeEmitter::getBranchTargetOpVal
return MO.getImm();
assert(MO.isExpr() && "Unexpected ADR target type!");
- MCFixupKind Kind = MI.getOpcode() == ARM64::BL
- ? MCFixupKind(ARM64::fixup_arm64_pcrel_call26)
- : MCFixupKind(ARM64::fixup_arm64_pcrel_branch26);
+ MCFixupKind Kind = MI.getOpcode() == AArch64::BL
+ ? MCFixupKind(AArch64::fixup_aarch64_pcrel_call26)
+ : MCFixupKind(AArch64::fixup_aarch64_pcrel_branch26);
Fixups.push_back(MCFixup::Create(0, MO.getExpr(), Kind, MI.getLoc()));
++MCNumFixups;
@@ -422,9 +422,9 @@ ARM64MCCodeEmitter::getBranchTargetOpVal
/// 10 -> 16
/// 11 -> 24
uint32_t
-ARM64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the shift amount!");
@@ -446,36 +446,35 @@ ARM64MCCodeEmitter::getVecShifterOpValue
}
uint32_t
-ARM64MCCodeEmitter::getSIMDShift64OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getSIMDShift64OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the shift amount!");
return 64 - (MO.getImm());
}
-uint32_t
-ARM64MCCodeEmitter::getSIMDShift64_32OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+uint32_t AArch64MCCodeEmitter::getSIMDShift64_32OpValue(
+ const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the shift amount!");
return 64 - (MO.getImm() | 32);
}
uint32_t
-ARM64MCCodeEmitter::getSIMDShift32OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getSIMDShift32OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the shift amount!");
return 32 - (MO.getImm() | 16);
}
uint32_t
-ARM64MCCodeEmitter::getSIMDShift16OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getSIMDShift16OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the shift amount!");
return 16 - (MO.getImm() | 8);
@@ -483,7 +482,7 @@ ARM64MCCodeEmitter::getSIMDShift16OpValu
/// getFixedPointScaleOpValue - Return the encoded value for the
// FP-to-fixed-point scale factor.
-uint32_t ARM64MCCodeEmitter::getFixedPointScaleOpValue(
+uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
@@ -492,72 +491,72 @@ uint32_t ARM64MCCodeEmitter::getFixedPoi
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftR64OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return 64 - MO.getImm();
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftR32OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return 32 - MO.getImm();
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftR16OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return 16 - MO.getImm();
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftR8OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return 8 - MO.getImm();
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftL64OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return MO.getImm() - 64;
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftL32OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return MO.getImm() - 32;
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftL16OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return MO.getImm() - 16;
}
uint32_t
-ARM64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() && "Expected an immediate value for the scale amount!");
return MO.getImm() - 8;
@@ -565,20 +564,19 @@ ARM64MCCodeEmitter::getVecShiftL8OpValue
/// getMoveVecShifterOpValue - Return the encoded value for the vector move
/// shifter (MSL).
-uint32_t
-ARM64MCCodeEmitter::getMoveVecShifterOpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
+ const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpIdx);
assert(MO.isImm() &&
"Expected an immediate value for the move shift amount!");
- unsigned ShiftVal = ARM64_AM::getShiftValue(MO.getImm());
+ unsigned ShiftVal = AArch64_AM::getShiftValue(MO.getImm());
assert((ShiftVal == 8 || ShiftVal == 16) && "Invalid shift amount!");
return ShiftVal == 8 ? 0 : 1;
}
-unsigned ARM64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
- const MCSubtargetInfo &STI) const {
+unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
+ const MCSubtargetInfo &STI) const {
// If one of the signed fixup kinds is applied to a MOVZ instruction, the
// eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
// job to ensure that any bits possibly affected by this are 0. This means we
@@ -589,15 +587,15 @@ unsigned ARM64MCCodeEmitter::fixMOVZ(con
if (UImm16MO.isImm())
return EncodedValue;
- const ARM64MCExpr *A64E = cast<ARM64MCExpr>(UImm16MO.getExpr());
+ const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
switch (A64E->getKind()) {
- case ARM64MCExpr::VK_DTPREL_G2:
- case ARM64MCExpr::VK_DTPREL_G1:
- case ARM64MCExpr::VK_DTPREL_G0:
- case ARM64MCExpr::VK_GOTTPREL_G1:
- case ARM64MCExpr::VK_TPREL_G2:
- case ARM64MCExpr::VK_TPREL_G1:
- case ARM64MCExpr::VK_TPREL_G0:
+ case AArch64MCExpr::VK_DTPREL_G2:
+ case AArch64MCExpr::VK_DTPREL_G1:
+ case AArch64MCExpr::VK_DTPREL_G0:
+ case AArch64MCExpr::VK_GOTTPREL_G1:
+ case AArch64MCExpr::VK_TPREL_G2:
+ case AArch64MCExpr::VK_TPREL_G1:
+ case AArch64MCExpr::VK_TPREL_G0:
return EncodedValue & ~(1u << 30);
default:
// Nothing to do for an unsigned fixup.
@@ -608,14 +606,14 @@ unsigned ARM64MCCodeEmitter::fixMOVZ(con
return EncodedValue & ~(1u << 30);
}
-void ARM64MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- if (MI.getOpcode() == ARM64::TLSDESCCALL) {
+void AArch64MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ if (MI.getOpcode() == AArch64::TLSDESCCALL) {
// This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
// following (BLR) instruction. It doesn't emit any code itself so it
// doesn't go through the normal TableGenerated channels.
- MCFixupKind Fixup = MCFixupKind(ARM64::fixup_arm64_tlsdesc_call);
+ MCFixupKind Fixup = MCFixupKind(AArch64::fixup_aarch64_tlsdesc_call);
Fixups.push_back(MCFixup::Create(0, MI.getOperand(0).getExpr(), Fixup));
return;
}
@@ -626,9 +624,9 @@ void ARM64MCCodeEmitter::EncodeInstructi
}
unsigned
-ARM64MCCodeEmitter::fixMulHigh(const MCInst &MI,
- unsigned EncodedValue,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
+ unsigned EncodedValue,
+ const MCSubtargetInfo &STI) const {
// The Ra field of SMULH and UMULH is unused: it should be assembled as 31
// (i.e. all bits 1) but is ignored by the processor.
EncodedValue |= 0x1f << 10;
@@ -636,23 +634,21 @@ ARM64MCCodeEmitter::fixMulHigh(const MCI
}
template<int hasRs, int hasRt2> unsigned
-ARM64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
- unsigned EncodedValue,
- const MCSubtargetInfo &STI) const {
+AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
+ unsigned EncodedValue,
+ const MCSubtargetInfo &STI) const {
if (!hasRs) EncodedValue |= 0x001F0000;
if (!hasRt2) EncodedValue |= 0x00007C00;
return EncodedValue;
}
-unsigned
-ARM64MCCodeEmitter::fixOneOperandFPComparison(const MCInst &MI,
- unsigned EncodedValue,
- const MCSubtargetInfo &STI) const {
+unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
+ const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const {
// The Rm field of FCMP and friends is unused - it should be assembled
// as 0, but is ignored by the processor.
EncodedValue &= ~(0x1f << 16);
return EncodedValue;
}
-#include "ARM64GenMCCodeEmitter.inc"
+#include "AArch64GenMCCodeEmitter.inc"
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64MCExpr.cpp - ARM64 specific MC expression classes --------===//
+//===-- AArch64MCExpr.cpp - AArch64 specific MC expression classes --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "ARM64MCExpr.h"
+#include "AArch64MCExpr.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELF.h"
@@ -25,12 +25,12 @@ using namespace llvm;
#define DEBUG_TYPE "aarch64symbolrefexpr"
-const ARM64MCExpr *ARM64MCExpr::Create(const MCExpr *Expr, VariantKind Kind,
+const AArch64MCExpr *AArch64MCExpr::Create(const MCExpr *Expr, VariantKind Kind,
MCContext &Ctx) {
- return new (Ctx) ARM64MCExpr(Expr, Kind);
+ return new (Ctx) AArch64MCExpr(Expr, Kind);
}
-StringRef ARM64MCExpr::getVariantKindName() const {
+StringRef AArch64MCExpr::getVariantKindName() const {
switch (static_cast<uint32_t>(getKind())) {
case VK_CALL: return "";
case VK_LO12: return ":lo12:";
@@ -75,7 +75,7 @@ StringRef ARM64MCExpr::getVariantKindNam
}
}
-void ARM64MCExpr::PrintImpl(raw_ostream &OS) const {
+void AArch64MCExpr::PrintImpl(raw_ostream &OS) const {
if (getKind() != VK_NONE)
OS << getVariantKindName();
OS << *Expr;
@@ -110,15 +110,15 @@ static void AddValueSymbolsImpl(const MC
}
}
-void ARM64MCExpr::AddValueSymbols(MCAssembler *Asm) const {
+void AArch64MCExpr::AddValueSymbols(MCAssembler *Asm) const {
AddValueSymbolsImpl(getSubExpr(), Asm);
}
-const MCSection *ARM64MCExpr::FindAssociatedSection() const {
+const MCSection *AArch64MCExpr::FindAssociatedSection() const {
llvm_unreachable("FIXME: what goes here?");
}
-bool ARM64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
+bool AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const {
if (!getSubExpr()->EvaluateAsRelocatable(Res, Layout))
return false;
@@ -159,7 +159,7 @@ static void fixELFSymbolsInTLSFixupsImpl
}
}
-void ARM64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
+void AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
switch (getSymbolLoc(Kind)) {
default:
return;
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCExpr.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//=---- ARM64MCExpr.h - ARM64 specific MC expression classes ------*- C++ -*-=//
+//=--- AArch64MCExpr.h - AArch64 specific MC expression classes ---*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,20 +7,20 @@
//
//===----------------------------------------------------------------------===//
//
-// This file describes ARM64-specific MCExprs, used for modifiers like
+// This file describes AArch64-specific MCExprs, used for modifiers like
// ":lo12:" or ":gottprel_g1:".
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ARM64MCEXPR_H
-#define LLVM_ARM64MCEXPR_H
+#ifndef LLVM_AArch64MCEXPR_H
+#define LLVM_AArch64MCEXPR_H
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
-class ARM64MCExpr : public MCTargetExpr {
+class AArch64MCExpr : public MCTargetExpr {
public:
enum VariantKind {
VK_NONE = 0x000,
@@ -105,14 +105,14 @@ private:
const MCExpr *Expr;
const VariantKind Kind;
- explicit ARM64MCExpr(const MCExpr *Expr, VariantKind Kind)
+ explicit AArch64MCExpr(const MCExpr *Expr, VariantKind Kind)
: Expr(Expr), Kind(Kind) {}
public:
/// @name Construction
/// @{
- static const ARM64MCExpr *Create(const MCExpr *Expr, VariantKind Kind,
+ static const AArch64MCExpr *Create(const MCExpr *Expr, VariantKind Kind,
MCContext &Ctx);
/// @}
@@ -160,7 +160,7 @@ public:
return E->getKind() == MCExpr::Target;
}
- static bool classof(const ARM64MCExpr *) { return true; }
+ static bool classof(const AArch64MCExpr *) { return true; }
};
} // end namespace llvm
Added: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp (added)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp Sat May 24 07:50:23 2014
@@ -0,0 +1,225 @@
+//===-- AArch64MCTargetDesc.cpp - AArch64 Target Descriptions ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides AArch64 specific target descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AArch64MCTargetDesc.h"
+#include "AArch64ELFStreamer.h"
+#include "AArch64MCAsmInfo.h"
+#include "InstPrinter/AArch64InstPrinter.h"
+#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
+
+using namespace llvm;
+
+#define GET_INSTRINFO_MC_DESC
+#include "AArch64GenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_MC_DESC
+#include "AArch64GenSubtargetInfo.inc"
+
+#define GET_REGINFO_MC_DESC
+#include "AArch64GenRegisterInfo.inc"
+
+static MCInstrInfo *createAArch64MCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitAArch64MCInstrInfo(X);
+ return X;
+}
+
+static MCSubtargetInfo *
+createAArch64MCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) {
+ MCSubtargetInfo *X = new MCSubtargetInfo();
+
+ if (CPU.empty())
+ CPU = "generic";
+
+ InitAArch64MCSubtargetInfo(X, TT, CPU, FS);
+ return X;
+}
+
+static MCRegisterInfo *createAArch64MCRegisterInfo(StringRef Triple) {
+ MCRegisterInfo *X = new MCRegisterInfo();
+ InitAArch64MCRegisterInfo(X, AArch64::LR);
+ return X;
+}
+
+static MCAsmInfo *createAArch64MCAsmInfo(const MCRegisterInfo &MRI,
+ StringRef TT) {
+ Triple TheTriple(TT);
+
+ MCAsmInfo *MAI;
+ if (TheTriple.isOSDarwin())
+ MAI = new AArch64MCAsmInfoDarwin();
+ else {
+ assert(TheTriple.isOSBinFormatELF() && "Only expect Darwin or ELF");
+ MAI = new AArch64MCAsmInfoELF(TT);
+ }
+
+ // Initial state of the frame pointer is SP.
+ unsigned Reg = MRI.getDwarfRegNum(AArch64::SP, true);
+ MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
+ MAI->addInitialFrameState(Inst);
+
+ return MAI;
+}
+
+static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) {
+ Triple TheTriple(TT);
+ assert((TheTriple.isOSBinFormatELF() || TheTriple.isOSBinFormatMachO()) &&
+ "Only expect Darwin and ELF targets");
+
+ if (CM == CodeModel::Default)
+ CM = CodeModel::Small;
+ // The default MCJIT memory managers make no guarantees about where they can
+ // find an executable page; JITed code needs to be able to refer to globals
+ // no matter how far away they are.
+ else if (CM == CodeModel::JITDefault)
+ CM = CodeModel::Large;
+ else if (CM != CodeModel::Small && CM != CodeModel::Large)
+ report_fatal_error(
+ "Only small and large code models are allowed on AArch64");
+
+ // AArch64 Darwin is always PIC.
+ if (TheTriple.isOSDarwin())
+ RM = Reloc::PIC_;
+ // On ELF platforms the default static relocation model has a smart enough
+ // linker to cope with referencing external symbols defined in a shared
+ // library. Hence DynamicNoPIC doesn't need to be promoted to PIC.
+ else if (RM == Reloc::Default || RM == Reloc::DynamicNoPIC)
+ RM = Reloc::Static;
+
+ MCCodeGenInfo *X = new MCCodeGenInfo();
+ X->InitMCCodeGenInfo(RM, CM, OL);
+ return X;
+}
+
+static MCInstPrinter *createAArch64MCInstPrinter(const Target &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI) {
+ if (SyntaxVariant == 0)
+ return new AArch64InstPrinter(MAI, MII, MRI, STI);
+ if (SyntaxVariant == 1)
+ return new AArch64AppleInstPrinter(MAI, MII, MRI, STI);
+
+ return nullptr;
+}
+
+static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
+ MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ const MCSubtargetInfo &STI, bool RelaxAll,
+ bool NoExecStack) {
+ Triple TheTriple(TT);
+
+ if (TheTriple.isOSDarwin())
+ return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ /*LabelSections*/ true);
+
+ return createAArch64ELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
+}
+
+// Force static initialization.
+extern "C" void LLVMInitializeAArch64TargetMC() {
+ // Register the MC asm info.
+ RegisterMCAsmInfoFn X(TheAArch64leTarget, createAArch64MCAsmInfo);
+ RegisterMCAsmInfoFn Y(TheAArch64beTarget, createAArch64MCAsmInfo);
+ RegisterMCAsmInfoFn Z(TheARM64leTarget, createAArch64MCAsmInfo);
+ RegisterMCAsmInfoFn W(TheARM64beTarget, createAArch64MCAsmInfo);
+
+ // Register the MC codegen info.
+ TargetRegistry::RegisterMCCodeGenInfo(TheAArch64leTarget,
+ createAArch64MCCodeGenInfo);
+ TargetRegistry::RegisterMCCodeGenInfo(TheAArch64beTarget,
+ createAArch64MCCodeGenInfo);
+ TargetRegistry::RegisterMCCodeGenInfo(TheARM64leTarget,
+ createAArch64MCCodeGenInfo);
+ TargetRegistry::RegisterMCCodeGenInfo(TheARM64beTarget,
+ createAArch64MCCodeGenInfo);
+
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(TheAArch64leTarget,
+ createAArch64MCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(TheAArch64beTarget,
+ createAArch64MCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(TheARM64leTarget,
+ createAArch64MCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(TheARM64beTarget,
+ createAArch64MCInstrInfo);
+
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(TheAArch64leTarget,
+ createAArch64MCRegisterInfo);
+ TargetRegistry::RegisterMCRegInfo(TheAArch64beTarget,
+ createAArch64MCRegisterInfo);
+ TargetRegistry::RegisterMCRegInfo(TheARM64leTarget,
+ createAArch64MCRegisterInfo);
+ TargetRegistry::RegisterMCRegInfo(TheARM64beTarget,
+ createAArch64MCRegisterInfo);
+
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(TheAArch64leTarget,
+ createAArch64MCSubtargetInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(TheAArch64beTarget,
+ createAArch64MCSubtargetInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(TheARM64leTarget,
+ createAArch64MCSubtargetInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(TheARM64beTarget,
+ createAArch64MCSubtargetInfo);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterMCAsmBackend(TheAArch64leTarget,
+ createAArch64leAsmBackend);
+ TargetRegistry::RegisterMCAsmBackend(TheAArch64beTarget,
+ createAArch64beAsmBackend);
+ TargetRegistry::RegisterMCAsmBackend(TheARM64leTarget,
+ createAArch64leAsmBackend);
+ TargetRegistry::RegisterMCAsmBackend(TheARM64beTarget,
+ createAArch64beAsmBackend);
+
+ // Register the MC Code Emitter
+ TargetRegistry::RegisterMCCodeEmitter(TheAArch64leTarget,
+ createAArch64MCCodeEmitter);
+ TargetRegistry::RegisterMCCodeEmitter(TheAArch64beTarget,
+ createAArch64MCCodeEmitter);
+ TargetRegistry::RegisterMCCodeEmitter(TheARM64leTarget,
+ createAArch64MCCodeEmitter);
+ TargetRegistry::RegisterMCCodeEmitter(TheARM64beTarget,
+ createAArch64MCCodeEmitter);
+
+ // Register the object streamer.
+ TargetRegistry::RegisterMCObjectStreamer(TheAArch64leTarget,
+ createMCStreamer);
+ TargetRegistry::RegisterMCObjectStreamer(TheAArch64beTarget,
+ createMCStreamer);
+ TargetRegistry::RegisterMCObjectStreamer(TheARM64leTarget, createMCStreamer);
+ TargetRegistry::RegisterMCObjectStreamer(TheARM64beTarget, createMCStreamer);
+
+ // Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(TheAArch64leTarget,
+ createAArch64MCInstPrinter);
+ TargetRegistry::RegisterMCInstPrinter(TheAArch64beTarget,
+ createAArch64MCInstPrinter);
+ TargetRegistry::RegisterMCInstPrinter(TheARM64leTarget,
+ createAArch64MCInstPrinter);
+ TargetRegistry::RegisterMCInstPrinter(TheARM64beTarget,
+ createAArch64MCInstPrinter);
+}
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64MCTargetDesc.h - ARM64 Target Descriptions ---------*- C++ -*-===//
+//===-- AArch64MCTargetDesc.h - AArch64 Target Descriptions -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file provides ARM64 specific target descriptions.
+// This file provides AArch64 specific target descriptions.
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64MCTARGETDESC_H
-#define ARM64MCTARGETDESC_H
+#ifndef AArch64MCTARGETDESC_H
+#define AArch64MCTARGETDESC_H
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -29,40 +29,42 @@ class StringRef;
class Target;
class raw_ostream;
-extern Target TheARM64leTarget;
-extern Target TheARM64beTarget;
extern Target TheAArch64leTarget;
extern Target TheAArch64beTarget;
+extern Target TheARM64leTarget;
+extern Target TheARM64beTarget;
-MCCodeEmitter *createARM64MCCodeEmitter(const MCInstrInfo &MCII,
+MCCodeEmitter *createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx);
-MCAsmBackend *createARM64leAsmBackend(const Target &T, const MCRegisterInfo &MRI,
- StringRef TT, StringRef CPU);
-MCAsmBackend *createARM64beAsmBackend(const Target &T, const MCRegisterInfo &MRI,
- StringRef TT, StringRef CPU);
+MCAsmBackend *createAArch64leAsmBackend(const Target &T,
+ const MCRegisterInfo &MRI, StringRef TT,
+ StringRef CPU);
+MCAsmBackend *createAArch64beAsmBackend(const Target &T,
+ const MCRegisterInfo &MRI, StringRef TT,
+ StringRef CPU);
- MCObjectWriter *createARM64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI,
- bool IsLittleEndian);
+MCObjectWriter *createAArch64ELFObjectWriter(raw_ostream &OS, uint8_t OSABI,
+ bool IsLittleEndian);
-MCObjectWriter *createARM64MachObjectWriter(raw_ostream &OS, uint32_t CPUType,
+MCObjectWriter *createAArch64MachObjectWriter(raw_ostream &OS, uint32_t CPUType,
uint32_t CPUSubtype);
} // End llvm namespace
-// Defines symbolic names for ARM64 registers. This defines a mapping from
+// Defines symbolic names for AArch64 registers. This defines a mapping from
// register name to register number.
//
#define GET_REGINFO_ENUM
-#include "ARM64GenRegisterInfo.inc"
+#include "AArch64GenRegisterInfo.inc"
-// Defines symbolic names for the ARM64 instructions.
+// Defines symbolic names for the AArch64 instructions.
//
#define GET_INSTRINFO_ENUM
-#include "ARM64GenInstrInfo.inc"
+#include "AArch64GenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM
-#include "ARM64GenSubtargetInfo.inc"
+#include "AArch64GenSubtargetInfo.inc"
#endif
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MachObjectWriter.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MachObjectWriter.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/ARM64MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===//
+//===-- AArch64MachObjectWriter.cpp - ARM Mach Object Writer --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/ARM64FixupKinds.h"
-#include "MCTargetDesc/ARM64MCTargetDesc.h"
+#include "MCTargetDesc/AArch64FixupKinds.h"
+#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCContext.h"
@@ -23,13 +23,13 @@
using namespace llvm;
namespace {
-class ARM64MachObjectWriter : public MCMachObjectTargetWriter {
- bool getARM64FixupKindMachOInfo(const MCFixup &Fixup, unsigned &RelocType,
+class AArch64MachObjectWriter : public MCMachObjectTargetWriter {
+ bool getAArch64FixupKindMachOInfo(const MCFixup &Fixup, unsigned &RelocType,
const MCSymbolRefExpr *Sym,
unsigned &Log2Size, const MCAssembler &Asm);
public:
- ARM64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
+ AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
: MCMachObjectTargetWriter(true /* is64Bit */, CPUType, CPUSubtype,
/*UseAggressiveSymbolFolding=*/true) {}
@@ -40,7 +40,7 @@ public:
};
}
-bool ARM64MachObjectWriter::getARM64FixupKindMachOInfo(
+bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(
const MCFixup &Fixup, unsigned &RelocType, const MCSymbolRefExpr *Sym,
unsigned &Log2Size, const MCAssembler &Asm) {
RelocType = unsigned(MachO::ARM64_RELOC_UNSIGNED);
@@ -66,12 +66,12 @@ bool ARM64MachObjectWriter::getARM64Fixu
if (Sym->getKind() == MCSymbolRefExpr::VK_GOT)
RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
return true;
- case ARM64::fixup_arm64_add_imm12:
- case ARM64::fixup_arm64_ldst_imm12_scale1:
- case ARM64::fixup_arm64_ldst_imm12_scale2:
- case ARM64::fixup_arm64_ldst_imm12_scale4:
- case ARM64::fixup_arm64_ldst_imm12_scale8:
- case ARM64::fixup_arm64_ldst_imm12_scale16:
+ case AArch64::fixup_aarch64_add_imm12:
+ case AArch64::fixup_aarch64_ldst_imm12_scale1:
+ case AArch64::fixup_aarch64_ldst_imm12_scale2:
+ case AArch64::fixup_aarch64_ldst_imm12_scale4:
+ case AArch64::fixup_aarch64_ldst_imm12_scale8:
+ case AArch64::fixup_aarch64_ldst_imm12_scale16:
Log2Size = llvm::Log2_32(4);
switch (Sym->getKind()) {
default:
@@ -86,7 +86,7 @@ bool ARM64MachObjectWriter::getARM64Fixu
RelocType = unsigned(MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12);
return true;
}
- case ARM64::fixup_arm64_pcrel_adrp_imm21:
+ case AArch64::fixup_aarch64_pcrel_adrp_imm21:
Log2Size = llvm::Log2_32(4);
// This encompasses the relocation for the whole 21-bit value.
switch (Sym->getKind()) {
@@ -104,15 +104,15 @@ bool ARM64MachObjectWriter::getARM64Fixu
return true;
}
return true;
- case ARM64::fixup_arm64_pcrel_branch26:
- case ARM64::fixup_arm64_pcrel_call26:
+ case AArch64::fixup_aarch64_pcrel_branch26:
+ case AArch64::fixup_aarch64_pcrel_call26:
Log2Size = llvm::Log2_32(4);
RelocType = unsigned(MachO::ARM64_RELOC_BRANCH26);
return true;
}
}
-void ARM64MachObjectWriter::RecordRelocation(
+void AArch64MachObjectWriter::RecordRelocation(
MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) {
@@ -129,20 +129,20 @@ void ARM64MachObjectWriter::RecordReloca
FixupOffset += Fixup.getOffset();
- // ARM64 pcrel relocation addends do not include the section offset.
+ // AArch64 pcrel relocation addends do not include the section offset.
if (IsPCRel)
FixedValue += FixupOffset;
// ADRP fixups use relocations for the whole symbol value and only
// put the addend in the instruction itself. Clear out any value the
// generic code figured out from the sybmol definition.
- if (Kind == ARM64::fixup_arm64_pcrel_adrp_imm21)
+ if (Kind == AArch64::fixup_aarch64_pcrel_adrp_imm21)
FixedValue = 0;
// imm19 relocations are for conditional branches, which require
// assembler local symbols. If we got here, that's not what we have,
// so complain loudly.
- if (Kind == ARM64::fixup_arm64_pcrel_branch19) {
+ if (Kind == AArch64::fixup_aarch64_pcrel_branch19) {
Asm.getContext().FatalError(Fixup.getLoc(),
"conditional branch requires assembler-local"
" label. '" +
@@ -153,15 +153,15 @@ void ARM64MachObjectWriter::RecordReloca
// 14-bit branch relocations should only target internal labels, and so
// should never get here.
- if (Kind == ARM64::fixup_arm64_pcrel_branch14) {
+ if (Kind == AArch64::fixup_aarch64_pcrel_branch14) {
Asm.getContext().FatalError(Fixup.getLoc(),
"Invalid relocation on conditional branch!");
return;
}
- if (!getARM64FixupKindMachOInfo(Fixup, Type, Target.getSymA(), Log2Size,
+ if (!getAArch64FixupKindMachOInfo(Fixup, Type, Target.getSymA(), Log2Size,
Asm)) {
- Asm.getContext().FatalError(Fixup.getLoc(), "unknown ARM64 fixup kind!");
+ Asm.getContext().FatalError(Fixup.getLoc(), "unknown AArch64 fixup kind!");
return;
}
@@ -220,7 +220,7 @@ void ARM64MachObjectWriter::RecordReloca
"unsupported pc-relative relocation of "
"difference");
- // ARM64 always uses external relocations. If there is no symbol to use as
+ // AArch64 always uses external relocations. If there is no symbol to use as
// a base address (a local symbol with no preceding non-local symbol),
// error out.
//
@@ -305,9 +305,9 @@ void ARM64MachObjectWriter::RecordReloca
Base = nullptr;
}
- // ARM64 uses external relocations as much as possible. For debug sections,
- // and for pointer-sized relocations (.quad), we allow section relocations.
- // It's code sections that run into trouble.
+ // AArch64 uses external relocations as much as possible. For debug
+ // sections, and for pointer-sized relocations (.quad), we allow section
+ // relocations. It's code sections that run into trouble.
if (Base) {
Index = Base->getIndex();
IsExtern = 1;
@@ -387,9 +387,10 @@ void ARM64MachObjectWriter::RecordReloca
Writer->addRelocation(Fragment->getParent(), MRE);
}
-MCObjectWriter *llvm::createARM64MachObjectWriter(raw_ostream &OS,
+MCObjectWriter *llvm::createAArch64MachObjectWriter(raw_ostream &OS,
uint32_t CPUType,
uint32_t CPUSubtype) {
- return createMachObjectWriter(new ARM64MachObjectWriter(CPUType, CPUSubtype),
- OS, /*IsLittleEndian=*/true);
+ return createMachObjectWriter(
+ new AArch64MachObjectWriter(CPUType, CPUSubtype), OS,
+ /*IsLittleEndian=*/true);
}
Added: llvm/trunk/lib/Target/AArch64/MCTargetDesc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/CMakeLists.txt?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -0,0 +1,14 @@
+add_llvm_library(LLVMAArch64Desc
+ AArch64AsmBackend.cpp
+ AArch64ELFObjectWriter.cpp
+ AArch64ELFStreamer.cpp
+ AArch64MCAsmInfo.cpp
+ AArch64MCCodeEmitter.cpp
+ AArch64MCExpr.cpp
+ AArch64MCTargetDesc.cpp
+ AArch64MachObjectWriter.cpp
+)
+add_dependencies(LLVMAArch64Desc AArch64CommonTableGen)
+
+# Hack: we need to include 'main' target directory to grab private headers
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..)
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/MCTargetDesc/LLVMBuild.txt ------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/MCTargetDesc/LLVMBuild.txt ------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,8 +17,8 @@
[component_0]
type = Library
-name = ARM64Desc
-parent = ARM64
-required_libraries = ARM64AsmPrinter ARM64Info MC Support
-add_to_library_groups = ARM64
+name = AArch64Desc
+parent = AArch64
+required_libraries = AArch64AsmPrinter AArch64Info MC Support
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/MCTargetDesc/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/MCTargetDesc/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/Makefile?p2=llvm/trunk/lib/Target/AArch64/MCTargetDesc/Makefile&p1=llvm/trunk/lib/Target/ARM64/MCTargetDesc/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/MCTargetDesc/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM64/TargetDesc/Makefile ----------------*- Makefile -*-===##
+##===- lib/Target/AArch64/TargetDesc/Makefile --------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64Desc
+LIBRARYNAME = LLVMAArch64Desc
# Hack: we need to include 'main' target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
Added: llvm/trunk/lib/Target/AArch64/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Makefile?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Makefile (added)
+++ llvm/trunk/lib/Target/AArch64/Makefile Sat May 24 07:50:23 2014
@@ -0,0 +1,25 @@
+##===- lib/Target/AArch64/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMAArch64CodeGen
+TARGET = AArch64
+
+# Make sure that tblgen is run, first thing.
+BUILT_SOURCES = AArch64GenRegisterInfo.inc AArch64GenInstrInfo.inc \
+ AArch64GenAsmWriter.inc AArch64GenAsmWriter1.inc \
+ AArch64GenDAGISel.inc \
+ AArch64GenCallingConv.inc AArch64GenAsmMatcher.inc \
+ AArch64GenSubtargetInfo.inc AArch64GenMCCodeEmitter.inc \
+ AArch64GenFastISel.inc AArch64GenDisassemblerTables.inc \
+ AArch64GenMCPseudoLowering.inc
+
+DIRS = TargetInfo InstPrinter AsmParser Disassembler MCTargetDesc Utils
+
+include $(LEVEL)/Makefile.common
Copied: llvm/trunk/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/TargetInfo/ARM64TargetInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/TargetInfo/AArch64TargetInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64TargetInfo.cpp - ARM64 Target Implementation -----------------===//
+//===-- AArch64TargetInfo.cpp - AArch64 Target Implementation -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,20 +12,20 @@
using namespace llvm;
namespace llvm {
-Target TheARM64leTarget;
-Target TheARM64beTarget;
Target TheAArch64leTarget;
Target TheAArch64beTarget;
+Target TheARM64leTarget;
+Target TheARM64beTarget;
} // end namespace llvm
-extern "C" void LLVMInitializeARM64TargetInfo() {
+extern "C" void LLVMInitializeAArch64TargetInfo() {
RegisterTarget<Triple::arm64, /*HasJIT=*/true> X(TheARM64leTarget, "arm64",
- "ARM64 (little endian)");
+ "AArch64 (little endian)");
RegisterTarget<Triple::arm64_be, /*HasJIT=*/true> Y(TheARM64beTarget, "arm64_be",
- "ARM64 (big endian)");
+ "AArch64 (big endian)");
RegisterTarget<Triple::aarch64, /*HasJIT=*/true> Z(
- TheAArch64leTarget, "aarch64", "ARM64 (little endian)");
+ TheAArch64leTarget, "aarch64", "AArch64 (little endian)");
RegisterTarget<Triple::aarch64_be, /*HasJIT=*/true> W(
- TheAArch64beTarget, "aarch64_be", "ARM64 (big endian)");
+ TheAArch64beTarget, "aarch64_be", "AArch64 (big endian)");
}
Added: llvm/trunk/lib/Target/AArch64/TargetInfo/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/TargetInfo/CMakeLists.txt?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/TargetInfo/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/AArch64/TargetInfo/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -0,0 +1,7 @@
+include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
+
+add_llvm_library(LLVMAArch64Info
+ AArch64TargetInfo.cpp
+ )
+
+add_dependencies(LLVMAArch64Info AArch64CommonTableGen)
Copied: llvm/trunk/lib/Target/AArch64/TargetInfo/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/Utils/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/TargetInfo/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/TargetInfo/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/Utils/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Utils/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/TargetInfo/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/Utils/LLVMBuild.txt ----------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/TargetInfo/LLVMBuild.txt --------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,7 +17,7 @@
[component_0]
type = Library
-name = ARM64Utils
-parent = ARM64
+name = AArch64Info
+parent = AArch64
required_libraries = Support
-add_to_library_groups = ARM64
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/TargetInfo/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/TargetInfo/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/TargetInfo/Makefile?p2=llvm/trunk/lib/Target/AArch64/TargetInfo/Makefile&p1=llvm/trunk/lib/Target/ARM64/TargetInfo/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/TargetInfo/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/TargetInfo/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM64/TargetInfo/Makefile ----------------*- Makefile -*-===##
+##===- lib/Target/AArch64/TargetInfo/Makefile --------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,7 +7,7 @@
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64Info
+LIBRARYNAME = LLVMAArch64Info
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
Copied: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp (from r209576, llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp?p2=llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp&p1=llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.cpp&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64BaseInfo.cpp - ARM64 Base encoding information------------===//
+//===-- AArch64BaseInfo.cpp - AArch64 Base encoding information------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file provides basic encoding and assembly information for ARM64.
+// This file provides basic encoding and assembly information for AArch64.
//
//===----------------------------------------------------------------------===//
-#include "ARM64BaseInfo.h"
+#include "AArch64BaseInfo.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -18,7 +18,7 @@
using namespace llvm;
-StringRef ARM64NamedImmMapper::toString(uint32_t Value, bool &Valid) const {
+StringRef AArch64NamedImmMapper::toString(uint32_t Value, bool &Valid) const {
for (unsigned i = 0; i < NumPairs; ++i) {
if (Pairs[i].Value == Value) {
Valid = true;
@@ -30,7 +30,7 @@ StringRef ARM64NamedImmMapper::toString(
return StringRef();
}
-uint32_t ARM64NamedImmMapper::fromString(StringRef Name, bool &Valid) const {
+uint32_t AArch64NamedImmMapper::fromString(StringRef Name, bool &Valid) const {
std::string LowerCaseName = Name.lower();
for (unsigned i = 0; i < NumPairs; ++i) {
if (Pairs[i].Name == LowerCaseName) {
@@ -43,11 +43,11 @@ uint32_t ARM64NamedImmMapper::fromString
return -1;
}
-bool ARM64NamedImmMapper::validImm(uint32_t Value) const {
+bool AArch64NamedImmMapper::validImm(uint32_t Value) const {
return Value < TooBigImm;
}
-const ARM64NamedImmMapper::Mapping ARM64AT::ATMapper::ATPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64AT::ATMapper::ATPairs[] = {
{"s1e1r", S1E1R},
{"s1e2r", S1E2R},
{"s1e3r", S1E3R},
@@ -62,10 +62,10 @@ const ARM64NamedImmMapper::Mapping ARM64
{"s12e0w", S12E0W},
};
-ARM64AT::ATMapper::ATMapper()
- : ARM64NamedImmMapper(ATPairs, 0) {}
+AArch64AT::ATMapper::ATMapper()
+ : AArch64NamedImmMapper(ATPairs, 0) {}
-const ARM64NamedImmMapper::Mapping ARM64DB::DBarrierMapper::DBarrierPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64DB::DBarrierMapper::DBarrierPairs[] = {
{"oshld", OSHLD},
{"oshst", OSHST},
{"osh", OSH},
@@ -80,10 +80,10 @@ const ARM64NamedImmMapper::Mapping ARM64
{"sy", SY}
};
-ARM64DB::DBarrierMapper::DBarrierMapper()
- : ARM64NamedImmMapper(DBarrierPairs, 16u) {}
+AArch64DB::DBarrierMapper::DBarrierMapper()
+ : AArch64NamedImmMapper(DBarrierPairs, 16u) {}
-const ARM64NamedImmMapper::Mapping ARM64DC::DCMapper::DCPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64DC::DCMapper::DCPairs[] = {
{"zva", ZVA},
{"ivac", IVAC},
{"isw", ISW},
@@ -94,26 +94,26 @@ const ARM64NamedImmMapper::Mapping ARM64
{"cisw", CISW}
};
-ARM64DC::DCMapper::DCMapper()
- : ARM64NamedImmMapper(DCPairs, 0) {}
+AArch64DC::DCMapper::DCMapper()
+ : AArch64NamedImmMapper(DCPairs, 0) {}
-const ARM64NamedImmMapper::Mapping ARM64IC::ICMapper::ICPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64IC::ICMapper::ICPairs[] = {
{"ialluis", IALLUIS},
{"iallu", IALLU},
{"ivau", IVAU}
};
-ARM64IC::ICMapper::ICMapper()
- : ARM64NamedImmMapper(ICPairs, 0) {}
+AArch64IC::ICMapper::ICMapper()
+ : AArch64NamedImmMapper(ICPairs, 0) {}
-const ARM64NamedImmMapper::Mapping ARM64ISB::ISBMapper::ISBPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64ISB::ISBMapper::ISBPairs[] = {
{"sy", SY},
};
-ARM64ISB::ISBMapper::ISBMapper()
- : ARM64NamedImmMapper(ISBPairs, 16) {}
+AArch64ISB::ISBMapper::ISBMapper()
+ : AArch64NamedImmMapper(ISBPairs, 16) {}
-const ARM64NamedImmMapper::Mapping ARM64PRFM::PRFMMapper::PRFMPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64PRFM::PRFMMapper::PRFMPairs[] = {
{"pldl1keep", PLDL1KEEP},
{"pldl1strm", PLDL1STRM},
{"pldl2keep", PLDL2KEEP},
@@ -134,19 +134,19 @@ const ARM64NamedImmMapper::Mapping ARM64
{"pstl3strm", PSTL3STRM}
};
-ARM64PRFM::PRFMMapper::PRFMMapper()
- : ARM64NamedImmMapper(PRFMPairs, 32) {}
+AArch64PRFM::PRFMMapper::PRFMMapper()
+ : AArch64NamedImmMapper(PRFMPairs, 32) {}
-const ARM64NamedImmMapper::Mapping ARM64PState::PStateMapper::PStatePairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64PState::PStateMapper::PStatePairs[] = {
{"spsel", SPSel},
{"daifset", DAIFSet},
{"daifclr", DAIFClr}
};
-ARM64PState::PStateMapper::PStateMapper()
- : ARM64NamedImmMapper(PStatePairs, 0) {}
+AArch64PState::PStateMapper::PStateMapper()
+ : AArch64NamedImmMapper(PStatePairs, 0) {}
-const ARM64NamedImmMapper::Mapping ARM64SysReg::MRSMapper::MRSPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64SysReg::MRSMapper::MRSPairs[] = {
{"mdccsr_el0", MDCCSR_EL0},
{"dbgdtrrx_el0", DBGDTRRX_EL0},
{"mdrar_el1", MDRAR_EL1},
@@ -176,16 +176,16 @@ const ARM64NamedImmMapper::Mapping ARM64
{"id_isar3_el1", ID_ISAR3_EL1},
{"id_isar4_el1", ID_ISAR4_EL1},
{"id_isar5_el1", ID_ISAR5_EL1},
- {"id_aa64pfr0_el1", ID_AARM64PFR0_EL1},
- {"id_aa64pfr1_el1", ID_AARM64PFR1_EL1},
- {"id_aa64dfr0_el1", ID_AARM64DFR0_EL1},
- {"id_aa64dfr1_el1", ID_AARM64DFR1_EL1},
- {"id_aa64afr0_el1", ID_AARM64AFR0_EL1},
- {"id_aa64afr1_el1", ID_AARM64AFR1_EL1},
- {"id_aa64isar0_el1", ID_AARM64ISAR0_EL1},
- {"id_aa64isar1_el1", ID_AARM64ISAR1_EL1},
- {"id_aa64mmfr0_el1", ID_AARM64MMFR0_EL1},
- {"id_aa64mmfr1_el1", ID_AARM64MMFR1_EL1},
+ {"id_aa64pfr0_el1", ID_A64PFR0_EL1},
+ {"id_aa64pfr1_el1", ID_A64PFR1_EL1},
+ {"id_aa64dfr0_el1", ID_A64DFR0_EL1},
+ {"id_aa64dfr1_el1", ID_A64DFR1_EL1},
+ {"id_aa64afr0_el1", ID_A64AFR0_EL1},
+ {"id_aa64afr1_el1", ID_A64AFR1_EL1},
+ {"id_aa64isar0_el1", ID_A64ISAR0_EL1},
+ {"id_aa64isar1_el1", ID_A64ISAR1_EL1},
+ {"id_aa64mmfr0_el1", ID_A64MMFR0_EL1},
+ {"id_aa64mmfr1_el1", ID_A64MMFR1_EL1},
{"mvfr0_el1", MVFR0_EL1},
{"mvfr1_el1", MVFR1_EL1},
{"mvfr2_el1", MVFR2_EL1},
@@ -245,13 +245,13 @@ const ARM64NamedImmMapper::Mapping ARM64
{"ich_elsr_el2", ICH_ELSR_EL2}
};
-ARM64SysReg::MRSMapper::MRSMapper(uint64_t FeatureBits)
+AArch64SysReg::MRSMapper::MRSMapper(uint64_t FeatureBits)
: SysRegMapper(FeatureBits) {
InstPairs = &MRSPairs[0];
NumInstPairs = llvm::array_lengthof(MRSPairs);
}
-const ARM64NamedImmMapper::Mapping ARM64SysReg::MSRMapper::MSRPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64SysReg::MSRMapper::MSRPairs[] = {
{"dbgdtrtx_el0", DBGDTRTX_EL0},
{"oslar_el1", OSLAR_EL1},
{"pmswinc_el0", PMSWINC_EL0},
@@ -269,14 +269,14 @@ const ARM64NamedImmMapper::Mapping ARM64
{"icc_sgi0r_el1", ICC_SGI0R_EL1}
};
-ARM64SysReg::MSRMapper::MSRMapper(uint64_t FeatureBits)
+AArch64SysReg::MSRMapper::MSRMapper(uint64_t FeatureBits)
: SysRegMapper(FeatureBits) {
InstPairs = &MSRPairs[0];
NumInstPairs = llvm::array_lengthof(MSRPairs);
}
-const ARM64NamedImmMapper::Mapping ARM64SysReg::SysRegMapper::SysRegPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64SysReg::SysRegMapper::SysRegPairs[] = {
{"osdtrrx_el1", OSDTRRX_EL1},
{"osdtrtx_el1", OSDTRTX_EL1},
{"teecr32_el1", TEECR32_EL1},
@@ -755,13 +755,13 @@ const ARM64NamedImmMapper::Mapping ARM64
{"ich_lr15_el2", ICH_LR15_EL2}
};
-const ARM64NamedImmMapper::Mapping
-ARM64SysReg::SysRegMapper::CycloneSysRegPairs[] = {
+const AArch64NamedImmMapper::Mapping
+AArch64SysReg::SysRegMapper::CycloneSysRegPairs[] = {
{"cpm_ioacc_ctl_el3", CPM_IOACC_CTL_EL3}
};
uint32_t
-ARM64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
+AArch64SysReg::SysRegMapper::fromString(StringRef Name, bool &Valid) const {
std::string NameLower = Name.lower();
// First search the registers shared by all
@@ -773,7 +773,7 @@ ARM64SysReg::SysRegMapper::fromString(St
}
// Next search for target specific registers
- if (FeatureBits & ARM64::ProcCyclone) {
+ if (FeatureBits & AArch64::ProcCyclone) {
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
if (CycloneSysRegPairs[i].Name == NameLower) {
Valid = true;
@@ -814,7 +814,7 @@ ARM64SysReg::SysRegMapper::fromString(St
}
std::string
-ARM64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
+AArch64SysReg::SysRegMapper::toString(uint32_t Bits, bool &Valid) const {
// First search the registers shared by all
for (unsigned i = 0; i < array_lengthof(SysRegPairs); ++i) {
if (SysRegPairs[i].Value == Bits) {
@@ -824,7 +824,7 @@ ARM64SysReg::SysRegMapper::toString(uint
}
// Next search for target specific registers
- if (FeatureBits & ARM64::ProcCyclone) {
+ if (FeatureBits & AArch64::ProcCyclone) {
for (unsigned i = 0; i < array_lengthof(CycloneSysRegPairs); ++i) {
if (CycloneSysRegPairs[i].Value == Bits) {
Valid = true;
@@ -862,7 +862,7 @@ ARM64SysReg::SysRegMapper::toString(uint
+ "_c" + utostr(CRm) + "_" + utostr(Op2);
}
-const ARM64NamedImmMapper::Mapping ARM64TLBI::TLBIMapper::TLBIPairs[] = {
+const AArch64NamedImmMapper::Mapping AArch64TLBI::TLBIMapper::TLBIPairs[] = {
{"ipas2e1is", IPAS2E1IS},
{"ipas2le1is", IPAS2LE1IS},
{"vmalle1is", VMALLE1IS},
@@ -897,5 +897,5 @@ const ARM64NamedImmMapper::Mapping ARM64
{"vaale1", VAALE1}
};
-ARM64TLBI::TLBIMapper::TLBIMapper()
- : ARM64NamedImmMapper(TLBIPairs, 0) {}
+AArch64TLBI::TLBIMapper::TLBIMapper()
+ : AArch64NamedImmMapper(TLBIPairs, 0) {}
Copied: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h (from r209576, llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h?p2=llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h&p1=llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.h&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Utils/ARM64BaseInfo.h (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-//===-- ARM64BaseInfo.h - Top level definitions for ARM64 -------*- C++ -*-===//
+//===-- AArch64BaseInfo.h - Top level definitions for AArch64 ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,18 +8,18 @@
//===----------------------------------------------------------------------===//
//
// This file contains small standalone helper functions and enum definitions for
-// the ARM64 target useful for the compiler back-end and the MC libraries.
+// the AArch64 target useful for the compiler back-end and the MC libraries.
// As such, it deliberately does not include references to LLVM core
// code gen types, passes, etc..
//
//===----------------------------------------------------------------------===//
-#ifndef ARM64BASEINFO_H
-#define ARM64BASEINFO_H
+#ifndef AArch64BASEINFO_H
+#define AArch64BASEINFO_H
// FIXME: Is it easiest to fix this layering violation by moving the .inc
-// #includes from ARM64MCTargetDesc.h to here?
-#include "MCTargetDesc/ARM64MCTargetDesc.h" // For ARM64::X0 and friends.
+// #includes from AArch64MCTargetDesc.h to here?
+#include "MCTargetDesc/AArch64MCTargetDesc.h" // For AArch64::X0 and friends.
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
@@ -28,39 +28,39 @@ namespace llvm {
inline static unsigned getWRegFromXReg(unsigned Reg) {
switch (Reg) {
- case ARM64::X0: return ARM64::W0;
- case ARM64::X1: return ARM64::W1;
- case ARM64::X2: return ARM64::W2;
- case ARM64::X3: return ARM64::W3;
- case ARM64::X4: return ARM64::W4;
- case ARM64::X5: return ARM64::W5;
- case ARM64::X6: return ARM64::W6;
- case ARM64::X7: return ARM64::W7;
- case ARM64::X8: return ARM64::W8;
- case ARM64::X9: return ARM64::W9;
- case ARM64::X10: return ARM64::W10;
- case ARM64::X11: return ARM64::W11;
- case ARM64::X12: return ARM64::W12;
- case ARM64::X13: return ARM64::W13;
- case ARM64::X14: return ARM64::W14;
- case ARM64::X15: return ARM64::W15;
- case ARM64::X16: return ARM64::W16;
- case ARM64::X17: return ARM64::W17;
- case ARM64::X18: return ARM64::W18;
- case ARM64::X19: return ARM64::W19;
- case ARM64::X20: return ARM64::W20;
- case ARM64::X21: return ARM64::W21;
- case ARM64::X22: return ARM64::W22;
- case ARM64::X23: return ARM64::W23;
- case ARM64::X24: return ARM64::W24;
- case ARM64::X25: return ARM64::W25;
- case ARM64::X26: return ARM64::W26;
- case ARM64::X27: return ARM64::W27;
- case ARM64::X28: return ARM64::W28;
- case ARM64::FP: return ARM64::W29;
- case ARM64::LR: return ARM64::W30;
- case ARM64::SP: return ARM64::WSP;
- case ARM64::XZR: return ARM64::WZR;
+ case AArch64::X0: return AArch64::W0;
+ case AArch64::X1: return AArch64::W1;
+ case AArch64::X2: return AArch64::W2;
+ case AArch64::X3: return AArch64::W3;
+ case AArch64::X4: return AArch64::W4;
+ case AArch64::X5: return AArch64::W5;
+ case AArch64::X6: return AArch64::W6;
+ case AArch64::X7: return AArch64::W7;
+ case AArch64::X8: return AArch64::W8;
+ case AArch64::X9: return AArch64::W9;
+ case AArch64::X10: return AArch64::W10;
+ case AArch64::X11: return AArch64::W11;
+ case AArch64::X12: return AArch64::W12;
+ case AArch64::X13: return AArch64::W13;
+ case AArch64::X14: return AArch64::W14;
+ case AArch64::X15: return AArch64::W15;
+ case AArch64::X16: return AArch64::W16;
+ case AArch64::X17: return AArch64::W17;
+ case AArch64::X18: return AArch64::W18;
+ case AArch64::X19: return AArch64::W19;
+ case AArch64::X20: return AArch64::W20;
+ case AArch64::X21: return AArch64::W21;
+ case AArch64::X22: return AArch64::W22;
+ case AArch64::X23: return AArch64::W23;
+ case AArch64::X24: return AArch64::W24;
+ case AArch64::X25: return AArch64::W25;
+ case AArch64::X26: return AArch64::W26;
+ case AArch64::X27: return AArch64::W27;
+ case AArch64::X28: return AArch64::W28;
+ case AArch64::FP: return AArch64::W29;
+ case AArch64::LR: return AArch64::W30;
+ case AArch64::SP: return AArch64::WSP;
+ case AArch64::XZR: return AArch64::WZR;
}
// For anything else, return it unchanged.
return Reg;
@@ -68,39 +68,39 @@ inline static unsigned getWRegFromXReg(u
inline static unsigned getXRegFromWReg(unsigned Reg) {
switch (Reg) {
- case ARM64::W0: return ARM64::X0;
- case ARM64::W1: return ARM64::X1;
- case ARM64::W2: return ARM64::X2;
- case ARM64::W3: return ARM64::X3;
- case ARM64::W4: return ARM64::X4;
- case ARM64::W5: return ARM64::X5;
- case ARM64::W6: return ARM64::X6;
- case ARM64::W7: return ARM64::X7;
- case ARM64::W8: return ARM64::X8;
- case ARM64::W9: return ARM64::X9;
- case ARM64::W10: return ARM64::X10;
- case ARM64::W11: return ARM64::X11;
- case ARM64::W12: return ARM64::X12;
- case ARM64::W13: return ARM64::X13;
- case ARM64::W14: return ARM64::X14;
- case ARM64::W15: return ARM64::X15;
- case ARM64::W16: return ARM64::X16;
- case ARM64::W17: return ARM64::X17;
- case ARM64::W18: return ARM64::X18;
- case ARM64::W19: return ARM64::X19;
- case ARM64::W20: return ARM64::X20;
- case ARM64::W21: return ARM64::X21;
- case ARM64::W22: return ARM64::X22;
- case ARM64::W23: return ARM64::X23;
- case ARM64::W24: return ARM64::X24;
- case ARM64::W25: return ARM64::X25;
- case ARM64::W26: return ARM64::X26;
- case ARM64::W27: return ARM64::X27;
- case ARM64::W28: return ARM64::X28;
- case ARM64::W29: return ARM64::FP;
- case ARM64::W30: return ARM64::LR;
- case ARM64::WSP: return ARM64::SP;
- case ARM64::WZR: return ARM64::XZR;
+ case AArch64::W0: return AArch64::X0;
+ case AArch64::W1: return AArch64::X1;
+ case AArch64::W2: return AArch64::X2;
+ case AArch64::W3: return AArch64::X3;
+ case AArch64::W4: return AArch64::X4;
+ case AArch64::W5: return AArch64::X5;
+ case AArch64::W6: return AArch64::X6;
+ case AArch64::W7: return AArch64::X7;
+ case AArch64::W8: return AArch64::X8;
+ case AArch64::W9: return AArch64::X9;
+ case AArch64::W10: return AArch64::X10;
+ case AArch64::W11: return AArch64::X11;
+ case AArch64::W12: return AArch64::X12;
+ case AArch64::W13: return AArch64::X13;
+ case AArch64::W14: return AArch64::X14;
+ case AArch64::W15: return AArch64::X15;
+ case AArch64::W16: return AArch64::X16;
+ case AArch64::W17: return AArch64::X17;
+ case AArch64::W18: return AArch64::X18;
+ case AArch64::W19: return AArch64::X19;
+ case AArch64::W20: return AArch64::X20;
+ case AArch64::W21: return AArch64::X21;
+ case AArch64::W22: return AArch64::X22;
+ case AArch64::W23: return AArch64::X23;
+ case AArch64::W24: return AArch64::X24;
+ case AArch64::W25: return AArch64::X25;
+ case AArch64::W26: return AArch64::X26;
+ case AArch64::W27: return AArch64::X27;
+ case AArch64::W28: return AArch64::X28;
+ case AArch64::W29: return AArch64::FP;
+ case AArch64::W30: return AArch64::LR;
+ case AArch64::WSP: return AArch64::SP;
+ case AArch64::WZR: return AArch64::XZR;
}
// For anything else, return it unchanged.
return Reg;
@@ -108,38 +108,38 @@ inline static unsigned getXRegFromWReg(u
static inline unsigned getBRegFromDReg(unsigned Reg) {
switch (Reg) {
- case ARM64::D0: return ARM64::B0;
- case ARM64::D1: return ARM64::B1;
- case ARM64::D2: return ARM64::B2;
- case ARM64::D3: return ARM64::B3;
- case ARM64::D4: return ARM64::B4;
- case ARM64::D5: return ARM64::B5;
- case ARM64::D6: return ARM64::B6;
- case ARM64::D7: return ARM64::B7;
- case ARM64::D8: return ARM64::B8;
- case ARM64::D9: return ARM64::B9;
- case ARM64::D10: return ARM64::B10;
- case ARM64::D11: return ARM64::B11;
- case ARM64::D12: return ARM64::B12;
- case ARM64::D13: return ARM64::B13;
- case ARM64::D14: return ARM64::B14;
- case ARM64::D15: return ARM64::B15;
- case ARM64::D16: return ARM64::B16;
- case ARM64::D17: return ARM64::B17;
- case ARM64::D18: return ARM64::B18;
- case ARM64::D19: return ARM64::B19;
- case ARM64::D20: return ARM64::B20;
- case ARM64::D21: return ARM64::B21;
- case ARM64::D22: return ARM64::B22;
- case ARM64::D23: return ARM64::B23;
- case ARM64::D24: return ARM64::B24;
- case ARM64::D25: return ARM64::B25;
- case ARM64::D26: return ARM64::B26;
- case ARM64::D27: return ARM64::B27;
- case ARM64::D28: return ARM64::B28;
- case ARM64::D29: return ARM64::B29;
- case ARM64::D30: return ARM64::B30;
- case ARM64::D31: return ARM64::B31;
+ case AArch64::D0: return AArch64::B0;
+ case AArch64::D1: return AArch64::B1;
+ case AArch64::D2: return AArch64::B2;
+ case AArch64::D3: return AArch64::B3;
+ case AArch64::D4: return AArch64::B4;
+ case AArch64::D5: return AArch64::B5;
+ case AArch64::D6: return AArch64::B6;
+ case AArch64::D7: return AArch64::B7;
+ case AArch64::D8: return AArch64::B8;
+ case AArch64::D9: return AArch64::B9;
+ case AArch64::D10: return AArch64::B10;
+ case AArch64::D11: return AArch64::B11;
+ case AArch64::D12: return AArch64::B12;
+ case AArch64::D13: return AArch64::B13;
+ case AArch64::D14: return AArch64::B14;
+ case AArch64::D15: return AArch64::B15;
+ case AArch64::D16: return AArch64::B16;
+ case AArch64::D17: return AArch64::B17;
+ case AArch64::D18: return AArch64::B18;
+ case AArch64::D19: return AArch64::B19;
+ case AArch64::D20: return AArch64::B20;
+ case AArch64::D21: return AArch64::B21;
+ case AArch64::D22: return AArch64::B22;
+ case AArch64::D23: return AArch64::B23;
+ case AArch64::D24: return AArch64::B24;
+ case AArch64::D25: return AArch64::B25;
+ case AArch64::D26: return AArch64::B26;
+ case AArch64::D27: return AArch64::B27;
+ case AArch64::D28: return AArch64::B28;
+ case AArch64::D29: return AArch64::B29;
+ case AArch64::D30: return AArch64::B30;
+ case AArch64::D31: return AArch64::B31;
}
// For anything else, return it unchanged.
return Reg;
@@ -148,44 +148,44 @@ static inline unsigned getBRegFromDReg(u
static inline unsigned getDRegFromBReg(unsigned Reg) {
switch (Reg) {
- case ARM64::B0: return ARM64::D0;
- case ARM64::B1: return ARM64::D1;
- case ARM64::B2: return ARM64::D2;
- case ARM64::B3: return ARM64::D3;
- case ARM64::B4: return ARM64::D4;
- case ARM64::B5: return ARM64::D5;
- case ARM64::B6: return ARM64::D6;
- case ARM64::B7: return ARM64::D7;
- case ARM64::B8: return ARM64::D8;
- case ARM64::B9: return ARM64::D9;
- case ARM64::B10: return ARM64::D10;
- case ARM64::B11: return ARM64::D11;
- case ARM64::B12: return ARM64::D12;
- case ARM64::B13: return ARM64::D13;
- case ARM64::B14: return ARM64::D14;
- case ARM64::B15: return ARM64::D15;
- case ARM64::B16: return ARM64::D16;
- case ARM64::B17: return ARM64::D17;
- case ARM64::B18: return ARM64::D18;
- case ARM64::B19: return ARM64::D19;
- case ARM64::B20: return ARM64::D20;
- case ARM64::B21: return ARM64::D21;
- case ARM64::B22: return ARM64::D22;
- case ARM64::B23: return ARM64::D23;
- case ARM64::B24: return ARM64::D24;
- case ARM64::B25: return ARM64::D25;
- case ARM64::B26: return ARM64::D26;
- case ARM64::B27: return ARM64::D27;
- case ARM64::B28: return ARM64::D28;
- case ARM64::B29: return ARM64::D29;
- case ARM64::B30: return ARM64::D30;
- case ARM64::B31: return ARM64::D31;
+ case AArch64::B0: return AArch64::D0;
+ case AArch64::B1: return AArch64::D1;
+ case AArch64::B2: return AArch64::D2;
+ case AArch64::B3: return AArch64::D3;
+ case AArch64::B4: return AArch64::D4;
+ case AArch64::B5: return AArch64::D5;
+ case AArch64::B6: return AArch64::D6;
+ case AArch64::B7: return AArch64::D7;
+ case AArch64::B8: return AArch64::D8;
+ case AArch64::B9: return AArch64::D9;
+ case AArch64::B10: return AArch64::D10;
+ case AArch64::B11: return AArch64::D11;
+ case AArch64::B12: return AArch64::D12;
+ case AArch64::B13: return AArch64::D13;
+ case AArch64::B14: return AArch64::D14;
+ case AArch64::B15: return AArch64::D15;
+ case AArch64::B16: return AArch64::D16;
+ case AArch64::B17: return AArch64::D17;
+ case AArch64::B18: return AArch64::D18;
+ case AArch64::B19: return AArch64::D19;
+ case AArch64::B20: return AArch64::D20;
+ case AArch64::B21: return AArch64::D21;
+ case AArch64::B22: return AArch64::D22;
+ case AArch64::B23: return AArch64::D23;
+ case AArch64::B24: return AArch64::D24;
+ case AArch64::B25: return AArch64::D25;
+ case AArch64::B26: return AArch64::D26;
+ case AArch64::B27: return AArch64::D27;
+ case AArch64::B28: return AArch64::D28;
+ case AArch64::B29: return AArch64::D29;
+ case AArch64::B30: return AArch64::D30;
+ case AArch64::B31: return AArch64::D31;
}
// For anything else, return it unchanged.
return Reg;
}
-namespace ARM64CC {
+namespace AArch64CC {
// The CondCodes constants map directly to the 4-bit encoding of the condition
// field for predicated instructions.
@@ -277,7 +277,7 @@ inline static unsigned getNZCVToSatisfyC
case LE: return Z; // Z == 1 || N != V
}
}
-} // end namespace ARM64CC
+} // end namespace AArch64CC
/// Instances of this class can perform bidirectional mapping from random
/// identifier strings to operand encodings. For example "MSR" takes a named
@@ -290,14 +290,14 @@ inline static unsigned getNZCVToSatisfyC
/// out just how often these instructions are emitted before working on it. It
/// might even be optimal to just reorder the tables for the common instructions
/// rather than changing the algorithm.
-struct ARM64NamedImmMapper {
+struct AArch64NamedImmMapper {
struct Mapping {
const char *Name;
uint32_t Value;
};
template<int N>
- ARM64NamedImmMapper(const Mapping (&Pairs)[N], uint32_t TooBigImm)
+ AArch64NamedImmMapper(const Mapping (&Pairs)[N], uint32_t TooBigImm)
: Pairs(&Pairs[0]), NumPairs(N), TooBigImm(TooBigImm) {}
StringRef toString(uint32_t Value, bool &Valid) const;
@@ -313,7 +313,7 @@ protected:
uint32_t TooBigImm;
};
-namespace ARM64AT {
+namespace AArch64AT {
enum ATValues {
Invalid = -1, // Op0 Op1 CRn CRm Op2
S1E1R = 0x43c0, // 01 000 0111 1000 000
@@ -330,14 +330,14 @@ namespace ARM64AT {
S12E0W = 0x63c7 // 01 100 0111 1000 111
};
- struct ATMapper : ARM64NamedImmMapper {
+ struct ATMapper : AArch64NamedImmMapper {
const static Mapping ATPairs[];
ATMapper();
};
}
-namespace ARM64DB {
+namespace AArch64DB {
enum DBValues {
Invalid = -1,
OSHLD = 0x1,
@@ -354,14 +354,14 @@ namespace ARM64DB {
SY = 0xf
};
- struct DBarrierMapper : ARM64NamedImmMapper {
+ struct DBarrierMapper : AArch64NamedImmMapper {
const static Mapping DBarrierPairs[];
DBarrierMapper();
};
}
-namespace ARM64DC {
+namespace AArch64DC {
enum DCValues {
Invalid = -1, // Op1 CRn CRm Op2
ZVA = 0x5ba1, // 01 011 0111 0100 001
@@ -374,7 +374,7 @@ namespace ARM64DC {
CISW = 0x43f2 // 01 000 0111 1110 010
};
- struct DCMapper : ARM64NamedImmMapper {
+ struct DCMapper : AArch64NamedImmMapper {
const static Mapping DCPairs[];
DCMapper();
@@ -382,7 +382,7 @@ namespace ARM64DC {
}
-namespace ARM64IC {
+namespace AArch64IC {
enum ICValues {
Invalid = -1, // Op1 CRn CRm Op2
IALLUIS = 0x0388, // 000 0111 0001 000
@@ -391,7 +391,7 @@ namespace ARM64IC {
};
- struct ICMapper : ARM64NamedImmMapper {
+ struct ICMapper : AArch64NamedImmMapper {
const static Mapping ICPairs[];
ICMapper();
@@ -402,19 +402,19 @@ namespace ARM64IC {
}
}
-namespace ARM64ISB {
+namespace AArch64ISB {
enum ISBValues {
Invalid = -1,
SY = 0xf
};
- struct ISBMapper : ARM64NamedImmMapper {
+ struct ISBMapper : AArch64NamedImmMapper {
const static Mapping ISBPairs[];
ISBMapper();
};
}
-namespace ARM64PRFM {
+namespace AArch64PRFM {
enum PRFMValues {
Invalid = -1,
PLDL1KEEP = 0x00,
@@ -437,14 +437,14 @@ namespace ARM64PRFM {
PSTL3STRM = 0x15
};
- struct PRFMMapper : ARM64NamedImmMapper {
+ struct PRFMMapper : AArch64NamedImmMapper {
const static Mapping PRFMPairs[];
PRFMMapper();
};
}
-namespace ARM64PState {
+namespace AArch64PState {
enum PStateValues {
Invalid = -1,
SPSel = 0x05,
@@ -452,7 +452,7 @@ namespace ARM64PState {
DAIFClr = 0x1f
};
- struct PStateMapper : ARM64NamedImmMapper {
+ struct PStateMapper : AArch64NamedImmMapper {
const static Mapping PStatePairs[];
PStateMapper();
@@ -460,7 +460,7 @@ namespace ARM64PState {
}
-namespace ARM64SE {
+namespace AArch64SE {
enum ShiftExtSpecifiers {
Invalid = -1,
LSL,
@@ -481,7 +481,7 @@ namespace ARM64SE {
};
}
-namespace ARM64Layout {
+namespace AArch64Layout {
enum VectorLayout {
Invalid = -1,
VL_8B,
@@ -504,43 +504,43 @@ namespace ARM64Layout {
}
inline static const char *
-ARM64VectorLayoutToString(ARM64Layout::VectorLayout Layout) {
+AArch64VectorLayoutToString(AArch64Layout::VectorLayout Layout) {
switch (Layout) {
- case ARM64Layout::VL_8B: return ".8b";
- case ARM64Layout::VL_4H: return ".4h";
- case ARM64Layout::VL_2S: return ".2s";
- case ARM64Layout::VL_1D: return ".1d";
- case ARM64Layout::VL_16B: return ".16b";
- case ARM64Layout::VL_8H: return ".8h";
- case ARM64Layout::VL_4S: return ".4s";
- case ARM64Layout::VL_2D: return ".2d";
- case ARM64Layout::VL_B: return ".b";
- case ARM64Layout::VL_H: return ".h";
- case ARM64Layout::VL_S: return ".s";
- case ARM64Layout::VL_D: return ".d";
+ case AArch64Layout::VL_8B: return ".8b";
+ case AArch64Layout::VL_4H: return ".4h";
+ case AArch64Layout::VL_2S: return ".2s";
+ case AArch64Layout::VL_1D: return ".1d";
+ case AArch64Layout::VL_16B: return ".16b";
+ case AArch64Layout::VL_8H: return ".8h";
+ case AArch64Layout::VL_4S: return ".4s";
+ case AArch64Layout::VL_2D: return ".2d";
+ case AArch64Layout::VL_B: return ".b";
+ case AArch64Layout::VL_H: return ".h";
+ case AArch64Layout::VL_S: return ".s";
+ case AArch64Layout::VL_D: return ".d";
default: llvm_unreachable("Unknown Vector Layout");
}
}
-inline static ARM64Layout::VectorLayout
-ARM64StringToVectorLayout(StringRef LayoutStr) {
- return StringSwitch<ARM64Layout::VectorLayout>(LayoutStr)
- .Case(".8b", ARM64Layout::VL_8B)
- .Case(".4h", ARM64Layout::VL_4H)
- .Case(".2s", ARM64Layout::VL_2S)
- .Case(".1d", ARM64Layout::VL_1D)
- .Case(".16b", ARM64Layout::VL_16B)
- .Case(".8h", ARM64Layout::VL_8H)
- .Case(".4s", ARM64Layout::VL_4S)
- .Case(".2d", ARM64Layout::VL_2D)
- .Case(".b", ARM64Layout::VL_B)
- .Case(".h", ARM64Layout::VL_H)
- .Case(".s", ARM64Layout::VL_S)
- .Case(".d", ARM64Layout::VL_D)
- .Default(ARM64Layout::Invalid);
+inline static AArch64Layout::VectorLayout
+AArch64StringToVectorLayout(StringRef LayoutStr) {
+ return StringSwitch<AArch64Layout::VectorLayout>(LayoutStr)
+ .Case(".8b", AArch64Layout::VL_8B)
+ .Case(".4h", AArch64Layout::VL_4H)
+ .Case(".2s", AArch64Layout::VL_2S)
+ .Case(".1d", AArch64Layout::VL_1D)
+ .Case(".16b", AArch64Layout::VL_16B)
+ .Case(".8h", AArch64Layout::VL_8H)
+ .Case(".4s", AArch64Layout::VL_4S)
+ .Case(".2d", AArch64Layout::VL_2D)
+ .Case(".b", AArch64Layout::VL_B)
+ .Case(".h", AArch64Layout::VL_H)
+ .Case(".s", AArch64Layout::VL_S)
+ .Case(".d", AArch64Layout::VL_D)
+ .Default(AArch64Layout::Invalid);
}
-namespace ARM64SysReg {
+namespace AArch64SysReg {
enum SysRegROValues {
MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000
DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000
@@ -571,16 +571,16 @@ namespace ARM64SysReg {
ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011
ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100
ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101
- ID_AARM64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000
- ID_AARM64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001
- ID_AARM64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000
- ID_AARM64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001
- ID_AARM64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100
- ID_AARM64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101
- ID_AARM64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000
- ID_AARM64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001
- ID_AARM64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000
- ID_AARM64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001
+ ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000
+ ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001
+ ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000
+ ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001
+ ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100
+ ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101
+ ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000
+ ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001
+ ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000
+ ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001
MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000
MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001
MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010
@@ -1143,15 +1143,15 @@ namespace ARM64SysReg {
CPM_IOACC_CTL_EL3 = 0xff90
};
- // Note that these do not inherit from ARM64NamedImmMapper. This class is
+ // Note that these do not inherit from AArch64NamedImmMapper. This class is
// sufficiently different in its behaviour that I don't believe it's worth
- // burdening the common ARM64NamedImmMapper with abstractions only needed in
+ // burdening the common AArch64NamedImmMapper with abstractions only needed in
// this one case.
struct SysRegMapper {
- static const ARM64NamedImmMapper::Mapping SysRegPairs[];
- static const ARM64NamedImmMapper::Mapping CycloneSysRegPairs[];
+ static const AArch64NamedImmMapper::Mapping SysRegPairs[];
+ static const AArch64NamedImmMapper::Mapping CycloneSysRegPairs[];
- const ARM64NamedImmMapper::Mapping *InstPairs;
+ const AArch64NamedImmMapper::Mapping *InstPairs;
size_t NumInstPairs;
uint64_t FeatureBits;
@@ -1161,19 +1161,19 @@ namespace ARM64SysReg {
};
struct MSRMapper : SysRegMapper {
- static const ARM64NamedImmMapper::Mapping MSRPairs[];
+ static const AArch64NamedImmMapper::Mapping MSRPairs[];
MSRMapper(uint64_t FeatureBits);
};
struct MRSMapper : SysRegMapper {
- static const ARM64NamedImmMapper::Mapping MRSPairs[];
+ static const AArch64NamedImmMapper::Mapping MRSPairs[];
MRSMapper(uint64_t FeatureBits);
};
uint32_t ParseGenericRegister(StringRef Name, bool &Valid);
}
-namespace ARM64TLBI {
+namespace AArch64TLBI {
enum TLBIValues {
Invalid = -1, // Op0 Op1 CRn CRm Op2
IPAS2E1IS = 0x6401, // 01 100 1000 0000 001
@@ -1210,7 +1210,7 @@ namespace ARM64TLBI {
VAALE1 = 0x443f // 01 000 1000 0111 111
};
- struct TLBIMapper : ARM64NamedImmMapper {
+ struct TLBIMapper : AArch64NamedImmMapper {
const static Mapping TLBIPairs[];
TLBIMapper();
@@ -1235,11 +1235,11 @@ namespace ARM64TLBI {
}
}
-namespace ARM64II {
+namespace AArch64II {
/// Target Operand Flag enum.
enum TOF {
//===------------------------------------------------------------------===//
- // ARM64 Specific MachineOperand flags.
+ // AArch64 Specific MachineOperand flags.
MO_NO_FLAG,
@@ -1287,7 +1287,7 @@ namespace ARM64II {
/// referee will affect interpretation.
MO_TLS = 0x20
};
-} // end namespace ARM64II
+} // end namespace AArch64II
} // end namespace llvm
Added: llvm/trunk/lib/Target/AArch64/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/CMakeLists.txt?rev=209577&view=auto
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Utils/CMakeLists.txt (added)
+++ llvm/trunk/lib/Target/AArch64/Utils/CMakeLists.txt Sat May 24 07:50:23 2014
@@ -0,0 +1,3 @@
+add_llvm_library(LLVMAArch64Utils
+ AArch64BaseInfo.cpp
+ )
Copied: llvm/trunk/lib/Target/AArch64/Utils/LLVMBuild.txt (from r209576, llvm/trunk/lib/Target/ARM64/TargetInfo/LLVMBuild.txt)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/LLVMBuild.txt?p2=llvm/trunk/lib/Target/AArch64/Utils/LLVMBuild.txt&p1=llvm/trunk/lib/Target/ARM64/TargetInfo/LLVMBuild.txt&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/TargetInfo/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/LLVMBuild.txt Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-;===- ./lib/Target/ARM64/TargetInfo/LLVMBuild.txt --------------*- Conf -*--===;
+;===- ./lib/Target/AArch64/Utils/LLVMBuild.txt ----------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,7 +17,7 @@
[component_0]
type = Library
-name = ARM64Info
-parent = ARM64
+name = AArch64Utils
+parent = AArch64
required_libraries = Support
-add_to_library_groups = ARM64
+add_to_library_groups = AArch64
Copied: llvm/trunk/lib/Target/AArch64/Utils/Makefile (from r209576, llvm/trunk/lib/Target/ARM64/Utils/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Utils/Makefile?p2=llvm/trunk/lib/Target/AArch64/Utils/Makefile&p1=llvm/trunk/lib/Target/ARM64/Utils/Makefile&r1=209576&r2=209577&rev=209577&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/Utils/Makefile (original)
+++ llvm/trunk/lib/Target/AArch64/Utils/Makefile Sat May 24 07:50:23 2014
@@ -1,4 +1,4 @@
-##===- lib/Target/ARM64/Utils/Makefile -------------------*- Makefile -*-===##
+##===- lib/Target/AArch64/Utils/Makefile -------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -7,9 +7,10 @@
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
-LIBRARYNAME = LLVMARM64Utils
+LIBRARYNAME = LLVMAArch64Utils
-# Hack: we need to include 'main' ARM64 target directory to grab private headers
+# Hack: we need to include 'main' AArch64 target directory to grab private
+# headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
Removed: llvm/trunk/lib/Target/ARM64/ARM64.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64.h?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64.h (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64.h (removed)
@@ -1,48 +0,0 @@
-//===-- ARM64.h - Top-level interface for ARM64 representation --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the entry points for global functions defined in the LLVM
-// ARM64 back-end.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TARGET_ARM64_H
-#define TARGET_ARM64_H
-
-#include "Utils/ARM64BaseInfo.h"
-#include "MCTargetDesc/ARM64MCTargetDesc.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-class ARM64TargetMachine;
-class FunctionPass;
-class MachineFunctionPass;
-
-FunctionPass *createARM64DeadRegisterDefinitions();
-FunctionPass *createARM64ConditionalCompares();
-FunctionPass *createARM64AdvSIMDScalar();
-FunctionPass *createARM64BranchRelaxation();
-FunctionPass *createARM64ISelDag(ARM64TargetMachine &TM,
- CodeGenOpt::Level OptLevel);
-FunctionPass *createARM64StorePairSuppressPass();
-FunctionPass *createARM64ExpandPseudoPass();
-FunctionPass *createARM64LoadStoreOptimizationPass();
-ModulePass *createARM64PromoteConstantPass();
-FunctionPass *createARM64AddressTypePromotionPass();
-/// \brief Creates an ARM-specific Target Transformation Info pass.
-ImmutablePass *createARM64TargetTransformInfoPass(const ARM64TargetMachine *TM);
-
-FunctionPass *createARM64CleanupLocalDynamicTLSPass();
-
-FunctionPass *createARM64CollectLOHPass();
-} // end namespace llvm
-
-#endif
Removed: llvm/trunk/lib/Target/ARM64/ARM64.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64.td?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64.td (removed)
@@ -1,134 +0,0 @@
-//===- ARM64.td - Describe the ARM64 Target Machine --------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Target-independent interfaces which we are implementing
-//===----------------------------------------------------------------------===//
-
-include "llvm/Target/Target.td"
-
-//===----------------------------------------------------------------------===//
-// ARM64 Subtarget features.
-//
-
-def FeatureFPARMv8 : SubtargetFeature<"fp-armv8", "HasFPARMv8", "true",
- "Enable ARMv8 FP">;
-
-def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
- "Enable Advanced SIMD instructions", [FeatureFPARMv8]>;
-
-def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
- "Enable cryptographic instructions">;
-
-def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true",
- "Enable ARMv8 CRC-32 checksum instructions">;
-
-/// Cyclone has register move instructions which are "free".
-def FeatureZCRegMove : SubtargetFeature<"zcm", "HasZeroCycleRegMove", "true",
- "Has zero-cycle register moves">;
-
-/// Cyclone has instructions which zero registers for "free".
-def FeatureZCZeroing : SubtargetFeature<"zcz", "HasZeroCycleZeroing", "true",
- "Has zero-cycle zeroing instructions">;
-
-//===----------------------------------------------------------------------===//
-// Register File Description
-//===----------------------------------------------------------------------===//
-
-include "ARM64RegisterInfo.td"
-include "ARM64CallingConvention.td"
-
-//===----------------------------------------------------------------------===//
-// Instruction Descriptions
-//===----------------------------------------------------------------------===//
-
-include "ARM64Schedule.td"
-include "ARM64InstrInfo.td"
-
-def ARM64InstrInfo : InstrInfo;
-
-//===----------------------------------------------------------------------===//
-// ARM64 Processors supported.
-//
-include "ARM64SchedA53.td"
-include "ARM64SchedCyclone.td"
-
-def ProcA53 : SubtargetFeature<"a53", "ARMProcFamily", "CortexA53",
- "Cortex-A53 ARM processors",
- [FeatureFPARMv8,
- FeatureNEON,
- FeatureCrypto,
- FeatureCRC]>;
-
-def ProcA57 : SubtargetFeature<"a57", "ARMProcFamily", "CortexA57",
- "Cortex-A57 ARM processors",
- [FeatureFPARMv8,
- FeatureNEON,
- FeatureCrypto,
- FeatureCRC]>;
-
-def ProcCyclone : SubtargetFeature<"cyclone", "ARMProcFamily", "Cyclone",
- "Cyclone",
- [FeatureFPARMv8,
- FeatureNEON,
- FeatureCrypto,
- FeatureCRC,
- FeatureZCRegMove, FeatureZCZeroing]>;
-
-def : ProcessorModel<"generic", NoSchedModel, [FeatureFPARMv8,
- FeatureNEON,
- FeatureCRC]>;
-
-def : ProcessorModel<"cortex-a53", CortexA53Model, [ProcA53]>;
-def : ProcessorModel<"cortex-a57", NoSchedModel, [ProcA57]>;
-def : ProcessorModel<"cyclone", CycloneModel, [ProcCyclone]>;
-
-//===----------------------------------------------------------------------===//
-// Assembly parser
-//===----------------------------------------------------------------------===//
-
-def GenericAsmParserVariant : AsmParserVariant {
- int Variant = 0;
- string Name = "generic";
-}
-
-def AppleAsmParserVariant : AsmParserVariant {
- int Variant = 1;
- string Name = "apple-neon";
-}
-
-//===----------------------------------------------------------------------===//
-// Assembly printer
-//===----------------------------------------------------------------------===//
-// ARM64 Uses the MC printer for asm output, so make sure the TableGen
-// AsmWriter bits get associated with the correct class.
-def GenericAsmWriter : AsmWriter {
- string AsmWriterClassName = "InstPrinter";
- int Variant = 0;
- bit isMCAsmWriter = 1;
-}
-
-def AppleAsmWriter : AsmWriter {
- let AsmWriterClassName = "AppleInstPrinter";
- int Variant = 1;
- int isMCAsmWriter = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// Target Declaration
-//===----------------------------------------------------------------------===//
-
-def ARM64 : Target {
- let InstructionSet = ARM64InstrInfo;
- let AssemblyParserVariants = [GenericAsmParserVariant, AppleAsmParserVariant];
- let AssemblyWriters = [GenericAsmWriter, AppleAsmWriter];
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64AddressTypePromotion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64AddressTypePromotion.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64AddressTypePromotion.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64AddressTypePromotion.cpp (removed)
@@ -1,493 +0,0 @@
-
-//===-- ARM64AddressTypePromotion.cpp --- Promote type for addr accesses -===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass tries to promote the computations use to obtained a sign extended
-// value used into memory accesses.
-// E.g.
-// a = add nsw i32 b, 3
-// d = sext i32 a to i64
-// e = getelementptr ..., i64 d
-//
-// =>
-// f = sext i32 b to i64
-// a = add nsw i64 f, 3
-// e = getelementptr ..., i64 a
-//
-// This is legal to do so if the computations are markers with either nsw or nuw
-// markers.
-// Moreover, the current heuristic is simple: it does not create new sext
-// operations, i.e., it gives up when a sext would have forked (e.g., if
-// a = add i32 b, c, two sexts are required to promote the computation).
-//
-// FIXME: This pass may be useful for other targets too.
-// ===---------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-type-promotion"
-
-static cl::opt<bool>
-EnableAddressTypePromotion("arm64-type-promotion", cl::Hidden,
- cl::desc("Enable the type promotion pass"),
- cl::init(true));
-static cl::opt<bool>
-EnableMerge("arm64-type-promotion-merge", cl::Hidden,
- cl::desc("Enable merging of redundant sexts when one is dominating"
- " the other."),
- cl::init(true));
-
-//===----------------------------------------------------------------------===//
-// ARM64AddressTypePromotion
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-void initializeARM64AddressTypePromotionPass(PassRegistry &);
-}
-
-namespace {
-class ARM64AddressTypePromotion : public FunctionPass {
-
-public:
- static char ID;
- ARM64AddressTypePromotion()
- : FunctionPass(ID), Func(nullptr), ConsideredSExtType(nullptr) {
- initializeARM64AddressTypePromotionPass(*PassRegistry::getPassRegistry());
- }
-
- const char *getPassName() const override {
- return "ARM64 Address Type Promotion";
- }
-
- /// Iterate over the functions and promote the computation of interesting
- // sext instructions.
- bool runOnFunction(Function &F) override;
-
-private:
- /// The current function.
- Function *Func;
- /// Filter out all sexts that does not have this type.
- /// Currently initialized with Int64Ty.
- Type *ConsideredSExtType;
-
- // This transformation requires dominator info.
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- FunctionPass::getAnalysisUsage(AU);
- }
-
- typedef SmallPtrSet<Instruction *, 32> SetOfInstructions;
- typedef SmallVector<Instruction *, 16> Instructions;
- typedef DenseMap<Value *, Instructions> ValueToInsts;
-
- /// Check if it is profitable to move a sext through this instruction.
- /// Currently, we consider it is profitable if:
- /// - Inst is used only once (no need to insert truncate).
- /// - Inst has only one operand that will require a sext operation (we do
- /// do not create new sext operation).
- bool shouldGetThrough(const Instruction *Inst);
-
- /// Check if it is possible and legal to move a sext through this
- /// instruction.
- /// Current heuristic considers that we can get through:
- /// - Arithmetic operation marked with the nsw or nuw flag.
- /// - Other sext operation.
- /// - Truncate operation if it was just dropping sign extended bits.
- bool canGetThrough(const Instruction *Inst);
-
- /// Move sext operations through safe to sext instructions.
- bool propagateSignExtension(Instructions &SExtInsts);
-
- /// Is this sext should be considered for code motion.
- /// We look for sext with ConsideredSExtType and uses in at least one
- // GetElementPtrInst.
- bool shouldConsiderSExt(const Instruction *SExt) const;
-
- /// Collect all interesting sext operations, i.e., the ones with the right
- /// type and used in memory accesses.
- /// More precisely, a sext instruction is considered as interesting if it
- /// is used in a "complex" getelementptr or it exits at least another
- /// sext instruction that sign extended the same initial value.
- /// A getelementptr is considered as "complex" if it has more than 2
- // operands.
- void analyzeSExtension(Instructions &SExtInsts);
-
- /// Merge redundant sign extension operations in common dominator.
- void mergeSExts(ValueToInsts &ValToSExtendedUses,
- SetOfInstructions &ToRemove);
-};
-} // end anonymous namespace.
-
-char ARM64AddressTypePromotion::ID = 0;
-
-INITIALIZE_PASS_BEGIN(ARM64AddressTypePromotion, "arm64-type-promotion",
- "ARM64 Type Promotion Pass", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_END(ARM64AddressTypePromotion, "arm64-type-promotion",
- "ARM64 Type Promotion Pass", false, false)
-
-FunctionPass *llvm::createARM64AddressTypePromotionPass() {
- return new ARM64AddressTypePromotion();
-}
-
-bool ARM64AddressTypePromotion::canGetThrough(const Instruction *Inst) {
- if (isa<SExtInst>(Inst))
- return true;
-
- const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst);
- if (BinOp && isa<OverflowingBinaryOperator>(BinOp) &&
- (BinOp->hasNoUnsignedWrap() || BinOp->hasNoSignedWrap()))
- return true;
-
- // sext(trunc(sext)) --> sext
- if (isa<TruncInst>(Inst) && isa<SExtInst>(Inst->getOperand(0))) {
- const Instruction *Opnd = cast<Instruction>(Inst->getOperand(0));
- // Check that the truncate just drop sign extended bits.
- if (Inst->getType()->getIntegerBitWidth() >=
- Opnd->getOperand(0)->getType()->getIntegerBitWidth() &&
- Inst->getOperand(0)->getType()->getIntegerBitWidth() <=
- ConsideredSExtType->getIntegerBitWidth())
- return true;
- }
-
- return false;
-}
-
-bool ARM64AddressTypePromotion::shouldGetThrough(const Instruction *Inst) {
- // If the type of the sext is the same as the considered one, this sext
- // will become useless.
- // Otherwise, we will have to do something to preserve the original value,
- // unless it is used once.
- if (isa<SExtInst>(Inst) &&
- (Inst->getType() == ConsideredSExtType || Inst->hasOneUse()))
- return true;
-
- // If the Inst is used more that once, we may need to insert truncate
- // operations and we don't do that at the moment.
- if (!Inst->hasOneUse())
- return false;
-
- // This truncate is used only once, thus if we can get thourgh, it will become
- // useless.
- if (isa<TruncInst>(Inst))
- return true;
-
- // If both operands are not constant, a new sext will be created here.
- // Current heuristic is: each step should be profitable.
- // Therefore we don't allow to increase the number of sext even if it may
- // be profitable later on.
- if (isa<BinaryOperator>(Inst) && isa<ConstantInt>(Inst->getOperand(1)))
- return true;
-
- return false;
-}
-
-static bool shouldSExtOperand(const Instruction *Inst, int OpIdx) {
- if (isa<SelectInst>(Inst) && OpIdx == 0)
- return false;
- return true;
-}
-
-bool
-ARM64AddressTypePromotion::shouldConsiderSExt(const Instruction *SExt) const {
- if (SExt->getType() != ConsideredSExtType)
- return false;
-
- for (const Use &U : SExt->uses()) {
- if (isa<GetElementPtrInst>(*U))
- return true;
- }
-
- return false;
-}
-
-// Input:
-// - SExtInsts contains all the sext instructions that are use direclty in
-// GetElementPtrInst, i.e., access to memory.
-// Algorithm:
-// - For each sext operation in SExtInsts:
-// Let var be the operand of sext.
-// while it is profitable (see shouldGetThrough), legal, and safe
-// (see canGetThrough) to move sext through var's definition:
-// * promote the type of var's definition.
-// * fold var into sext uses.
-// * move sext above var's definition.
-// * update sext operand to use the operand of var that should be sign
-// extended (by construction there is only one).
-//
-// E.g.,
-// a = ... i32 c, 3
-// b = sext i32 a to i64 <- is it legal/safe/profitable to get through 'a'
-// ...
-// = b
-// => Yes, update the code
-// b = sext i32 c to i64
-// a = ... i64 b, 3
-// ...
-// = a
-// Iterate on 'c'.
-bool
-ARM64AddressTypePromotion::propagateSignExtension(Instructions &SExtInsts) {
- DEBUG(dbgs() << "*** Propagate Sign Extension ***\n");
-
- bool LocalChange = false;
- SetOfInstructions ToRemove;
- ValueToInsts ValToSExtendedUses;
- while (!SExtInsts.empty()) {
- // Get through simple chain.
- Instruction *SExt = SExtInsts.pop_back_val();
-
- DEBUG(dbgs() << "Consider:\n" << *SExt << '\n');
-
- // If this SExt has already been merged continue.
- if (SExt->use_empty() && ToRemove.count(SExt)) {
- DEBUG(dbgs() << "No uses => marked as delete\n");
- continue;
- }
-
- // Now try to get through the chain of definitions.
- while (isa<Instruction>(SExt->getOperand(0))) {
- Instruction *Inst = dyn_cast<Instruction>(SExt->getOperand(0));
- DEBUG(dbgs() << "Try to get through:\n" << *Inst << '\n');
- if (!canGetThrough(Inst) || !shouldGetThrough(Inst)) {
- // We cannot get through something that is not an Instruction
- // or not safe to SExt.
- DEBUG(dbgs() << "Cannot get through\n");
- break;
- }
-
- LocalChange = true;
- // If this is a sign extend, it becomes useless.
- if (isa<SExtInst>(Inst) || isa<TruncInst>(Inst)) {
- DEBUG(dbgs() << "SExt or trunc, mark it as to remove\n");
- // We cannot use replaceAllUsesWith here because we may trigger some
- // assertion on the type as all involved sext operation may have not
- // been moved yet.
- while (!Inst->use_empty()) {
- Value::use_iterator UseIt = Inst->use_begin();
- Instruction *UseInst = dyn_cast<Instruction>(*UseIt);
- assert(UseInst && "Use of sext is not an Instruction!");
- UseInst->setOperand(UseIt->getOperandNo(), SExt);
- }
- ToRemove.insert(Inst);
- SExt->setOperand(0, Inst->getOperand(0));
- SExt->moveBefore(Inst);
- continue;
- }
-
- // Get through the Instruction:
- // 1. Update its type.
- // 2. Replace the uses of SExt by Inst.
- // 3. Sign extend each operand that needs to be sign extended.
-
- // Step #1.
- Inst->mutateType(SExt->getType());
- // Step #2.
- SExt->replaceAllUsesWith(Inst);
- // Step #3.
- Instruction *SExtForOpnd = SExt;
-
- DEBUG(dbgs() << "Propagate SExt to operands\n");
- for (int OpIdx = 0, EndOpIdx = Inst->getNumOperands(); OpIdx != EndOpIdx;
- ++OpIdx) {
- DEBUG(dbgs() << "Operand:\n" << *(Inst->getOperand(OpIdx)) << '\n');
- if (Inst->getOperand(OpIdx)->getType() == SExt->getType() ||
- !shouldSExtOperand(Inst, OpIdx)) {
- DEBUG(dbgs() << "No need to propagate\n");
- continue;
- }
- // Check if we can statically sign extend the operand.
- Value *Opnd = Inst->getOperand(OpIdx);
- if (const ConstantInt *Cst = dyn_cast<ConstantInt>(Opnd)) {
- DEBUG(dbgs() << "Statically sign extend\n");
- Inst->setOperand(OpIdx, ConstantInt::getSigned(SExt->getType(),
- Cst->getSExtValue()));
- continue;
- }
- // UndefValue are typed, so we have to statically sign extend them.
- if (isa<UndefValue>(Opnd)) {
- DEBUG(dbgs() << "Statically sign extend\n");
- Inst->setOperand(OpIdx, UndefValue::get(SExt->getType()));
- continue;
- }
-
- // Otherwise we have to explicity sign extend it.
- assert(SExtForOpnd &&
- "Only one operand should have been sign extended");
-
- SExtForOpnd->setOperand(0, Opnd);
-
- DEBUG(dbgs() << "Move before:\n" << *Inst << "\nSign extend\n");
- // Move the sign extension before the insertion point.
- SExtForOpnd->moveBefore(Inst);
- Inst->setOperand(OpIdx, SExtForOpnd);
- // If more sext are required, new instructions will have to be created.
- SExtForOpnd = nullptr;
- }
- if (SExtForOpnd == SExt) {
- DEBUG(dbgs() << "Sign extension is useless now\n");
- ToRemove.insert(SExt);
- break;
- }
- }
-
- // If the use is already of the right type, connect its uses to its argument
- // and delete it.
- // This can happen for an Instruction which all uses are sign extended.
- if (!ToRemove.count(SExt) &&
- SExt->getType() == SExt->getOperand(0)->getType()) {
- DEBUG(dbgs() << "Sign extension is useless, attach its use to "
- "its argument\n");
- SExt->replaceAllUsesWith(SExt->getOperand(0));
- ToRemove.insert(SExt);
- } else
- ValToSExtendedUses[SExt->getOperand(0)].push_back(SExt);
- }
-
- if (EnableMerge)
- mergeSExts(ValToSExtendedUses, ToRemove);
-
- // Remove all instructions marked as ToRemove.
- for (Instruction *I: ToRemove)
- I->eraseFromParent();
- return LocalChange;
-}
-
-void ARM64AddressTypePromotion::mergeSExts(ValueToInsts &ValToSExtendedUses,
- SetOfInstructions &ToRemove) {
- DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-
- for (auto &Entry : ValToSExtendedUses) {
- Instructions &Insts = Entry.second;
- Instructions CurPts;
- for (Instruction *Inst : Insts) {
- if (ToRemove.count(Inst))
- continue;
- bool inserted = false;
- for (auto Pt : CurPts) {
- if (DT.dominates(Inst, Pt)) {
- DEBUG(dbgs() << "Replace all uses of:\n" << *Pt << "\nwith:\n"
- << *Inst << '\n');
- (Pt)->replaceAllUsesWith(Inst);
- ToRemove.insert(Pt);
- Pt = Inst;
- inserted = true;
- break;
- }
- if (!DT.dominates(Pt, Inst))
- // Give up if we need to merge in a common dominator as the
- // expermients show it is not profitable.
- continue;
-
- DEBUG(dbgs() << "Replace all uses of:\n" << *Inst << "\nwith:\n"
- << *Pt << '\n');
- Inst->replaceAllUsesWith(Pt);
- ToRemove.insert(Inst);
- inserted = true;
- break;
- }
- if (!inserted)
- CurPts.push_back(Inst);
- }
- }
-}
-
-void ARM64AddressTypePromotion::analyzeSExtension(Instructions &SExtInsts) {
- DEBUG(dbgs() << "*** Analyze Sign Extensions ***\n");
-
- DenseMap<Value *, Instruction *> SeenChains;
-
- for (auto &BB : *Func) {
- for (auto &II : BB) {
- Instruction *SExt = &II;
-
- // Collect all sext operation per type.
- if (!isa<SExtInst>(SExt) || !shouldConsiderSExt(SExt))
- continue;
-
- DEBUG(dbgs() << "Found:\n" << (*SExt) << '\n');
-
- // Cases where we actually perform the optimization:
- // 1. SExt is used in a getelementptr with more than 2 operand =>
- // likely we can merge some computation if they are done on 64 bits.
- // 2. The beginning of the SExt chain is SExt several time. =>
- // code sharing is possible.
-
- bool insert = false;
- // #1.
- for (const Use &U : SExt->uses()) {
- const Instruction *Inst = dyn_cast<GetElementPtrInst>(U);
- if (Inst && Inst->getNumOperands() > 2) {
- DEBUG(dbgs() << "Interesting use in GetElementPtrInst\n" << *Inst
- << '\n');
- insert = true;
- break;
- }
- }
-
- // #2.
- // Check the head of the chain.
- Instruction *Inst = SExt;
- Value *Last;
- do {
- int OpdIdx = 0;
- const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst);
- if (BinOp && isa<ConstantInt>(BinOp->getOperand(0)))
- OpdIdx = 1;
- Last = Inst->getOperand(OpdIdx);
- Inst = dyn_cast<Instruction>(Last);
- } while (Inst && canGetThrough(Inst) && shouldGetThrough(Inst));
-
- DEBUG(dbgs() << "Head of the chain:\n" << *Last << '\n');
- DenseMap<Value *, Instruction *>::iterator AlreadySeen =
- SeenChains.find(Last);
- if (insert || AlreadySeen != SeenChains.end()) {
- DEBUG(dbgs() << "Insert\n");
- SExtInsts.push_back(SExt);
- if (AlreadySeen != SeenChains.end() && AlreadySeen->second != nullptr) {
- DEBUG(dbgs() << "Insert chain member\n");
- SExtInsts.push_back(AlreadySeen->second);
- SeenChains[Last] = nullptr;
- }
- } else {
- DEBUG(dbgs() << "Record its chain membership\n");
- SeenChains[Last] = SExt;
- }
- }
- }
-}
-
-bool ARM64AddressTypePromotion::runOnFunction(Function &F) {
- if (!EnableAddressTypePromotion || F.isDeclaration())
- return false;
- Func = &F;
- ConsideredSExtType = Type::getInt64Ty(Func->getContext());
-
- DEBUG(dbgs() << "*** " << getPassName() << ": " << Func->getName() << '\n');
-
- Instructions SExtInsts;
- analyzeSExtension(SExtInsts);
- return propagateSignExtension(SExtInsts);
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64AdvSIMDScalarPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64AdvSIMDScalarPass.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64AdvSIMDScalarPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64AdvSIMDScalarPass.cpp (removed)
@@ -1,385 +0,0 @@
-//===-- ARM64AdvSIMDScalar.cpp - Replace dead defs w/ zero reg --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// When profitable, replace GPR targeting i64 instructions with their
-// AdvSIMD scalar equivalents. Generally speaking, "profitable" is defined
-// as minimizing the number of cross-class register copies.
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// TODO: Graph based predicate heuristics.
-// Walking the instruction list linearly will get many, perhaps most, of
-// the cases, but to do a truly thorough job of this, we need a more
-// wholistic approach.
-//
-// This optimization is very similar in spirit to the register allocator's
-// spill placement, only here we're determining where to place cross-class
-// register copies rather than spills. As such, a similar approach is
-// called for.
-//
-// We want to build up a set of graphs of all instructions which are candidates
-// for transformation along with instructions which generate their inputs and
-// consume their outputs. For each edge in the graph, we assign a weight
-// based on whether there is a copy required there (weight zero if not) and
-// the block frequency of the block containing the defining or using
-// instruction, whichever is less. Our optimization is then a graph problem
-// to minimize the total weight of all the graphs, then transform instructions
-// and add or remove copy instructions as called for to implement the
-// solution.
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64RegisterInfo.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-simd-scalar"
-
-// Allow forcing all i64 operations with equivalent SIMD instructions to use
-// them. For stress-testing the transformation function.
-static cl::opt<bool>
-TransformAll("arm64-simd-scalar-force-all",
- cl::desc("Force use of AdvSIMD scalar instructions everywhere"),
- cl::init(false), cl::Hidden);
-
-STATISTIC(NumScalarInsnsUsed, "Number of scalar instructions used");
-STATISTIC(NumCopiesDeleted, "Number of cross-class copies deleted");
-STATISTIC(NumCopiesInserted, "Number of cross-class copies inserted");
-
-namespace {
-class ARM64AdvSIMDScalar : public MachineFunctionPass {
- MachineRegisterInfo *MRI;
- const ARM64InstrInfo *TII;
-
-private:
- // isProfitableToTransform - Predicate function to determine whether an
- // instruction should be transformed to its equivalent AdvSIMD scalar
- // instruction. "add Xd, Xn, Xm" ==> "add Dd, Da, Db", for example.
- bool isProfitableToTransform(const MachineInstr *MI) const;
-
- // transformInstruction - Perform the transformation of an instruction
- // to its equivalant AdvSIMD scalar instruction. Update inputs and outputs
- // to be the correct register class, minimizing cross-class copies.
- void transformInstruction(MachineInstr *MI);
-
- // processMachineBasicBlock - Main optimzation loop.
- bool processMachineBasicBlock(MachineBasicBlock *MBB);
-
-public:
- static char ID; // Pass identification, replacement for typeid.
- explicit ARM64AdvSIMDScalar() : MachineFunctionPass(ID) {}
-
- bool runOnMachineFunction(MachineFunction &F) override;
-
- const char *getPassName() const override {
- return "AdvSIMD Scalar Operation Optimization";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-char ARM64AdvSIMDScalar::ID = 0;
-} // end anonymous namespace
-
-static bool isGPR64(unsigned Reg, unsigned SubReg,
- const MachineRegisterInfo *MRI) {
- if (SubReg)
- return false;
- if (TargetRegisterInfo::isVirtualRegister(Reg))
- return MRI->getRegClass(Reg)->hasSuperClassEq(&ARM64::GPR64RegClass);
- return ARM64::GPR64RegClass.contains(Reg);
-}
-
-static bool isFPR64(unsigned Reg, unsigned SubReg,
- const MachineRegisterInfo *MRI) {
- if (TargetRegisterInfo::isVirtualRegister(Reg))
- return (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM64::FPR64RegClass) &&
- SubReg == 0) ||
- (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM64::FPR128RegClass) &&
- SubReg == ARM64::dsub);
- // Physical register references just check the register class directly.
- return (ARM64::FPR64RegClass.contains(Reg) && SubReg == 0) ||
- (ARM64::FPR128RegClass.contains(Reg) && SubReg == ARM64::dsub);
-}
-
-// getSrcFromCopy - Get the original source register for a GPR64 <--> FPR64
-// copy instruction. Return zero_reg if the instruction is not a copy.
-static unsigned getSrcFromCopy(const MachineInstr *MI,
- const MachineRegisterInfo *MRI,
- unsigned &SubReg) {
- SubReg = 0;
- // The "FMOV Xd, Dn" instruction is the typical form.
- if (MI->getOpcode() == ARM64::FMOVDXr || MI->getOpcode() == ARM64::FMOVXDr)
- return MI->getOperand(1).getReg();
- // A lane zero extract "UMOV.d Xd, Vn[0]" is equivalent. We shouldn't see
- // these at this stage, but it's easy to check for.
- if (MI->getOpcode() == ARM64::UMOVvi64 && MI->getOperand(2).getImm() == 0) {
- SubReg = ARM64::dsub;
- return MI->getOperand(1).getReg();
- }
- // Or just a plain COPY instruction. This can be directly to/from FPR64,
- // or it can be a dsub subreg reference to an FPR128.
- if (MI->getOpcode() == ARM64::COPY) {
- if (isFPR64(MI->getOperand(0).getReg(), MI->getOperand(0).getSubReg(),
- MRI) &&
- isGPR64(MI->getOperand(1).getReg(), MI->getOperand(1).getSubReg(), MRI))
- return MI->getOperand(1).getReg();
- if (isGPR64(MI->getOperand(0).getReg(), MI->getOperand(0).getSubReg(),
- MRI) &&
- isFPR64(MI->getOperand(1).getReg(), MI->getOperand(1).getSubReg(),
- MRI)) {
- SubReg = MI->getOperand(1).getSubReg();
- return MI->getOperand(1).getReg();
- }
- }
-
- // Otherwise, this is some other kind of instruction.
- return 0;
-}
-
-// getTransformOpcode - For any opcode for which there is an AdvSIMD equivalent
-// that we're considering transforming to, return that AdvSIMD opcode. For all
-// others, return the original opcode.
-static int getTransformOpcode(unsigned Opc) {
- switch (Opc) {
- default:
- break;
- // FIXME: Lots more possibilities.
- case ARM64::ADDXrr:
- return ARM64::ADDv1i64;
- case ARM64::SUBXrr:
- return ARM64::SUBv1i64;
- }
- // No AdvSIMD equivalent, so just return the original opcode.
- return Opc;
-}
-
-static bool isTransformable(const MachineInstr *MI) {
- int Opc = MI->getOpcode();
- return Opc != getTransformOpcode(Opc);
-}
-
-// isProfitableToTransform - Predicate function to determine whether an
-// instruction should be transformed to its equivalent AdvSIMD scalar
-// instruction. "add Xd, Xn, Xm" ==> "add Dd, Da, Db", for example.
-bool ARM64AdvSIMDScalar::isProfitableToTransform(const MachineInstr *MI) const {
- // If this instruction isn't eligible to be transformed (no SIMD equivalent),
- // early exit since that's the common case.
- if (!isTransformable(MI))
- return false;
-
- // Count the number of copies we'll need to add and approximate the number
- // of copies that a transform will enable us to remove.
- unsigned NumNewCopies = 3;
- unsigned NumRemovableCopies = 0;
-
- unsigned OrigSrc0 = MI->getOperand(1).getReg();
- unsigned OrigSrc1 = MI->getOperand(2).getReg();
- unsigned Src0 = 0, SubReg0;
- unsigned Src1 = 0, SubReg1;
- if (!MRI->def_empty(OrigSrc0)) {
- MachineRegisterInfo::def_instr_iterator Def =
- MRI->def_instr_begin(OrigSrc0);
- assert(std::next(Def) == MRI->def_instr_end() && "Multiple def in SSA!");
- Src0 = getSrcFromCopy(&*Def, MRI, SubReg0);
- // If the source was from a copy, we don't need to insert a new copy.
- if (Src0)
- --NumNewCopies;
- // If there are no other users of the original source, we can delete
- // that instruction.
- if (Src0 && MRI->hasOneNonDBGUse(OrigSrc0))
- ++NumRemovableCopies;
- }
- if (!MRI->def_empty(OrigSrc1)) {
- MachineRegisterInfo::def_instr_iterator Def =
- MRI->def_instr_begin(OrigSrc1);
- assert(std::next(Def) == MRI->def_instr_end() && "Multiple def in SSA!");
- Src1 = getSrcFromCopy(&*Def, MRI, SubReg1);
- if (Src1)
- --NumNewCopies;
- // If there are no other users of the original source, we can delete
- // that instruction.
- if (Src1 && MRI->hasOneNonDBGUse(OrigSrc1))
- ++NumRemovableCopies;
- }
-
- // If any of the uses of the original instructions is a cross class copy,
- // that's a copy that will be removable if we transform. Likewise, if
- // any of the uses is a transformable instruction, it's likely the tranforms
- // will chain, enabling us to save a copy there, too. This is an aggressive
- // heuristic that approximates the graph based cost analysis described above.
- unsigned Dst = MI->getOperand(0).getReg();
- bool AllUsesAreCopies = true;
- for (MachineRegisterInfo::use_instr_nodbg_iterator
- Use = MRI->use_instr_nodbg_begin(Dst),
- E = MRI->use_instr_nodbg_end();
- Use != E; ++Use) {
- unsigned SubReg;
- if (getSrcFromCopy(&*Use, MRI, SubReg) || isTransformable(&*Use))
- ++NumRemovableCopies;
- // If the use is an INSERT_SUBREG, that's still something that can
- // directly use the FPR64, so we don't invalidate AllUsesAreCopies. It's
- // preferable to have it use the FPR64 in most cases, as if the source
- // vector is an IMPLICIT_DEF, the INSERT_SUBREG just goes away entirely.
- // Ditto for a lane insert.
- else if (Use->getOpcode() == ARM64::INSERT_SUBREG ||
- Use->getOpcode() == ARM64::INSvi64gpr)
- ;
- else
- AllUsesAreCopies = false;
- }
- // If all of the uses of the original destination register are copies to
- // FPR64, then we won't end up having a new copy back to GPR64 either.
- if (AllUsesAreCopies)
- --NumNewCopies;
-
- // If a transform will not increase the number of cross-class copies required,
- // return true.
- if (NumNewCopies <= NumRemovableCopies)
- return true;
-
- // Finally, even if we otherwise wouldn't transform, check if we're forcing
- // transformation of everything.
- return TransformAll;
-}
-
-static MachineInstr *insertCopy(const ARM64InstrInfo *TII, MachineInstr *MI,
- unsigned Dst, unsigned Src, bool IsKill) {
- MachineInstrBuilder MIB =
- BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(ARM64::COPY),
- Dst)
- .addReg(Src, getKillRegState(IsKill));
- DEBUG(dbgs() << " adding copy: " << *MIB);
- ++NumCopiesInserted;
- return MIB;
-}
-
-// transformInstruction - Perform the transformation of an instruction
-// to its equivalant AdvSIMD scalar instruction. Update inputs and outputs
-// to be the correct register class, minimizing cross-class copies.
-void ARM64AdvSIMDScalar::transformInstruction(MachineInstr *MI) {
- DEBUG(dbgs() << "Scalar transform: " << *MI);
-
- MachineBasicBlock *MBB = MI->getParent();
- int OldOpc = MI->getOpcode();
- int NewOpc = getTransformOpcode(OldOpc);
- assert(OldOpc != NewOpc && "transform an instruction to itself?!");
-
- // Check if we need a copy for the source registers.
- unsigned OrigSrc0 = MI->getOperand(1).getReg();
- unsigned OrigSrc1 = MI->getOperand(2).getReg();
- unsigned Src0 = 0, SubReg0;
- unsigned Src1 = 0, SubReg1;
- if (!MRI->def_empty(OrigSrc0)) {
- MachineRegisterInfo::def_instr_iterator Def =
- MRI->def_instr_begin(OrigSrc0);
- assert(std::next(Def) == MRI->def_instr_end() && "Multiple def in SSA!");
- Src0 = getSrcFromCopy(&*Def, MRI, SubReg0);
- // If there are no other users of the original source, we can delete
- // that instruction.
- if (Src0 && MRI->hasOneNonDBGUse(OrigSrc0)) {
- assert(Src0 && "Can't delete copy w/o a valid original source!");
- Def->eraseFromParent();
- ++NumCopiesDeleted;
- }
- }
- if (!MRI->def_empty(OrigSrc1)) {
- MachineRegisterInfo::def_instr_iterator Def =
- MRI->def_instr_begin(OrigSrc1);
- assert(std::next(Def) == MRI->def_instr_end() && "Multiple def in SSA!");
- Src1 = getSrcFromCopy(&*Def, MRI, SubReg1);
- // If there are no other users of the original source, we can delete
- // that instruction.
- if (Src1 && MRI->hasOneNonDBGUse(OrigSrc1)) {
- assert(Src1 && "Can't delete copy w/o a valid original source!");
- Def->eraseFromParent();
- ++NumCopiesDeleted;
- }
- }
- // If we weren't able to reference the original source directly, create a
- // copy.
- if (!Src0) {
- SubReg0 = 0;
- Src0 = MRI->createVirtualRegister(&ARM64::FPR64RegClass);
- insertCopy(TII, MI, Src0, OrigSrc0, true);
- }
- if (!Src1) {
- SubReg1 = 0;
- Src1 = MRI->createVirtualRegister(&ARM64::FPR64RegClass);
- insertCopy(TII, MI, Src1, OrigSrc1, true);
- }
-
- // Create a vreg for the destination.
- // FIXME: No need to do this if the ultimate user expects an FPR64.
- // Check for that and avoid the copy if possible.
- unsigned Dst = MRI->createVirtualRegister(&ARM64::FPR64RegClass);
-
- // For now, all of the new instructions have the same simple three-register
- // form, so no need to special case based on what instruction we're
- // building.
- BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(NewOpc), Dst)
- .addReg(Src0, getKillRegState(true), SubReg0)
- .addReg(Src1, getKillRegState(true), SubReg1);
-
- // Now copy the result back out to a GPR.
- // FIXME: Try to avoid this if all uses could actually just use the FPR64
- // directly.
- insertCopy(TII, MI, MI->getOperand(0).getReg(), Dst, true);
-
- // Erase the old instruction.
- MI->eraseFromParent();
-
- ++NumScalarInsnsUsed;
-}
-
-// processMachineBasicBlock - Main optimzation loop.
-bool ARM64AdvSIMDScalar::processMachineBasicBlock(MachineBasicBlock *MBB) {
- bool Changed = false;
- for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) {
- MachineInstr *MI = I;
- ++I;
- if (isProfitableToTransform(MI)) {
- transformInstruction(MI);
- Changed = true;
- }
- }
- return Changed;
-}
-
-// runOnMachineFunction - Pass entry point from PassManager.
-bool ARM64AdvSIMDScalar::runOnMachineFunction(MachineFunction &mf) {
- bool Changed = false;
- DEBUG(dbgs() << "***** ARM64AdvSIMDScalar *****\n");
-
- const TargetMachine &TM = mf.getTarget();
- MRI = &mf.getRegInfo();
- TII = static_cast<const ARM64InstrInfo *>(TM.getInstrInfo());
-
- // Just check things on a one-block-at-a-time basis.
- for (MachineFunction::iterator I = mf.begin(), E = mf.end(); I != E; ++I)
- if (processMachineBasicBlock(I))
- Changed = true;
- return Changed;
-}
-
-// createARM64AdvSIMDScalar - Factory function used by ARM64TargetMachine
-// to add the pass to the PassManager.
-FunctionPass *llvm::createARM64AdvSIMDScalar() {
- return new ARM64AdvSIMDScalar();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64AsmPrinter.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64AsmPrinter.cpp (removed)
@@ -1,514 +0,0 @@
-//===-- ARM64AsmPrinter.cpp - ARM64 LLVM assembly writer ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a printer that converts from our internal representation
-// of machine-dependent LLVM code to the ARM64 assembly language.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64MachineFunctionInfo.h"
-#include "ARM64MCInstLower.h"
-#include "ARM64RegisterInfo.h"
-#include "ARM64Subtarget.h"
-#include "InstPrinter/ARM64InstPrinter.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/StackMaps.h"
-#include "llvm/CodeGen/MachineModuleInfoImpls.h"
-#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstBuilder.h"
-#include "llvm/MC/MCLinkerOptimizationHint.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/TargetRegistry.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "asm-printer"
-
-namespace {
-
-class ARM64AsmPrinter : public AsmPrinter {
- /// Subtarget - Keep a pointer to the ARM64Subtarget around so that we can
- /// make the right decision when printing asm code for different targets.
- const ARM64Subtarget *Subtarget;
-
- ARM64MCInstLower MCInstLowering;
- StackMaps SM;
-
-public:
- ARM64AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
- : AsmPrinter(TM, Streamer), Subtarget(&TM.getSubtarget<ARM64Subtarget>()),
- MCInstLowering(OutContext, *Mang, *this), SM(*this), ARM64FI(nullptr),
- LOHLabelCounter(0) {}
-
- const char *getPassName() const override { return "ARM64 Assembly Printer"; }
-
- /// \brief Wrapper for MCInstLowering.lowerOperand() for the
- /// tblgen'erated pseudo lowering.
- bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
- return MCInstLowering.lowerOperand(MO, MCOp);
- }
-
- void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI);
- void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI);
- /// \brief tblgen'erated driver function for lowering simple MI->MC
- /// pseudo instructions.
- bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
- const MachineInstr *MI);
-
- void EmitInstruction(const MachineInstr *MI) override;
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AsmPrinter::getAnalysisUsage(AU);
- AU.setPreservesAll();
- }
-
- bool runOnMachineFunction(MachineFunction &F) override {
- ARM64FI = F.getInfo<ARM64FunctionInfo>();
- return AsmPrinter::runOnMachineFunction(F);
- }
-
-private:
- MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
- void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O);
- bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
- bool printAsmRegInClass(const MachineOperand &MO,
- const TargetRegisterClass *RC, bool isVector,
- raw_ostream &O);
-
- bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &O) override;
- bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &O) override;
-
- void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
-
- void EmitFunctionBodyEnd() override;
-
- MCSymbol *GetCPISymbol(unsigned CPID) const override;
- void EmitEndOfAsmFile(Module &M) override;
- ARM64FunctionInfo *ARM64FI;
-
- /// \brief Emit the LOHs contained in ARM64FI.
- void EmitLOHs();
-
- typedef std::map<const MachineInstr *, MCSymbol *> MInstToMCSymbol;
- MInstToMCSymbol LOHInstToLabel;
- unsigned LOHLabelCounter;
-};
-
-} // end of anonymous namespace
-
-//===----------------------------------------------------------------------===//
-
-void ARM64AsmPrinter::EmitEndOfAsmFile(Module &M) {
- if (Subtarget->isTargetMachO()) {
- // Funny Darwin hack: This flag tells the linker that no global symbols
- // contain code that falls through to other global symbols (e.g. the obvious
- // implementation of multiple entry points). If this doesn't occur, the
- // linker can safely perform dead code stripping. Since LLVM never
- // generates code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
- SM.serializeToStackMapSection();
- }
-
- // Emit a .data.rel section containing any stubs that were created.
- if (Subtarget->isTargetELF()) {
- const TargetLoweringObjectFileELF &TLOFELF =
- static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
-
- MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
-
- // Output stubs for external and common global variables.
- MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
- if (!Stubs.empty()) {
- OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
- const DataLayout *TD = TM.getDataLayout();
-
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- OutStreamer.EmitLabel(Stubs[i].first);
- OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
- TD->getPointerSize(0));
- }
- Stubs.clear();
- }
- }
-
-}
-
-MachineLocation
-ARM64AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
- MachineLocation Location;
- assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
- // Frame address. Currently handles register +- offset only.
- if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
- Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
- else {
- DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
- }
- return Location;
-}
-
-void ARM64AsmPrinter::EmitLOHs() {
- SmallVector<MCSymbol *, 3> MCArgs;
-
- for (const auto &D : ARM64FI->getLOHContainer()) {
- for (const MachineInstr *MI : D.getArgs()) {
- MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(MI);
- assert(LabelIt != LOHInstToLabel.end() &&
- "Label hasn't been inserted for LOH related instruction");
- MCArgs.push_back(LabelIt->second);
- }
- OutStreamer.EmitLOHDirective(D.getKind(), MCArgs);
- MCArgs.clear();
- }
-}
-
-void ARM64AsmPrinter::EmitFunctionBodyEnd() {
- if (!ARM64FI->getLOHRelated().empty())
- EmitLOHs();
-}
-
-/// GetCPISymbol - Return the symbol for the specified constant pool entry.
-MCSymbol *ARM64AsmPrinter::GetCPISymbol(unsigned CPID) const {
- // Darwin uses a linker-private symbol name for constant-pools (to
- // avoid addends on the relocation?), ELF has no such concept and
- // uses a normal private symbol.
- if (getDataLayout().getLinkerPrivateGlobalPrefix()[0])
- return OutContext.GetOrCreateSymbol(
- Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) + "CPI" +
- Twine(getFunctionNumber()) + "_" + Twine(CPID));
-
- return OutContext.GetOrCreateSymbol(
- Twine(getDataLayout().getPrivateGlobalPrefix()) + "CPI" +
- Twine(getFunctionNumber()) + "_" + Twine(CPID));
-}
-
-void ARM64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum,
- raw_ostream &O) {
- const MachineOperand &MO = MI->getOperand(OpNum);
- switch (MO.getType()) {
- default:
- assert(0 && "<unknown operand type>");
- case MachineOperand::MO_Register: {
- unsigned Reg = MO.getReg();
- assert(TargetRegisterInfo::isPhysicalRegister(Reg));
- assert(!MO.getSubReg() && "Subregs should be eliminated!");
- O << ARM64InstPrinter::getRegisterName(Reg);
- break;
- }
- case MachineOperand::MO_Immediate: {
- int64_t Imm = MO.getImm();
- O << '#' << Imm;
- break;
- }
- }
-}
-
-bool ARM64AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
- raw_ostream &O) {
- unsigned Reg = MO.getReg();
- switch (Mode) {
- default:
- return true; // Unknown mode.
- case 'w':
- Reg = getWRegFromXReg(Reg);
- break;
- case 'x':
- Reg = getXRegFromWReg(Reg);
- break;
- }
-
- O << ARM64InstPrinter::getRegisterName(Reg);
- return false;
-}
-
-// Prints the register in MO using class RC using the offset in the
-// new register class. This should not be used for cross class
-// printing.
-bool ARM64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
- const TargetRegisterClass *RC,
- bool isVector, raw_ostream &O) {
- assert(MO.isReg() && "Should only get here with a register!");
- const ARM64RegisterInfo *RI =
- static_cast<const ARM64RegisterInfo *>(TM.getRegisterInfo());
- unsigned Reg = MO.getReg();
- unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
- assert(RI->regsOverlap(RegToPrint, Reg));
- O << ARM64InstPrinter::getRegisterName(
- RegToPrint, isVector ? ARM64::vreg : ARM64::NoRegAltName);
- return false;
-}
-
-bool ARM64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant,
- const char *ExtraCode, raw_ostream &O) {
- const MachineOperand &MO = MI->getOperand(OpNum);
- // Does this asm operand have a single letter operand modifier?
- if (ExtraCode && ExtraCode[0]) {
- if (ExtraCode[1] != 0)
- return true; // Unknown modifier.
-
- switch (ExtraCode[0]) {
- default:
- return true; // Unknown modifier.
- case 'w': // Print W register
- case 'x': // Print X register
- if (MO.isReg())
- return printAsmMRegister(MO, ExtraCode[0], O);
- if (MO.isImm() && MO.getImm() == 0) {
- unsigned Reg = ExtraCode[0] == 'w' ? ARM64::WZR : ARM64::XZR;
- O << ARM64InstPrinter::getRegisterName(Reg);
- return false;
- }
- printOperand(MI, OpNum, O);
- return false;
- case 'b': // Print B register.
- case 'h': // Print H register.
- case 's': // Print S register.
- case 'd': // Print D register.
- case 'q': // Print Q register.
- if (MO.isReg()) {
- const TargetRegisterClass *RC;
- switch (ExtraCode[0]) {
- case 'b':
- RC = &ARM64::FPR8RegClass;
- break;
- case 'h':
- RC = &ARM64::FPR16RegClass;
- break;
- case 's':
- RC = &ARM64::FPR32RegClass;
- break;
- case 'd':
- RC = &ARM64::FPR64RegClass;
- break;
- case 'q':
- RC = &ARM64::FPR128RegClass;
- break;
- default:
- return true;
- }
- return printAsmRegInClass(MO, RC, false /* vector */, O);
- }
- printOperand(MI, OpNum, O);
- return false;
- }
- }
-
- // According to ARM, we should emit x and v registers unless we have a
- // modifier.
- if (MO.isReg()) {
- unsigned Reg = MO.getReg();
-
- // If this is a w or x register, print an x register.
- if (ARM64::GPR32allRegClass.contains(Reg) ||
- ARM64::GPR64allRegClass.contains(Reg))
- return printAsmMRegister(MO, 'x', O);
-
- // If this is a b, h, s, d, or q register, print it as a v register.
- return printAsmRegInClass(MO, &ARM64::FPR128RegClass, true /* vector */, O);
- }
-
- printOperand(MI, OpNum, O);
- return false;
-}
-
-bool ARM64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
- unsigned OpNum, unsigned AsmVariant,
- const char *ExtraCode,
- raw_ostream &O) {
- if (ExtraCode && ExtraCode[0])
- return true; // Unknown modifier.
-
- const MachineOperand &MO = MI->getOperand(OpNum);
- assert(MO.isReg() && "unexpected inline asm memory operand");
- O << "[" << ARM64InstPrinter::getRegisterName(MO.getReg()) << "]";
- return false;
-}
-
-void ARM64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
- raw_ostream &OS) {
- unsigned NOps = MI->getNumOperands();
- assert(NOps == 4);
- OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
- // cast away const; DIetc do not take const operands for some reason.
- DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps - 1).getMetadata()));
- OS << V.getName();
- OS << " <- ";
- // Frame address. Currently handles register +- offset only.
- assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
- OS << '[';
- printOperand(MI, 0, OS);
- OS << '+';
- printOperand(MI, 1, OS);
- OS << ']';
- OS << "+";
- printOperand(MI, NOps - 2, OS);
-}
-
-void ARM64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI) {
- unsigned NumNOPBytes = MI.getOperand(1).getImm();
-
- SM.recordStackMap(MI);
- // Emit padding.
- assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
- for (unsigned i = 0; i < NumNOPBytes; i += 4)
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::HINT).addImm(0));
-}
-
-// Lower a patchpoint of the form:
-// [<def>], <id>, <numBytes>, <target>, <numArgs>
-void ARM64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
- const MachineInstr &MI) {
- SM.recordPatchPoint(MI);
-
- PatchPointOpers Opers(&MI);
-
- int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
- unsigned EncodedBytes = 0;
- if (CallTarget) {
- assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
- "High 16 bits of call target should be zero.");
- unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
- EncodedBytes = 16;
- // Materialize the jump address:
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::MOVZWi)
- .addReg(ScratchReg)
- .addImm((CallTarget >> 32) & 0xFFFF)
- .addImm(32));
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::MOVKWi)
- .addReg(ScratchReg)
- .addReg(ScratchReg)
- .addImm((CallTarget >> 16) & 0xFFFF)
- .addImm(16));
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::MOVKWi)
- .addReg(ScratchReg)
- .addReg(ScratchReg)
- .addImm(CallTarget & 0xFFFF)
- .addImm(0));
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::BLR).addReg(ScratchReg));
- }
- // Emit padding.
- unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
- assert(NumBytes >= EncodedBytes &&
- "Patchpoint can't request size less than the length of a call.");
- assert((NumBytes - EncodedBytes) % 4 == 0 &&
- "Invalid number of NOP bytes requested!");
- for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
- EmitToStreamer(OutStreamer, MCInstBuilder(ARM64::HINT).addImm(0));
-}
-
-// Simple pseudo-instructions have their lowering (with expansion to real
-// instructions) auto-generated.
-#include "ARM64GenMCPseudoLowering.inc"
-
-void ARM64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
- // Do any auto-generated pseudo lowerings.
- if (emitPseudoExpansionLowering(OutStreamer, MI))
- return;
-
- if (ARM64FI->getLOHRelated().count(MI)) {
- // Generate a label for LOH related instruction
- MCSymbol *LOHLabel = GetTempSymbol("loh", LOHLabelCounter++);
- // Associate the instruction with the label
- LOHInstToLabel[MI] = LOHLabel;
- OutStreamer.EmitLabel(LOHLabel);
- }
-
- // Do any manual lowerings.
- switch (MI->getOpcode()) {
- default:
- break;
- case ARM64::DBG_VALUE: {
- if (isVerbose() && OutStreamer.hasRawTextSupport()) {
- SmallString<128> TmpStr;
- raw_svector_ostream OS(TmpStr);
- PrintDebugValueComment(MI, OS);
- OutStreamer.EmitRawText(StringRef(OS.str()));
- }
- return;
- }
-
- // Tail calls use pseudo instructions so they have the proper code-gen
- // attributes (isCall, isReturn, etc.). We lower them to the real
- // instruction here.
- case ARM64::TCRETURNri: {
- MCInst TmpInst;
- TmpInst.setOpcode(ARM64::BR);
- TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
- EmitToStreamer(OutStreamer, TmpInst);
- return;
- }
- case ARM64::TCRETURNdi: {
- MCOperand Dest;
- MCInstLowering.lowerOperand(MI->getOperand(0), Dest);
- MCInst TmpInst;
- TmpInst.setOpcode(ARM64::B);
- TmpInst.addOperand(Dest);
- EmitToStreamer(OutStreamer, TmpInst);
- return;
- }
- case ARM64::TLSDESC_BLR: {
- MCOperand Callee, Sym;
- MCInstLowering.lowerOperand(MI->getOperand(0), Callee);
- MCInstLowering.lowerOperand(MI->getOperand(1), Sym);
-
- // First emit a relocation-annotation. This expands to no code, but requests
- // the following instruction gets an R_AARCH64_TLSDESC_CALL.
- MCInst TLSDescCall;
- TLSDescCall.setOpcode(ARM64::TLSDESCCALL);
- TLSDescCall.addOperand(Sym);
- EmitToStreamer(OutStreamer, TLSDescCall);
-
- // Other than that it's just a normal indirect call to the function loaded
- // from the descriptor.
- MCInst BLR;
- BLR.setOpcode(ARM64::BLR);
- BLR.addOperand(Callee);
- EmitToStreamer(OutStreamer, BLR);
-
- return;
- }
-
- case TargetOpcode::STACKMAP:
- return LowerSTACKMAP(OutStreamer, SM, *MI);
-
- case TargetOpcode::PATCHPOINT:
- return LowerPATCHPOINT(OutStreamer, SM, *MI);
- }
-
- // Finally, do the automated lowerings for everything else.
- MCInst TmpInst;
- MCInstLowering.Lower(MI, TmpInst);
- EmitToStreamer(OutStreamer, TmpInst);
-}
-
-// Force static initialization.
-extern "C" void LLVMInitializeARM64AsmPrinter() {
- RegisterAsmPrinter<ARM64AsmPrinter> X(TheARM64leTarget);
- RegisterAsmPrinter<ARM64AsmPrinter> Y(TheARM64beTarget);
-
- RegisterAsmPrinter<ARM64AsmPrinter> Z(TheAArch64leTarget);
- RegisterAsmPrinter<ARM64AsmPrinter> W(TheAArch64beTarget);
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64BranchRelaxation.cpp (removed)
@@ -1,509 +0,0 @@
-//===-- ARM64BranchRelaxation.cpp - ARM64 branch relaxation ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64MachineFunctionInfo.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-branch-relax"
-
-static cl::opt<bool>
-BranchRelaxation("arm64-branch-relax", cl::Hidden, cl::init(true),
- cl::desc("Relax out of range conditional branches"));
-
-static cl::opt<unsigned>
-TBZDisplacementBits("arm64-tbz-offset-bits", cl::Hidden, cl::init(14),
- cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"));
-
-static cl::opt<unsigned>
-CBZDisplacementBits("arm64-cbz-offset-bits", cl::Hidden, cl::init(19),
- cl::desc("Restrict range of CB[N]Z instructions (DEBUG)"));
-
-static cl::opt<unsigned>
-BCCDisplacementBits("arm64-bcc-offset-bits", cl::Hidden, cl::init(19),
- cl::desc("Restrict range of Bcc instructions (DEBUG)"));
-
-STATISTIC(NumSplit, "Number of basic blocks split");
-STATISTIC(NumRelaxed, "Number of conditional branches relaxed");
-
-namespace {
-class ARM64BranchRelaxation : public MachineFunctionPass {
- /// BasicBlockInfo - Information about the offset and size of a single
- /// basic block.
- struct BasicBlockInfo {
- /// Offset - Distance from the beginning of the function to the beginning
- /// of this basic block.
- ///
- /// The offset is always aligned as required by the basic block.
- unsigned Offset;
-
- /// Size - Size of the basic block in bytes. If the block contains
- /// inline assembly, this is a worst case estimate.
- ///
- /// The size does not include any alignment padding whether from the
- /// beginning of the block, or from an aligned jump table at the end.
- unsigned Size;
-
- BasicBlockInfo() : Offset(0), Size(0) {}
-
- /// Compute the offset immediately following this block. If LogAlign is
- /// specified, return the offset the successor block will get if it has
- /// this alignment.
- unsigned postOffset(unsigned LogAlign = 0) const {
- unsigned PO = Offset + Size;
- unsigned Align = 1 << LogAlign;
- return (PO + Align - 1) / Align * Align;
- }
- };
-
- SmallVector<BasicBlockInfo, 16> BlockInfo;
-
- MachineFunction *MF;
- const ARM64InstrInfo *TII;
-
- bool relaxBranchInstructions();
- void scanFunction();
- MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI);
- void adjustBlockOffsets(MachineBasicBlock &MBB);
- bool isBlockInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
- bool fixupConditionalBranch(MachineInstr *MI);
- void computeBlockSize(const MachineBasicBlock &MBB);
- unsigned getInstrOffset(MachineInstr *MI) const;
- void dumpBBs();
- void verify();
-
-public:
- static char ID;
- ARM64BranchRelaxation() : MachineFunctionPass(ID) {}
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- const char *getPassName() const override {
- return "ARM64 branch relaxation pass";
- }
-};
-char ARM64BranchRelaxation::ID = 0;
-}
-
-/// verify - check BBOffsets, BBSizes, alignment of islands
-void ARM64BranchRelaxation::verify() {
-#ifndef NDEBUG
- unsigned PrevNum = MF->begin()->getNumber();
- for (MachineBasicBlock &MBB : *MF) {
- unsigned Align = MBB.getAlignment();
- unsigned Num = MBB.getNumber();
- assert(BlockInfo[Num].Offset % (1u << Align) == 0);
- assert(!Num || BlockInfo[PrevNum].postOffset() <= BlockInfo[Num].Offset);
- PrevNum = Num;
- }
-#endif
-}
-
-/// print block size and offset information - debugging
-void ARM64BranchRelaxation::dumpBBs() {
- for (auto &MBB : *MF) {
- const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
- dbgs() << format("BB#%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset)
- << format("size=%#x\n", BBI.Size);
- }
-}
-
-/// BBHasFallthrough - Return true if the specified basic block can fallthrough
-/// into the block immediately after it.
-static bool BBHasFallthrough(MachineBasicBlock *MBB) {
- // Get the next machine basic block in the function.
- MachineFunction::iterator MBBI = MBB;
- // Can't fall off end of function.
- MachineBasicBlock *NextBB = std::next(MBBI);
- if (NextBB == MBB->getParent()->end())
- return false;
-
- for (MachineBasicBlock *S : MBB->successors())
- if (S == NextBB)
- return true;
-
- return false;
-}
-
-/// scanFunction - Do the initial scan of the function, building up
-/// information about each block.
-void ARM64BranchRelaxation::scanFunction() {
- BlockInfo.clear();
- BlockInfo.resize(MF->getNumBlockIDs());
-
- // First thing, compute the size of all basic blocks, and see if the function
- // has any inline assembly in it. If so, we have to be conservative about
- // alignment assumptions, as we don't know for sure the size of any
- // instructions in the inline assembly.
- for (MachineBasicBlock &MBB : *MF)
- computeBlockSize(MBB);
-
- // Compute block offsets and known bits.
- adjustBlockOffsets(*MF->begin());
-}
-
-/// computeBlockSize - Compute the size for MBB.
-/// This function updates BlockInfo directly.
-void ARM64BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) {
- unsigned Size = 0;
- for (const MachineInstr &MI : MBB)
- Size += TII->GetInstSizeInBytes(&MI);
- BlockInfo[MBB.getNumber()].Size = Size;
-}
-
-/// getInstrOffset - Return the current offset of the specified machine
-/// instruction from the start of the function. This offset changes as stuff is
-/// moved around inside the function.
-unsigned ARM64BranchRelaxation::getInstrOffset(MachineInstr *MI) const {
- MachineBasicBlock *MBB = MI->getParent();
-
- // The offset is composed of two things: the sum of the sizes of all MBB's
- // before this instruction's block, and the offset from the start of the block
- // it is in.
- unsigned Offset = BlockInfo[MBB->getNumber()].Offset;
-
- // Sum instructions before MI in MBB.
- for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
- assert(I != MBB->end() && "Didn't find MI in its own basic block?");
- Offset += TII->GetInstSizeInBytes(I);
- }
- return Offset;
-}
-
-void ARM64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
- unsigned PrevNum = Start.getNumber();
- for (auto &MBB : make_range(MachineFunction::iterator(Start), MF->end())) {
- unsigned Num = MBB.getNumber();
- if (!Num) // block zero is never changed from offset zero.
- continue;
- // Get the offset and known bits at the end of the layout predecessor.
- // Include the alignment of the current block.
- unsigned LogAlign = MBB.getAlignment();
- BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(LogAlign);
- PrevNum = Num;
- }
-}
-
-/// Split the basic block containing MI into two blocks, which are joined by
-/// an unconditional branch. Update data structures and renumber blocks to
-/// account for this change and returns the newly created block.
-/// NOTE: Successor list of the original BB is out of date after this function,
-/// and must be updated by the caller! Other transforms follow using this
-/// utility function, so no point updating now rather than waiting.
-MachineBasicBlock *
-ARM64BranchRelaxation::splitBlockBeforeInstr(MachineInstr *MI) {
- MachineBasicBlock *OrigBB = MI->getParent();
-
- // Create a new MBB for the code after the OrigBB.
- MachineBasicBlock *NewBB =
- MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
- MachineFunction::iterator MBBI = OrigBB;
- ++MBBI;
- MF->insert(MBBI, NewBB);
-
- // Splice the instructions starting with MI over to NewBB.
- NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
-
- // Add an unconditional branch from OrigBB to NewBB.
- // Note the new unconditional branch is not being recorded.
- // There doesn't seem to be meaningful DebugInfo available; this doesn't
- // correspond to anything in the source.
- BuildMI(OrigBB, DebugLoc(), TII->get(ARM64::B)).addMBB(NewBB);
-
- // Insert an entry into BlockInfo to align it properly with the block numbers.
- BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
-
- // Figure out how large the OrigBB is. As the first half of the original
- // block, it cannot contain a tablejump. The size includes
- // the new jump we added. (It should be possible to do this without
- // recounting everything, but it's very confusing, and this is rarely
- // executed.)
- computeBlockSize(*OrigBB);
-
- // Figure out how large the NewMBB is. As the second half of the original
- // block, it may contain a tablejump.
- computeBlockSize(*NewBB);
-
- // All BBOffsets following these blocks must be modified.
- adjustBlockOffsets(*OrigBB);
-
- ++NumSplit;
-
- return NewBB;
-}
-
-/// isBlockInRange - Returns true if the distance between specific MI and
-/// specific BB can fit in MI's displacement field.
-bool ARM64BranchRelaxation::isBlockInRange(MachineInstr *MI,
- MachineBasicBlock *DestBB,
- unsigned Bits) {
- unsigned MaxOffs = ((1 << (Bits - 1)) - 1) << 2;
- unsigned BrOffset = getInstrOffset(MI);
- unsigned DestOffset = BlockInfo[DestBB->getNumber()].Offset;
-
- DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()
- << " from BB#" << MI->getParent()->getNumber()
- << " max delta=" << MaxOffs << " from " << getInstrOffset(MI)
- << " to " << DestOffset << " offset "
- << int(DestOffset - BrOffset) << "\t" << *MI);
-
- // Branch before the Dest.
- if (BrOffset <= DestOffset)
- return (DestOffset - BrOffset <= MaxOffs);
- return (BrOffset - DestOffset <= MaxOffs);
-}
-
-static bool isConditionalBranch(unsigned Opc) {
- switch (Opc) {
- default:
- return false;
- case ARM64::TBZW:
- case ARM64::TBNZW:
- case ARM64::TBZX:
- case ARM64::TBNZX:
- case ARM64::CBZW:
- case ARM64::CBNZW:
- case ARM64::CBZX:
- case ARM64::CBNZX:
- case ARM64::Bcc:
- return true;
- }
-}
-
-static MachineBasicBlock *getDestBlock(MachineInstr *MI) {
- switch (MI->getOpcode()) {
- default:
- assert(0 && "unexpected opcode!");
- case ARM64::TBZW:
- case ARM64::TBNZW:
- case ARM64::TBZX:
- case ARM64::TBNZX:
- return MI->getOperand(2).getMBB();
- case ARM64::CBZW:
- case ARM64::CBNZW:
- case ARM64::CBZX:
- case ARM64::CBNZX:
- case ARM64::Bcc:
- return MI->getOperand(1).getMBB();
- }
-}
-
-static unsigned getOppositeConditionOpcode(unsigned Opc) {
- switch (Opc) {
- default:
- assert(0 && "unexpected opcode!");
- case ARM64::TBNZW: return ARM64::TBZW;
- case ARM64::TBNZX: return ARM64::TBZX;
- case ARM64::TBZW: return ARM64::TBNZW;
- case ARM64::TBZX: return ARM64::TBNZX;
- case ARM64::CBNZW: return ARM64::CBZW;
- case ARM64::CBNZX: return ARM64::CBZX;
- case ARM64::CBZW: return ARM64::CBNZW;
- case ARM64::CBZX: return ARM64::CBNZX;
- case ARM64::Bcc: return ARM64::Bcc; // Condition is an operand for Bcc.
- }
-}
-
-static unsigned getBranchDisplacementBits(unsigned Opc) {
- switch (Opc) {
- default:
- assert(0 && "unexpected opcode!");
- case ARM64::TBNZW:
- case ARM64::TBZW:
- case ARM64::TBNZX:
- case ARM64::TBZX:
- return TBZDisplacementBits;
- case ARM64::CBNZW:
- case ARM64::CBZW:
- case ARM64::CBNZX:
- case ARM64::CBZX:
- return CBZDisplacementBits;
- case ARM64::Bcc:
- return BCCDisplacementBits;
- }
-}
-
-static inline void invertBccCondition(MachineInstr *MI) {
- assert(MI->getOpcode() == ARM64::Bcc && "Unexpected opcode!");
- ARM64CC::CondCode CC = (ARM64CC::CondCode)MI->getOperand(0).getImm();
- CC = ARM64CC::getInvertedCondCode(CC);
- MI->getOperand(0).setImm((int64_t)CC);
-}
-
-/// fixupConditionalBranch - Fix up a conditional branch whose destination is
-/// too far away to fit in its displacement field. It is converted to an inverse
-/// conditional branch + an unconditional branch to the destination.
-bool ARM64BranchRelaxation::fixupConditionalBranch(MachineInstr *MI) {
- MachineBasicBlock *DestBB = getDestBlock(MI);
-
- // Add an unconditional branch to the destination and invert the branch
- // condition to jump over it:
- // tbz L1
- // =>
- // tbnz L2
- // b L1
- // L2:
-
- // If the branch is at the end of its MBB and that has a fall-through block,
- // direct the updated conditional branch to the fall-through block. Otherwise,
- // split the MBB before the next instruction.
- MachineBasicBlock *MBB = MI->getParent();
- MachineInstr *BMI = &MBB->back();
- bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
-
- if (BMI != MI) {
- if (std::next(MachineBasicBlock::iterator(MI)) ==
- std::prev(MBB->getLastNonDebugInstr()) &&
- BMI->getOpcode() == ARM64::B) {
- // Last MI in the BB is an unconditional branch. Can we simply invert the
- // condition and swap destinations:
- // beq L1
- // b L2
- // =>
- // bne L2
- // b L1
- MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB();
- if (isBlockInRange(MI, NewDest,
- getBranchDisplacementBits(MI->getOpcode()))) {
- DEBUG(dbgs() << " Invert condition and swap its destination with "
- << *BMI);
- BMI->getOperand(0).setMBB(DestBB);
- unsigned OpNum =
- (MI->getOpcode() == ARM64::TBZW || MI->getOpcode() == ARM64::TBNZW ||
- MI->getOpcode() == ARM64::TBZX || MI->getOpcode() == ARM64::TBNZX)
- ? 2
- : 1;
- MI->getOperand(OpNum).setMBB(NewDest);
- MI->setDesc(TII->get(getOppositeConditionOpcode(MI->getOpcode())));
- if (MI->getOpcode() == ARM64::Bcc)
- invertBccCondition(MI);
- return true;
- }
- }
- }
-
- if (NeedSplit) {
- // Analyze the branch so we know how to update the successor lists.
- MachineBasicBlock *TBB, *FBB;
- SmallVector<MachineOperand, 2> Cond;
- TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, false);
-
- MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI);
- // No need for the branch to the next block. We're adding an unconditional
- // branch to the destination.
- int delta = TII->GetInstSizeInBytes(&MBB->back());
- BlockInfo[MBB->getNumber()].Size -= delta;
- MBB->back().eraseFromParent();
- // BlockInfo[SplitBB].Offset is wrong temporarily, fixed below
-
- // Update the successor lists according to the transformation to follow.
- // Do it here since if there's no split, no update is needed.
- MBB->replaceSuccessor(FBB, NewBB);
- NewBB->addSuccessor(FBB);
- }
- MachineBasicBlock *NextBB = std::next(MachineFunction::iterator(MBB));
-
- DEBUG(dbgs() << " Insert B to BB#" << DestBB->getNumber()
- << ", invert condition and change dest. to BB#"
- << NextBB->getNumber() << "\n");
-
- // Insert a new conditional branch and a new unconditional branch.
- MachineInstrBuilder MIB = BuildMI(
- MBB, DebugLoc(), TII->get(getOppositeConditionOpcode(MI->getOpcode())))
- .addOperand(MI->getOperand(0));
- if (MI->getOpcode() == ARM64::TBZW || MI->getOpcode() == ARM64::TBNZW ||
- MI->getOpcode() == ARM64::TBZX || MI->getOpcode() == ARM64::TBNZX)
- MIB.addOperand(MI->getOperand(1));
- if (MI->getOpcode() == ARM64::Bcc)
- invertBccCondition(MIB);
- MIB.addMBB(NextBB);
- BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
- BuildMI(MBB, DebugLoc(), TII->get(ARM64::B)).addMBB(DestBB);
- BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
-
- // Remove the old conditional branch. It may or may not still be in MBB.
- BlockInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(MI);
- MI->eraseFromParent();
-
- // Finally, keep the block offsets up to date.
- adjustBlockOffsets(*MBB);
- return true;
-}
-
-bool ARM64BranchRelaxation::relaxBranchInstructions() {
- bool Changed = false;
- // Relaxing branches involves creating new basic blocks, so re-eval
- // end() for termination.
- for (auto &MBB : *MF) {
- MachineInstr *MI = MBB.getFirstTerminator();
- if (isConditionalBranch(MI->getOpcode()) &&
- !isBlockInRange(MI, getDestBlock(MI),
- getBranchDisplacementBits(MI->getOpcode()))) {
- fixupConditionalBranch(MI);
- ++NumRelaxed;
- Changed = true;
- }
- }
- return Changed;
-}
-
-bool ARM64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) {
- MF = &mf;
-
- // If the pass is disabled, just bail early.
- if (!BranchRelaxation)
- return false;
-
- DEBUG(dbgs() << "***** ARM64BranchRelaxation *****\n");
-
- TII = (const ARM64InstrInfo *)MF->getTarget().getInstrInfo();
-
- // Renumber all of the machine basic blocks in the function, guaranteeing that
- // the numbers agree with the position of the block in the function.
- MF->RenumberBlocks();
-
- // Do the initial scan of the function, building up information about the
- // sizes of each block.
- scanFunction();
-
- DEBUG(dbgs() << " Basic blocks before relaxation\n");
- DEBUG(dumpBBs());
-
- bool MadeChange = false;
- while (relaxBranchInstructions())
- MadeChange = true;
-
- // After a while, this might be made debug-only, but it is not expensive.
- verify();
-
- DEBUG(dbgs() << " Basic blocks after relaxation\n");
- DEBUG(dbgs() << '\n'; dumpBBs());
-
- BlockInfo.clear();
-
- return MadeChange;
-}
-
-/// createARM64BranchRelaxation - returns an instance of the constpool
-/// island pass.
-FunctionPass *llvm::createARM64BranchRelaxation() {
- return new ARM64BranchRelaxation();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64CallingConv.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64CallingConv.h?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64CallingConv.h (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64CallingConv.h (removed)
@@ -1,94 +0,0 @@
-//=== ARM64CallingConv.h - Custom Calling Convention Routines -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the custom routines for the ARM64 Calling Convention that
-// aren't done by tablegen.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ARM64CALLINGCONV_H
-#define ARM64CALLINGCONV_H
-
-#include "ARM64InstrInfo.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/CodeGen/CallingConvLower.h"
-#include "llvm/Target/TargetInstrInfo.h"
-
-namespace llvm {
-
-/// CC_ARM64_Custom_i1i8i16_Reg - customized handling of passing i1/i8/i16 via
-/// register. Here, ValVT can be i1/i8/i16 or i32 depending on whether the
-/// argument is already promoted and LocVT is i1/i8/i16. We only promote the
-/// argument to i32 if we are sure this argument will be passed in register.
-static bool CC_ARM64_Custom_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State,
- bool IsWebKitJS = false) {
- static const MCPhysReg RegList1[] = { ARM64::W0, ARM64::W1, ARM64::W2,
- ARM64::W3, ARM64::W4, ARM64::W5,
- ARM64::W6, ARM64::W7 };
- static const MCPhysReg RegList2[] = { ARM64::X0, ARM64::X1, ARM64::X2,
- ARM64::X3, ARM64::X4, ARM64::X5,
- ARM64::X6, ARM64::X7 };
- static const MCPhysReg WebKitRegList1[] = { ARM64::W0 };
- static const MCPhysReg WebKitRegList2[] = { ARM64::X0 };
-
- const MCPhysReg *List1 = IsWebKitJS ? WebKitRegList1 : RegList1;
- const MCPhysReg *List2 = IsWebKitJS ? WebKitRegList2 : RegList2;
-
- if (unsigned Reg = State.AllocateReg(List1, List2, 8)) {
- // Customized extra section for handling i1/i8/i16:
- // We need to promote the argument to i32 if it is not done already.
- if (ValVT != MVT::i32) {
- if (ArgFlags.isSExt())
- LocInfo = CCValAssign::SExt;
- else if (ArgFlags.isZExt())
- LocInfo = CCValAssign::ZExt;
- else
- LocInfo = CCValAssign::AExt;
- ValVT = MVT::i32;
- }
- // Set LocVT to i32 as well if passing via register.
- LocVT = MVT::i32;
- State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
- return true;
- }
- return false;
-}
-
-/// CC_ARM64_WebKit_JS_i1i8i16_Reg - customized handling of passing i1/i8/i16
-/// via register. This behaves the same as CC_ARM64_Custom_i1i8i16_Reg, but only
-/// uses the first register.
-static bool CC_ARM64_WebKit_JS_i1i8i16_Reg(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State) {
- return CC_ARM64_Custom_i1i8i16_Reg(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
- State, true);
-}
-
-/// CC_ARM64_Custom_i1i8i16_Stack: customized handling of passing i1/i8/i16 on
-/// stack. Here, ValVT can be i1/i8/i16 or i32 depending on whether the argument
-/// is already promoted and LocVT is i1/i8/i16. If ValVT is already promoted,
-/// it will be truncated back to i1/i8/i16.
-static bool CC_ARM64_Custom_i1i8i16_Stack(unsigned ValNo, MVT ValVT, MVT LocVT,
- CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags,
- CCState &State) {
- unsigned Space = ((LocVT == MVT::i1 || LocVT == MVT::i8) ? 1 : 2);
- unsigned Offset12 = State.AllocateStack(Space, Space);
- ValVT = LocVT;
- State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset12, LocVT, LocInfo));
- return true;
-}
-
-} // End llvm namespace
-
-#endif
Removed: llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64CallingConvention.td (removed)
@@ -1,236 +0,0 @@
-//===- ARM64CallingConv.td - Calling Conventions for ARM64 -*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This describes the calling conventions for ARM64 architecture.
-//
-//===----------------------------------------------------------------------===//
-
-/// CCIfAlign - Match of the original alignment of the arg
-class CCIfAlign<string Align, CCAction A> :
- CCIf<!strconcat("ArgFlags.getOrigAlign() == ", Align), A>;
-/// CCIfBigEndian - Match only if we're in big endian mode.
-class CCIfBigEndian<CCAction A> :
- CCIf<"State.getTarget().getDataLayout()->isBigEndian()", A>;
-
-//===----------------------------------------------------------------------===//
-// ARM AAPCS64 Calling Convention
-//===----------------------------------------------------------------------===//
-
-def CC_ARM64_AAPCS : CallingConv<[
- CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
- CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
-
- // Big endian vectors must be passed as if they were 1-element vectors so that
- // their lanes are in a consistent order.
- CCIfBigEndian<CCIfType<[v2i32, v2f32, v4i16, v4f16, v8i8],
- CCBitConvertToType<f64>>>,
- CCIfBigEndian<CCIfType<[v2i64, v2f64, v4i32, v4f32, v8i16, v8f16, v16i8],
- CCBitConvertToType<f128>>>,
-
- // An SRet is passed in X8, not X0 like a normal pointer parameter.
- CCIfSRet<CCIfType<[i64], CCAssignToRegWithShadow<[X8], [W8]>>>,
-
- // Put ByVal arguments directly on the stack. Minimum size and alignment of a
- // slot is 64-bit.
- CCIfByVal<CCPassByVal<8, 8>>,
-
- // Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
- // up to eight each of GPR and FPR.
- CCIfType<[i1, i8, i16], CCCustom<"CC_ARM64_Custom_i1i8i16_Reg">>,
- CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
- [X0, X1, X2, X3, X4, X5, X6, X7]>>,
- // i128 is split to two i64s, we can't fit half to register X7.
- CCIfType<[i64], CCIfSplit<CCAssignToRegWithShadow<[X0, X2, X4, X6],
- [X0, X1, X3, X5]>>>,
-
- // i128 is split to two i64s, and its stack alignment is 16 bytes.
- CCIfType<[i64], CCIfSplit<CCAssignToStackWithShadow<8, 16, [X7]>>>,
-
- CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
- [W0, W1, W2, W3, W4, W5, W6, W7]>>,
- CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[v1i64, v2i32, v4i16, v8i8, v1f64, v2f32],
- CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f128, v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
- CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
-
- // If more than will fit in registers, pass them on the stack instead.
- CCIfType<[i1, i8, i16], CCAssignToStack<8, 8>>,
- CCIfType<[i32, f32], CCAssignToStack<8, 8>>,
- CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
- CCAssignToStack<8, 8>>,
- CCIfType<[f128, v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
- CCAssignToStack<16, 16>>
-]>;
-
-def RetCC_ARM64_AAPCS : CallingConv<[
- CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
- CCIfType<[v2f64, v4f32], CCBitConvertToType<v2i64>>,
-
- // Big endian vectors must be passed as if they were 1-element vectors so that
- // their lanes are in a consistent order.
- CCIfBigEndian<CCIfType<[v2i32, v2f32, v4i16, v4f16, v8i8],
- CCBitConvertToType<f64>>>,
- CCIfBigEndian<CCIfType<[v2i64, v2f64, v4i32, v4f32, v8i16, v8f16, v16i8],
- CCBitConvertToType<f128>>>,
-
- CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
- [X0, X1, X2, X3, X4, X5, X6, X7]>>,
- CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
- [W0, W1, W2, W3, W4, W5, W6, W7]>>,
- CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[v1i64, v2i32, v4i16, v8i8, v1f64, v2f32],
- CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f128, v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
- CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>
-]>;
-
-
-// Darwin uses a calling convention which differs in only two ways
-// from the standard one at this level:
-// + i128s (i.e. split i64s) don't need even registers.
-// + Stack slots are sized as needed rather than being at least 64-bit.
-def CC_ARM64_DarwinPCS : CallingConv<[
- CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
- CCIfType<[v2f64, v4f32, f128], CCBitConvertToType<v2i64>>,
-
- // An SRet is passed in X8, not X0 like a normal pointer parameter.
- CCIfSRet<CCIfType<[i64], CCAssignToRegWithShadow<[X8], [W8]>>>,
-
- // Put ByVal arguments directly on the stack. Minimum size and alignment of a
- // slot is 64-bit.
- CCIfByVal<CCPassByVal<8, 8>>,
-
- // Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers,
- // up to eight each of GPR and FPR.
- CCIfType<[i1, i8, i16], CCCustom<"CC_ARM64_Custom_i1i8i16_Reg">>,
- CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
- [X0, X1, X2, X3, X4, X5, X6, X7]>>,
- // i128 is split to two i64s, we can't fit half to register X7.
- CCIfType<[i64],
- CCIfSplit<CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6],
- [W0, W1, W2, W3, W4, W5, W6]>>>,
- // i128 is split to two i64s, and its stack alignment is 16 bytes.
- CCIfType<[i64], CCIfSplit<CCAssignToStackWithShadow<8, 16, [X7]>>>,
-
- CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
- [W0, W1, W2, W3, W4, W5, W6, W7]>>,
- CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[v1i64, v2i32, v4i16, v8i8, v1f64, v2f32],
- CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64],
- CCAssignToReg<[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
-
- // If more than will fit in registers, pass them on the stack instead.
- CCIfType<[i1, i8, i16], CCCustom<"CC_ARM64_Custom_i1i8i16_Stack">>,
- CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
- CCIfType<[i64, f64, v1f64, v2f32, v1i64, v2i32, v4i16, v8i8],
- CCAssignToStack<8, 8>>,
- CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64], CCAssignToStack<16, 16>>
-]>;
-
-def CC_ARM64_DarwinPCS_VarArg : CallingConv<[
- CCIfType<[v2f32], CCBitConvertToType<v2i32>>,
- CCIfType<[v2f64, v4f32, f128], CCBitConvertToType<v2i64>>,
-
- // Handle all scalar types as either i64 or f64.
- CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
- CCIfType<[f32], CCPromoteToType<f64>>,
-
- // Everything is on the stack.
- // i128 is split to two i64s, and its stack alignment is 16 bytes.
- CCIfType<[i64], CCIfSplit<CCAssignToStack<8, 16>>>,
- CCIfType<[i64, f64, v1i64, v2i32, v4i16, v8i8, v1f64, v2f32], CCAssignToStack<8, 8>>,
- CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32, v2f64], CCAssignToStack<16, 16>>
-]>;
-
-// The WebKit_JS calling convention only passes the first argument (the callee)
-// in register and the remaining arguments on stack. We allow 32bit stack slots,
-// so that WebKit can write partial values in the stack and define the other
-// 32bit quantity as undef.
-def CC_ARM64_WebKit_JS : CallingConv<[
- // Handle i1, i8, i16, i32, and i64 passing in register X0 (W0).
- CCIfType<[i1, i8, i16], CCCustom<"CC_ARM64_WebKit_JS_i1i8i16_Reg">>,
- CCIfType<[i32], CCAssignToRegWithShadow<[W0], [X0]>>,
- CCIfType<[i64], CCAssignToRegWithShadow<[X0], [W0]>>,
-
- // Pass the remaining arguments on the stack instead.
- CCIfType<[i1, i8, i16], CCAssignToStack<4, 4>>,
- CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
- CCIfType<[i64, f64], CCAssignToStack<8, 8>>
-]>;
-
-def RetCC_ARM64_WebKit_JS : CallingConv<[
- CCIfType<[i32], CCAssignToRegWithShadow<[W0, W1, W2, W3, W4, W5, W6, W7],
- [X0, X1, X2, X3, X4, X5, X6, X7]>>,
- CCIfType<[i64], CCAssignToRegWithShadow<[X0, X1, X2, X3, X4, X5, X6, X7],
- [W0, W1, W2, W3, W4, W5, W6, W7]>>,
- CCIfType<[f32], CCAssignToRegWithShadow<[S0, S1, S2, S3, S4, S5, S6, S7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>,
- CCIfType<[f64], CCAssignToRegWithShadow<[D0, D1, D2, D3, D4, D5, D6, D7],
- [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]>>
-]>;
-
-// FIXME: LR is only callee-saved in the sense that *we* preserve it and are
-// presumably a callee to someone. External functions may not do so, but this
-// is currently safe since BL has LR as an implicit-def and what happens after a
-// tail call doesn't matter.
-//
-// It would be better to model its preservation semantics properly (create a
-// vreg on entry, use it in RET & tail call generation; make that vreg def if we
-// end up saving LR as part of a call frame). Watch this space...
-def CSR_ARM64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22,
- X23, X24, X25, X26, X27, X28,
- D8, D9, D10, D11,
- D12, D13, D14, D15)>;
-
-// Constructors and destructors return 'this' in the iOS 64-bit C++ ABI; since
-// 'this' and the pointer return value are both passed in X0 in these cases,
-// this can be partially modelled by treating X0 as a callee-saved register;
-// only the resulting RegMask is used; the SaveList is ignored
-//
-// (For generic ARM 64-bit ABI code, clang will not generate constructors or
-// destructors with 'this' returns, so this RegMask will not be used in that
-// case)
-def CSR_ARM64_AAPCS_ThisReturn : CalleeSavedRegs<(add CSR_ARM64_AAPCS, X0)>;
-
-// The function used by Darwin to obtain the address of a thread-local variable
-// guarantees more than a normal AAPCS function. x16 and x17 are used on the
-// fast path for calculation, but other registers except X0 (argument/return)
-// and LR (it is a call, after all) are preserved.
-def CSR_ARM64_TLS_Darwin
- : CalleeSavedRegs<(add (sub (sequence "X%u", 1, 28), X16, X17),
- FP,
- (sequence "Q%u", 0, 31))>;
-
-// The ELF stub used for TLS-descriptor access saves every feasible
-// register. Only X0 and LR are clobbered.
-def CSR_ARM64_TLS_ELF
- : CalleeSavedRegs<(add (sequence "X%u", 1, 28), FP,
- (sequence "Q%u", 0, 31))>;
-
-def CSR_ARM64_AllRegs
- : CalleeSavedRegs<(add (sequence "W%u", 0, 30), WSP,
- (sequence "X%u", 0, 28), FP, LR, SP,
- (sequence "B%u", 0, 31), (sequence "H%u", 0, 31),
- (sequence "S%u", 0, 31), (sequence "D%u", 0, 31),
- (sequence "Q%u", 0, 31))>;
-
Removed: llvm/trunk/lib/Target/ARM64/ARM64CleanupLocalDynamicTLSPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64CleanupLocalDynamicTLSPass.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64CleanupLocalDynamicTLSPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64CleanupLocalDynamicTLSPass.cpp (removed)
@@ -1,147 +0,0 @@
-//===-- ARM64CleanupLocalDynamicTLSPass.cpp -----------------------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Local-dynamic access to thread-local variables proceeds in three stages.
-//
-// 1. The offset of this Module's thread-local area from TPIDR_EL0 is calculated
-// in much the same way as a general-dynamic TLS-descriptor access against
-// the special symbol _TLS_MODULE_BASE.
-// 2. The variable's offset from _TLS_MODULE_BASE_ is calculated using
-// instructions with "dtprel" modifiers.
-// 3. These two are added, together with TPIDR_EL0, to obtain the variable's
-// true address.
-//
-// This is only better than general-dynamic access to the variable if two or
-// more of the first stage TLS-descriptor calculations can be combined. This
-// pass looks through a function and performs such combinations.
-//
-//===----------------------------------------------------------------------===//
-#include "ARM64.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64MachineFunctionInfo.h"
-#include "ARM64TargetMachine.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-using namespace llvm;
-
-namespace {
-struct LDTLSCleanup : public MachineFunctionPass {
- static char ID;
- LDTLSCleanup() : MachineFunctionPass(ID) {}
-
- bool runOnMachineFunction(MachineFunction &MF) override {
- ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
- if (AFI->getNumLocalDynamicTLSAccesses() < 2) {
- // No point folding accesses if there isn't at least two.
- return false;
- }
-
- MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
- return VisitNode(DT->getRootNode(), 0);
- }
-
- // Visit the dominator subtree rooted at Node in pre-order.
- // If TLSBaseAddrReg is non-null, then use that to replace any
- // TLS_base_addr instructions. Otherwise, create the register
- // when the first such instruction is seen, and then use it
- // as we encounter more instructions.
- bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
- MachineBasicBlock *BB = Node->getBlock();
- bool Changed = false;
-
- // Traverse the current block.
- for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
- ++I) {
- switch (I->getOpcode()) {
- case ARM64::TLSDESC_BLR:
- // Make sure it's a local dynamic access.
- if (!I->getOperand(1).isSymbol() ||
- strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
- break;
-
- if (TLSBaseAddrReg)
- I = replaceTLSBaseAddrCall(I, TLSBaseAddrReg);
- else
- I = setRegister(I, &TLSBaseAddrReg);
- Changed = true;
- break;
- default:
- break;
- }
- }
-
- // Visit the children of this block in the dominator tree.
- for (MachineDomTreeNode *N : *Node) {
- Changed |= VisitNode(N, TLSBaseAddrReg);
- }
-
- return Changed;
- }
-
- // Replace the TLS_base_addr instruction I with a copy from
- // TLSBaseAddrReg, returning the new instruction.
- MachineInstr *replaceTLSBaseAddrCall(MachineInstr *I,
- unsigned TLSBaseAddrReg) {
- MachineFunction *MF = I->getParent()->getParent();
- const ARM64TargetMachine *TM =
- static_cast<const ARM64TargetMachine *>(&MF->getTarget());
- const ARM64InstrInfo *TII = TM->getInstrInfo();
-
- // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
- // code sequence assumes the address will be.
- MachineInstr *Copy =
- BuildMI(*I->getParent(), I, I->getDebugLoc(),
- TII->get(TargetOpcode::COPY), ARM64::X0).addReg(TLSBaseAddrReg);
-
- // Erase the TLS_base_addr instruction.
- I->eraseFromParent();
-
- return Copy;
- }
-
- // Create a virtal register in *TLSBaseAddrReg, and populate it by
- // inserting a copy instruction after I. Returns the new instruction.
- MachineInstr *setRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) {
- MachineFunction *MF = I->getParent()->getParent();
- const ARM64TargetMachine *TM =
- static_cast<const ARM64TargetMachine *>(&MF->getTarget());
- const ARM64InstrInfo *TII = TM->getInstrInfo();
-
- // Create a virtual register for the TLS base address.
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- *TLSBaseAddrReg = RegInfo.createVirtualRegister(&ARM64::GPR64RegClass);
-
- // Insert a copy from X0 to TLSBaseAddrReg for later.
- MachineInstr *Next = I->getNextNode();
- MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
- TII->get(TargetOpcode::COPY),
- *TLSBaseAddrReg).addReg(ARM64::X0);
-
- return Copy;
- }
-
- const char *getPassName() const override {
- return "Local Dynamic TLS Access Clean-up";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- AU.addRequired<MachineDominatorTree>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-}
-
-char LDTLSCleanup::ID = 0;
-FunctionPass *llvm::createARM64CleanupLocalDynamicTLSPass() {
- return new LDTLSCleanup();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64CollectLOH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64CollectLOH.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64CollectLOH.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64CollectLOH.cpp (removed)
@@ -1,1117 +0,0 @@
-//===-------------- ARM64CollectLOH.cpp - ARM64 collect LOH pass --*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a pass that collect the Linker Optimization Hint (LOH).
-// This pass should be run at the very end of the compilation flow, just before
-// assembly printer.
-// To be useful for the linker, the LOH must be printed into the assembly file.
-//
-// A LOH describes a sequence of instructions that may be optimized by the
-// linker.
-// This same sequence cannot be optimized by the compiler because some of
-// the information will be known at link time.
-// For instance, consider the following sequence:
-// L1: adrp xA, sym at PAGE
-// L2: add xB, xA, sym at PAGEOFF
-// L3: ldr xC, [xB, #imm]
-// This sequence can be turned into:
-// A literal load if sym at PAGE + sym at PAGEOFF + #imm - address(L3) is < 1MB:
-// L3: ldr xC, sym+#imm
-// It may also be turned into either the following more efficient
-// code sequences:
-// - If sym at PAGEOFF + #imm fits the encoding space of L3.
-// L1: adrp xA, sym at PAGE
-// L3: ldr xC, [xB, sym at PAGEOFF + #imm]
-// - If sym at PAGE + sym at PAGEOFF - address(L1) < 1MB:
-// L1: adr xA, sym
-// L3: ldr xC, [xB, #imm]
-//
-// To be valid a LOH must meet all the requirements needed by all the related
-// possible linker transformations.
-// For instance, using the running example, the constraints to emit
-// ".loh AdrpAddLdr" are:
-// - L1, L2, and L3 instructions are of the expected type, i.e.,
-// respectively ADRP, ADD (immediate), and LD.
-// - The result of L1 is used only by L2.
-// - The register argument (xA) used in the ADD instruction is defined
-// only by L1.
-// - The result of L2 is used only by L3.
-// - The base address (xB) in L3 is defined only L2.
-// - The ADRP in L1 and the ADD in L2 must reference the same symbol using
-// @PAGE/@PAGEOFF with no additional constants
-//
-// Currently supported LOHs are:
-// * So called non-ADRP-related:
-// - .loh AdrpAddLdr L1, L2, L3:
-// L1: adrp xA, sym at PAGE
-// L2: add xB, xA, sym at PAGEOFF
-// L3: ldr xC, [xB, #imm]
-// - .loh AdrpLdrGotLdr L1, L2, L3:
-// L1: adrp xA, sym at GOTPAGE
-// L2: ldr xB, [xA, sym at GOTPAGEOFF]
-// L3: ldr xC, [xB, #imm]
-// - .loh AdrpLdr L1, L3:
-// L1: adrp xA, sym at PAGE
-// L3: ldr xC, [xA, sym at PAGEOFF]
-// - .loh AdrpAddStr L1, L2, L3:
-// L1: adrp xA, sym at PAGE
-// L2: add xB, xA, sym at PAGEOFF
-// L3: str xC, [xB, #imm]
-// - .loh AdrpLdrGotStr L1, L2, L3:
-// L1: adrp xA, sym at GOTPAGE
-// L2: ldr xB, [xA, sym at GOTPAGEOFF]
-// L3: str xC, [xB, #imm]
-// - .loh AdrpAdd L1, L2:
-// L1: adrp xA, sym at PAGE
-// L2: add xB, xA, sym at PAGEOFF
-// For all these LOHs, L1, L2, L3 form a simple chain:
-// L1 result is used only by L2 and L2 result by L3.
-// L3 LOH-related argument is defined only by L2 and L2 LOH-related argument
-// by L1.
-// All these LOHs aim at using more efficient load/store patterns by folding
-// some instructions used to compute the address directly into the load/store.
-//
-// * So called ADRP-related:
-// - .loh AdrpAdrp L2, L1:
-// L2: ADRP xA, sym1 at PAGE
-// L1: ADRP xA, sym2 at PAGE
-// L2 dominates L1 and xA is not redifined between L2 and L1
-// This LOH aims at getting rid of redundant ADRP instructions.
-//
-// The overall design for emitting the LOHs is:
-// 1. ARM64CollectLOH (this pass) records the LOHs in the ARM64FunctionInfo.
-// 2. ARM64AsmPrinter reads the LOHs from ARM64FunctionInfo and it:
-// 1. Associates them a label.
-// 2. Emits them in a MCStreamer (EmitLOHDirective).
-// - The MCMachOStreamer records them into the MCAssembler.
-// - The MCAsmStreamer prints them.
-// - Other MCStreamers ignore them.
-// 3. Closes the MCStreamer:
-// - The MachObjectWriter gets them from the MCAssembler and writes
-// them in the object file.
-// - Other ObjectWriters ignore them.
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64MachineFunctionInfo.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/Statistic.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-collect-loh"
-
-static cl::opt<bool>
-PreCollectRegister("arm64-collect-loh-pre-collect-register", cl::Hidden,
- cl::desc("Restrict analysis to registers invovled"
- " in LOHs"),
- cl::init(true));
-
-static cl::opt<bool>
-BasicBlockScopeOnly("arm64-collect-loh-bb-only", cl::Hidden,
- cl::desc("Restrict analysis at basic block scope"),
- cl::init(true));
-
-STATISTIC(NumADRPSimpleCandidate,
- "Number of simplifiable ADRP dominate by another");
-STATISTIC(NumADRPComplexCandidate2,
- "Number of simplifiable ADRP reachable by 2 defs");
-STATISTIC(NumADRPComplexCandidate3,
- "Number of simplifiable ADRP reachable by 3 defs");
-STATISTIC(NumADRPComplexCandidateOther,
- "Number of simplifiable ADRP reachable by 4 or more defs");
-STATISTIC(NumADDToSTRWithImm,
- "Number of simplifiable STR with imm reachable by ADD");
-STATISTIC(NumLDRToSTRWithImm,
- "Number of simplifiable STR with imm reachable by LDR");
-STATISTIC(NumADDToSTR, "Number of simplifiable STR reachable by ADD");
-STATISTIC(NumLDRToSTR, "Number of simplifiable STR reachable by LDR");
-STATISTIC(NumADDToLDRWithImm,
- "Number of simplifiable LDR with imm reachable by ADD");
-STATISTIC(NumLDRToLDRWithImm,
- "Number of simplifiable LDR with imm reachable by LDR");
-STATISTIC(NumADDToLDR, "Number of simplifiable LDR reachable by ADD");
-STATISTIC(NumLDRToLDR, "Number of simplifiable LDR reachable by LDR");
-STATISTIC(NumADRPToLDR, "Number of simplifiable LDR reachable by ADRP");
-STATISTIC(NumCplxLvl1, "Number of complex case of level 1");
-STATISTIC(NumTooCplxLvl1, "Number of too complex case of level 1");
-STATISTIC(NumCplxLvl2, "Number of complex case of level 2");
-STATISTIC(NumTooCplxLvl2, "Number of too complex case of level 2");
-STATISTIC(NumADRSimpleCandidate, "Number of simplifiable ADRP + ADD");
-STATISTIC(NumADRComplexCandidate, "Number of too complex ADRP + ADD");
-
-namespace llvm {
-void initializeARM64CollectLOHPass(PassRegistry &);
-}
-
-namespace {
-struct ARM64CollectLOH : public MachineFunctionPass {
- static char ID;
- ARM64CollectLOH() : MachineFunctionPass(ID) {
- initializeARM64CollectLOHPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- const char *getPassName() const override {
- return "ARM64 Collect Linker Optimization Hint (LOH)";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- AU.addRequired<MachineDominatorTree>();
- }
-
-private:
-};
-
-/// A set of MachineInstruction.
-typedef SetVector<const MachineInstr *> SetOfMachineInstr;
-/// Map a basic block to a set of instructions per register.
-/// This is used to represent the exposed uses of a basic block
-/// per register.
-typedef MapVector<const MachineBasicBlock *, SetOfMachineInstr *>
-BlockToSetOfInstrsPerColor;
-/// Map a basic block to an instruction per register.
-/// This is used to represent the live-out definitions of a basic block
-/// per register.
-typedef MapVector<const MachineBasicBlock *, const MachineInstr **>
-BlockToInstrPerColor;
-/// Map an instruction to a set of instructions. Used to represent the
-/// mapping def to reachable uses or use to definitions.
-typedef MapVector<const MachineInstr *, SetOfMachineInstr> InstrToInstrs;
-/// Map a basic block to a BitVector.
-/// This is used to record the kill registers per basic block.
-typedef MapVector<const MachineBasicBlock *, BitVector> BlockToRegSet;
-
-/// Map a register to a dense id.
-typedef DenseMap<unsigned, unsigned> MapRegToId;
-/// Map a dense id to a register. Used for debug purposes.
-typedef SmallVector<unsigned, 32> MapIdToReg;
-} // end anonymous namespace.
-
-char ARM64CollectLOH::ID = 0;
-
-INITIALIZE_PASS_BEGIN(ARM64CollectLOH, "arm64-collect-loh",
- "ARM64 Collect Linker Optimization Hint (LOH)", false,
- false)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_END(ARM64CollectLOH, "arm64-collect-loh",
- "ARM64 Collect Linker Optimization Hint (LOH)", false,
- false)
-
-/// Given a couple (MBB, reg) get the corresponding set of instruction from
-/// the given "sets".
-/// If this couple does not reference any set, an empty set is added to "sets"
-/// for this couple and returned.
-/// \param nbRegs is used internally allocate some memory. It must be consistent
-/// with the way sets is used.
-static SetOfMachineInstr &getSet(BlockToSetOfInstrsPerColor &sets,
- const MachineBasicBlock &MBB, unsigned reg,
- unsigned nbRegs) {
- SetOfMachineInstr *result;
- BlockToSetOfInstrsPerColor::iterator it = sets.find(&MBB);
- if (it != sets.end())
- result = it->second;
- else
- result = sets[&MBB] = new SetOfMachineInstr[nbRegs];
-
- return result[reg];
-}
-
-/// Given a couple (reg, MI) get the corresponding set of instructions from the
-/// the given "sets".
-/// This is used to get the uses record in sets of a definition identified by
-/// MI and reg, i.e., MI defines reg.
-/// If the couple does not reference anything, an empty set is added to
-/// "sets[reg]".
-/// \pre set[reg] is valid.
-static SetOfMachineInstr &getUses(InstrToInstrs *sets, unsigned reg,
- const MachineInstr &MI) {
- return sets[reg][&MI];
-}
-
-/// Same as getUses but does not modify the input map: sets.
-/// \return NULL if the couple (reg, MI) is not in sets.
-static const SetOfMachineInstr *getUses(const InstrToInstrs *sets, unsigned reg,
- const MachineInstr &MI) {
- InstrToInstrs::const_iterator Res = sets[reg].find(&MI);
- if (Res != sets[reg].end())
- return &(Res->second);
- return nullptr;
-}
-
-/// Initialize the reaching definition algorithm:
-/// For each basic block BB in MF, record:
-/// - its kill set.
-/// - its reachable uses (uses that are exposed to BB's predecessors).
-/// - its the generated definitions.
-/// \param DummyOp if not NULL, specifies a Dummy Operation to be added to
-/// the list of uses of exposed defintions.
-/// \param ADRPMode specifies to only consider ADRP instructions for generated
-/// definition. It also consider definitions of ADRP instructions as uses and
-/// ignore other uses. The ADRPMode is used to collect the information for LHO
-/// that involve ADRP operation only.
-static void initReachingDef(MachineFunction &MF,
- InstrToInstrs *ColorOpToReachedUses,
- BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
- BlockToSetOfInstrsPerColor &ReachableUses,
- const MapRegToId &RegToId,
- const MachineInstr *DummyOp, bool ADRPMode) {
- const TargetMachine &TM = MF.getTarget();
- const TargetRegisterInfo *TRI = TM.getRegisterInfo();
-
- unsigned NbReg = RegToId.size();
-
- for (MachineBasicBlock &MBB : MF) {
- const MachineInstr **&BBGen = Gen[&MBB];
- BBGen = new const MachineInstr *[NbReg];
- memset(BBGen, 0, sizeof(const MachineInstr *) * NbReg);
-
- BitVector &BBKillSet = Kill[&MBB];
- BBKillSet.resize(NbReg);
- for (const MachineInstr &MI : MBB) {
- bool IsADRP = MI.getOpcode() == ARM64::ADRP;
-
- // Process uses first.
- if (IsADRP || !ADRPMode)
- for (const MachineOperand &MO : MI.operands()) {
- // Treat ADRP def as use, as the goal of the analysis is to find
- // ADRP defs reached by other ADRP defs.
- if (!MO.isReg() || (!ADRPMode && !MO.isUse()) ||
- (ADRPMode && (!IsADRP || !MO.isDef())))
- continue;
- unsigned CurReg = MO.getReg();
- MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
- if (ItCurRegId == RegToId.end())
- continue;
- CurReg = ItCurRegId->second;
-
- // if CurReg has not been defined, this use is reachable.
- if (!BBGen[CurReg] && !BBKillSet.test(CurReg))
- getSet(ReachableUses, MBB, CurReg, NbReg).insert(&MI);
- // current basic block definition for this color, if any, is in Gen.
- if (BBGen[CurReg])
- getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(&MI);
- }
-
- // Process clobbers.
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isRegMask())
- continue;
- // Clobbers kill the related colors.
- const uint32_t *PreservedRegs = MO.getRegMask();
-
- // Set generated regs.
- for (const auto Entry : RegToId) {
- unsigned Reg = Entry.second;
- // Use the global register ID when querying APIs external to this
- // pass.
- if (MachineOperand::clobbersPhysReg(PreservedRegs, Entry.first)) {
- // Do not register clobbered definition for no ADRP.
- // This definition is not used anyway (otherwise register
- // allocation is wrong).
- BBGen[Reg] = ADRPMode ? &MI : nullptr;
- BBKillSet.set(Reg);
- }
- }
- }
-
- // Process register defs.
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isDef())
- continue;
- unsigned CurReg = MO.getReg();
- MapRegToId::const_iterator ItCurRegId = RegToId.find(CurReg);
- if (ItCurRegId == RegToId.end())
- continue;
-
- for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI) {
- MapRegToId::const_iterator ItRegId = RegToId.find(*AI);
- assert(ItRegId != RegToId.end() &&
- "Sub-register of an "
- "involved register, not recorded as involved!");
- BBKillSet.set(ItRegId->second);
- BBGen[ItRegId->second] = &MI;
- }
- BBGen[ItCurRegId->second] = &MI;
- }
- }
-
- // If we restrict our analysis to basic block scope, conservatively add a
- // dummy
- // use for each generated value.
- if (!ADRPMode && DummyOp && !MBB.succ_empty())
- for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg)
- if (BBGen[CurReg])
- getUses(ColorOpToReachedUses, CurReg, *BBGen[CurReg]).insert(DummyOp);
- }
-}
-
-/// Reaching def core algorithm:
-/// while an Out has changed
-/// for each bb
-/// for each color
-/// In[bb][color] = U Out[bb.predecessors][color]
-/// insert reachableUses[bb][color] in each in[bb][color]
-/// op.reachedUses
-///
-/// Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
-static void reachingDefAlgorithm(MachineFunction &MF,
- InstrToInstrs *ColorOpToReachedUses,
- BlockToSetOfInstrsPerColor &In,
- BlockToSetOfInstrsPerColor &Out,
- BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
- BlockToSetOfInstrsPerColor &ReachableUses,
- unsigned NbReg) {
- bool HasChanged;
- do {
- HasChanged = false;
- for (MachineBasicBlock &MBB : MF) {
- unsigned CurReg;
- for (CurReg = 0; CurReg < NbReg; ++CurReg) {
- SetOfMachineInstr &BBInSet = getSet(In, MBB, CurReg, NbReg);
- SetOfMachineInstr &BBReachableUses =
- getSet(ReachableUses, MBB, CurReg, NbReg);
- SetOfMachineInstr &BBOutSet = getSet(Out, MBB, CurReg, NbReg);
- unsigned Size = BBOutSet.size();
- // In[bb][color] = U Out[bb.predecessors][color]
- for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
- SetOfMachineInstr &PredOutSet = getSet(Out, *PredMBB, CurReg, NbReg);
- BBInSet.insert(PredOutSet.begin(), PredOutSet.end());
- }
- // insert reachableUses[bb][color] in each in[bb][color] op.reachedses
- for (const MachineInstr *MI : BBInSet) {
- SetOfMachineInstr &OpReachedUses =
- getUses(ColorOpToReachedUses, CurReg, *MI);
- OpReachedUses.insert(BBReachableUses.begin(), BBReachableUses.end());
- }
- // Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
- if (!Kill[&MBB].test(CurReg))
- BBOutSet.insert(BBInSet.begin(), BBInSet.end());
- if (Gen[&MBB][CurReg])
- BBOutSet.insert(Gen[&MBB][CurReg]);
- HasChanged |= BBOutSet.size() != Size;
- }
- }
- } while (HasChanged);
-}
-
-/// Release all memory dynamically allocated during the reaching
-/// definition algorithm.
-static void finitReachingDef(BlockToSetOfInstrsPerColor &In,
- BlockToSetOfInstrsPerColor &Out,
- BlockToInstrPerColor &Gen,
- BlockToSetOfInstrsPerColor &ReachableUses) {
- for (auto &IT : Out)
- delete[] IT.second;
- for (auto &IT : In)
- delete[] IT.second;
- for (auto &IT : ReachableUses)
- delete[] IT.second;
- for (auto &IT : Gen)
- delete[] IT.second;
-}
-
-/// Reaching definition algorithm.
-/// \param MF function on which the algorithm will operate.
-/// \param[out] ColorOpToReachedUses will contain the result of the reaching
-/// def algorithm.
-/// \param ADRPMode specify whether the reaching def algorithm should be tuned
-/// for ADRP optimization. \see initReachingDef for more details.
-/// \param DummyOp if not NULL, the algorithm will work at
-/// basic block scope and will set for every exposed definition a use to
-/// @p DummyOp.
-/// \pre ColorOpToReachedUses is an array of at least number of registers of
-/// InstrToInstrs.
-static void reachingDef(MachineFunction &MF,
- InstrToInstrs *ColorOpToReachedUses,
- const MapRegToId &RegToId, bool ADRPMode = false,
- const MachineInstr *DummyOp = nullptr) {
- // structures:
- // For each basic block.
- // Out: a set per color of definitions that reach the
- // out boundary of this block.
- // In: Same as Out but for in boundary.
- // Gen: generated color in this block (one operation per color).
- // Kill: register set of killed color in this block.
- // ReachableUses: a set per color of uses (operation) reachable
- // for "In" definitions.
- BlockToSetOfInstrsPerColor Out, In, ReachableUses;
- BlockToInstrPerColor Gen;
- BlockToRegSet Kill;
-
- // Initialize Gen, kill and reachableUses.
- initReachingDef(MF, ColorOpToReachedUses, Gen, Kill, ReachableUses, RegToId,
- DummyOp, ADRPMode);
-
- // Algo.
- if (!DummyOp)
- reachingDefAlgorithm(MF, ColorOpToReachedUses, In, Out, Gen, Kill,
- ReachableUses, RegToId.size());
-
- // finit.
- finitReachingDef(In, Out, Gen, ReachableUses);
-}
-
-#ifndef NDEBUG
-/// print the result of the reaching definition algorithm.
-static void printReachingDef(const InstrToInstrs *ColorOpToReachedUses,
- unsigned NbReg, const TargetRegisterInfo *TRI,
- const MapIdToReg &IdToReg) {
- unsigned CurReg;
- for (CurReg = 0; CurReg < NbReg; ++CurReg) {
- if (ColorOpToReachedUses[CurReg].empty())
- continue;
- DEBUG(dbgs() << "*** Reg " << PrintReg(IdToReg[CurReg], TRI) << " ***\n");
-
- for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
- DEBUG(dbgs() << "Def:\n");
- DEBUG(DefsIt.first->print(dbgs()));
- DEBUG(dbgs() << "Reachable uses:\n");
- for (const MachineInstr *MI : DefsIt.second) {
- DEBUG(MI->print(dbgs()));
- }
- }
- }
-}
-#endif // NDEBUG
-
-/// Answer the following question: Can Def be one of the definition
-/// involved in a part of a LOH?
-static bool canDefBePartOfLOH(const MachineInstr *Def) {
- unsigned Opc = Def->getOpcode();
- // Accept ADRP, ADDLow and LOADGot.
- switch (Opc) {
- default:
- return false;
- case ARM64::ADRP:
- return true;
- case ARM64::ADDXri:
- // Check immediate to see if the immediate is an address.
- switch (Def->getOperand(2).getType()) {
- default:
- return false;
- case MachineOperand::MO_GlobalAddress:
- case MachineOperand::MO_JumpTableIndex:
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_BlockAddress:
- return true;
- }
- case ARM64::LDRXui:
- // Check immediate to see if the immediate is an address.
- switch (Def->getOperand(2).getType()) {
- default:
- return false;
- case MachineOperand::MO_GlobalAddress:
- return true;
- }
- }
- // Unreachable.
- return false;
-}
-
-/// Check whether the given instruction can the end of a LOH chain involving a
-/// store.
-static bool isCandidateStore(const MachineInstr *Instr) {
- switch (Instr->getOpcode()) {
- default:
- return false;
- case ARM64::STRBui:
- case ARM64::STRHui:
- case ARM64::STRWui:
- case ARM64::STRXui:
- case ARM64::STRSui:
- case ARM64::STRDui:
- case ARM64::STRQui:
- // In case we have str xA, [xA, #imm], this is two different uses
- // of xA and we cannot fold, otherwise the xA stored may be wrong,
- // even if #imm == 0.
- if (Instr->getOperand(0).getReg() != Instr->getOperand(1).getReg())
- return true;
- }
- return false;
-}
-
-/// Given the result of a reaching definition algorithm in ColorOpToReachedUses,
-/// Build the Use to Defs information and filter out obvious non-LOH candidates.
-/// In ADRPMode, non-LOH candidates are "uses" with non-ADRP definitions.
-/// In non-ADRPMode, non-LOH candidates are "uses" with several definition,
-/// i.e., no simple chain.
-/// \param ADRPMode -- \see initReachingDef.
-static void reachedUsesToDefs(InstrToInstrs &UseToReachingDefs,
- const InstrToInstrs *ColorOpToReachedUses,
- const MapRegToId &RegToId,
- bool ADRPMode = false) {
-
- SetOfMachineInstr NotCandidate;
- unsigned NbReg = RegToId.size();
- MapRegToId::const_iterator EndIt = RegToId.end();
- for (unsigned CurReg = 0; CurReg < NbReg; ++CurReg) {
- // If this color is never defined, continue.
- if (ColorOpToReachedUses[CurReg].empty())
- continue;
-
- for (const auto &DefsIt : ColorOpToReachedUses[CurReg]) {
- for (const MachineInstr *MI : DefsIt.second) {
- const MachineInstr *Def = DefsIt.first;
- MapRegToId::const_iterator It;
- // if all the reaching defs are not adrp, this use will not be
- // simplifiable.
- if ((ADRPMode && Def->getOpcode() != ARM64::ADRP) ||
- (!ADRPMode && !canDefBePartOfLOH(Def)) ||
- (!ADRPMode && isCandidateStore(MI) &&
- // store are LOH candidate iff the end of the chain is used as
- // base.
- ((It = RegToId.find((MI)->getOperand(1).getReg())) == EndIt ||
- It->second != CurReg))) {
- NotCandidate.insert(MI);
- continue;
- }
- // Do not consider self reaching as a simplifiable case for ADRP.
- if (!ADRPMode || MI != DefsIt.first) {
- UseToReachingDefs[MI].insert(DefsIt.first);
- // If UsesIt has several reaching definitions, it is not
- // candidate for simplificaton in non-ADRPMode.
- if (!ADRPMode && UseToReachingDefs[MI].size() > 1)
- NotCandidate.insert(MI);
- }
- }
- }
- }
- for (const MachineInstr *Elem : NotCandidate) {
- DEBUG(dbgs() << "Too many reaching defs: " << *Elem << "\n");
- // It would have been better if we could just remove the entry
- // from the map. Because of that, we have to filter the garbage
- // (second.empty) in the subsequence analysis.
- UseToReachingDefs[Elem].clear();
- }
-}
-
-/// Based on the use to defs information (in ADRPMode), compute the
-/// opportunities of LOH ADRP-related.
-static void computeADRP(const InstrToInstrs &UseToDefs,
- ARM64FunctionInfo &ARM64FI,
- const MachineDominatorTree *MDT) {
- DEBUG(dbgs() << "*** Compute LOH for ADRP\n");
- for (const auto &Entry : UseToDefs) {
- unsigned Size = Entry.second.size();
- if (Size == 0)
- continue;
- if (Size == 1) {
- const MachineInstr *L2 = *Entry.second.begin();
- const MachineInstr *L1 = Entry.first;
- if (!MDT->dominates(L2, L1)) {
- DEBUG(dbgs() << "Dominance check failed:\n" << *L2 << '\n' << *L1
- << '\n');
- continue;
- }
- DEBUG(dbgs() << "Record AdrpAdrp:\n" << *L2 << '\n' << *L1 << '\n');
- SmallVector<const MachineInstr *, 2> Args;
- Args.push_back(L2);
- Args.push_back(L1);
- ARM64FI.addLOHDirective(MCLOH_AdrpAdrp, Args);
- ++NumADRPSimpleCandidate;
- }
-#ifdef DEBUG
- else if (Size == 2)
- ++NumADRPComplexCandidate2;
- else if (Size == 3)
- ++NumADRPComplexCandidate3;
- else
- ++NumADRPComplexCandidateOther;
-#endif
- // if Size < 1, the use should have been removed from the candidates
- assert(Size >= 1 && "No reaching defs for that use!");
- }
-}
-
-/// Check whether the given instruction can be the end of a LOH chain
-/// involving a load.
-static bool isCandidateLoad(const MachineInstr *Instr) {
- switch (Instr->getOpcode()) {
- default:
- return false;
- case ARM64::LDRSBWui:
- case ARM64::LDRSBXui:
- case ARM64::LDRSHWui:
- case ARM64::LDRSHXui:
- case ARM64::LDRSWui:
- case ARM64::LDRBui:
- case ARM64::LDRHui:
- case ARM64::LDRWui:
- case ARM64::LDRXui:
- case ARM64::LDRSui:
- case ARM64::LDRDui:
- case ARM64::LDRQui:
- if (Instr->getOperand(2).getTargetFlags() & ARM64II::MO_GOT)
- return false;
- return true;
- }
- // Unreachable.
- return false;
-}
-
-/// Check whether the given instruction can load a litteral.
-static bool supportLoadFromLiteral(const MachineInstr *Instr) {
- switch (Instr->getOpcode()) {
- default:
- return false;
- case ARM64::LDRSWui:
- case ARM64::LDRWui:
- case ARM64::LDRXui:
- case ARM64::LDRSui:
- case ARM64::LDRDui:
- case ARM64::LDRQui:
- return true;
- }
- // Unreachable.
- return false;
-}
-
-/// Check whether the given instruction is a LOH candidate.
-/// \param UseToDefs is used to check that Instr is at the end of LOH supported
-/// chain.
-/// \pre UseToDefs contains only on def per use, i.e., obvious non candidate are
-/// already been filtered out.
-static bool isCandidate(const MachineInstr *Instr,
- const InstrToInstrs &UseToDefs,
- const MachineDominatorTree *MDT) {
- if (!isCandidateLoad(Instr) && !isCandidateStore(Instr))
- return false;
-
- const MachineInstr *Def = *UseToDefs.find(Instr)->second.begin();
- if (Def->getOpcode() != ARM64::ADRP) {
- // At this point, Def is ADDXri or LDRXui of the right type of
- // symbol, because we filtered out the uses that were not defined
- // by these kind of instructions (+ ADRP).
-
- // Check if this forms a simple chain: each intermediate node must
- // dominates the next one.
- if (!MDT->dominates(Def, Instr))
- return false;
- // Move one node up in the simple chain.
- if (UseToDefs.find(Def) ==
- UseToDefs.end()
- // The map may contain garbage we have to ignore.
- ||
- UseToDefs.find(Def)->second.empty())
- return false;
- Instr = Def;
- Def = *UseToDefs.find(Def)->second.begin();
- }
- // Check if we reached the top of the simple chain:
- // - top is ADRP.
- // - check the simple chain property: each intermediate node must
- // dominates the next one.
- if (Def->getOpcode() == ARM64::ADRP)
- return MDT->dominates(Def, Instr);
- return false;
-}
-
-static bool registerADRCandidate(const MachineInstr &Use,
- const InstrToInstrs &UseToDefs,
- const InstrToInstrs *DefsPerColorToUses,
- ARM64FunctionInfo &ARM64FI,
- SetOfMachineInstr *InvolvedInLOHs,
- const MapRegToId &RegToId) {
- // Look for opportunities to turn ADRP -> ADD or
- // ADRP -> LDR GOTPAGEOFF into ADR.
- // If ADRP has more than one use. Give up.
- if (Use.getOpcode() != ARM64::ADDXri &&
- (Use.getOpcode() != ARM64::LDRXui ||
- !(Use.getOperand(2).getTargetFlags() & ARM64II::MO_GOT)))
- return false;
- InstrToInstrs::const_iterator It = UseToDefs.find(&Use);
- // The map may contain garbage that we need to ignore.
- if (It == UseToDefs.end() || It->second.empty())
- return false;
- const MachineInstr &Def = **It->second.begin();
- if (Def.getOpcode() != ARM64::ADRP)
- return false;
- // Check the number of users of ADRP.
- const SetOfMachineInstr *Users =
- getUses(DefsPerColorToUses,
- RegToId.find(Def.getOperand(0).getReg())->second, Def);
- if (Users->size() > 1) {
- ++NumADRComplexCandidate;
- return false;
- }
- ++NumADRSimpleCandidate;
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Def)) &&
- "ADRP already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(&Use)) &&
- "ADD already involved in LOH.");
- DEBUG(dbgs() << "Record AdrpAdd\n" << Def << '\n' << Use << '\n');
-
- SmallVector<const MachineInstr *, 2> Args;
- Args.push_back(&Def);
- Args.push_back(&Use);
-
- ARM64FI.addLOHDirective(Use.getOpcode() == ARM64::ADDXri ? MCLOH_AdrpAdd
- : MCLOH_AdrpLdrGot,
- Args);
- return true;
-}
-
-/// Based on the use to defs information (in non-ADRPMode), compute the
-/// opportunities of LOH non-ADRP-related
-static void computeOthers(const InstrToInstrs &UseToDefs,
- const InstrToInstrs *DefsPerColorToUses,
- ARM64FunctionInfo &ARM64FI, const MapRegToId &RegToId,
- const MachineDominatorTree *MDT) {
- SetOfMachineInstr *InvolvedInLOHs = nullptr;
-#ifdef DEBUG
- SetOfMachineInstr InvolvedInLOHsStorage;
- InvolvedInLOHs = &InvolvedInLOHsStorage;
-#endif // DEBUG
- DEBUG(dbgs() << "*** Compute LOH for Others\n");
- // ADRP -> ADD/LDR -> LDR/STR pattern.
- // Fall back to ADRP -> ADD pattern if we fail to catch the bigger pattern.
-
- // FIXME: When the statistics are not important,
- // This initial filtering loop can be merged into the next loop.
- // Currently, we didn't do it to have the same code for both DEBUG and
- // NDEBUG builds. Indeed, the iterator of the second loop would need
- // to be changed.
- SetOfMachineInstr PotentialCandidates;
- SetOfMachineInstr PotentialADROpportunities;
- for (auto &Use : UseToDefs) {
- // If no definition is available, this is a non candidate.
- if (Use.second.empty())
- continue;
- // Keep only instructions that are load or store and at the end of
- // a ADRP -> ADD/LDR/Nothing chain.
- // We already filtered out the no-chain cases.
- if (!isCandidate(Use.first, UseToDefs, MDT)) {
- PotentialADROpportunities.insert(Use.first);
- continue;
- }
- PotentialCandidates.insert(Use.first);
- }
-
- // Make the following distinctions for statistics as the linker does
- // know how to decode instructions:
- // - ADD/LDR/Nothing make there different patterns.
- // - LDR/STR make two different patterns.
- // Hence, 6 - 1 base patterns.
- // (because ADRP-> Nothing -> STR is not simplifiable)
-
- // The linker is only able to have a simple semantic, i.e., if pattern A
- // do B.
- // However, we want to see the opportunity we may miss if we were able to
- // catch more complex cases.
-
- // PotentialCandidates are result of a chain ADRP -> ADD/LDR ->
- // A potential candidate becomes a candidate, if its current immediate
- // operand is zero and all nodes of the chain have respectively only one user
-#ifdef DEBUG
- SetOfMachineInstr DefsOfPotentialCandidates;
-#endif
- for (const MachineInstr *Candidate : PotentialCandidates) {
- // Get the definition of the candidate i.e., ADD or LDR.
- const MachineInstr *Def = *UseToDefs.find(Candidate)->second.begin();
- // Record the elements of the chain.
- const MachineInstr *L1 = Def;
- const MachineInstr *L2 = nullptr;
- unsigned ImmediateDefOpc = Def->getOpcode();
- if (Def->getOpcode() != ARM64::ADRP) {
- // Check the number of users of this node.
- const SetOfMachineInstr *Users =
- getUses(DefsPerColorToUses,
- RegToId.find(Def->getOperand(0).getReg())->second, *Def);
- if (Users->size() > 1) {
-#ifdef DEBUG
- // if all the uses of this def are in potential candidate, this is
- // a complex candidate of level 2.
- bool IsLevel2 = true;
- for (const MachineInstr *MI : *Users) {
- if (!PotentialCandidates.count(MI)) {
- ++NumTooCplxLvl2;
- IsLevel2 = false;
- break;
- }
- }
- if (IsLevel2)
- ++NumCplxLvl2;
-#endif // DEBUG
- PotentialADROpportunities.insert(Def);
- continue;
- }
- L2 = Def;
- Def = *UseToDefs.find(Def)->second.begin();
- L1 = Def;
- } // else the element in the middle of the chain is nothing, thus
- // Def already contains the first element of the chain.
-
- // Check the number of users of the first node in the chain, i.e., ADRP
- const SetOfMachineInstr *Users =
- getUses(DefsPerColorToUses,
- RegToId.find(Def->getOperand(0).getReg())->second, *Def);
- if (Users->size() > 1) {
-#ifdef DEBUG
- // if all the uses of this def are in the defs of the potential candidate,
- // this is a complex candidate of level 1
- if (DefsOfPotentialCandidates.empty()) {
- // lazy init
- DefsOfPotentialCandidates = PotentialCandidates;
- for (const MachineInstr *Candidate : PotentialCandidates) {
- if (!UseToDefs.find(Candidate)->second.empty())
- DefsOfPotentialCandidates.insert(
- *UseToDefs.find(Candidate)->second.begin());
- }
- }
- bool Found = false;
- for (auto &Use : *Users) {
- if (!DefsOfPotentialCandidates.count(Use)) {
- ++NumTooCplxLvl1;
- Found = true;
- break;
- }
- }
- if (!Found)
- ++NumCplxLvl1;
-#endif // DEBUG
- continue;
- }
-
- bool IsL2Add = (ImmediateDefOpc == ARM64::ADDXri);
- // If the chain is three instructions long and ldr is the second element,
- // then this ldr must load form GOT, otherwise this is not a correct chain.
- if (L2 && !IsL2Add && L2->getOperand(2).getTargetFlags() != ARM64II::MO_GOT)
- continue;
- SmallVector<const MachineInstr *, 3> Args;
- MCLOHType Kind;
- if (isCandidateLoad(Candidate)) {
- if (!L2) {
- // At this point, the candidate LOH indicates that the ldr instruction
- // may use a direct access to the symbol. There is not such encoding
- // for loads of byte and half.
- if (!supportLoadFromLiteral(Candidate))
- continue;
-
- DEBUG(dbgs() << "Record AdrpLdr:\n" << *L1 << '\n' << *Candidate
- << '\n');
- Kind = MCLOH_AdrpLdr;
- Args.push_back(L1);
- Args.push_back(Candidate);
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
- "L1 already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
- "Candidate already involved in LOH.");
- ++NumADRPToLDR;
- } else {
- DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
- << "Ldr:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
- << '\n');
-
- Kind = IsL2Add ? MCLOH_AdrpAddLdr : MCLOH_AdrpLdrGotLdr;
- Args.push_back(L1);
- Args.push_back(L2);
- Args.push_back(Candidate);
-
- PotentialADROpportunities.remove(L2);
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
- "L1 already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
- "L2 already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
- "Candidate already involved in LOH.");
-#ifdef DEBUG
- // get the immediate of the load
- if (Candidate->getOperand(2).getImm() == 0)
- if (ImmediateDefOpc == ARM64::ADDXri)
- ++NumADDToLDR;
- else
- ++NumLDRToLDR;
- else if (ImmediateDefOpc == ARM64::ADDXri)
- ++NumADDToLDRWithImm;
- else
- ++NumLDRToLDRWithImm;
-#endif // DEBUG
- }
- } else {
- if (ImmediateDefOpc == ARM64::ADRP)
- continue;
- else {
-
- DEBUG(dbgs() << "Record Adrp" << (IsL2Add ? "Add" : "LdrGot")
- << "Str:\n" << *L1 << '\n' << *L2 << '\n' << *Candidate
- << '\n');
-
- Kind = IsL2Add ? MCLOH_AdrpAddStr : MCLOH_AdrpLdrGotStr;
- Args.push_back(L1);
- Args.push_back(L2);
- Args.push_back(Candidate);
-
- PotentialADROpportunities.remove(L2);
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L1)) &&
- "L1 already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(L2)) &&
- "L2 already involved in LOH.");
- assert((!InvolvedInLOHs || InvolvedInLOHs->insert(Candidate)) &&
- "Candidate already involved in LOH.");
-#ifdef DEBUG
- // get the immediate of the store
- if (Candidate->getOperand(2).getImm() == 0)
- if (ImmediateDefOpc == ARM64::ADDXri)
- ++NumADDToSTR;
- else
- ++NumLDRToSTR;
- else if (ImmediateDefOpc == ARM64::ADDXri)
- ++NumADDToSTRWithImm;
- else
- ++NumLDRToSTRWithImm;
-#endif // DEBUG
- }
- }
- ARM64FI.addLOHDirective(Kind, Args);
- }
-
- // Now, we grabbed all the big patterns, check ADR opportunities.
- for (const MachineInstr *Candidate : PotentialADROpportunities)
- registerADRCandidate(*Candidate, UseToDefs, DefsPerColorToUses, ARM64FI,
- InvolvedInLOHs, RegToId);
-}
-
-/// Look for every register defined by potential LOHs candidates.
-/// Map these registers with dense id in @p RegToId and vice-versa in
-/// @p IdToReg. @p IdToReg is populated only in DEBUG mode.
-static void collectInvolvedReg(MachineFunction &MF, MapRegToId &RegToId,
- MapIdToReg &IdToReg,
- const TargetRegisterInfo *TRI) {
- unsigned CurRegId = 0;
- if (!PreCollectRegister) {
- unsigned NbReg = TRI->getNumRegs();
- for (; CurRegId < NbReg; ++CurRegId) {
- RegToId[CurRegId] = CurRegId;
- DEBUG(IdToReg.push_back(CurRegId));
- DEBUG(assert(IdToReg[CurRegId] == CurRegId && "Reg index mismatches"));
- }
- return;
- }
-
- DEBUG(dbgs() << "** Collect Involved Register\n");
- for (const auto &MBB : MF) {
- for (const MachineInstr &MI : MBB) {
- if (!canDefBePartOfLOH(&MI))
- continue;
-
- // Process defs
- for (MachineInstr::const_mop_iterator IO = MI.operands_begin(),
- IOEnd = MI.operands_end();
- IO != IOEnd; ++IO) {
- if (!IO->isReg() || !IO->isDef())
- continue;
- unsigned CurReg = IO->getReg();
- for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI)
- if (RegToId.find(*AI) == RegToId.end()) {
- DEBUG(IdToReg.push_back(*AI);
- assert(IdToReg[CurRegId] == *AI &&
- "Reg index mismatches insertion index."));
- RegToId[*AI] = CurRegId++;
- DEBUG(dbgs() << "Register: " << PrintReg(*AI, TRI) << '\n');
- }
- }
- }
- }
-}
-
-bool ARM64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
- const TargetMachine &TM = MF.getTarget();
- const TargetRegisterInfo *TRI = TM.getRegisterInfo();
- const MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
-
- MapRegToId RegToId;
- MapIdToReg IdToReg;
- ARM64FunctionInfo *ARM64FI = MF.getInfo<ARM64FunctionInfo>();
- assert(ARM64FI && "No MachineFunctionInfo for this function!");
-
- DEBUG(dbgs() << "Looking for LOH in " << MF.getName() << '\n');
-
- collectInvolvedReg(MF, RegToId, IdToReg, TRI);
- if (RegToId.empty())
- return false;
-
- MachineInstr *DummyOp = nullptr;
- if (BasicBlockScopeOnly) {
- const ARM64InstrInfo *TII =
- static_cast<const ARM64InstrInfo *>(TM.getInstrInfo());
- // For local analysis, create a dummy operation to record uses that are not
- // local.
- DummyOp = MF.CreateMachineInstr(TII->get(ARM64::COPY), DebugLoc());
- }
-
- unsigned NbReg = RegToId.size();
- bool Modified = false;
-
- // Start with ADRP.
- InstrToInstrs *ColorOpToReachedUses = new InstrToInstrs[NbReg];
-
- // Compute the reaching def in ADRP mode, meaning ADRP definitions
- // are first considered as uses.
- reachingDef(MF, ColorOpToReachedUses, RegToId, true, DummyOp);
- DEBUG(dbgs() << "ADRP reaching defs\n");
- DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
-
- // Translate the definition to uses map into a use to definitions map to ease
- // statistic computation.
- InstrToInstrs ADRPToReachingDefs;
- reachedUsesToDefs(ADRPToReachingDefs, ColorOpToReachedUses, RegToId, true);
-
- // Compute LOH for ADRP.
- computeADRP(ADRPToReachingDefs, *ARM64FI, MDT);
- delete[] ColorOpToReachedUses;
-
- // Continue with general ADRP -> ADD/LDR -> LDR/STR pattern.
- ColorOpToReachedUses = new InstrToInstrs[NbReg];
-
- // first perform a regular reaching def analysis.
- reachingDef(MF, ColorOpToReachedUses, RegToId, false, DummyOp);
- DEBUG(dbgs() << "All reaching defs\n");
- DEBUG(printReachingDef(ColorOpToReachedUses, NbReg, TRI, IdToReg));
-
- // Turn that into a use to defs to ease statistic computation.
- InstrToInstrs UsesToReachingDefs;
- reachedUsesToDefs(UsesToReachingDefs, ColorOpToReachedUses, RegToId, false);
-
- // Compute other than AdrpAdrp LOH.
- computeOthers(UsesToReachingDefs, ColorOpToReachedUses, *ARM64FI, RegToId,
- MDT);
- delete[] ColorOpToReachedUses;
-
- if (BasicBlockScopeOnly)
- MF.DeleteMachineInstr(DummyOp);
-
- return Modified;
-}
-
-/// createARM64CollectLOHPass - returns an instance of the Statistic for
-/// linker optimization pass.
-FunctionPass *llvm::createARM64CollectLOHPass() {
- return new ARM64CollectLOH();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64ConditionalCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ConditionalCompares.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64ConditionalCompares.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64ConditionalCompares.cpp (removed)
@@ -1,919 +0,0 @@
-//===-- ARM64ConditionalCompares.cpp --- CCMP formation for ARM64 ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the ARM64ConditionalCompares pass which reduces
-// branching and code size by using the conditional compare instructions CCMP,
-// CCMN, and FCMP.
-//
-// The CFG transformations for forming conditional compares are very similar to
-// if-conversion, and this pass should run immediately before the early
-// if-conversion pass.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SparseSet.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MachineTraceMetrics.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-ccmp"
-
-// Absolute maximum number of instructions allowed per speculated block.
-// This bypasses all other heuristics, so it should be set fairly high.
-static cl::opt<unsigned> BlockInstrLimit(
- "arm64-ccmp-limit", cl::init(30), cl::Hidden,
- cl::desc("Maximum number of instructions per speculated block."));
-
-// Stress testing mode - disable heuristics.
-static cl::opt<bool> Stress("arm64-stress-ccmp", cl::Hidden,
- cl::desc("Turn all knobs to 11"));
-
-STATISTIC(NumConsidered, "Number of ccmps considered");
-STATISTIC(NumPhiRejs, "Number of ccmps rejected (PHI)");
-STATISTIC(NumPhysRejs, "Number of ccmps rejected (Physregs)");
-STATISTIC(NumPhi2Rejs, "Number of ccmps rejected (PHI2)");
-STATISTIC(NumHeadBranchRejs, "Number of ccmps rejected (Head branch)");
-STATISTIC(NumCmpBranchRejs, "Number of ccmps rejected (CmpBB branch)");
-STATISTIC(NumCmpTermRejs, "Number of ccmps rejected (CmpBB is cbz...)");
-STATISTIC(NumImmRangeRejs, "Number of ccmps rejected (Imm out of range)");
-STATISTIC(NumLiveDstRejs, "Number of ccmps rejected (Cmp dest live)");
-STATISTIC(NumMultNZCVUses, "Number of ccmps rejected (NZCV used)");
-STATISTIC(NumUnknNZCVDefs, "Number of ccmps rejected (NZCV def unknown)");
-
-STATISTIC(NumSpeculateRejs, "Number of ccmps rejected (Can't speculate)");
-
-STATISTIC(NumConverted, "Number of ccmp instructions created");
-STATISTIC(NumCompBranches, "Number of cbz/cbnz branches converted");
-
-//===----------------------------------------------------------------------===//
-// SSACCmpConv
-//===----------------------------------------------------------------------===//
-//
-// The SSACCmpConv class performs ccmp-conversion on SSA form machine code
-// after determining if it is possible. The class contains no heuristics;
-// external code should be used to determine when ccmp-conversion is a good
-// idea.
-//
-// CCmp-formation works on a CFG representing chained conditions, typically
-// from C's short-circuit || and && operators:
-//
-// From: Head To: Head
-// / | CmpBB
-// / | / |
-// | CmpBB / |
-// | / | Tail |
-// | / | | |
-// Tail | | |
-// | | | |
-// ... ... ... ...
-//
-// The Head block is terminated by a br.cond instruction, and the CmpBB block
-// contains compare + br.cond. Tail must be a successor of both.
-//
-// The cmp-conversion turns the compare instruction in CmpBB into a conditional
-// compare, and merges CmpBB into Head, speculatively executing its
-// instructions. The ARM64 conditional compare instructions have an immediate
-// operand that specifies the NZCV flag values when the condition is false and
-// the compare isn't executed. This makes it possible to chain compares with
-// different condition codes.
-//
-// Example:
-//
-// if (a == 5 || b == 17)
-// foo();
-//
-// Head:
-// cmp w0, #5
-// b.eq Tail
-// CmpBB:
-// cmp w1, #17
-// b.eq Tail
-// ...
-// Tail:
-// bl _foo
-//
-// Becomes:
-//
-// Head:
-// cmp w0, #5
-// ccmp w1, #17, 4, ne ; 4 = nZcv
-// b.eq Tail
-// ...
-// Tail:
-// bl _foo
-//
-// The ccmp condition code is the one that would cause the Head terminator to
-// branch to CmpBB.
-//
-// FIXME: It should also be possible to speculate a block on the critical edge
-// between Head and Tail, just like if-converting a diamond.
-//
-// FIXME: Handle PHIs in Tail by turning them into selects (if-conversion).
-
-namespace {
-class SSACCmpConv {
- MachineFunction *MF;
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- MachineRegisterInfo *MRI;
-
-public:
- /// The first block containing a conditional branch, dominating everything
- /// else.
- MachineBasicBlock *Head;
-
- /// The block containing cmp+br.cond with a successor shared with Head.
- MachineBasicBlock *CmpBB;
-
- /// The common successor for Head and CmpBB.
- MachineBasicBlock *Tail;
-
- /// The compare instruction in CmpBB that can be converted to a ccmp.
- MachineInstr *CmpMI;
-
-private:
- /// The branch condition in Head as determined by AnalyzeBranch.
- SmallVector<MachineOperand, 4> HeadCond;
-
- /// The condition code that makes Head branch to CmpBB.
- ARM64CC::CondCode HeadCmpBBCC;
-
- /// The branch condition in CmpBB.
- SmallVector<MachineOperand, 4> CmpBBCond;
-
- /// The condition code that makes CmpBB branch to Tail.
- ARM64CC::CondCode CmpBBTailCC;
-
- /// Check if the Tail PHIs are trivially convertible.
- bool trivialTailPHIs();
-
- /// Remove CmpBB from the Tail PHIs.
- void updateTailPHIs();
-
- /// Check if an operand defining DstReg is dead.
- bool isDeadDef(unsigned DstReg);
-
- /// Find the compare instruction in MBB that controls the conditional branch.
- /// Return NULL if a convertible instruction can't be found.
- MachineInstr *findConvertibleCompare(MachineBasicBlock *MBB);
-
- /// Return true if all non-terminator instructions in MBB can be safely
- /// speculated.
- bool canSpeculateInstrs(MachineBasicBlock *MBB, const MachineInstr *CmpMI);
-
-public:
- /// runOnMachineFunction - Initialize per-function data structures.
- void runOnMachineFunction(MachineFunction &MF) {
- this->MF = &MF;
- TII = MF.getTarget().getInstrInfo();
- TRI = MF.getTarget().getRegisterInfo();
- MRI = &MF.getRegInfo();
- }
-
- /// If the sub-CFG headed by MBB can be cmp-converted, initialize the
- /// internal state, and return true.
- bool canConvert(MachineBasicBlock *MBB);
-
- /// Cmo-convert the last block passed to canConvertCmp(), assuming
- /// it is possible. Add any erased blocks to RemovedBlocks.
- void convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks);
-
- /// Return the expected code size delta if the conversion into a
- /// conditional compare is performed.
- int expectedCodeSizeDelta() const;
-};
-} // end anonymous namespace
-
-// Check that all PHIs in Tail are selecting the same value from Head and CmpBB.
-// This means that no if-conversion is required when merging CmpBB into Head.
-bool SSACCmpConv::trivialTailPHIs() {
- for (auto &I : *Tail) {
- if (!I.isPHI())
- break;
- unsigned HeadReg = 0, CmpBBReg = 0;
- // PHI operands come in (VReg, MBB) pairs.
- for (unsigned oi = 1, oe = I.getNumOperands(); oi != oe; oi += 2) {
- MachineBasicBlock *MBB = I.getOperand(oi + 1).getMBB();
- unsigned Reg = I.getOperand(oi).getReg();
- if (MBB == Head) {
- assert((!HeadReg || HeadReg == Reg) && "Inconsistent PHI operands");
- HeadReg = Reg;
- }
- if (MBB == CmpBB) {
- assert((!CmpBBReg || CmpBBReg == Reg) && "Inconsistent PHI operands");
- CmpBBReg = Reg;
- }
- }
- if (HeadReg != CmpBBReg)
- return false;
- }
- return true;
-}
-
-// Assuming that trivialTailPHIs() is true, update the Tail PHIs by simply
-// removing the CmpBB operands. The Head operands will be identical.
-void SSACCmpConv::updateTailPHIs() {
- for (auto &I : *Tail) {
- if (!I.isPHI())
- break;
- // I is a PHI. It can have multiple entries for CmpBB.
- for (unsigned oi = I.getNumOperands(); oi > 2; oi -= 2) {
- // PHI operands are (Reg, MBB) at (oi-2, oi-1).
- if (I.getOperand(oi - 1).getMBB() == CmpBB) {
- I.RemoveOperand(oi - 1);
- I.RemoveOperand(oi - 2);
- }
- }
- }
-}
-
-// This pass runs before the ARM64DeadRegisterDefinitions pass, so compares are
-// still writing virtual registers without any uses.
-bool SSACCmpConv::isDeadDef(unsigned DstReg) {
- // Writes to the zero register are dead.
- if (DstReg == ARM64::WZR || DstReg == ARM64::XZR)
- return true;
- if (!TargetRegisterInfo::isVirtualRegister(DstReg))
- return false;
- // A virtual register def without any uses will be marked dead later, and
- // eventually replaced by the zero register.
- return MRI->use_nodbg_empty(DstReg);
-}
-
-// Parse a condition code returned by AnalyzeBranch, and compute the CondCode
-// corresponding to TBB.
-// Return
-static bool parseCond(ArrayRef<MachineOperand> Cond, ARM64CC::CondCode &CC) {
- // A normal br.cond simply has the condition code.
- if (Cond[0].getImm() != -1) {
- assert(Cond.size() == 1 && "Unknown Cond array format");
- CC = (ARM64CC::CondCode)(int)Cond[0].getImm();
- return true;
- }
- // For tbz and cbz instruction, the opcode is next.
- switch (Cond[1].getImm()) {
- default:
- // This includes tbz / tbnz branches which can't be converted to
- // ccmp + br.cond.
- return false;
- case ARM64::CBZW:
- case ARM64::CBZX:
- assert(Cond.size() == 3 && "Unknown Cond array format");
- CC = ARM64CC::EQ;
- return true;
- case ARM64::CBNZW:
- case ARM64::CBNZX:
- assert(Cond.size() == 3 && "Unknown Cond array format");
- CC = ARM64CC::NE;
- return true;
- }
-}
-
-MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) {
- MachineBasicBlock::iterator I = MBB->getFirstTerminator();
- if (I == MBB->end())
- return nullptr;
- // The terminator must be controlled by the flags.
- if (!I->readsRegister(ARM64::NZCV)) {
- switch (I->getOpcode()) {
- case ARM64::CBZW:
- case ARM64::CBZX:
- case ARM64::CBNZW:
- case ARM64::CBNZX:
- // These can be converted into a ccmp against #0.
- return I;
- }
- ++NumCmpTermRejs;
- DEBUG(dbgs() << "Flags not used by terminator: " << *I);
- return nullptr;
- }
-
- // Now find the instruction controlling the terminator.
- for (MachineBasicBlock::iterator B = MBB->begin(); I != B;) {
- --I;
- assert(!I->isTerminator() && "Spurious terminator");
- switch (I->getOpcode()) {
- // cmp is an alias for subs with a dead destination register.
- case ARM64::SUBSWri:
- case ARM64::SUBSXri:
- // cmn is an alias for adds with a dead destination register.
- case ARM64::ADDSWri:
- case ARM64::ADDSXri:
- // Check that the immediate operand is within range, ccmp wants a uimm5.
- // Rd = SUBSri Rn, imm, shift
- if (I->getOperand(3).getImm() || !isUInt<5>(I->getOperand(2).getImm())) {
- DEBUG(dbgs() << "Immediate out of range for ccmp: " << *I);
- ++NumImmRangeRejs;
- return nullptr;
- }
- // Fall through.
- case ARM64::SUBSWrr:
- case ARM64::SUBSXrr:
- case ARM64::ADDSWrr:
- case ARM64::ADDSXrr:
- if (isDeadDef(I->getOperand(0).getReg()))
- return I;
- DEBUG(dbgs() << "Can't convert compare with live destination: " << *I);
- ++NumLiveDstRejs;
- return nullptr;
- case ARM64::FCMPSrr:
- case ARM64::FCMPDrr:
- case ARM64::FCMPESrr:
- case ARM64::FCMPEDrr:
- return I;
- }
-
- // Check for flag reads and clobbers.
- MIOperands::PhysRegInfo PRI =
- MIOperands(I).analyzePhysReg(ARM64::NZCV, TRI);
-
- if (PRI.Reads) {
- // The ccmp doesn't produce exactly the same flags as the original
- // compare, so reject the transform if there are uses of the flags
- // besides the terminators.
- DEBUG(dbgs() << "Can't create ccmp with multiple uses: " << *I);
- ++NumMultNZCVUses;
- return nullptr;
- }
-
- if (PRI.Clobbers) {
- DEBUG(dbgs() << "Not convertible compare: " << *I);
- ++NumUnknNZCVDefs;
- return nullptr;
- }
- }
- DEBUG(dbgs() << "Flags not defined in BB#" << MBB->getNumber() << '\n');
- return nullptr;
-}
-
-/// Determine if all the instructions in MBB can safely
-/// be speculated. The terminators are not considered.
-///
-/// Only CmpMI is allowed to clobber the flags.
-///
-bool SSACCmpConv::canSpeculateInstrs(MachineBasicBlock *MBB,
- const MachineInstr *CmpMI) {
- // Reject any live-in physregs. It's probably NZCV/EFLAGS, and very hard to
- // get right.
- if (!MBB->livein_empty()) {
- DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has live-ins.\n");
- return false;
- }
-
- unsigned InstrCount = 0;
-
- // Check all instructions, except the terminators. It is assumed that
- // terminators never have side effects or define any used register values.
- for (auto &I : make_range(MBB->begin(), MBB->getFirstTerminator())) {
- if (I.isDebugValue())
- continue;
-
- if (++InstrCount > BlockInstrLimit && !Stress) {
- DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has more than "
- << BlockInstrLimit << " instructions.\n");
- return false;
- }
-
- // There shouldn't normally be any phis in a single-predecessor block.
- if (I.isPHI()) {
- DEBUG(dbgs() << "Can't hoist: " << I);
- return false;
- }
-
- // Don't speculate loads. Note that it may be possible and desirable to
- // speculate GOT or constant pool loads that are guaranteed not to trap,
- // but we don't support that for now.
- if (I.mayLoad()) {
- DEBUG(dbgs() << "Won't speculate load: " << I);
- return false;
- }
-
- // We never speculate stores, so an AA pointer isn't necessary.
- bool DontMoveAcrossStore = true;
- if (!I.isSafeToMove(TII, nullptr, DontMoveAcrossStore)) {
- DEBUG(dbgs() << "Can't speculate: " << I);
- return false;
- }
-
- // Only CmpMI is allowed to clobber the flags.
- if (&I != CmpMI && I.modifiesRegister(ARM64::NZCV, TRI)) {
- DEBUG(dbgs() << "Clobbers flags: " << I);
- return false;
- }
- }
- return true;
-}
-
-/// Analyze the sub-cfg rooted in MBB, and return true if it is a potential
-/// candidate for cmp-conversion. Fill out the internal state.
-///
-bool SSACCmpConv::canConvert(MachineBasicBlock *MBB) {
- Head = MBB;
- Tail = CmpBB = nullptr;
-
- if (Head->succ_size() != 2)
- return false;
- MachineBasicBlock *Succ0 = Head->succ_begin()[0];
- MachineBasicBlock *Succ1 = Head->succ_begin()[1];
-
- // CmpBB can only have a single predecessor. Tail is allowed many.
- if (Succ0->pred_size() != 1)
- std::swap(Succ0, Succ1);
-
- // Succ0 is our candidate for CmpBB.
- if (Succ0->pred_size() != 1 || Succ0->succ_size() != 2)
- return false;
-
- CmpBB = Succ0;
- Tail = Succ1;
-
- if (!CmpBB->isSuccessor(Tail))
- return false;
-
- // The CFG topology checks out.
- DEBUG(dbgs() << "\nTriangle: BB#" << Head->getNumber() << " -> BB#"
- << CmpBB->getNumber() << " -> BB#" << Tail->getNumber() << '\n');
- ++NumConsidered;
-
- // Tail is allowed to have many predecessors, but we can't handle PHIs yet.
- //
- // FIXME: Real PHIs could be if-converted as long as the CmpBB values are
- // defined before The CmpBB cmp clobbers the flags. Alternatively, it should
- // always be safe to sink the ccmp down to immediately before the CmpBB
- // terminators.
- if (!trivialTailPHIs()) {
- DEBUG(dbgs() << "Can't handle phis in Tail.\n");
- ++NumPhiRejs;
- return false;
- }
-
- if (!Tail->livein_empty()) {
- DEBUG(dbgs() << "Can't handle live-in physregs in Tail.\n");
- ++NumPhysRejs;
- return false;
- }
-
- // CmpBB should never have PHIs since Head is its only predecessor.
- // FIXME: Clean them up if it happens.
- if (!CmpBB->empty() && CmpBB->front().isPHI()) {
- DEBUG(dbgs() << "Can't handle phis in CmpBB.\n");
- ++NumPhi2Rejs;
- return false;
- }
-
- if (!CmpBB->livein_empty()) {
- DEBUG(dbgs() << "Can't handle live-in physregs in CmpBB.\n");
- ++NumPhysRejs;
- return false;
- }
-
- // The branch we're looking to eliminate must be analyzable.
- HeadCond.clear();
- MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
- if (TII->AnalyzeBranch(*Head, TBB, FBB, HeadCond)) {
- DEBUG(dbgs() << "Head branch not analyzable.\n");
- ++NumHeadBranchRejs;
- return false;
- }
-
- // This is weird, probably some sort of degenerate CFG, or an edge to a
- // landing pad.
- if (!TBB || HeadCond.empty()) {
- DEBUG(dbgs() << "AnalyzeBranch didn't find conditional branch in Head.\n");
- ++NumHeadBranchRejs;
- return false;
- }
-
- if (!parseCond(HeadCond, HeadCmpBBCC)) {
- DEBUG(dbgs() << "Unsupported branch type on Head\n");
- ++NumHeadBranchRejs;
- return false;
- }
-
- // Make sure the branch direction is right.
- if (TBB != CmpBB) {
- assert(TBB == Tail && "Unexpected TBB");
- HeadCmpBBCC = ARM64CC::getInvertedCondCode(HeadCmpBBCC);
- }
-
- CmpBBCond.clear();
- TBB = FBB = nullptr;
- if (TII->AnalyzeBranch(*CmpBB, TBB, FBB, CmpBBCond)) {
- DEBUG(dbgs() << "CmpBB branch not analyzable.\n");
- ++NumCmpBranchRejs;
- return false;
- }
-
- if (!TBB || CmpBBCond.empty()) {
- DEBUG(dbgs() << "AnalyzeBranch didn't find conditional branch in CmpBB.\n");
- ++NumCmpBranchRejs;
- return false;
- }
-
- if (!parseCond(CmpBBCond, CmpBBTailCC)) {
- DEBUG(dbgs() << "Unsupported branch type on CmpBB\n");
- ++NumCmpBranchRejs;
- return false;
- }
-
- if (TBB != Tail)
- CmpBBTailCC = ARM64CC::getInvertedCondCode(CmpBBTailCC);
-
- DEBUG(dbgs() << "Head->CmpBB on " << ARM64CC::getCondCodeName(HeadCmpBBCC)
- << ", CmpBB->Tail on " << ARM64CC::getCondCodeName(CmpBBTailCC)
- << '\n');
-
- CmpMI = findConvertibleCompare(CmpBB);
- if (!CmpMI)
- return false;
-
- if (!canSpeculateInstrs(CmpBB, CmpMI)) {
- ++NumSpeculateRejs;
- return false;
- }
- return true;
-}
-
-void SSACCmpConv::convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks) {
- DEBUG(dbgs() << "Merging BB#" << CmpBB->getNumber() << " into BB#"
- << Head->getNumber() << ":\n" << *CmpBB);
-
- // All CmpBB instructions are moved into Head, and CmpBB is deleted.
- // Update the CFG first.
- updateTailPHIs();
- Head->removeSuccessor(CmpBB);
- CmpBB->removeSuccessor(Tail);
- Head->transferSuccessorsAndUpdatePHIs(CmpBB);
- DebugLoc TermDL = Head->getFirstTerminator()->getDebugLoc();
- TII->RemoveBranch(*Head);
-
- // If the Head terminator was one of the cbz / tbz branches with built-in
- // compare, we need to insert an explicit compare instruction in its place.
- if (HeadCond[0].getImm() == -1) {
- ++NumCompBranches;
- unsigned Opc = 0;
- switch (HeadCond[1].getImm()) {
- case ARM64::CBZW:
- case ARM64::CBNZW:
- Opc = ARM64::SUBSWri;
- break;
- case ARM64::CBZX:
- case ARM64::CBNZX:
- Opc = ARM64::SUBSXri;
- break;
- default:
- llvm_unreachable("Cannot convert Head branch");
- }
- const MCInstrDesc &MCID = TII->get(Opc);
- // Create a dummy virtual register for the SUBS def.
- unsigned DestReg =
- MRI->createVirtualRegister(TII->getRegClass(MCID, 0, TRI, *MF));
- // Insert a SUBS Rn, #0 instruction instead of the cbz / cbnz.
- BuildMI(*Head, Head->end(), TermDL, MCID)
- .addReg(DestReg, RegState::Define | RegState::Dead)
- .addOperand(HeadCond[2])
- .addImm(0)
- .addImm(0);
- // SUBS uses the GPR*sp register classes.
- MRI->constrainRegClass(HeadCond[2].getReg(),
- TII->getRegClass(MCID, 1, TRI, *MF));
- }
-
- Head->splice(Head->end(), CmpBB, CmpBB->begin(), CmpBB->end());
-
- // Now replace CmpMI with a ccmp instruction that also considers the incoming
- // flags.
- unsigned Opc = 0;
- unsigned FirstOp = 1; // First CmpMI operand to copy.
- bool isZBranch = false; // CmpMI is a cbz/cbnz instruction.
- switch (CmpMI->getOpcode()) {
- default:
- llvm_unreachable("Unknown compare opcode");
- case ARM64::SUBSWri: Opc = ARM64::CCMPWi; break;
- case ARM64::SUBSWrr: Opc = ARM64::CCMPWr; break;
- case ARM64::SUBSXri: Opc = ARM64::CCMPXi; break;
- case ARM64::SUBSXrr: Opc = ARM64::CCMPXr; break;
- case ARM64::ADDSWri: Opc = ARM64::CCMNWi; break;
- case ARM64::ADDSWrr: Opc = ARM64::CCMNWr; break;
- case ARM64::ADDSXri: Opc = ARM64::CCMNXi; break;
- case ARM64::ADDSXrr: Opc = ARM64::CCMNXr; break;
- case ARM64::FCMPSrr: Opc = ARM64::FCCMPSrr; FirstOp = 0; break;
- case ARM64::FCMPDrr: Opc = ARM64::FCCMPDrr; FirstOp = 0; break;
- case ARM64::FCMPESrr: Opc = ARM64::FCCMPESrr; FirstOp = 0; break;
- case ARM64::FCMPEDrr: Opc = ARM64::FCCMPEDrr; FirstOp = 0; break;
- case ARM64::CBZW:
- case ARM64::CBNZW:
- Opc = ARM64::CCMPWi;
- FirstOp = 0;
- isZBranch = true;
- break;
- case ARM64::CBZX:
- case ARM64::CBNZX:
- Opc = ARM64::CCMPXi;
- FirstOp = 0;
- isZBranch = true;
- break;
- }
-
- // The ccmp instruction should set the flags according to the comparison when
- // Head would have branched to CmpBB.
- // The NZCV immediate operand should provide flags for the case where Head
- // would have branched to Tail. These flags should cause the new Head
- // terminator to branch to tail.
- unsigned NZCV = ARM64CC::getNZCVToSatisfyCondCode(CmpBBTailCC);
- const MCInstrDesc &MCID = TII->get(Opc);
- MRI->constrainRegClass(CmpMI->getOperand(FirstOp).getReg(),
- TII->getRegClass(MCID, 0, TRI, *MF));
- if (CmpMI->getOperand(FirstOp + 1).isReg())
- MRI->constrainRegClass(CmpMI->getOperand(FirstOp + 1).getReg(),
- TII->getRegClass(MCID, 1, TRI, *MF));
- MachineInstrBuilder MIB =
- BuildMI(*Head, CmpMI, CmpMI->getDebugLoc(), MCID)
- .addOperand(CmpMI->getOperand(FirstOp)); // Register Rn
- if (isZBranch)
- MIB.addImm(0); // cbz/cbnz Rn -> ccmp Rn, #0
- else
- MIB.addOperand(CmpMI->getOperand(FirstOp + 1)); // Register Rm / Immediate
- MIB.addImm(NZCV).addImm(HeadCmpBBCC);
-
- // If CmpMI was a terminator, we need a new conditional branch to replace it.
- // This now becomes a Head terminator.
- if (isZBranch) {
- bool isNZ = CmpMI->getOpcode() == ARM64::CBNZW ||
- CmpMI->getOpcode() == ARM64::CBNZX;
- BuildMI(*Head, CmpMI, CmpMI->getDebugLoc(), TII->get(ARM64::Bcc))
- .addImm(isNZ ? ARM64CC::NE : ARM64CC::EQ)
- .addOperand(CmpMI->getOperand(1)); // Branch target.
- }
- CmpMI->eraseFromParent();
- Head->updateTerminator();
-
- RemovedBlocks.push_back(CmpBB);
- CmpBB->eraseFromParent();
- DEBUG(dbgs() << "Result:\n" << *Head);
- ++NumConverted;
-}
-
-int SSACCmpConv::expectedCodeSizeDelta() const {
- int delta = 0;
- // If the Head terminator was one of the cbz / tbz branches with built-in
- // compare, we need to insert an explicit compare instruction in its place
- // plus a branch instruction.
- if (HeadCond[0].getImm() == -1) {
- switch (HeadCond[1].getImm()) {
- case ARM64::CBZW:
- case ARM64::CBNZW:
- case ARM64::CBZX:
- case ARM64::CBNZX:
- // Therefore delta += 1
- delta = 1;
- break;
- default:
- llvm_unreachable("Cannot convert Head branch");
- }
- }
- // If the Cmp terminator was one of the cbz / tbz branches with
- // built-in compare, it will be turned into a compare instruction
- // into Head, but we do not save any instruction.
- // Otherwise, we save the branch instruction.
- switch (CmpMI->getOpcode()) {
- default:
- --delta;
- break;
- case ARM64::CBZW:
- case ARM64::CBNZW:
- case ARM64::CBZX:
- case ARM64::CBNZX:
- break;
- }
- return delta;
-}
-
-//===----------------------------------------------------------------------===//
-// ARM64ConditionalCompares Pass
-//===----------------------------------------------------------------------===//
-
-namespace {
-class ARM64ConditionalCompares : public MachineFunctionPass {
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- const MCSchedModel *SchedModel;
- // Does the proceeded function has Oz attribute.
- bool MinSize;
- MachineRegisterInfo *MRI;
- MachineDominatorTree *DomTree;
- MachineLoopInfo *Loops;
- MachineTraceMetrics *Traces;
- MachineTraceMetrics::Ensemble *MinInstr;
- SSACCmpConv CmpConv;
-
-public:
- static char ID;
- ARM64ConditionalCompares() : MachineFunctionPass(ID) {}
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnMachineFunction(MachineFunction &MF) override;
- const char *getPassName() const override {
- return "ARM64 Conditional Compares";
- }
-
-private:
- bool tryConvert(MachineBasicBlock *);
- void updateDomTree(ArrayRef<MachineBasicBlock *> Removed);
- void updateLoops(ArrayRef<MachineBasicBlock *> Removed);
- void invalidateTraces();
- bool shouldConvert();
-};
-} // end anonymous namespace
-
-char ARM64ConditionalCompares::ID = 0;
-
-namespace llvm {
-void initializeARM64ConditionalComparesPass(PassRegistry &);
-}
-
-INITIALIZE_PASS_BEGIN(ARM64ConditionalCompares, "arm64-ccmp", "ARM64 CCMP Pass",
- false, false)
-INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics)
-INITIALIZE_PASS_END(ARM64ConditionalCompares, "arm64-ccmp", "ARM64 CCMP Pass",
- false, false)
-
-FunctionPass *llvm::createARM64ConditionalCompares() {
- return new ARM64ConditionalCompares();
-}
-
-void ARM64ConditionalCompares::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<MachineBranchProbabilityInfo>();
- AU.addRequired<MachineDominatorTree>();
- AU.addPreserved<MachineDominatorTree>();
- AU.addRequired<MachineLoopInfo>();
- AU.addPreserved<MachineLoopInfo>();
- AU.addRequired<MachineTraceMetrics>();
- AU.addPreserved<MachineTraceMetrics>();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-/// Update the dominator tree after if-conversion erased some blocks.
-void
-ARM64ConditionalCompares::updateDomTree(ArrayRef<MachineBasicBlock *> Removed) {
- // convert() removes CmpBB which was previously dominated by Head.
- // CmpBB children should be transferred to Head.
- MachineDomTreeNode *HeadNode = DomTree->getNode(CmpConv.Head);
- for (unsigned i = 0, e = Removed.size(); i != e; ++i) {
- MachineDomTreeNode *Node = DomTree->getNode(Removed[i]);
- assert(Node != HeadNode && "Cannot erase the head node");
- assert(Node->getIDom() == HeadNode && "CmpBB should be dominated by Head");
- while (Node->getNumChildren())
- DomTree->changeImmediateDominator(Node->getChildren().back(), HeadNode);
- DomTree->eraseNode(Removed[i]);
- }
-}
-
-/// Update LoopInfo after if-conversion.
-void
-ARM64ConditionalCompares::updateLoops(ArrayRef<MachineBasicBlock *> Removed) {
- if (!Loops)
- return;
- for (unsigned i = 0, e = Removed.size(); i != e; ++i)
- Loops->removeBlock(Removed[i]);
-}
-
-/// Invalidate MachineTraceMetrics before if-conversion.
-void ARM64ConditionalCompares::invalidateTraces() {
- Traces->invalidate(CmpConv.Head);
- Traces->invalidate(CmpConv.CmpBB);
-}
-
-/// Apply cost model and heuristics to the if-conversion in IfConv.
-/// Return true if the conversion is a good idea.
-///
-bool ARM64ConditionalCompares::shouldConvert() {
- // Stress testing mode disables all cost considerations.
- if (Stress)
- return true;
- if (!MinInstr)
- MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
-
- // Head dominates CmpBB, so it is always included in its trace.
- MachineTraceMetrics::Trace Trace = MinInstr->getTrace(CmpConv.CmpBB);
-
- // If code size is the main concern
- if (MinSize) {
- int CodeSizeDelta = CmpConv.expectedCodeSizeDelta();
- DEBUG(dbgs() << "Code size delta: " << CodeSizeDelta << '\n');
- // If we are minimizing the code size, do the conversion whatever
- // the cost is.
- if (CodeSizeDelta < 0)
- return true;
- if (CodeSizeDelta > 0) {
- DEBUG(dbgs() << "Code size is increasing, give up on this one.\n");
- return false;
- }
- // CodeSizeDelta == 0, continue with the regular heuristics
- }
-
- // Heuristic: The compare conversion delays the execution of the branch
- // instruction because we must wait for the inputs to the second compare as
- // well. The branch has no dependent instructions, but delaying it increases
- // the cost of a misprediction.
- //
- // Set a limit on the delay we will accept.
- unsigned DelayLimit = SchedModel->MispredictPenalty * 3 / 4;
-
- // Instruction depths can be computed for all trace instructions above CmpBB.
- unsigned HeadDepth =
- Trace.getInstrCycles(CmpConv.Head->getFirstTerminator()).Depth;
- unsigned CmpBBDepth =
- Trace.getInstrCycles(CmpConv.CmpBB->getFirstTerminator()).Depth;
- DEBUG(dbgs() << "Head depth: " << HeadDepth
- << "\nCmpBB depth: " << CmpBBDepth << '\n');
- if (CmpBBDepth > HeadDepth + DelayLimit) {
- DEBUG(dbgs() << "Branch delay would be larger than " << DelayLimit
- << " cycles.\n");
- return false;
- }
-
- // Check the resource depth at the bottom of CmpBB - these instructions will
- // be speculated.
- unsigned ResDepth = Trace.getResourceDepth(true);
- DEBUG(dbgs() << "Resources: " << ResDepth << '\n');
-
- // Heuristic: The speculatively executed instructions must all be able to
- // merge into the Head block. The Head critical path should dominate the
- // resource cost of the speculated instructions.
- if (ResDepth > HeadDepth) {
- DEBUG(dbgs() << "Too many instructions to speculate.\n");
- return false;
- }
- return true;
-}
-
-bool ARM64ConditionalCompares::tryConvert(MachineBasicBlock *MBB) {
- bool Changed = false;
- while (CmpConv.canConvert(MBB) && shouldConvert()) {
- invalidateTraces();
- SmallVector<MachineBasicBlock *, 4> RemovedBlocks;
- CmpConv.convert(RemovedBlocks);
- Changed = true;
- updateDomTree(RemovedBlocks);
- updateLoops(RemovedBlocks);
- }
- return Changed;
-}
-
-bool ARM64ConditionalCompares::runOnMachineFunction(MachineFunction &MF) {
- DEBUG(dbgs() << "********** ARM64 Conditional Compares **********\n"
- << "********** Function: " << MF.getName() << '\n');
- TII = MF.getTarget().getInstrInfo();
- TRI = MF.getTarget().getRegisterInfo();
- SchedModel =
- MF.getTarget().getSubtarget<TargetSubtargetInfo>().getSchedModel();
- MRI = &MF.getRegInfo();
- DomTree = &getAnalysis<MachineDominatorTree>();
- Loops = getAnalysisIfAvailable<MachineLoopInfo>();
- Traces = &getAnalysis<MachineTraceMetrics>();
- MinInstr = nullptr;
- MinSize = MF.getFunction()->getAttributes().hasAttribute(
- AttributeSet::FunctionIndex, Attribute::MinSize);
-
- bool Changed = false;
- CmpConv.runOnMachineFunction(MF);
-
- // Visit blocks in dominator tree pre-order. The pre-order enables multiple
- // cmp-conversions from the same head block.
- // Note that updateDomTree() modifies the children of the DomTree node
- // currently being visited. The df_iterator supports that; it doesn't look at
- // child_begin() / child_end() until after a node has been visited.
- for (auto *I : depth_first(DomTree))
- if (tryConvert(I->getBlock()))
- Changed = true;
-
- return Changed;
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64DeadRegisterDefinitionsPass.cpp (removed)
@@ -1,134 +0,0 @@
-//===-- ARM64DeadRegisterDefinitions.cpp - Replace dead defs w/ zero reg --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// When allowed by the instruction, replace a dead definition of a GPR with
-// the zero register. This makes the code a bit friendlier towards the
-// hardware's register renamer.
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64RegisterInfo.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-dead-defs"
-
-STATISTIC(NumDeadDefsReplaced, "Number of dead definitions replaced");
-
-namespace {
-class ARM64DeadRegisterDefinitions : public MachineFunctionPass {
-private:
- const TargetRegisterInfo *TRI;
- bool implicitlyDefinesOverlappingReg(unsigned Reg, const MachineInstr &MI);
- bool processMachineBasicBlock(MachineBasicBlock &MBB);
- bool usesFrameIndex(const MachineInstr &MI);
-public:
- static char ID; // Pass identification, replacement for typeid.
- explicit ARM64DeadRegisterDefinitions() : MachineFunctionPass(ID) {}
-
- virtual bool runOnMachineFunction(MachineFunction &F) override;
-
- const char *getPassName() const override { return "Dead register definitions"; }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-char ARM64DeadRegisterDefinitions::ID = 0;
-} // end anonymous namespace
-
-bool ARM64DeadRegisterDefinitions::implicitlyDefinesOverlappingReg(
- unsigned Reg, const MachineInstr &MI) {
- for (const MachineOperand &MO : MI.implicit_operands())
- if (MO.isReg() && MO.isDef())
- if (TRI->regsOverlap(Reg, MO.getReg()))
- return true;
- return false;
-}
-
-bool ARM64DeadRegisterDefinitions::usesFrameIndex(const MachineInstr &MI) {
- for (const MachineOperand &Op : MI.uses())
- if (Op.isFI())
- return true;
- return false;
-}
-
-bool
-ARM64DeadRegisterDefinitions::processMachineBasicBlock(MachineBasicBlock &MBB) {
- bool Changed = false;
- for (MachineInstr &MI : MBB) {
- if (usesFrameIndex(MI)) {
- // We need to skip this instruction because while it appears to have a
- // dead def it uses a frame index which might expand into a multi
- // instruction sequence during EPI.
- DEBUG(dbgs() << " Ignoring, operand is frame index\n");
- continue;
- }
- for (int i = 0, e = MI.getDesc().getNumDefs(); i != e; ++i) {
- MachineOperand &MO = MI.getOperand(i);
- if (MO.isReg() && MO.isDead() && MO.isDef()) {
- assert(!MO.isImplicit() && "Unexpected implicit def!");
- DEBUG(dbgs() << " Dead def operand #" << i << " in:\n ";
- MI.print(dbgs()));
- // Be careful not to change the register if it's a tied operand.
- if (MI.isRegTiedToUseOperand(i)) {
- DEBUG(dbgs() << " Ignoring, def is tied operand.\n");
- continue;
- }
- // Don't change the register if there's an implicit def of a subreg or
- // supperreg.
- if (implicitlyDefinesOverlappingReg(MO.getReg(), MI)) {
- DEBUG(dbgs() << " Ignoring, implicitly defines overlap reg.\n");
- continue;
- }
- // Make sure the instruction take a register class that contains
- // the zero register and replace it if so.
- unsigned NewReg;
- switch (MI.getDesc().OpInfo[i].RegClass) {
- default:
- DEBUG(dbgs() << " Ignoring, register is not a GPR.\n");
- continue;
- case ARM64::GPR32RegClassID:
- NewReg = ARM64::WZR;
- break;
- case ARM64::GPR64RegClassID:
- NewReg = ARM64::XZR;
- break;
- }
- DEBUG(dbgs() << " Replacing with zero register. New:\n ");
- MO.setReg(NewReg);
- DEBUG(MI.print(dbgs()));
- ++NumDeadDefsReplaced;
- }
- }
- }
- return Changed;
-}
-
-// Scan the function for instructions that have a dead definition of a
-// register. Replace that register with the zero register when possible.
-bool ARM64DeadRegisterDefinitions::runOnMachineFunction(MachineFunction &MF) {
- TRI = MF.getTarget().getRegisterInfo();
- bool Changed = false;
- DEBUG(dbgs() << "***** ARM64DeadRegisterDefinitions *****\n");
-
- for (auto &MBB : MF)
- if (processMachineBasicBlock(MBB))
- Changed = true;
- return Changed;
-}
-
-FunctionPass *llvm::createARM64DeadRegisterDefinitions() {
- return new ARM64DeadRegisterDefinitions();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64ExpandPseudoInsts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ExpandPseudoInsts.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64ExpandPseudoInsts.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64ExpandPseudoInsts.cpp (removed)
@@ -1,745 +0,0 @@
-//===-- ARM64ExpandPseudoInsts.cpp - Expand pseudo instructions ---*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a pass that expands pseudo instructions into target
-// instructions to allow proper scheduling and other late optimizations. This
-// pass should be run after register allocation but before the post-regalloc
-// scheduling pass.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "ARM64InstrInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Support/MathExtras.h"
-using namespace llvm;
-
-namespace {
-class ARM64ExpandPseudo : public MachineFunctionPass {
-public:
- static char ID;
- ARM64ExpandPseudo() : MachineFunctionPass(ID) {}
-
- const ARM64InstrInfo *TII;
-
- bool runOnMachineFunction(MachineFunction &Fn) override;
-
- const char *getPassName() const override {
- return "ARM64 pseudo instruction expansion pass";
- }
-
-private:
- bool expandMBB(MachineBasicBlock &MBB);
- bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI);
- bool expandMOVImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
- unsigned BitSize);
-};
-char ARM64ExpandPseudo::ID = 0;
-}
-
-/// \brief Transfer implicit operands on the pseudo instruction to the
-/// instructions created from the expansion.
-static void transferImpOps(MachineInstr &OldMI, MachineInstrBuilder &UseMI,
- MachineInstrBuilder &DefMI) {
- const MCInstrDesc &Desc = OldMI.getDesc();
- for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands(); i != e;
- ++i) {
- const MachineOperand &MO = OldMI.getOperand(i);
- assert(MO.isReg() && MO.getReg());
- if (MO.isUse())
- UseMI.addOperand(MO);
- else
- DefMI.addOperand(MO);
- }
-}
-
-/// \brief Helper function which extracts the specified 16-bit chunk from a
-/// 64-bit value.
-static uint64_t getChunk(uint64_t Imm, unsigned ChunkIdx) {
- assert(ChunkIdx < 4 && "Out of range chunk index specified!");
-
- return (Imm >> (ChunkIdx * 16)) & 0xFFFF;
-}
-
-/// \brief Helper function which replicates a 16-bit chunk within a 64-bit
-/// value. Indices correspond to element numbers in a v4i16.
-static uint64_t replicateChunk(uint64_t Imm, unsigned FromIdx, unsigned ToIdx) {
- assert((FromIdx < 4) && (ToIdx < 4) && "Out of range chunk index specified!");
- const unsigned ShiftAmt = ToIdx * 16;
-
- // Replicate the source chunk to the destination position.
- const uint64_t Chunk = getChunk(Imm, FromIdx) << ShiftAmt;
- // Clear the destination chunk.
- Imm &= ~(0xFFFFLL << ShiftAmt);
- // Insert the replicated chunk.
- return Imm | Chunk;
-}
-
-/// \brief Helper function which tries to materialize a 64-bit value with an
-/// ORR + MOVK instruction sequence.
-static bool tryOrrMovk(uint64_t UImm, uint64_t OrrImm, MachineInstr &MI,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI,
- const ARM64InstrInfo *TII, unsigned ChunkIdx) {
- assert(ChunkIdx < 4 && "Out of range chunk index specified!");
- const unsigned ShiftAmt = ChunkIdx * 16;
-
- uint64_t Encoding;
- if (ARM64_AM::processLogicalImmediate(OrrImm, 64, Encoding)) {
- // Create the ORR-immediate instruction.
- MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ORRXri))
- .addOperand(MI.getOperand(0))
- .addReg(ARM64::XZR)
- .addImm(Encoding);
-
- // Create the MOVK instruction.
- const unsigned Imm16 = getChunk(UImm, ChunkIdx);
- const unsigned DstReg = MI.getOperand(0).getReg();
- const bool DstIsDead = MI.getOperand(0).isDead();
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::MOVKXi))
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg)
- .addImm(Imm16)
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, ShiftAmt));
-
- transferImpOps(MI, MIB, MIB1);
- MI.eraseFromParent();
- return true;
- }
-
- return false;
-}
-
-/// \brief Check whether the given 16-bit chunk replicated to full 64-bit width
-/// can be materialized with an ORR instruction.
-static bool canUseOrr(uint64_t Chunk, uint64_t &Encoding) {
- Chunk = (Chunk << 48) | (Chunk << 32) | (Chunk << 16) | Chunk;
-
- return ARM64_AM::processLogicalImmediate(Chunk, 64, Encoding);
-}
-
-/// \brief Check for identical 16-bit chunks within the constant and if so
-/// materialize them with a single ORR instruction. The remaining one or two
-/// 16-bit chunks will be materialized with MOVK instructions.
-///
-/// This allows us to materialize constants like |A|B|A|A| or |A|B|C|A| (order
-/// of the chunks doesn't matter), assuming |A|A|A|A| can be materialized with
-/// an ORR instruction.
-///
-static bool tryToreplicateChunks(uint64_t UImm, MachineInstr &MI,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI,
- const ARM64InstrInfo *TII) {
- typedef DenseMap<uint64_t, unsigned> CountMap;
- CountMap Counts;
-
- // Scan the constant and count how often every chunk occurs.
- for (unsigned Idx = 0; Idx < 4; ++Idx)
- ++Counts[getChunk(UImm, Idx)];
-
- // Traverse the chunks to find one which occurs more than once.
- for (CountMap::const_iterator Chunk = Counts.begin(), End = Counts.end();
- Chunk != End; ++Chunk) {
- const uint64_t ChunkVal = Chunk->first;
- const unsigned Count = Chunk->second;
-
- uint64_t Encoding = 0;
-
- // We are looking for chunks which have two or three instances and can be
- // materialized with an ORR instruction.
- if ((Count != 2 && Count != 3) || !canUseOrr(ChunkVal, Encoding))
- continue;
-
- const bool CountThree = Count == 3;
- // Create the ORR-immediate instruction.
- MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ORRXri))
- .addOperand(MI.getOperand(0))
- .addReg(ARM64::XZR)
- .addImm(Encoding);
-
- const unsigned DstReg = MI.getOperand(0).getReg();
- const bool DstIsDead = MI.getOperand(0).isDead();
-
- unsigned ShiftAmt = 0;
- uint64_t Imm16 = 0;
- // Find the first chunk not materialized with the ORR instruction.
- for (; ShiftAmt < 64; ShiftAmt += 16) {
- Imm16 = (UImm >> ShiftAmt) & 0xFFFF;
-
- if (Imm16 != ChunkVal)
- break;
- }
-
- // Create the first MOVK instruction.
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::MOVKXi))
- .addReg(DstReg,
- RegState::Define | getDeadRegState(DstIsDead && CountThree))
- .addReg(DstReg)
- .addImm(Imm16)
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, ShiftAmt));
-
- // In case we have three instances the whole constant is now materialized
- // and we can exit.
- if (CountThree) {
- transferImpOps(MI, MIB, MIB1);
- MI.eraseFromParent();
- return true;
- }
-
- // Find the remaining chunk which needs to be materialized.
- for (ShiftAmt += 16; ShiftAmt < 64; ShiftAmt += 16) {
- Imm16 = (UImm >> ShiftAmt) & 0xFFFF;
-
- if (Imm16 != ChunkVal)
- break;
- }
-
- // Create the second MOVK instruction.
- MachineInstrBuilder MIB2 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::MOVKXi))
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg)
- .addImm(Imm16)
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, ShiftAmt));
-
- transferImpOps(MI, MIB, MIB2);
- MI.eraseFromParent();
- return true;
- }
-
- return false;
-}
-
-/// \brief Check whether this chunk matches the pattern '1...0...'. This pattern
-/// starts a contiguous sequence of ones if we look at the bits from the LSB
-/// towards the MSB.
-static bool isStartChunk(uint64_t Chunk) {
- if (Chunk == 0 || Chunk == UINT64_MAX)
- return false;
-
- return (CountLeadingOnes_64(Chunk) + countTrailingZeros(Chunk)) == 64;
-}
-
-/// \brief Check whether this chunk matches the pattern '0...1...' This pattern
-/// ends a contiguous sequence of ones if we look at the bits from the LSB
-/// towards the MSB.
-static bool isEndChunk(uint64_t Chunk) {
- if (Chunk == 0 || Chunk == UINT64_MAX)
- return false;
-
- return (countLeadingZeros(Chunk) + CountTrailingOnes_64(Chunk)) == 64;
-}
-
-/// \brief Clear or set all bits in the chunk at the given index.
-static uint64_t updateImm(uint64_t Imm, unsigned Idx, bool Clear) {
- const uint64_t Mask = 0xFFFF;
-
- if (Clear)
- // Clear chunk in the immediate.
- Imm &= ~(Mask << (Idx * 16));
- else
- // Set all bits in the immediate for the particular chunk.
- Imm |= Mask << (Idx * 16);
-
- return Imm;
-}
-
-/// \brief Check whether the constant contains a sequence of contiguous ones,
-/// which might be interrupted by one or two chunks. If so, materialize the
-/// sequence of contiguous ones with an ORR instruction.
-/// Materialize the chunks which are either interrupting the sequence or outside
-/// of the sequence with a MOVK instruction.
-///
-/// Assuming S is a chunk which starts the sequence (1...0...), E is a chunk
-/// which ends the sequence (0...1...). Then we are looking for constants which
-/// contain at least one S and E chunk.
-/// E.g. |E|A|B|S|, |A|E|B|S| or |A|B|E|S|.
-///
-/// We are also looking for constants like |S|A|B|E| where the contiguous
-/// sequence of ones wraps around the MSB into the LSB.
-///
-static bool trySequenceOfOnes(uint64_t UImm, MachineInstr &MI,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI,
- const ARM64InstrInfo *TII) {
- const int NotSet = -1;
- const uint64_t Mask = 0xFFFF;
-
- int StartIdx = NotSet;
- int EndIdx = NotSet;
- // Try to find the chunks which start/end a contiguous sequence of ones.
- for (int Idx = 0; Idx < 4; ++Idx) {
- int64_t Chunk = getChunk(UImm, Idx);
- // Sign extend the 16-bit chunk to 64-bit.
- Chunk = (Chunk << 48) >> 48;
-
- if (isStartChunk(Chunk))
- StartIdx = Idx;
- else if (isEndChunk(Chunk))
- EndIdx = Idx;
- }
-
- // Early exit in case we can't find a start/end chunk.
- if (StartIdx == NotSet || EndIdx == NotSet)
- return false;
-
- // Outside of the contiguous sequence of ones everything needs to be zero.
- uint64_t Outside = 0;
- // Chunks between the start and end chunk need to have all their bits set.
- uint64_t Inside = Mask;
-
- // If our contiguous sequence of ones wraps around from the MSB into the LSB,
- // just swap indices and pretend we are materializing a contiguous sequence
- // of zeros surrounded by a contiguous sequence of ones.
- if (StartIdx > EndIdx) {
- std::swap(StartIdx, EndIdx);
- std::swap(Outside, Inside);
- }
-
- uint64_t OrrImm = UImm;
- int FirstMovkIdx = NotSet;
- int SecondMovkIdx = NotSet;
-
- // Find out which chunks we need to patch up to obtain a contiguous sequence
- // of ones.
- for (int Idx = 0; Idx < 4; ++Idx) {
- const uint64_t Chunk = getChunk(UImm, Idx);
-
- // Check whether we are looking at a chunk which is not part of the
- // contiguous sequence of ones.
- if ((Idx < StartIdx || EndIdx < Idx) && Chunk != Outside) {
- OrrImm = updateImm(OrrImm, Idx, Outside == 0);
-
- // Remember the index we need to patch.
- if (FirstMovkIdx == NotSet)
- FirstMovkIdx = Idx;
- else
- SecondMovkIdx = Idx;
-
- // Check whether we are looking a chunk which is part of the contiguous
- // sequence of ones.
- } else if (Idx > StartIdx && Idx < EndIdx && Chunk != Inside) {
- OrrImm = updateImm(OrrImm, Idx, Inside != Mask);
-
- // Remember the index we need to patch.
- if (FirstMovkIdx == NotSet)
- FirstMovkIdx = Idx;
- else
- SecondMovkIdx = Idx;
- }
- }
- assert(FirstMovkIdx != NotSet && "Constant materializable with single ORR!");
-
- // Create the ORR-immediate instruction.
- uint64_t Encoding = 0;
- ARM64_AM::processLogicalImmediate(OrrImm, 64, Encoding);
- MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ORRXri))
- .addOperand(MI.getOperand(0))
- .addReg(ARM64::XZR)
- .addImm(Encoding);
-
- const unsigned DstReg = MI.getOperand(0).getReg();
- const bool DstIsDead = MI.getOperand(0).isDead();
-
- const bool SingleMovk = SecondMovkIdx == NotSet;
- // Create the first MOVK instruction.
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::MOVKXi))
- .addReg(DstReg,
- RegState::Define | getDeadRegState(DstIsDead && SingleMovk))
- .addReg(DstReg)
- .addImm(getChunk(UImm, FirstMovkIdx))
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, FirstMovkIdx * 16));
-
- // Early exit in case we only need to emit a single MOVK instruction.
- if (SingleMovk) {
- transferImpOps(MI, MIB, MIB1);
- MI.eraseFromParent();
- return true;
- }
-
- // Create the second MOVK instruction.
- MachineInstrBuilder MIB2 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::MOVKXi))
- .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(DstReg)
- .addImm(getChunk(UImm, SecondMovkIdx))
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, SecondMovkIdx * 16));
-
- transferImpOps(MI, MIB, MIB2);
- MI.eraseFromParent();
- return true;
-}
-
-/// \brief Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more
-/// real move-immediate instructions to synthesize the immediate.
-bool ARM64ExpandPseudo::expandMOVImm(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned BitSize) {
- MachineInstr &MI = *MBBI;
- uint64_t Imm = MI.getOperand(1).getImm();
- const unsigned Mask = 0xFFFF;
-
- // Try a MOVI instruction (aka ORR-immediate with the zero register).
- uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize);
- uint64_t Encoding;
- if (ARM64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) {
- unsigned Opc = (BitSize == 32 ? ARM64::ORRWri : ARM64::ORRXri);
- MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc))
- .addOperand(MI.getOperand(0))
- .addReg(BitSize == 32 ? ARM64::WZR : ARM64::XZR)
- .addImm(Encoding);
- transferImpOps(MI, MIB, MIB);
- MI.eraseFromParent();
- return true;
- }
-
- // Scan the immediate and count the number of 16-bit chunks which are either
- // all ones or all zeros.
- unsigned OneChunks = 0;
- unsigned ZeroChunks = 0;
- for (unsigned Shift = 0; Shift < BitSize; Shift += 16) {
- const unsigned Chunk = (Imm >> Shift) & Mask;
- if (Chunk == Mask)
- OneChunks++;
- else if (Chunk == 0)
- ZeroChunks++;
- }
-
- // Since we can't materialize the constant with a single ORR instruction,
- // let's see whether we can materialize 3/4 of the constant with an ORR
- // instruction and use an additional MOVK instruction to materialize the
- // remaining 1/4.
- //
- // We are looking for constants with a pattern like: |A|X|B|X| or |X|A|X|B|.
- //
- // E.g. assuming |A|X|A|X| is a pattern which can be materialized with ORR,
- // we would create the following instruction sequence:
- //
- // ORR x0, xzr, |A|X|A|X|
- // MOVK x0, |B|, LSL #16
- //
- // Only look at 64-bit constants which can't be materialized with a single
- // instruction e.g. which have less than either three all zero or all one
- // chunks.
- //
- // Ignore 32-bit constants here, they always can be materialized with a
- // MOVZ/MOVN + MOVK pair. Since the 32-bit constant can't be materialized
- // with a single ORR, the best sequence we can achieve is a ORR + MOVK pair.
- // Thus we fall back to the default code below which in the best case creates
- // a single MOVZ/MOVN instruction (in case one chunk is all zero or all one).
- //
- if (BitSize == 64 && OneChunks < 3 && ZeroChunks < 3) {
- // If we interpret the 64-bit constant as a v4i16, are elements 0 and 2
- // identical?
- if (getChunk(UImm, 0) == getChunk(UImm, 2)) {
- // See if we can come up with a constant which can be materialized with
- // ORR-immediate by replicating element 3 into element 1.
- uint64_t OrrImm = replicateChunk(UImm, 3, 1);
- if (tryOrrMovk(UImm, OrrImm, MI, MBB, MBBI, TII, 1))
- return true;
-
- // See if we can come up with a constant which can be materialized with
- // ORR-immediate by replicating element 1 into element 3.
- OrrImm = replicateChunk(UImm, 1, 3);
- if (tryOrrMovk(UImm, OrrImm, MI, MBB, MBBI, TII, 3))
- return true;
-
- // If we interpret the 64-bit constant as a v4i16, are elements 1 and 3
- // identical?
- } else if (getChunk(UImm, 1) == getChunk(UImm, 3)) {
- // See if we can come up with a constant which can be materialized with
- // ORR-immediate by replicating element 2 into element 0.
- uint64_t OrrImm = replicateChunk(UImm, 2, 0);
- if (tryOrrMovk(UImm, OrrImm, MI, MBB, MBBI, TII, 0))
- return true;
-
- // See if we can come up with a constant which can be materialized with
- // ORR-immediate by replicating element 1 into element 3.
- OrrImm = replicateChunk(UImm, 0, 2);
- if (tryOrrMovk(UImm, OrrImm, MI, MBB, MBBI, TII, 2))
- return true;
- }
- }
-
- // Check for identical 16-bit chunks within the constant and if so materialize
- // them with a single ORR instruction. The remaining one or two 16-bit chunks
- // will be materialized with MOVK instructions.
- if (BitSize == 64 && tryToreplicateChunks(UImm, MI, MBB, MBBI, TII))
- return true;
-
- // Check whether the constant contains a sequence of contiguous ones, which
- // might be interrupted by one or two chunks. If so, materialize the sequence
- // of contiguous ones with an ORR instruction. Materialize the chunks which
- // are either interrupting the sequence or outside of the sequence with a
- // MOVK instruction.
- if (BitSize == 64 && trySequenceOfOnes(UImm, MI, MBB, MBBI, TII))
- return true;
-
- // Use a MOVZ or MOVN instruction to set the high bits, followed by one or
- // more MOVK instructions to insert additional 16-bit portions into the
- // lower bits.
- bool isNeg = false;
-
- // Use MOVN to materialize the high bits if we have more all one chunks
- // than all zero chunks.
- if (OneChunks > ZeroChunks) {
- isNeg = true;
- Imm = ~Imm;
- }
-
- unsigned FirstOpc;
- if (BitSize == 32) {
- Imm &= (1LL << 32) - 1;
- FirstOpc = (isNeg ? ARM64::MOVNWi : ARM64::MOVZWi);
- } else {
- FirstOpc = (isNeg ? ARM64::MOVNXi : ARM64::MOVZXi);
- }
- unsigned Shift = 0; // LSL amount for high bits with MOVZ/MOVN
- unsigned LastShift = 0; // LSL amount for last MOVK
- if (Imm != 0) {
- unsigned LZ = countLeadingZeros(Imm);
- unsigned TZ = countTrailingZeros(Imm);
- Shift = ((63 - LZ) / 16) * 16;
- LastShift = (TZ / 16) * 16;
- }
- unsigned Imm16 = (Imm >> Shift) & Mask;
- unsigned DstReg = MI.getOperand(0).getReg();
- bool DstIsDead = MI.getOperand(0).isDead();
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(FirstOpc))
- .addReg(DstReg, RegState::Define |
- getDeadRegState(DstIsDead && Shift == LastShift))
- .addImm(Imm16)
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, Shift));
-
- // If a MOVN was used for the high bits of a negative value, flip the rest
- // of the bits back for use with MOVK.
- if (isNeg)
- Imm = ~Imm;
-
- if (Shift == LastShift) {
- transferImpOps(MI, MIB1, MIB1);
- MI.eraseFromParent();
- return true;
- }
-
- MachineInstrBuilder MIB2;
- unsigned Opc = (BitSize == 32 ? ARM64::MOVKWi : ARM64::MOVKXi);
- while (Shift != LastShift) {
- Shift -= 16;
- Imm16 = (Imm >> Shift) & Mask;
- if (Imm16 == (isNeg ? Mask : 0))
- continue; // This 16-bit portion is already set correctly.
- MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc))
- .addReg(DstReg,
- RegState::Define |
- getDeadRegState(DstIsDead && Shift == LastShift))
- .addReg(DstReg)
- .addImm(Imm16)
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, Shift));
- }
-
- transferImpOps(MI, MIB1, MIB2);
- MI.eraseFromParent();
- return true;
-}
-
-/// \brief If MBBI references a pseudo instruction that should be expanded here,
-/// do the expansion and return true. Otherwise return false.
-bool ARM64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI) {
- MachineInstr &MI = *MBBI;
- unsigned Opcode = MI.getOpcode();
- switch (Opcode) {
- default:
- break;
-
- case ARM64::ADDWrr:
- case ARM64::SUBWrr:
- case ARM64::ADDXrr:
- case ARM64::SUBXrr:
- case ARM64::ADDSWrr:
- case ARM64::SUBSWrr:
- case ARM64::ADDSXrr:
- case ARM64::SUBSXrr:
- case ARM64::ANDWrr:
- case ARM64::ANDXrr:
- case ARM64::BICWrr:
- case ARM64::BICXrr:
- case ARM64::ANDSWrr:
- case ARM64::ANDSXrr:
- case ARM64::BICSWrr:
- case ARM64::BICSXrr:
- case ARM64::EONWrr:
- case ARM64::EONXrr:
- case ARM64::EORWrr:
- case ARM64::EORXrr:
- case ARM64::ORNWrr:
- case ARM64::ORNXrr:
- case ARM64::ORRWrr:
- case ARM64::ORRXrr: {
- unsigned Opcode;
- switch (MI.getOpcode()) {
- default:
- return false;
- case ARM64::ADDWrr: Opcode = ARM64::ADDWrs; break;
- case ARM64::SUBWrr: Opcode = ARM64::SUBWrs; break;
- case ARM64::ADDXrr: Opcode = ARM64::ADDXrs; break;
- case ARM64::SUBXrr: Opcode = ARM64::SUBXrs; break;
- case ARM64::ADDSWrr: Opcode = ARM64::ADDSWrs; break;
- case ARM64::SUBSWrr: Opcode = ARM64::SUBSWrs; break;
- case ARM64::ADDSXrr: Opcode = ARM64::ADDSXrs; break;
- case ARM64::SUBSXrr: Opcode = ARM64::SUBSXrs; break;
- case ARM64::ANDWrr: Opcode = ARM64::ANDWrs; break;
- case ARM64::ANDXrr: Opcode = ARM64::ANDXrs; break;
- case ARM64::BICWrr: Opcode = ARM64::BICWrs; break;
- case ARM64::BICXrr: Opcode = ARM64::BICXrs; break;
- case ARM64::ANDSWrr: Opcode = ARM64::ANDSWrs; break;
- case ARM64::ANDSXrr: Opcode = ARM64::ANDSXrs; break;
- case ARM64::BICSWrr: Opcode = ARM64::BICSWrs; break;
- case ARM64::BICSXrr: Opcode = ARM64::BICSXrs; break;
- case ARM64::EONWrr: Opcode = ARM64::EONWrs; break;
- case ARM64::EONXrr: Opcode = ARM64::EONXrs; break;
- case ARM64::EORWrr: Opcode = ARM64::EORWrs; break;
- case ARM64::EORXrr: Opcode = ARM64::EORXrs; break;
- case ARM64::ORNWrr: Opcode = ARM64::ORNWrs; break;
- case ARM64::ORNXrr: Opcode = ARM64::ORNXrs; break;
- case ARM64::ORRWrr: Opcode = ARM64::ORRWrs; break;
- case ARM64::ORRXrr: Opcode = ARM64::ORRXrs; break;
- }
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opcode),
- MI.getOperand(0).getReg())
- .addOperand(MI.getOperand(1))
- .addOperand(MI.getOperand(2))
- .addImm(ARM64_AM::getShifterImm(ARM64_AM::LSL, 0));
- transferImpOps(MI, MIB1, MIB1);
- MI.eraseFromParent();
- return true;
- }
-
- case ARM64::FCVTSHpseudo: {
- MachineOperand Src = MI.getOperand(1);
- Src.setImplicit();
- unsigned SrcH = TII->getRegisterInfo().getSubReg(Src.getReg(), ARM64::hsub);
- auto MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::FCVTSHr))
- .addOperand(MI.getOperand(0))
- .addReg(SrcH, RegState::Undef)
- .addOperand(Src);
- transferImpOps(MI, MIB, MIB);
- MI.eraseFromParent();
- return true;
- }
- case ARM64::LOADgot: {
- // Expand into ADRP + LDR.
- unsigned DstReg = MI.getOperand(0).getReg();
- const MachineOperand &MO1 = MI.getOperand(1);
- unsigned Flags = MO1.getTargetFlags();
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ADRP), DstReg);
- MachineInstrBuilder MIB2 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::LDRXui))
- .addOperand(MI.getOperand(0))
- .addReg(DstReg);
-
- if (MO1.isGlobal()) {
- MIB1.addGlobalAddress(MO1.getGlobal(), 0, Flags | ARM64II::MO_PAGE);
- MIB2.addGlobalAddress(MO1.getGlobal(), 0,
- Flags | ARM64II::MO_PAGEOFF | ARM64II::MO_NC);
- } else if (MO1.isSymbol()) {
- MIB1.addExternalSymbol(MO1.getSymbolName(), Flags | ARM64II::MO_PAGE);
- MIB2.addExternalSymbol(MO1.getSymbolName(),
- Flags | ARM64II::MO_PAGEOFF | ARM64II::MO_NC);
- } else {
- assert(MO1.isCPI() &&
- "Only expect globals, externalsymbols, or constant pools");
- MIB1.addConstantPoolIndex(MO1.getIndex(), MO1.getOffset(),
- Flags | ARM64II::MO_PAGE);
- MIB2.addConstantPoolIndex(MO1.getIndex(), MO1.getOffset(),
- Flags | ARM64II::MO_PAGEOFF | ARM64II::MO_NC);
- }
-
- transferImpOps(MI, MIB1, MIB2);
- MI.eraseFromParent();
- return true;
- }
-
- case ARM64::MOVaddr:
- case ARM64::MOVaddrJT:
- case ARM64::MOVaddrCP:
- case ARM64::MOVaddrBA:
- case ARM64::MOVaddrTLS:
- case ARM64::MOVaddrEXT: {
- // Expand into ADRP + ADD.
- unsigned DstReg = MI.getOperand(0).getReg();
- MachineInstrBuilder MIB1 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ADRP), DstReg)
- .addOperand(MI.getOperand(1));
-
- MachineInstrBuilder MIB2 =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::ADDXri))
- .addOperand(MI.getOperand(0))
- .addReg(DstReg)
- .addOperand(MI.getOperand(2))
- .addImm(0);
-
- transferImpOps(MI, MIB1, MIB2);
- MI.eraseFromParent();
- return true;
- }
-
- case ARM64::MOVi32imm:
- return expandMOVImm(MBB, MBBI, 32);
- case ARM64::MOVi64imm:
- return expandMOVImm(MBB, MBBI, 64);
- case ARM64::RET_ReallyLR:
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM64::RET))
- .addReg(ARM64::LR);
- MI.eraseFromParent();
- return true;
- }
- return false;
-}
-
-/// \brief Iterate over the instructions in basic block MBB and expand any
-/// pseudo instructions. Return true if anything was modified.
-bool ARM64ExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
- bool Modified = false;
-
- MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
- while (MBBI != E) {
- MachineBasicBlock::iterator NMBBI = std::next(MBBI);
- Modified |= expandMI(MBB, MBBI);
- MBBI = NMBBI;
- }
-
- return Modified;
-}
-
-bool ARM64ExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
- TII = static_cast<const ARM64InstrInfo *>(MF.getTarget().getInstrInfo());
-
- bool Modified = false;
- for (auto &MBB : MF)
- Modified |= expandMBB(MBB);
- return Modified;
-}
-
-/// \brief Returns an instance of the pseudo instruction expansion pass.
-FunctionPass *llvm::createARM64ExpandPseudoPass() {
- return new ARM64ExpandPseudo();
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64FastISel.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64FastISel.cpp (removed)
@@ -1,1977 +0,0 @@
-//===-- ARM6464FastISel.cpp - ARM64 FastISel implementation ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ARM64-specific support for the FastISel class. Some
-// of the target-specific code is generated by tablegen in the file
-// ARM64GenFastISel.inc, which is #included here.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64.h"
-#include "ARM64TargetMachine.h"
-#include "ARM64Subtarget.h"
-#include "ARM64CallingConv.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "llvm/CodeGen/CallingConvLower.h"
-#include "llvm/CodeGen/FastISel.h"
-#include "llvm/CodeGen/FunctionLoweringInfo.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/IR/GlobalAlias.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/Support/CommandLine.h"
-using namespace llvm;
-
-namespace {
-
-class ARM64FastISel : public FastISel {
-
- class Address {
- public:
- typedef enum {
- RegBase,
- FrameIndexBase
- } BaseKind;
-
- private:
- BaseKind Kind;
- union {
- unsigned Reg;
- int FI;
- } Base;
- int64_t Offset;
-
- public:
- Address() : Kind(RegBase), Offset(0) { Base.Reg = 0; }
- void setKind(BaseKind K) { Kind = K; }
- BaseKind getKind() const { return Kind; }
- bool isRegBase() const { return Kind == RegBase; }
- bool isFIBase() const { return Kind == FrameIndexBase; }
- void setReg(unsigned Reg) {
- assert(isRegBase() && "Invalid base register access!");
- Base.Reg = Reg;
- }
- unsigned getReg() const {
- assert(isRegBase() && "Invalid base register access!");
- return Base.Reg;
- }
- void setFI(unsigned FI) {
- assert(isFIBase() && "Invalid base frame index access!");
- Base.FI = FI;
- }
- unsigned getFI() const {
- assert(isFIBase() && "Invalid base frame index access!");
- return Base.FI;
- }
- void setOffset(int64_t O) { Offset = O; }
- int64_t getOffset() { return Offset; }
-
- bool isValid() { return isFIBase() || (isRegBase() && getReg() != 0); }
- };
-
- /// Subtarget - Keep a pointer to the ARM64Subtarget around so that we can
- /// make the right decision when generating code for different targets.
- const ARM64Subtarget *Subtarget;
- LLVMContext *Context;
-
-private:
- // Selection routines.
- bool SelectLoad(const Instruction *I);
- bool SelectStore(const Instruction *I);
- bool SelectBranch(const Instruction *I);
- bool SelectIndirectBr(const Instruction *I);
- bool SelectCmp(const Instruction *I);
- bool SelectSelect(const Instruction *I);
- bool SelectFPExt(const Instruction *I);
- bool SelectFPTrunc(const Instruction *I);
- bool SelectFPToInt(const Instruction *I, bool Signed);
- bool SelectIntToFP(const Instruction *I, bool Signed);
- bool SelectRem(const Instruction *I, unsigned ISDOpcode);
- bool SelectCall(const Instruction *I, const char *IntrMemName);
- bool SelectIntrinsicCall(const IntrinsicInst &I);
- bool SelectRet(const Instruction *I);
- bool SelectTrunc(const Instruction *I);
- bool SelectIntExt(const Instruction *I);
- bool SelectMul(const Instruction *I);
-
- // Utility helper routines.
- bool isTypeLegal(Type *Ty, MVT &VT);
- bool isLoadStoreTypeLegal(Type *Ty, MVT &VT);
- bool ComputeAddress(const Value *Obj, Address &Addr);
- bool SimplifyAddress(Address &Addr, MVT VT, int64_t ScaleFactor,
- bool UseUnscaled);
- void AddLoadStoreOperands(Address &Addr, const MachineInstrBuilder &MIB,
- unsigned Flags, bool UseUnscaled);
- bool IsMemCpySmall(uint64_t Len, unsigned Alignment);
- bool TryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
- unsigned Alignment);
- // Emit functions.
- bool EmitCmp(Value *Src1Value, Value *Src2Value, bool isZExt);
- bool EmitLoad(MVT VT, unsigned &ResultReg, Address Addr,
- bool UseUnscaled = false);
- bool EmitStore(MVT VT, unsigned SrcReg, Address Addr,
- bool UseUnscaled = false);
- unsigned EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);
- unsigned Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt);
-
- unsigned ARM64MaterializeFP(const ConstantFP *CFP, MVT VT);
- unsigned ARM64MaterializeGV(const GlobalValue *GV);
-
- // Call handling routines.
-private:
- CCAssignFn *CCAssignFnForCall(CallingConv::ID CC) const;
- bool ProcessCallArgs(SmallVectorImpl<Value *> &Args,
- SmallVectorImpl<unsigned> &ArgRegs,
- SmallVectorImpl<MVT> &ArgVTs,
- SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
- SmallVectorImpl<unsigned> &RegArgs, CallingConv::ID CC,
- unsigned &NumBytes);
- bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
- const Instruction *I, CallingConv::ID CC, unsigned &NumBytes);
-
-public:
- // Backend specific FastISel code.
- unsigned TargetMaterializeAlloca(const AllocaInst *AI) override;
- unsigned TargetMaterializeConstant(const Constant *C) override;
-
- explicit ARM64FastISel(FunctionLoweringInfo &funcInfo,
- const TargetLibraryInfo *libInfo)
- : FastISel(funcInfo, libInfo) {
- Subtarget = &TM.getSubtarget<ARM64Subtarget>();
- Context = &funcInfo.Fn->getContext();
- }
-
- bool TargetSelectInstruction(const Instruction *I) override;
-
-#include "ARM64GenFastISel.inc"
-};
-
-} // end anonymous namespace
-
-#include "ARM64GenCallingConv.inc"
-
-CCAssignFn *ARM64FastISel::CCAssignFnForCall(CallingConv::ID CC) const {
- if (CC == CallingConv::WebKit_JS)
- return CC_ARM64_WebKit_JS;
- return Subtarget->isTargetDarwin() ? CC_ARM64_DarwinPCS : CC_ARM64_AAPCS;
-}
-
-unsigned ARM64FastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
- assert(TLI.getValueType(AI->getType(), true) == MVT::i64 &&
- "Alloca should always return a pointer.");
-
- // Don't handle dynamic allocas.
- if (!FuncInfo.StaticAllocaMap.count(AI))
- return 0;
-
- DenseMap<const AllocaInst *, int>::iterator SI =
- FuncInfo.StaticAllocaMap.find(AI);
-
- if (SI != FuncInfo.StaticAllocaMap.end()) {
- unsigned ResultReg = createResultReg(&ARM64::GPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ADDXri),
- ResultReg)
- .addFrameIndex(SI->second)
- .addImm(0)
- .addImm(0);
- return ResultReg;
- }
-
- return 0;
-}
-
-unsigned ARM64FastISel::ARM64MaterializeFP(const ConstantFP *CFP, MVT VT) {
- if (VT != MVT::f32 && VT != MVT::f64)
- return 0;
-
- const APFloat Val = CFP->getValueAPF();
- bool is64bit = (VT == MVT::f64);
-
- // This checks to see if we can use FMOV instructions to materialize
- // a constant, otherwise we have to materialize via the constant pool.
- if (TLI.isFPImmLegal(Val, VT)) {
- int Imm;
- unsigned Opc;
- if (is64bit) {
- Imm = ARM64_AM::getFP64Imm(Val);
- Opc = ARM64::FMOVDi;
- } else {
- Imm = ARM64_AM::getFP32Imm(Val);
- Opc = ARM64::FMOVSi;
- }
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addImm(Imm);
- return ResultReg;
- }
-
- // Materialize via constant pool. MachineConstantPool wants an explicit
- // alignment.
- unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
- if (Align == 0)
- Align = DL.getTypeAllocSize(CFP->getType());
-
- unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
- unsigned ADRPReg = createResultReg(&ARM64::GPR64commonRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ADRP),
- ADRPReg).addConstantPoolIndex(Idx, 0, ARM64II::MO_PAGE);
-
- unsigned Opc = is64bit ? ARM64::LDRDui : ARM64::LDRSui;
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addReg(ADRPReg)
- .addConstantPoolIndex(Idx, 0, ARM64II::MO_PAGEOFF | ARM64II::MO_NC);
- return ResultReg;
-}
-
-unsigned ARM64FastISel::ARM64MaterializeGV(const GlobalValue *GV) {
- // We can't handle thread-local variables quickly yet. Unfortunately we have
- // to peer through any aliases to find out if that rule applies.
- const GlobalValue *TLSGV = GV;
- if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
- TLSGV = GA->getAliasee();
-
- if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(TLSGV))
- if (GVar->isThreadLocal())
- return 0;
-
- unsigned char OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
-
- EVT DestEVT = TLI.getValueType(GV->getType(), true);
- if (!DestEVT.isSimple())
- return 0;
-
- unsigned ADRPReg = createResultReg(&ARM64::GPR64commonRegClass);
- unsigned ResultReg;
-
- if (OpFlags & ARM64II::MO_GOT) {
- // ADRP + LDRX
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ADRP),
- ADRPReg)
- .addGlobalAddress(GV, 0, ARM64II::MO_GOT | ARM64II::MO_PAGE);
-
- ResultReg = createResultReg(&ARM64::GPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::LDRXui),
- ResultReg)
- .addReg(ADRPReg)
- .addGlobalAddress(GV, 0, ARM64II::MO_GOT | ARM64II::MO_PAGEOFF |
- ARM64II::MO_NC);
- } else {
- // ADRP + ADDX
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ADRP),
- ADRPReg).addGlobalAddress(GV, 0, ARM64II::MO_PAGE);
-
- ResultReg = createResultReg(&ARM64::GPR64spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ADDXri),
- ResultReg)
- .addReg(ADRPReg)
- .addGlobalAddress(GV, 0, ARM64II::MO_PAGEOFF | ARM64II::MO_NC)
- .addImm(0);
- }
- return ResultReg;
-}
-
-unsigned ARM64FastISel::TargetMaterializeConstant(const Constant *C) {
- EVT CEVT = TLI.getValueType(C->getType(), true);
-
- // Only handle simple types.
- if (!CEVT.isSimple())
- return 0;
- MVT VT = CEVT.getSimpleVT();
-
- // FIXME: Handle ConstantInt.
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
- return ARM64MaterializeFP(CFP, VT);
- else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
- return ARM64MaterializeGV(GV);
-
- return 0;
-}
-
-// Computes the address to get to an object.
-bool ARM64FastISel::ComputeAddress(const Value *Obj, Address &Addr) {
- const User *U = nullptr;
- unsigned Opcode = Instruction::UserOp1;
- if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
- // Don't walk into other basic blocks unless the object is an alloca from
- // another block, otherwise it may not have a virtual register assigned.
- if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
- FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
- Opcode = I->getOpcode();
- U = I;
- }
- } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
- Opcode = C->getOpcode();
- U = C;
- }
-
- if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType()))
- if (Ty->getAddressSpace() > 255)
- // Fast instruction selection doesn't support the special
- // address spaces.
- return false;
-
- switch (Opcode) {
- default:
- break;
- case Instruction::BitCast: {
- // Look through bitcasts.
- return ComputeAddress(U->getOperand(0), Addr);
- }
- case Instruction::IntToPtr: {
- // Look past no-op inttoptrs.
- if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy())
- return ComputeAddress(U->getOperand(0), Addr);
- break;
- }
- case Instruction::PtrToInt: {
- // Look past no-op ptrtoints.
- if (TLI.getValueType(U->getType()) == TLI.getPointerTy())
- return ComputeAddress(U->getOperand(0), Addr);
- break;
- }
- case Instruction::GetElementPtr: {
- Address SavedAddr = Addr;
- uint64_t TmpOffset = Addr.getOffset();
-
- // Iterate through the GEP folding the constants into offsets where
- // we can.
- gep_type_iterator GTI = gep_type_begin(U);
- for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e;
- ++i, ++GTI) {
- const Value *Op = *i;
- if (StructType *STy = dyn_cast<StructType>(*GTI)) {
- const StructLayout *SL = DL.getStructLayout(STy);
- unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
- TmpOffset += SL->getElementOffset(Idx);
- } else {
- uint64_t S = DL.getTypeAllocSize(GTI.getIndexedType());
- for (;;) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
- // Constant-offset addressing.
- TmpOffset += CI->getSExtValue() * S;
- break;
- }
- if (canFoldAddIntoGEP(U, Op)) {
- // A compatible add with a constant operand. Fold the constant.
- ConstantInt *CI =
- cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
- TmpOffset += CI->getSExtValue() * S;
- // Iterate on the other operand.
- Op = cast<AddOperator>(Op)->getOperand(0);
- continue;
- }
- // Unsupported
- goto unsupported_gep;
- }
- }
- }
-
- // Try to grab the base operand now.
- Addr.setOffset(TmpOffset);
- if (ComputeAddress(U->getOperand(0), Addr))
- return true;
-
- // We failed, restore everything and try the other options.
- Addr = SavedAddr;
-
- unsupported_gep:
- break;
- }
- case Instruction::Alloca: {
- const AllocaInst *AI = cast<AllocaInst>(Obj);
- DenseMap<const AllocaInst *, int>::iterator SI =
- FuncInfo.StaticAllocaMap.find(AI);
- if (SI != FuncInfo.StaticAllocaMap.end()) {
- Addr.setKind(Address::FrameIndexBase);
- Addr.setFI(SI->second);
- return true;
- }
- break;
- }
- }
-
- // Try to get this in a register if nothing else has worked.
- if (!Addr.isValid())
- Addr.setReg(getRegForValue(Obj));
- return Addr.isValid();
-}
-
-bool ARM64FastISel::isTypeLegal(Type *Ty, MVT &VT) {
- EVT evt = TLI.getValueType(Ty, true);
-
- // Only handle simple types.
- if (evt == MVT::Other || !evt.isSimple())
- return false;
- VT = evt.getSimpleVT();
-
- // This is a legal type, but it's not something we handle in fast-isel.
- if (VT == MVT::f128)
- return false;
-
- // Handle all other legal types, i.e. a register that will directly hold this
- // value.
- return TLI.isTypeLegal(VT);
-}
-
-bool ARM64FastISel::isLoadStoreTypeLegal(Type *Ty, MVT &VT) {
- if (isTypeLegal(Ty, VT))
- return true;
-
- // If this is a type than can be sign or zero-extended to a basic operation
- // go ahead and accept it now. For stores, this reflects truncation.
- if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
- return true;
-
- return false;
-}
-
-bool ARM64FastISel::SimplifyAddress(Address &Addr, MVT VT, int64_t ScaleFactor,
- bool UseUnscaled) {
- bool needsLowering = false;
- int64_t Offset = Addr.getOffset();
- switch (VT.SimpleTy) {
- default:
- return false;
- case MVT::i1:
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
- case MVT::i64:
- case MVT::f32:
- case MVT::f64:
- if (!UseUnscaled)
- // Using scaled, 12-bit, unsigned immediate offsets.
- needsLowering = ((Offset & 0xfff) != Offset);
- else
- // Using unscaled, 9-bit, signed immediate offsets.
- needsLowering = (Offset > 256 || Offset < -256);
- break;
- }
-
- // FIXME: If this is a stack pointer and the offset needs to be simplified
- // then put the alloca address into a register, set the base type back to
- // register and continue. This should almost never happen.
- if (needsLowering && Addr.getKind() == Address::FrameIndexBase) {
- return false;
- }
-
- // Since the offset is too large for the load/store instruction get the
- // reg+offset into a register.
- if (needsLowering) {
- uint64_t UnscaledOffset = Addr.getOffset() * ScaleFactor;
- unsigned ResultReg = FastEmit_ri_(MVT::i64, ISD::ADD, Addr.getReg(), false,
- UnscaledOffset, MVT::i64);
- if (ResultReg == 0)
- return false;
- Addr.setReg(ResultReg);
- Addr.setOffset(0);
- }
- return true;
-}
-
-void ARM64FastISel::AddLoadStoreOperands(Address &Addr,
- const MachineInstrBuilder &MIB,
- unsigned Flags, bool UseUnscaled) {
- int64_t Offset = Addr.getOffset();
- // Frame base works a bit differently. Handle it separately.
- if (Addr.getKind() == Address::FrameIndexBase) {
- int FI = Addr.getFI();
- // FIXME: We shouldn't be using getObjectSize/getObjectAlignment. The size
- // and alignment should be based on the VT.
- MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
- MachinePointerInfo::getFixedStack(FI, Offset), Flags,
- MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
- // Now add the rest of the operands.
- MIB.addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
- } else {
- // Now add the rest of the operands.
- MIB.addReg(Addr.getReg());
- MIB.addImm(Offset);
- }
-}
-
-bool ARM64FastISel::EmitLoad(MVT VT, unsigned &ResultReg, Address Addr,
- bool UseUnscaled) {
- // Negative offsets require unscaled, 9-bit, signed immediate offsets.
- // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
- if (!UseUnscaled && Addr.getOffset() < 0)
- UseUnscaled = true;
-
- unsigned Opc;
- const TargetRegisterClass *RC;
- bool VTIsi1 = false;
- int64_t ScaleFactor = 0;
- switch (VT.SimpleTy) {
- default:
- return false;
- case MVT::i1:
- VTIsi1 = true;
- // Intentional fall-through.
- case MVT::i8:
- Opc = UseUnscaled ? ARM64::LDURBBi : ARM64::LDRBBui;
- RC = &ARM64::GPR32RegClass;
- ScaleFactor = 1;
- break;
- case MVT::i16:
- Opc = UseUnscaled ? ARM64::LDURHHi : ARM64::LDRHHui;
- RC = &ARM64::GPR32RegClass;
- ScaleFactor = 2;
- break;
- case MVT::i32:
- Opc = UseUnscaled ? ARM64::LDURWi : ARM64::LDRWui;
- RC = &ARM64::GPR32RegClass;
- ScaleFactor = 4;
- break;
- case MVT::i64:
- Opc = UseUnscaled ? ARM64::LDURXi : ARM64::LDRXui;
- RC = &ARM64::GPR64RegClass;
- ScaleFactor = 8;
- break;
- case MVT::f32:
- Opc = UseUnscaled ? ARM64::LDURSi : ARM64::LDRSui;
- RC = TLI.getRegClassFor(VT);
- ScaleFactor = 4;
- break;
- case MVT::f64:
- Opc = UseUnscaled ? ARM64::LDURDi : ARM64::LDRDui;
- RC = TLI.getRegClassFor(VT);
- ScaleFactor = 8;
- break;
- }
- // Scale the offset.
- if (!UseUnscaled) {
- int64_t Offset = Addr.getOffset();
- if (Offset & (ScaleFactor - 1))
- // Retry using an unscaled, 9-bit, signed immediate offset.
- return EmitLoad(VT, ResultReg, Addr, /*UseUnscaled*/ true);
-
- Addr.setOffset(Offset / ScaleFactor);
- }
-
- // Simplify this down to something we can handle.
- if (!SimplifyAddress(Addr, VT, UseUnscaled ? 1 : ScaleFactor, UseUnscaled))
- return false;
-
- // Create the base instruction, then add the operands.
- ResultReg = createResultReg(RC);
- MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(Opc), ResultReg);
- AddLoadStoreOperands(Addr, MIB, MachineMemOperand::MOLoad, UseUnscaled);
-
- // Loading an i1 requires special handling.
- if (VTIsi1) {
- MRI.constrainRegClass(ResultReg, &ARM64::GPR32RegClass);
- unsigned ANDReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ANDReg)
- .addReg(ResultReg)
- .addImm(ARM64_AM::encodeLogicalImmediate(1, 32));
- ResultReg = ANDReg;
- }
- return true;
-}
-
-bool ARM64FastISel::SelectLoad(const Instruction *I) {
- MVT VT;
- // Verify we have a legal type before going any further. Currently, we handle
- // simple types that will directly fit in a register (i32/f32/i64/f64) or
- // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
- if (!isLoadStoreTypeLegal(I->getType(), VT) || cast<LoadInst>(I)->isAtomic())
- return false;
-
- // See if we can handle this address.
- Address Addr;
- if (!ComputeAddress(I->getOperand(0), Addr))
- return false;
-
- unsigned ResultReg;
- if (!EmitLoad(VT, ResultReg, Addr))
- return false;
-
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::EmitStore(MVT VT, unsigned SrcReg, Address Addr,
- bool UseUnscaled) {
- // Negative offsets require unscaled, 9-bit, signed immediate offsets.
- // Otherwise, we try using scaled, 12-bit, unsigned immediate offsets.
- if (!UseUnscaled && Addr.getOffset() < 0)
- UseUnscaled = true;
-
- unsigned StrOpc;
- bool VTIsi1 = false;
- int64_t ScaleFactor = 0;
- // Using scaled, 12-bit, unsigned immediate offsets.
- switch (VT.SimpleTy) {
- default:
- return false;
- case MVT::i1:
- VTIsi1 = true;
- case MVT::i8:
- StrOpc = UseUnscaled ? ARM64::STURBBi : ARM64::STRBBui;
- ScaleFactor = 1;
- break;
- case MVT::i16:
- StrOpc = UseUnscaled ? ARM64::STURHHi : ARM64::STRHHui;
- ScaleFactor = 2;
- break;
- case MVT::i32:
- StrOpc = UseUnscaled ? ARM64::STURWi : ARM64::STRWui;
- ScaleFactor = 4;
- break;
- case MVT::i64:
- StrOpc = UseUnscaled ? ARM64::STURXi : ARM64::STRXui;
- ScaleFactor = 8;
- break;
- case MVT::f32:
- StrOpc = UseUnscaled ? ARM64::STURSi : ARM64::STRSui;
- ScaleFactor = 4;
- break;
- case MVT::f64:
- StrOpc = UseUnscaled ? ARM64::STURDi : ARM64::STRDui;
- ScaleFactor = 8;
- break;
- }
- // Scale the offset.
- if (!UseUnscaled) {
- int64_t Offset = Addr.getOffset();
- if (Offset & (ScaleFactor - 1))
- // Retry using an unscaled, 9-bit, signed immediate offset.
- return EmitStore(VT, SrcReg, Addr, /*UseUnscaled*/ true);
-
- Addr.setOffset(Offset / ScaleFactor);
- }
-
- // Simplify this down to something we can handle.
- if (!SimplifyAddress(Addr, VT, UseUnscaled ? 1 : ScaleFactor, UseUnscaled))
- return false;
-
- // Storing an i1 requires special handling.
- if (VTIsi1) {
- MRI.constrainRegClass(SrcReg, &ARM64::GPR32RegClass);
- unsigned ANDReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ANDReg)
- .addReg(SrcReg)
- .addImm(ARM64_AM::encodeLogicalImmediate(1, 32));
- SrcReg = ANDReg;
- }
- // Create the base instruction, then add the operands.
- MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(StrOpc)).addReg(SrcReg);
- AddLoadStoreOperands(Addr, MIB, MachineMemOperand::MOStore, UseUnscaled);
- return true;
-}
-
-bool ARM64FastISel::SelectStore(const Instruction *I) {
- MVT VT;
- Value *Op0 = I->getOperand(0);
- // Verify we have a legal type before going any further. Currently, we handle
- // simple types that will directly fit in a register (i32/f32/i64/f64) or
- // those that can be sign or zero-extended to a basic operation (i1/i8/i16).
- if (!isLoadStoreTypeLegal(Op0->getType(), VT) ||
- cast<StoreInst>(I)->isAtomic())
- return false;
-
- // Get the value to be stored into a register.
- unsigned SrcReg = getRegForValue(Op0);
- if (SrcReg == 0)
- return false;
-
- // See if we can handle this address.
- Address Addr;
- if (!ComputeAddress(I->getOperand(1), Addr))
- return false;
-
- if (!EmitStore(VT, SrcReg, Addr))
- return false;
- return true;
-}
-
-static ARM64CC::CondCode getCompareCC(CmpInst::Predicate Pred) {
- switch (Pred) {
- case CmpInst::FCMP_ONE:
- case CmpInst::FCMP_UEQ:
- default:
- // AL is our "false" for now. The other two need more compares.
- return ARM64CC::AL;
- case CmpInst::ICMP_EQ:
- case CmpInst::FCMP_OEQ:
- return ARM64CC::EQ;
- case CmpInst::ICMP_SGT:
- case CmpInst::FCMP_OGT:
- return ARM64CC::GT;
- case CmpInst::ICMP_SGE:
- case CmpInst::FCMP_OGE:
- return ARM64CC::GE;
- case CmpInst::ICMP_UGT:
- case CmpInst::FCMP_UGT:
- return ARM64CC::HI;
- case CmpInst::FCMP_OLT:
- return ARM64CC::MI;
- case CmpInst::ICMP_ULE:
- case CmpInst::FCMP_OLE:
- return ARM64CC::LS;
- case CmpInst::FCMP_ORD:
- return ARM64CC::VC;
- case CmpInst::FCMP_UNO:
- return ARM64CC::VS;
- case CmpInst::FCMP_UGE:
- return ARM64CC::PL;
- case CmpInst::ICMP_SLT:
- case CmpInst::FCMP_ULT:
- return ARM64CC::LT;
- case CmpInst::ICMP_SLE:
- case CmpInst::FCMP_ULE:
- return ARM64CC::LE;
- case CmpInst::FCMP_UNE:
- case CmpInst::ICMP_NE:
- return ARM64CC::NE;
- case CmpInst::ICMP_UGE:
- return ARM64CC::HS;
- case CmpInst::ICMP_ULT:
- return ARM64CC::LO;
- }
-}
-
-bool ARM64FastISel::SelectBranch(const Instruction *I) {
- const BranchInst *BI = cast<BranchInst>(I);
- MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
- MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
-
- if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
- if (CI->hasOneUse() && (CI->getParent() == I->getParent())) {
- // We may not handle every CC for now.
- ARM64CC::CondCode CC = getCompareCC(CI->getPredicate());
- if (CC == ARM64CC::AL)
- return false;
-
- // Emit the cmp.
- if (!EmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
- return false;
-
- // Emit the branch.
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::Bcc))
- .addImm(CC)
- .addMBB(TBB);
- FuncInfo.MBB->addSuccessor(TBB);
-
- FastEmitBranch(FBB, DbgLoc);
- return true;
- }
- } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) {
- MVT SrcVT;
- if (TI->hasOneUse() && TI->getParent() == I->getParent() &&
- (isLoadStoreTypeLegal(TI->getOperand(0)->getType(), SrcVT))) {
- unsigned CondReg = getRegForValue(TI->getOperand(0));
- if (CondReg == 0)
- return false;
-
- // Issue an extract_subreg to get the lower 32-bits.
- if (SrcVT == MVT::i64)
- CondReg = FastEmitInst_extractsubreg(MVT::i32, CondReg, /*Kill=*/true,
- ARM64::sub_32);
-
- MRI.constrainRegClass(CondReg, &ARM64::GPR32RegClass);
- unsigned ANDReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ANDReg)
- .addReg(CondReg)
- .addImm(ARM64_AM::encodeLogicalImmediate(1, 32));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::SUBSWri))
- .addReg(ANDReg)
- .addReg(ANDReg)
- .addImm(0)
- .addImm(0);
-
- unsigned CC = ARM64CC::NE;
- if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
- std::swap(TBB, FBB);
- CC = ARM64CC::EQ;
- }
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::Bcc))
- .addImm(CC)
- .addMBB(TBB);
- FuncInfo.MBB->addSuccessor(TBB);
- FastEmitBranch(FBB, DbgLoc);
- return true;
- }
- } else if (const ConstantInt *CI =
- dyn_cast<ConstantInt>(BI->getCondition())) {
- uint64_t Imm = CI->getZExtValue();
- MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::B))
- .addMBB(Target);
- FuncInfo.MBB->addSuccessor(Target);
- return true;
- }
-
- unsigned CondReg = getRegForValue(BI->getCondition());
- if (CondReg == 0)
- return false;
-
- // We've been divorced from our compare! Our block was split, and
- // now our compare lives in a predecessor block. We musn't
- // re-compare here, as the children of the compare aren't guaranteed
- // live across the block boundary (we *could* check for this).
- // Regardless, the compare has been done in the predecessor block,
- // and it left a value for us in a virtual register. Ergo, we test
- // the one-bit value left in the virtual register.
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::SUBSWri),
- ARM64::WZR)
- .addReg(CondReg)
- .addImm(0)
- .addImm(0);
-
- unsigned CC = ARM64CC::NE;
- if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
- std::swap(TBB, FBB);
- CC = ARM64CC::EQ;
- }
-
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::Bcc))
- .addImm(CC)
- .addMBB(TBB);
- FuncInfo.MBB->addSuccessor(TBB);
- FastEmitBranch(FBB, DbgLoc);
- return true;
-}
-
-bool ARM64FastISel::SelectIndirectBr(const Instruction *I) {
- const IndirectBrInst *BI = cast<IndirectBrInst>(I);
- unsigned AddrReg = getRegForValue(BI->getOperand(0));
- if (AddrReg == 0)
- return false;
-
- // Emit the indirect branch.
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::BR))
- .addReg(AddrReg);
-
- // Make sure the CFG is up-to-date.
- for (unsigned i = 0, e = BI->getNumSuccessors(); i != e; ++i)
- FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[BI->getSuccessor(i)]);
-
- return true;
-}
-
-bool ARM64FastISel::EmitCmp(Value *Src1Value, Value *Src2Value, bool isZExt) {
- Type *Ty = Src1Value->getType();
- EVT SrcEVT = TLI.getValueType(Ty, true);
- if (!SrcEVT.isSimple())
- return false;
- MVT SrcVT = SrcEVT.getSimpleVT();
-
- // Check to see if the 2nd operand is a constant that we can encode directly
- // in the compare.
- uint64_t Imm;
- bool UseImm = false;
- bool isNegativeImm = false;
- if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(Src2Value)) {
- if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
- SrcVT == MVT::i8 || SrcVT == MVT::i1) {
- const APInt &CIVal = ConstInt->getValue();
-
- Imm = (isZExt) ? CIVal.getZExtValue() : CIVal.getSExtValue();
- if (CIVal.isNegative()) {
- isNegativeImm = true;
- Imm = -Imm;
- }
- // FIXME: We can handle more immediates using shifts.
- UseImm = ((Imm & 0xfff) == Imm);
- }
- } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) {
- if (SrcVT == MVT::f32 || SrcVT == MVT::f64)
- if (ConstFP->isZero() && !ConstFP->isNegative())
- UseImm = true;
- }
-
- unsigned ZReg;
- unsigned CmpOpc;
- bool isICmp = true;
- bool needsExt = false;
- switch (SrcVT.SimpleTy) {
- default:
- return false;
- case MVT::i1:
- case MVT::i8:
- case MVT::i16:
- needsExt = true;
- // Intentional fall-through.
- case MVT::i32:
- ZReg = ARM64::WZR;
- if (UseImm)
- CmpOpc = isNegativeImm ? ARM64::ADDSWri : ARM64::SUBSWri;
- else
- CmpOpc = ARM64::SUBSWrr;
- break;
- case MVT::i64:
- ZReg = ARM64::XZR;
- if (UseImm)
- CmpOpc = isNegativeImm ? ARM64::ADDSXri : ARM64::SUBSXri;
- else
- CmpOpc = ARM64::SUBSXrr;
- break;
- case MVT::f32:
- isICmp = false;
- CmpOpc = UseImm ? ARM64::FCMPSri : ARM64::FCMPSrr;
- break;
- case MVT::f64:
- isICmp = false;
- CmpOpc = UseImm ? ARM64::FCMPDri : ARM64::FCMPDrr;
- break;
- }
-
- unsigned SrcReg1 = getRegForValue(Src1Value);
- if (SrcReg1 == 0)
- return false;
-
- unsigned SrcReg2;
- if (!UseImm) {
- SrcReg2 = getRegForValue(Src2Value);
- if (SrcReg2 == 0)
- return false;
- }
-
- // We have i1, i8, or i16, we need to either zero extend or sign extend.
- if (needsExt) {
- SrcReg1 = EmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt);
- if (SrcReg1 == 0)
- return false;
- if (!UseImm) {
- SrcReg2 = EmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt);
- if (SrcReg2 == 0)
- return false;
- }
- }
-
- if (isICmp) {
- if (UseImm)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
- .addReg(ZReg)
- .addReg(SrcReg1)
- .addImm(Imm)
- .addImm(0);
- else
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
- .addReg(ZReg)
- .addReg(SrcReg1)
- .addReg(SrcReg2);
- } else {
- if (UseImm)
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
- .addReg(SrcReg1);
- else
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CmpOpc))
- .addReg(SrcReg1)
- .addReg(SrcReg2);
- }
- return true;
-}
-
-bool ARM64FastISel::SelectCmp(const Instruction *I) {
- const CmpInst *CI = cast<CmpInst>(I);
-
- // We may not handle every CC for now.
- ARM64CC::CondCode CC = getCompareCC(CI->getPredicate());
- if (CC == ARM64CC::AL)
- return false;
-
- // Emit the cmp.
- if (!EmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned()))
- return false;
-
- // Now set a register based on the comparison.
- ARM64CC::CondCode invertedCC = getInvertedCondCode(CC);
- unsigned ResultReg = createResultReg(&ARM64::GPR32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::CSINCWr),
- ResultReg)
- .addReg(ARM64::WZR)
- .addReg(ARM64::WZR)
- .addImm(invertedCC);
-
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectSelect(const Instruction *I) {
- const SelectInst *SI = cast<SelectInst>(I);
-
- EVT DestEVT = TLI.getValueType(SI->getType(), true);
- if (!DestEVT.isSimple())
- return false;
-
- MVT DestVT = DestEVT.getSimpleVT();
- if (DestVT != MVT::i32 && DestVT != MVT::i64 && DestVT != MVT::f32 &&
- DestVT != MVT::f64)
- return false;
-
- unsigned CondReg = getRegForValue(SI->getCondition());
- if (CondReg == 0)
- return false;
- unsigned TrueReg = getRegForValue(SI->getTrueValue());
- if (TrueReg == 0)
- return false;
- unsigned FalseReg = getRegForValue(SI->getFalseValue());
- if (FalseReg == 0)
- return false;
-
-
- MRI.constrainRegClass(CondReg, &ARM64::GPR32RegClass);
- unsigned ANDReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ANDReg)
- .addReg(CondReg)
- .addImm(ARM64_AM::encodeLogicalImmediate(1, 32));
-
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::SUBSWri))
- .addReg(ANDReg)
- .addReg(ANDReg)
- .addImm(0)
- .addImm(0);
-
- unsigned SelectOpc;
- switch (DestVT.SimpleTy) {
- default:
- return false;
- case MVT::i32:
- SelectOpc = ARM64::CSELWr;
- break;
- case MVT::i64:
- SelectOpc = ARM64::CSELXr;
- break;
- case MVT::f32:
- SelectOpc = ARM64::FCSELSrrr;
- break;
- case MVT::f64:
- SelectOpc = ARM64::FCSELDrrr;
- break;
- }
-
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(SelectOpc),
- ResultReg)
- .addReg(TrueReg)
- .addReg(FalseReg)
- .addImm(ARM64CC::NE);
-
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectFPExt(const Instruction *I) {
- Value *V = I->getOperand(0);
- if (!I->getType()->isDoubleTy() || !V->getType()->isFloatTy())
- return false;
-
- unsigned Op = getRegForValue(V);
- if (Op == 0)
- return false;
-
- unsigned ResultReg = createResultReg(&ARM64::FPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::FCVTDSr),
- ResultReg).addReg(Op);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectFPTrunc(const Instruction *I) {
- Value *V = I->getOperand(0);
- if (!I->getType()->isFloatTy() || !V->getType()->isDoubleTy())
- return false;
-
- unsigned Op = getRegForValue(V);
- if (Op == 0)
- return false;
-
- unsigned ResultReg = createResultReg(&ARM64::FPR32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::FCVTSDr),
- ResultReg).addReg(Op);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-// FPToUI and FPToSI
-bool ARM64FastISel::SelectFPToInt(const Instruction *I, bool Signed) {
- MVT DestVT;
- if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
- return false;
-
- unsigned SrcReg = getRegForValue(I->getOperand(0));
- if (SrcReg == 0)
- return false;
-
- EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType(), true);
- if (SrcVT == MVT::f128)
- return false;
-
- unsigned Opc;
- if (SrcVT == MVT::f64) {
- if (Signed)
- Opc = (DestVT == MVT::i32) ? ARM64::FCVTZSUWDr : ARM64::FCVTZSUXDr;
- else
- Opc = (DestVT == MVT::i32) ? ARM64::FCVTZUUWDr : ARM64::FCVTZUUXDr;
- } else {
- if (Signed)
- Opc = (DestVT == MVT::i32) ? ARM64::FCVTZSUWSr : ARM64::FCVTZSUXSr;
- else
- Opc = (DestVT == MVT::i32) ? ARM64::FCVTZUUWSr : ARM64::FCVTZUUXSr;
- }
- unsigned ResultReg = createResultReg(
- DestVT == MVT::i32 ? &ARM64::GPR32RegClass : &ARM64::GPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addReg(SrcReg);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectIntToFP(const Instruction *I, bool Signed) {
- MVT DestVT;
- if (!isTypeLegal(I->getType(), DestVT) || DestVT.isVector())
- return false;
- assert ((DestVT == MVT::f32 || DestVT == MVT::f64) &&
- "Unexpected value type.");
-
- unsigned SrcReg = getRegForValue(I->getOperand(0));
- if (SrcReg == 0)
- return false;
-
- EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType(), true);
-
- // Handle sign-extension.
- if (SrcVT == MVT::i16 || SrcVT == MVT::i8 || SrcVT == MVT::i1) {
- SrcReg =
- EmitIntExt(SrcVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ !Signed);
- if (SrcReg == 0)
- return false;
- }
-
- MRI.constrainRegClass(SrcReg, SrcVT == MVT::i64 ? &ARM64::GPR64RegClass
- : &ARM64::GPR32RegClass);
-
- unsigned Opc;
- if (SrcVT == MVT::i64) {
- if (Signed)
- Opc = (DestVT == MVT::f32) ? ARM64::SCVTFUXSri : ARM64::SCVTFUXDri;
- else
- Opc = (DestVT == MVT::f32) ? ARM64::UCVTFUXSri : ARM64::UCVTFUXDri;
- } else {
- if (Signed)
- Opc = (DestVT == MVT::f32) ? ARM64::SCVTFUWSri : ARM64::SCVTFUWDri;
- else
- Opc = (DestVT == MVT::f32) ? ARM64::UCVTFUWSri : ARM64::UCVTFUWDri;
- }
-
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addReg(SrcReg);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::ProcessCallArgs(SmallVectorImpl<Value *> &Args,
- SmallVectorImpl<unsigned> &ArgRegs,
- SmallVectorImpl<MVT> &ArgVTs,
- SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
- SmallVectorImpl<unsigned> &RegArgs,
- CallingConv::ID CC, unsigned &NumBytes) {
- SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CC, false, *FuncInfo.MF, TM, ArgLocs, *Context);
- CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC));
-
- // Get a count of how many bytes are to be pushed on the stack.
- NumBytes = CCInfo.getNextStackOffset();
-
- // Issue CALLSEQ_START
- unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown))
- .addImm(NumBytes);
-
- // Process the args.
- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
- CCValAssign &VA = ArgLocs[i];
- unsigned Arg = ArgRegs[VA.getValNo()];
- MVT ArgVT = ArgVTs[VA.getValNo()];
-
- // Handle arg promotion: SExt, ZExt, AExt.
- switch (VA.getLocInfo()) {
- case CCValAssign::Full:
- break;
- case CCValAssign::SExt: {
- MVT DestVT = VA.getLocVT();
- MVT SrcVT = ArgVT;
- Arg = EmitIntExt(SrcVT, Arg, DestVT, /*isZExt*/ false);
- if (Arg == 0)
- return false;
- ArgVT = DestVT;
- break;
- }
- case CCValAssign::AExt:
- // Intentional fall-through.
- case CCValAssign::ZExt: {
- MVT DestVT = VA.getLocVT();
- MVT SrcVT = ArgVT;
- Arg = EmitIntExt(SrcVT, Arg, DestVT, /*isZExt*/ true);
- if (Arg == 0)
- return false;
- ArgVT = DestVT;
- break;
- }
- default:
- llvm_unreachable("Unknown arg promotion!");
- }
-
- // Now copy/store arg to correct locations.
- if (VA.isRegLoc() && !VA.needsCustom()) {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::COPY), VA.getLocReg()).addReg(Arg);
- RegArgs.push_back(VA.getLocReg());
- } else if (VA.needsCustom()) {
- // FIXME: Handle custom args.
- return false;
- } else {
- assert(VA.isMemLoc() && "Assuming store on stack.");
-
- // Need to store on the stack.
- unsigned ArgSize = VA.getLocVT().getSizeInBits() / 8;
-
- unsigned BEAlign = 0;
- if (ArgSize < 8 && !Subtarget->isLittleEndian())
- BEAlign = 8 - ArgSize;
-
- Address Addr;
- Addr.setKind(Address::RegBase);
- Addr.setReg(ARM64::SP);
- Addr.setOffset(VA.getLocMemOffset() + BEAlign);
-
- if (!EmitStore(ArgVT, Arg, Addr))
- return false;
- }
- }
- return true;
-}
-
-bool ARM64FastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs,
- const Instruction *I, CallingConv::ID CC,
- unsigned &NumBytes) {
- // Issue CALLSEQ_END
- unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
- .addImm(NumBytes)
- .addImm(0);
-
- // Now the return value.
- if (RetVT != MVT::isVoid) {
- SmallVector<CCValAssign, 16> RVLocs;
- CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context);
- CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC));
-
- // Only handle a single return value.
- if (RVLocs.size() != 1)
- return false;
-
- // Copy all of the result registers out of their specified physreg.
- MVT CopyVT = RVLocs[0].getValVT();
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(CopyVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::COPY),
- ResultReg).addReg(RVLocs[0].getLocReg());
- UsedRegs.push_back(RVLocs[0].getLocReg());
-
- // Finally update the result.
- UpdateValueMap(I, ResultReg);
- }
-
- return true;
-}
-
-bool ARM64FastISel::SelectCall(const Instruction *I,
- const char *IntrMemName = nullptr) {
- const CallInst *CI = cast<CallInst>(I);
- const Value *Callee = CI->getCalledValue();
-
- // Don't handle inline asm or intrinsics.
- if (isa<InlineAsm>(Callee))
- return false;
-
- // Only handle global variable Callees.
- const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
- if (!GV)
- return false;
-
- // Check the calling convention.
- ImmutableCallSite CS(CI);
- CallingConv::ID CC = CS.getCallingConv();
-
- // Let SDISel handle vararg functions.
- PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
- FunctionType *FTy = cast<FunctionType>(PT->getElementType());
- if (FTy->isVarArg())
- return false;
-
- // Handle *simple* calls for now.
- MVT RetVT;
- Type *RetTy = I->getType();
- if (RetTy->isVoidTy())
- RetVT = MVT::isVoid;
- else if (!isTypeLegal(RetTy, RetVT))
- return false;
-
- // Set up the argument vectors.
- SmallVector<Value *, 8> Args;
- SmallVector<unsigned, 8> ArgRegs;
- SmallVector<MVT, 8> ArgVTs;
- SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
- Args.reserve(CS.arg_size());
- ArgRegs.reserve(CS.arg_size());
- ArgVTs.reserve(CS.arg_size());
- ArgFlags.reserve(CS.arg_size());
-
- for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
- i != e; ++i) {
- // If we're lowering a memory intrinsic instead of a regular call, skip the
- // last two arguments, which shouldn't be passed to the underlying function.
- if (IntrMemName && e - i <= 2)
- break;
-
- unsigned Arg = getRegForValue(*i);
- if (Arg == 0)
- return false;
-
- ISD::ArgFlagsTy Flags;
- unsigned AttrInd = i - CS.arg_begin() + 1;
- if (CS.paramHasAttr(AttrInd, Attribute::SExt))
- Flags.setSExt();
- if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
- Flags.setZExt();
-
- // FIXME: Only handle *easy* calls for now.
- if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
- CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
- CS.paramHasAttr(AttrInd, Attribute::Nest) ||
- CS.paramHasAttr(AttrInd, Attribute::ByVal))
- return false;
-
- MVT ArgVT;
- Type *ArgTy = (*i)->getType();
- if (!isTypeLegal(ArgTy, ArgVT) &&
- !(ArgVT == MVT::i1 || ArgVT == MVT::i8 || ArgVT == MVT::i16))
- return false;
-
- // We don't handle vector parameters yet.
- if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64)
- return false;
-
- unsigned OriginalAlignment = DL.getABITypeAlignment(ArgTy);
- Flags.setOrigAlign(OriginalAlignment);
-
- Args.push_back(*i);
- ArgRegs.push_back(Arg);
- ArgVTs.push_back(ArgVT);
- ArgFlags.push_back(Flags);
- }
-
- // Handle the arguments now that we've gotten them.
- SmallVector<unsigned, 4> RegArgs;
- unsigned NumBytes;
- if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, RegArgs, CC, NumBytes))
- return false;
-
- // Issue the call.
- MachineInstrBuilder MIB;
- MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::BL));
- if (!IntrMemName)
- MIB.addGlobalAddress(GV, 0, 0);
- else
- MIB.addExternalSymbol(IntrMemName, 0);
-
- // Add implicit physical register uses to the call.
- for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
- MIB.addReg(RegArgs[i], RegState::Implicit);
-
- // Add a register mask with the call-preserved registers.
- // Proper defs for return values will be added by setPhysRegsDeadExcept().
- MIB.addRegMask(TRI.getCallPreservedMask(CS.getCallingConv()));
-
- // Finish off the call including any return values.
- SmallVector<unsigned, 4> UsedRegs;
- if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes))
- return false;
-
- // Set all unused physreg defs as dead.
- static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
-
- return true;
-}
-
-bool ARM64FastISel::IsMemCpySmall(uint64_t Len, unsigned Alignment) {
- if (Alignment)
- return Len / Alignment <= 4;
- else
- return Len < 32;
-}
-
-bool ARM64FastISel::TryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len,
- unsigned Alignment) {
- // Make sure we don't bloat code by inlining very large memcpy's.
- if (!IsMemCpySmall(Len, Alignment))
- return false;
-
- int64_t UnscaledOffset = 0;
- Address OrigDest = Dest;
- Address OrigSrc = Src;
-
- while (Len) {
- MVT VT;
- if (!Alignment || Alignment >= 8) {
- if (Len >= 8)
- VT = MVT::i64;
- else if (Len >= 4)
- VT = MVT::i32;
- else if (Len >= 2)
- VT = MVT::i16;
- else {
- VT = MVT::i8;
- }
- } else {
- // Bound based on alignment.
- if (Len >= 4 && Alignment == 4)
- VT = MVT::i32;
- else if (Len >= 2 && Alignment == 2)
- VT = MVT::i16;
- else {
- VT = MVT::i8;
- }
- }
-
- bool RV;
- unsigned ResultReg;
- RV = EmitLoad(VT, ResultReg, Src);
- assert(RV == true && "Should be able to handle this load.");
- RV = EmitStore(VT, ResultReg, Dest);
- assert(RV == true && "Should be able to handle this store.");
- (void)RV;
-
- int64_t Size = VT.getSizeInBits() / 8;
- Len -= Size;
- UnscaledOffset += Size;
-
- // We need to recompute the unscaled offset for each iteration.
- Dest.setOffset(OrigDest.getOffset() + UnscaledOffset);
- Src.setOffset(OrigSrc.getOffset() + UnscaledOffset);
- }
-
- return true;
-}
-
-bool ARM64FastISel::SelectIntrinsicCall(const IntrinsicInst &I) {
- // FIXME: Handle more intrinsics.
- switch (I.getIntrinsicID()) {
- default:
- return false;
- case Intrinsic::memcpy:
- case Intrinsic::memmove: {
- const MemTransferInst &MTI = cast<MemTransferInst>(I);
- // Don't handle volatile.
- if (MTI.isVolatile())
- return false;
-
- // Disable inlining for memmove before calls to ComputeAddress. Otherwise,
- // we would emit dead code because we don't currently handle memmoves.
- bool isMemCpy = (I.getIntrinsicID() == Intrinsic::memcpy);
- if (isa<ConstantInt>(MTI.getLength()) && isMemCpy) {
- // Small memcpy's are common enough that we want to do them without a call
- // if possible.
- uint64_t Len = cast<ConstantInt>(MTI.getLength())->getZExtValue();
- unsigned Alignment = MTI.getAlignment();
- if (IsMemCpySmall(Len, Alignment)) {
- Address Dest, Src;
- if (!ComputeAddress(MTI.getRawDest(), Dest) ||
- !ComputeAddress(MTI.getRawSource(), Src))
- return false;
- if (TryEmitSmallMemCpy(Dest, Src, Len, Alignment))
- return true;
- }
- }
-
- if (!MTI.getLength()->getType()->isIntegerTy(64))
- return false;
-
- if (MTI.getSourceAddressSpace() > 255 || MTI.getDestAddressSpace() > 255)
- // Fast instruction selection doesn't support the special
- // address spaces.
- return false;
-
- const char *IntrMemName = isa<MemCpyInst>(I) ? "memcpy" : "memmove";
- return SelectCall(&I, IntrMemName);
- }
- case Intrinsic::memset: {
- const MemSetInst &MSI = cast<MemSetInst>(I);
- // Don't handle volatile.
- if (MSI.isVolatile())
- return false;
-
- if (!MSI.getLength()->getType()->isIntegerTy(64))
- return false;
-
- if (MSI.getDestAddressSpace() > 255)
- // Fast instruction selection doesn't support the special
- // address spaces.
- return false;
-
- return SelectCall(&I, "memset");
- }
- case Intrinsic::trap: {
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::BRK))
- .addImm(1);
- return true;
- }
- }
- return false;
-}
-
-bool ARM64FastISel::SelectRet(const Instruction *I) {
- const ReturnInst *Ret = cast<ReturnInst>(I);
- const Function &F = *I->getParent()->getParent();
-
- if (!FuncInfo.CanLowerReturn)
- return false;
-
- if (F.isVarArg())
- return false;
-
- // Build a list of return value registers.
- SmallVector<unsigned, 4> RetRegs;
-
- if (Ret->getNumOperands() > 0) {
- CallingConv::ID CC = F.getCallingConv();
- SmallVector<ISD::OutputArg, 4> Outs;
- GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI);
-
- // Analyze operands of the call, assigning locations to each operand.
- SmallVector<CCValAssign, 16> ValLocs;
- CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,
- I->getContext());
- CCAssignFn *RetCC = CC == CallingConv::WebKit_JS ? RetCC_ARM64_WebKit_JS
- : RetCC_ARM64_AAPCS;
- CCInfo.AnalyzeReturn(Outs, RetCC);
-
- // Only handle a single return value for now.
- if (ValLocs.size() != 1)
- return false;
-
- CCValAssign &VA = ValLocs[0];
- const Value *RV = Ret->getOperand(0);
-
- // Don't bother handling odd stuff for now.
- if (VA.getLocInfo() != CCValAssign::Full)
- return false;
- // Only handle register returns for now.
- if (!VA.isRegLoc())
- return false;
- unsigned Reg = getRegForValue(RV);
- if (Reg == 0)
- return false;
-
- unsigned SrcReg = Reg + VA.getValNo();
- unsigned DestReg = VA.getLocReg();
- // Avoid a cross-class copy. This is very unlikely.
- if (!MRI.getRegClass(SrcReg)->contains(DestReg))
- return false;
-
- EVT RVEVT = TLI.getValueType(RV->getType());
- if (!RVEVT.isSimple())
- return false;
-
- // Vectors (of > 1 lane) in big endian need tricky handling.
- if (RVEVT.isVector() && RVEVT.getVectorNumElements() > 1)
- return false;
-
- MVT RVVT = RVEVT.getSimpleVT();
- if (RVVT == MVT::f128)
- return false;
- MVT DestVT = VA.getValVT();
- // Special handling for extended integers.
- if (RVVT != DestVT) {
- if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)
- return false;
-
- if (!Outs[0].Flags.isZExt() && !Outs[0].Flags.isSExt())
- return false;
-
- bool isZExt = Outs[0].Flags.isZExt();
- SrcReg = EmitIntExt(RVVT, SrcReg, DestVT, isZExt);
- if (SrcReg == 0)
- return false;
- }
-
- // Make the copy.
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);
-
- // Add register to return instruction.
- RetRegs.push_back(VA.getLocReg());
- }
-
- MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(ARM64::RET_ReallyLR));
- for (unsigned i = 0, e = RetRegs.size(); i != e; ++i)
- MIB.addReg(RetRegs[i], RegState::Implicit);
- return true;
-}
-
-bool ARM64FastISel::SelectTrunc(const Instruction *I) {
- Type *DestTy = I->getType();
- Value *Op = I->getOperand(0);
- Type *SrcTy = Op->getType();
-
- EVT SrcEVT = TLI.getValueType(SrcTy, true);
- EVT DestEVT = TLI.getValueType(DestTy, true);
- if (!SrcEVT.isSimple())
- return false;
- if (!DestEVT.isSimple())
- return false;
-
- MVT SrcVT = SrcEVT.getSimpleVT();
- MVT DestVT = DestEVT.getSimpleVT();
-
- if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
- SrcVT != MVT::i8)
- return false;
- if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8 &&
- DestVT != MVT::i1)
- return false;
-
- unsigned SrcReg = getRegForValue(Op);
- if (!SrcReg)
- return false;
-
- // If we're truncating from i64 to a smaller non-legal type then generate an
- // AND. Otherwise, we know the high bits are undefined and a truncate doesn't
- // generate any code.
- if (SrcVT == MVT::i64) {
- uint64_t Mask = 0;
- switch (DestVT.SimpleTy) {
- default:
- // Trunc i64 to i32 is handled by the target-independent fast-isel.
- return false;
- case MVT::i1:
- Mask = 0x1;
- break;
- case MVT::i8:
- Mask = 0xff;
- break;
- case MVT::i16:
- Mask = 0xffff;
- break;
- }
- // Issue an extract_subreg to get the lower 32-bits.
- unsigned Reg32 = FastEmitInst_extractsubreg(MVT::i32, SrcReg, /*Kill=*/true,
- ARM64::sub_32);
- MRI.constrainRegClass(Reg32, &ARM64::GPR32RegClass);
- // Create the AND instruction which performs the actual truncation.
- unsigned ANDReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ANDReg)
- .addReg(Reg32)
- .addImm(ARM64_AM::encodeLogicalImmediate(Mask, 32));
- SrcReg = ANDReg;
- }
-
- UpdateValueMap(I, SrcReg);
- return true;
-}
-
-unsigned ARM64FastISel::Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt) {
- assert((DestVT == MVT::i8 || DestVT == MVT::i16 || DestVT == MVT::i32 ||
- DestVT == MVT::i64) &&
- "Unexpected value type.");
- // Handle i8 and i16 as i32.
- if (DestVT == MVT::i8 || DestVT == MVT::i16)
- DestVT = MVT::i32;
-
- if (isZExt) {
- MRI.constrainRegClass(SrcReg, &ARM64::GPR32RegClass);
- unsigned ResultReg = createResultReg(&ARM64::GPR32spRegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::ANDWri),
- ResultReg)
- .addReg(SrcReg)
- .addImm(ARM64_AM::encodeLogicalImmediate(1, 32));
-
- if (DestVT == MVT::i64) {
- // We're ZExt i1 to i64. The ANDWri Wd, Ws, #1 implicitly clears the
- // upper 32 bits. Emit a SUBREG_TO_REG to extend from Wd to Xd.
- unsigned Reg64 = MRI.createVirtualRegister(&ARM64::GPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(ARM64::SUBREG_TO_REG), Reg64)
- .addImm(0)
- .addReg(ResultReg)
- .addImm(ARM64::sub_32);
- ResultReg = Reg64;
- }
- return ResultReg;
- } else {
- if (DestVT == MVT::i64) {
- // FIXME: We're SExt i1 to i64.
- return 0;
- }
- unsigned ResultReg = createResultReg(&ARM64::GPR32RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(ARM64::SBFMWri),
- ResultReg)
- .addReg(SrcReg)
- .addImm(0)
- .addImm(0);
- return ResultReg;
- }
-}
-
-unsigned ARM64FastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
- bool isZExt) {
- assert(DestVT != MVT::i1 && "ZeroExt/SignExt an i1?");
- unsigned Opc;
- unsigned Imm = 0;
-
- switch (SrcVT.SimpleTy) {
- default:
- return 0;
- case MVT::i1:
- return Emiti1Ext(SrcReg, DestVT, isZExt);
- case MVT::i8:
- if (DestVT == MVT::i64)
- Opc = isZExt ? ARM64::UBFMXri : ARM64::SBFMXri;
- else
- Opc = isZExt ? ARM64::UBFMWri : ARM64::SBFMWri;
- Imm = 7;
- break;
- case MVT::i16:
- if (DestVT == MVT::i64)
- Opc = isZExt ? ARM64::UBFMXri : ARM64::SBFMXri;
- else
- Opc = isZExt ? ARM64::UBFMWri : ARM64::SBFMWri;
- Imm = 15;
- break;
- case MVT::i32:
- assert(DestVT == MVT::i64 && "IntExt i32 to i32?!?");
- Opc = isZExt ? ARM64::UBFMXri : ARM64::SBFMXri;
- Imm = 31;
- break;
- }
-
- // Handle i8 and i16 as i32.
- if (DestVT == MVT::i8 || DestVT == MVT::i16)
- DestVT = MVT::i32;
- else if (DestVT == MVT::i64) {
- unsigned Src64 = MRI.createVirtualRegister(&ARM64::GPR64RegClass);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(ARM64::SUBREG_TO_REG), Src64)
- .addImm(0)
- .addReg(SrcReg)
- .addImm(ARM64::sub_32);
- SrcReg = Src64;
- }
-
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addReg(SrcReg)
- .addImm(0)
- .addImm(Imm);
-
- return ResultReg;
-}
-
-bool ARM64FastISel::SelectIntExt(const Instruction *I) {
- // On ARM, in general, integer casts don't involve legal types; this code
- // handles promotable integers. The high bits for a type smaller than
- // the register size are assumed to be undefined.
- Type *DestTy = I->getType();
- Value *Src = I->getOperand(0);
- Type *SrcTy = Src->getType();
-
- bool isZExt = isa<ZExtInst>(I);
- unsigned SrcReg = getRegForValue(Src);
- if (!SrcReg)
- return false;
-
- EVT SrcEVT = TLI.getValueType(SrcTy, true);
- EVT DestEVT = TLI.getValueType(DestTy, true);
- if (!SrcEVT.isSimple())
- return false;
- if (!DestEVT.isSimple())
- return false;
-
- MVT SrcVT = SrcEVT.getSimpleVT();
- MVT DestVT = DestEVT.getSimpleVT();
- unsigned ResultReg = EmitIntExt(SrcVT, SrcReg, DestVT, isZExt);
- if (ResultReg == 0)
- return false;
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectRem(const Instruction *I, unsigned ISDOpcode) {
- EVT DestEVT = TLI.getValueType(I->getType(), true);
- if (!DestEVT.isSimple())
- return false;
-
- MVT DestVT = DestEVT.getSimpleVT();
- if (DestVT != MVT::i64 && DestVT != MVT::i32)
- return false;
-
- unsigned DivOpc;
- bool is64bit = (DestVT == MVT::i64);
- switch (ISDOpcode) {
- default:
- return false;
- case ISD::SREM:
- DivOpc = is64bit ? ARM64::SDIVXr : ARM64::SDIVWr;
- break;
- case ISD::UREM:
- DivOpc = is64bit ? ARM64::UDIVXr : ARM64::UDIVWr;
- break;
- }
- unsigned MSubOpc = is64bit ? ARM64::MSUBXrrr : ARM64::MSUBWrrr;
- unsigned Src0Reg = getRegForValue(I->getOperand(0));
- if (!Src0Reg)
- return false;
-
- unsigned Src1Reg = getRegForValue(I->getOperand(1));
- if (!Src1Reg)
- return false;
-
- unsigned QuotReg = createResultReg(TLI.getRegClassFor(DestVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(DivOpc), QuotReg)
- .addReg(Src0Reg)
- .addReg(Src1Reg);
- // The remainder is computed as numerator - (quotient * denominator) using the
- // MSUB instruction.
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(DestVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(MSubOpc), ResultReg)
- .addReg(QuotReg)
- .addReg(Src1Reg)
- .addReg(Src0Reg);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::SelectMul(const Instruction *I) {
- EVT SrcEVT = TLI.getValueType(I->getOperand(0)->getType(), true);
- if (!SrcEVT.isSimple())
- return false;
- MVT SrcVT = SrcEVT.getSimpleVT();
-
- // Must be simple value type. Don't handle vectors.
- if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16 &&
- SrcVT != MVT::i8)
- return false;
-
- unsigned Opc;
- unsigned ZReg;
- switch (SrcVT.SimpleTy) {
- default:
- return false;
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
- ZReg = ARM64::WZR;
- Opc = ARM64::MADDWrrr;
- break;
- case MVT::i64:
- ZReg = ARM64::XZR;
- Opc = ARM64::MADDXrrr;
- break;
- }
-
- unsigned Src0Reg = getRegForValue(I->getOperand(0));
- if (!Src0Reg)
- return false;
-
- unsigned Src1Reg = getRegForValue(I->getOperand(1));
- if (!Src1Reg)
- return false;
-
- // Create the base instruction, then add the operands.
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(SrcVT));
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
- .addReg(Src0Reg)
- .addReg(Src1Reg)
- .addReg(ZReg);
- UpdateValueMap(I, ResultReg);
- return true;
-}
-
-bool ARM64FastISel::TargetSelectInstruction(const Instruction *I) {
- switch (I->getOpcode()) {
- default:
- break;
- case Instruction::Load:
- return SelectLoad(I);
- case Instruction::Store:
- return SelectStore(I);
- case Instruction::Br:
- return SelectBranch(I);
- case Instruction::IndirectBr:
- return SelectIndirectBr(I);
- case Instruction::FCmp:
- case Instruction::ICmp:
- return SelectCmp(I);
- case Instruction::Select:
- return SelectSelect(I);
- case Instruction::FPExt:
- return SelectFPExt(I);
- case Instruction::FPTrunc:
- return SelectFPTrunc(I);
- case Instruction::FPToSI:
- return SelectFPToInt(I, /*Signed=*/true);
- case Instruction::FPToUI:
- return SelectFPToInt(I, /*Signed=*/false);
- case Instruction::SIToFP:
- return SelectIntToFP(I, /*Signed=*/true);
- case Instruction::UIToFP:
- return SelectIntToFP(I, /*Signed=*/false);
- case Instruction::SRem:
- return SelectRem(I, ISD::SREM);
- case Instruction::URem:
- return SelectRem(I, ISD::UREM);
- case Instruction::Call:
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
- return SelectIntrinsicCall(*II);
- return SelectCall(I);
- case Instruction::Ret:
- return SelectRet(I);
- case Instruction::Trunc:
- return SelectTrunc(I);
- case Instruction::ZExt:
- case Instruction::SExt:
- return SelectIntExt(I);
- case Instruction::Mul:
- // FIXME: This really should be handled by the target-independent selector.
- return SelectMul(I);
- }
- return false;
- // Silence warnings.
- (void)&CC_ARM64_DarwinPCS_VarArg;
-}
-
-namespace llvm {
-llvm::FastISel *ARM64::createFastISel(FunctionLoweringInfo &funcInfo,
- const TargetLibraryInfo *libInfo) {
- return new ARM64FastISel(funcInfo, libInfo);
-}
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.cpp (removed)
@@ -1,888 +0,0 @@
-//===- ARM64FrameLowering.cpp - ARM64 Frame Lowering -----------*- C++ -*-====//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the ARM64 implementation of TargetFrameLowering class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64FrameLowering.h"
-#include "ARM64InstrInfo.h"
-#include "ARM64MachineFunctionInfo.h"
-#include "ARM64Subtarget.h"
-#include "ARM64TargetMachine.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "frame-info"
-
-static cl::opt<bool> EnableRedZone("arm64-redzone",
- cl::desc("enable use of redzone on ARM64"),
- cl::init(false), cl::Hidden);
-
-STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
-
-static unsigned estimateStackSize(MachineFunction &MF) {
- const MachineFrameInfo *FFI = MF.getFrameInfo();
- int Offset = 0;
- for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
- int FixedOff = -FFI->getObjectOffset(i);
- if (FixedOff > Offset)
- Offset = FixedOff;
- }
- for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
- if (FFI->isDeadObjectIndex(i))
- continue;
- Offset += FFI->getObjectSize(i);
- unsigned Align = FFI->getObjectAlignment(i);
- // Adjust to alignment boundary
- Offset = (Offset + Align - 1) / Align * Align;
- }
- // This does not include the 16 bytes used for fp and lr.
- return (unsigned)Offset;
-}
-
-bool ARM64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
- if (!EnableRedZone)
- return false;
- // Don't use the red zone if the function explicitly asks us not to.
- // This is typically used for kernel code.
- if (MF.getFunction()->getAttributes().hasAttribute(
- AttributeSet::FunctionIndex, Attribute::NoRedZone))
- return false;
-
- const MachineFrameInfo *MFI = MF.getFrameInfo();
- const ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
- unsigned NumBytes = AFI->getLocalStackSize();
-
- // Note: currently hasFP() is always true for hasCalls(), but that's an
- // implementation detail of the current code, not a strict requirement,
- // so stay safe here and check both.
- if (MFI->hasCalls() || hasFP(MF) || NumBytes > 128)
- return false;
- return true;
-}
-
-/// hasFP - Return true if the specified function should have a dedicated frame
-/// pointer register.
-bool ARM64FrameLowering::hasFP(const MachineFunction &MF) const {
- const MachineFrameInfo *MFI = MF.getFrameInfo();
-
-#ifndef NDEBUG
- const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
- assert(!RegInfo->needsStackRealignment(MF) &&
- "No stack realignment on ARM64!");
-#endif
-
- return (MFI->hasCalls() || MFI->hasVarSizedObjects() ||
- MFI->isFrameAddressTaken());
-}
-
-/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
-/// not required, we reserve argument space for call sites in the function
-/// immediately on entry to the current function. This eliminates the need for
-/// add/sub sp brackets around call sites. Returns true if the call frame is
-/// included as part of the stack frame.
-bool ARM64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
- return !MF.getFrameInfo()->hasVarSizedObjects();
-}
-
-void ARM64FrameLowering::eliminateCallFramePseudoInstr(
- MachineFunction &MF, MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const {
- const ARM64InstrInfo *TII =
- static_cast<const ARM64InstrInfo *>(MF.getTarget().getInstrInfo());
- DebugLoc DL = I->getDebugLoc();
- int Opc = I->getOpcode();
- bool IsDestroy = Opc == TII->getCallFrameDestroyOpcode();
- uint64_t CalleePopAmount = IsDestroy ? I->getOperand(1).getImm() : 0;
-
- const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
- if (!TFI->hasReservedCallFrame(MF)) {
- unsigned Align = getStackAlignment();
-
- int64_t Amount = I->getOperand(0).getImm();
- Amount = RoundUpToAlignment(Amount, Align);
- if (!IsDestroy)
- Amount = -Amount;
-
- // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
- // doesn't have to pop anything), then the first operand will be zero too so
- // this adjustment is a no-op.
- if (CalleePopAmount == 0) {
- // FIXME: in-function stack adjustment for calls is limited to 24-bits
- // because there's no guaranteed temporary register available.
- //
- // ADD/SUB (immediate) has only LSL #0 and LSL #12 avaiable.
- // 1) For offset <= 12-bit, we use LSL #0
- // 2) For 12-bit <= offset <= 24-bit, we use two instructions. One uses
- // LSL #0, and the other uses LSL #12.
- //
- // Mostly call frames will be allocated at the start of a function so
- // this is OK, but it is a limitation that needs dealing with.
- assert(Amount > -0xffffff && Amount < 0xffffff && "call frame too large");
- emitFrameOffset(MBB, I, DL, ARM64::SP, ARM64::SP, Amount, TII);
- }
- } else if (CalleePopAmount != 0) {
- // If the calling convention demands that the callee pops arguments from the
- // stack, we want to add it back if we have a reserved call frame.
- assert(CalleePopAmount < 0xffffff && "call frame too large");
- emitFrameOffset(MBB, I, DL, ARM64::SP, ARM64::SP, -CalleePopAmount, TII);
- }
- MBB.erase(I);
-}
-
-void
-ARM64FrameLowering::emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned FramePtr) const {
- MachineFunction &MF = *MBB.getParent();
- MachineFrameInfo *MFI = MF.getFrameInfo();
- MachineModuleInfo &MMI = MF.getMMI();
- const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
- const ARM64InstrInfo *TII = TM.getInstrInfo();
- DebugLoc DL = MBB.findDebugLoc(MBBI);
-
- // Add callee saved registers to move list.
- const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
- if (CSI.empty())
- return;
-
- const DataLayout *TD = MF.getTarget().getDataLayout();
- bool HasFP = hasFP(MF);
-
- // Calculate amount of bytes used for return address storing.
- int stackGrowth = -TD->getPointerSize(0);
-
- // Calculate offsets.
- int64_t saveAreaOffset = (HasFP ? 2 : 1) * stackGrowth;
- unsigned TotalSkipped = 0;
- for (const auto &Info : CSI) {
- unsigned Reg = Info.getReg();
- int64_t Offset = MFI->getObjectOffset(Info.getFrameIdx()) -
- getOffsetOfLocalArea() + saveAreaOffset;
-
- // Don't output a new CFI directive if we're re-saving the frame pointer or
- // link register. This happens when the PrologEpilogInserter has inserted an
- // extra "STP" of the frame pointer and link register -- the "emitPrologue"
- // method automatically generates the directives when frame pointers are
- // used. If we generate CFI directives for the extra "STP"s, the linker will
- // lose track of the correct values for the frame pointer and link register.
- if (HasFP && (FramePtr == Reg || Reg == ARM64::LR)) {
- TotalSkipped += stackGrowth;
- continue;
- }
-
- unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
- unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
- nullptr, DwarfReg, Offset - TotalSkipped));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- }
-}
-
-void ARM64FrameLowering::emitPrologue(MachineFunction &MF) const {
- MachineBasicBlock &MBB = MF.front(); // Prologue goes in entry BB.
- MachineBasicBlock::iterator MBBI = MBB.begin();
- const MachineFrameInfo *MFI = MF.getFrameInfo();
- const Function *Fn = MF.getFunction();
- const ARM64RegisterInfo *RegInfo = TM.getRegisterInfo();
- const ARM64InstrInfo *TII = TM.getInstrInfo();
- MachineModuleInfo &MMI = MF.getMMI();
- ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
- bool needsFrameMoves = MMI.hasDebugInfo() || Fn->needsUnwindTableEntry();
- bool HasFP = hasFP(MF);
- DebugLoc DL = MBB.findDebugLoc(MBBI);
-
- int NumBytes = (int)MFI->getStackSize();
- if (!AFI->hasStackFrame()) {
- assert(!HasFP && "unexpected function without stack frame but with FP");
-
- // All of the stack allocation is for locals.
- AFI->setLocalStackSize(NumBytes);
-
- // Label used to tie together the PROLOG_LABEL and the MachineMoves.
- MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol();
-
- // REDZONE: If the stack size is less than 128 bytes, we don't need
- // to actually allocate.
- if (NumBytes && !canUseRedZone(MF)) {
- emitFrameOffset(MBB, MBBI, DL, ARM64::SP, ARM64::SP, -NumBytes, TII,
- MachineInstr::FrameSetup);
-
- // Encode the stack size of the leaf function.
- unsigned CFIIndex = MMI.addFrameInst(
- MCCFIInstruction::createDefCfaOffset(FrameLabel, -NumBytes));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- } else if (NumBytes) {
- ++NumRedZoneFunctions;
- }
-
- return;
- }
-
- // Only set up FP if we actually need to.
- int FPOffset = 0;
- if (HasFP) {
- // First instruction must a) allocate the stack and b) have an immediate
- // that is a multiple of -2.
- assert((MBBI->getOpcode() == ARM64::STPXpre ||
- MBBI->getOpcode() == ARM64::STPDpre) &&
- MBBI->getOperand(3).getReg() == ARM64::SP &&
- MBBI->getOperand(4).getImm() < 0 &&
- (MBBI->getOperand(4).getImm() & 1) == 0);
-
- // Frame pointer is fp = sp - 16. Since the STPXpre subtracts the space
- // required for the callee saved register area we get the frame pointer
- // by addding that offset - 16 = -getImm()*8 - 2*8 = -(getImm() + 2) * 8.
- FPOffset = -(MBBI->getOperand(4).getImm() + 2) * 8;
- assert(FPOffset >= 0 && "Bad Framepointer Offset");
- }
-
- // Move past the saves of the callee-saved registers.
- while (MBBI->getOpcode() == ARM64::STPXi ||
- MBBI->getOpcode() == ARM64::STPDi ||
- MBBI->getOpcode() == ARM64::STPXpre ||
- MBBI->getOpcode() == ARM64::STPDpre) {
- ++MBBI;
- NumBytes -= 16;
- }
- assert(NumBytes >= 0 && "Negative stack allocation size!?");
- if (HasFP) {
- // Issue sub fp, sp, FPOffset or
- // mov fp,sp when FPOffset is zero.
- // Note: All stores of callee-saved registers are marked as "FrameSetup".
- // This code marks the instruction(s) that set the FP also.
- emitFrameOffset(MBB, MBBI, DL, ARM64::FP, ARM64::SP, FPOffset, TII,
- MachineInstr::FrameSetup);
- }
-
- // All of the remaining stack allocations are for locals.
- AFI->setLocalStackSize(NumBytes);
-
- // Allocate space for the rest of the frame.
- if (NumBytes) {
- // If we're a leaf function, try using the red zone.
- if (!canUseRedZone(MF))
- emitFrameOffset(MBB, MBBI, DL, ARM64::SP, ARM64::SP, -NumBytes, TII,
- MachineInstr::FrameSetup);
- }
-
- // If we need a base pointer, set it up here. It's whatever the value of the
- // stack pointer is at this point. Any variable size objects will be allocated
- // after this, so we can still use the base pointer to reference locals.
- //
- // FIXME: Clarify FrameSetup flags here.
- // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
- // needed.
- //
- if (RegInfo->hasBasePointer(MF))
- TII->copyPhysReg(MBB, MBBI, DL, ARM64::X19, ARM64::SP, false);
-
- if (needsFrameMoves) {
- const DataLayout *TD = MF.getTarget().getDataLayout();
- const int StackGrowth = -TD->getPointerSize(0);
- unsigned FramePtr = RegInfo->getFrameRegister(MF);
-
- // An example of the prologue:
- //
- // .globl __foo
- // .align 2
- // __foo:
- // Ltmp0:
- // .cfi_startproc
- // .cfi_personality 155, ___gxx_personality_v0
- // Leh_func_begin:
- // .cfi_lsda 16, Lexception33
- //
- // stp xa,bx, [sp, -#offset]!
- // ...
- // stp x28, x27, [sp, #offset-32]
- // stp fp, lr, [sp, #offset-16]
- // add fp, sp, #offset - 16
- // sub sp, sp, #1360
- //
- // The Stack:
- // +-------------------------------------------+
- // 10000 | ........ | ........ | ........ | ........ |
- // 10004 | ........ | ........ | ........ | ........ |
- // +-------------------------------------------+
- // 10008 | ........ | ........ | ........ | ........ |
- // 1000c | ........ | ........ | ........ | ........ |
- // +===========================================+
- // 10010 | X28 Register |
- // 10014 | X28 Register |
- // +-------------------------------------------+
- // 10018 | X27 Register |
- // 1001c | X27 Register |
- // +===========================================+
- // 10020 | Frame Pointer |
- // 10024 | Frame Pointer |
- // +-------------------------------------------+
- // 10028 | Link Register |
- // 1002c | Link Register |
- // +===========================================+
- // 10030 | ........ | ........ | ........ | ........ |
- // 10034 | ........ | ........ | ........ | ........ |
- // +-------------------------------------------+
- // 10038 | ........ | ........ | ........ | ........ |
- // 1003c | ........ | ........ | ........ | ........ |
- // +-------------------------------------------+
- //
- // [sp] = 10030 :: >>initial value<<
- // sp = 10020 :: stp fp, lr, [sp, #-16]!
- // fp = sp == 10020 :: mov fp, sp
- // [sp] == 10020 :: stp x28, x27, [sp, #-16]!
- // sp == 10010 :: >>final value<<
- //
- // The frame pointer (w29) points to address 10020. If we use an offset of
- // '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24
- // for w27, and -32 for w28:
- //
- // Ltmp1:
- // .cfi_def_cfa w29, 16
- // Ltmp2:
- // .cfi_offset w30, -8
- // Ltmp3:
- // .cfi_offset w29, -16
- // Ltmp4:
- // .cfi_offset w27, -24
- // Ltmp5:
- // .cfi_offset w28, -32
-
- if (HasFP) {
- // Define the current CFA rule to use the provided FP.
- unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true);
- unsigned CFIIndex = MMI.addFrameInst(
- MCCFIInstruction::createDefCfa(nullptr, Reg, 2 * StackGrowth));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
-
- // Record the location of the stored LR
- unsigned LR = RegInfo->getDwarfRegNum(ARM64::LR, true);
- CFIIndex = MMI.addFrameInst(
- MCCFIInstruction::createOffset(nullptr, LR, StackGrowth));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
-
- // Record the location of the stored FP
- CFIIndex = MMI.addFrameInst(
- MCCFIInstruction::createOffset(nullptr, Reg, 2 * StackGrowth));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- } else {
- // Encode the stack size of the leaf function.
- unsigned CFIIndex = MMI.addFrameInst(
- MCCFIInstruction::createDefCfaOffset(nullptr, -MFI->getStackSize()));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex);
- }
-
- // Now emit the moves for whatever callee saved regs we have.
- emitCalleeSavedFrameMoves(MBB, MBBI, FramePtr);
- }
-}
-
-static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs) {
- for (unsigned i = 0; CSRegs[i]; ++i)
- if (Reg == CSRegs[i])
- return true;
- return false;
-}
-
-static bool isCSRestore(MachineInstr *MI, const MCPhysReg *CSRegs) {
- unsigned RtIdx = 0;
- if (MI->getOpcode() == ARM64::LDPXpost || MI->getOpcode() == ARM64::LDPDpost)
- RtIdx = 1;
-
- if (MI->getOpcode() == ARM64::LDPXpost ||
- MI->getOpcode() == ARM64::LDPDpost || MI->getOpcode() == ARM64::LDPXi ||
- MI->getOpcode() == ARM64::LDPDi) {
- if (!isCalleeSavedRegister(MI->getOperand(RtIdx).getReg(), CSRegs) ||
- !isCalleeSavedRegister(MI->getOperand(RtIdx + 1).getReg(), CSRegs) ||
- MI->getOperand(RtIdx + 2).getReg() != ARM64::SP)
- return false;
- return true;
- }
-
- return false;
-}
-
-void ARM64FrameLowering::emitEpilogue(MachineFunction &MF,
- MachineBasicBlock &MBB) const {
- MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
- assert(MBBI->isReturn() && "Can only insert epilog into returning blocks");
- MachineFrameInfo *MFI = MF.getFrameInfo();
- const ARM64InstrInfo *TII =
- static_cast<const ARM64InstrInfo *>(MF.getTarget().getInstrInfo());
- const ARM64RegisterInfo *RegInfo =
- static_cast<const ARM64RegisterInfo *>(MF.getTarget().getRegisterInfo());
- DebugLoc DL = MBBI->getDebugLoc();
- unsigned RetOpcode = MBBI->getOpcode();
-
- int NumBytes = MFI->getStackSize();
- const ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
-
- // Initial and residual are named for consitency with the prologue. Note that
- // in the epilogue, the residual adjustment is executed first.
- uint64_t ArgumentPopSize = 0;
- if (RetOpcode == ARM64::TCRETURNdi || RetOpcode == ARM64::TCRETURNri) {
- MachineOperand &StackAdjust = MBBI->getOperand(1);
-
- // For a tail-call in a callee-pops-arguments environment, some or all of
- // the stack may actually be in use for the call's arguments, this is
- // calculated during LowerCall and consumed here...
- ArgumentPopSize = StackAdjust.getImm();
- } else {
- // ... otherwise the amount to pop is *all* of the argument space,
- // conveniently stored in the MachineFunctionInfo by
- // LowerFormalArguments. This will, of course, be zero for the C calling
- // convention.
- ArgumentPopSize = AFI->getArgumentStackToRestore();
- }
-
- // The stack frame should be like below,
- //
- // ---------------------- ---
- // | | |
- // | BytesInStackArgArea| CalleeArgStackSize
- // | (NumReusableBytes) | (of tail call)
- // | | ---
- // | | |
- // ---------------------| --- |
- // | | | |
- // | CalleeSavedReg | | |
- // | (NumRestores * 16) | | |
- // | | | |
- // ---------------------| | NumBytes
- // | | StackSize (StackAdjustUp)
- // | LocalStackSize | | |
- // | (covering callee | | |
- // | args) | | |
- // | | | |
- // ---------------------- --- ---
- //
- // So NumBytes = StackSize + BytesInStackArgArea - CalleeArgStackSize
- // = StackSize + ArgumentPopSize
- //
- // ARM64TargetLowering::LowerCall figures out ArgumentPopSize and keeps
- // it as the 2nd argument of ARM64ISD::TC_RETURN.
- NumBytes += ArgumentPopSize;
-
- unsigned NumRestores = 0;
- // Move past the restores of the callee-saved registers.
- MachineBasicBlock::iterator LastPopI = MBBI;
- const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
- if (LastPopI != MBB.begin()) {
- do {
- ++NumRestores;
- --LastPopI;
- } while (LastPopI != MBB.begin() && isCSRestore(LastPopI, CSRegs));
- if (!isCSRestore(LastPopI, CSRegs)) {
- ++LastPopI;
- --NumRestores;
- }
- }
- NumBytes -= NumRestores * 16;
- assert(NumBytes >= 0 && "Negative stack allocation size!?");
-
- if (!hasFP(MF)) {
- // If this was a redzone leaf function, we don't need to restore the
- // stack pointer.
- if (!canUseRedZone(MF))
- emitFrameOffset(MBB, LastPopI, DL, ARM64::SP, ARM64::SP, NumBytes, TII);
- return;
- }
-
- // Restore the original stack pointer.
- // FIXME: Rather than doing the math here, we should instead just use
- // non-post-indexed loads for the restores if we aren't actually going to
- // be able to save any instructions.
- if (NumBytes || MFI->hasVarSizedObjects())
- emitFrameOffset(MBB, LastPopI, DL, ARM64::SP, ARM64::FP,
- -(NumRestores - 1) * 16, TII, MachineInstr::NoFlags);
-}
-
-/// getFrameIndexOffset - Returns the displacement from the frame register to
-/// the stack frame of the specified index.
-int ARM64FrameLowering::getFrameIndexOffset(const MachineFunction &MF,
- int FI) const {
- unsigned FrameReg;
- return getFrameIndexReference(MF, FI, FrameReg);
-}
-
-/// getFrameIndexReference - Provide a base+offset reference to an FI slot for
-/// debug info. It's the same as what we use for resolving the code-gen
-/// references for now. FIXME: This can go wrong when references are
-/// SP-relative and simple call frames aren't used.
-int ARM64FrameLowering::getFrameIndexReference(const MachineFunction &MF,
- int FI,
- unsigned &FrameReg) const {
- return resolveFrameIndexReference(MF, FI, FrameReg);
-}
-
-int ARM64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF,
- int FI, unsigned &FrameReg,
- bool PreferFP) const {
- const MachineFrameInfo *MFI = MF.getFrameInfo();
- const ARM64RegisterInfo *RegInfo =
- static_cast<const ARM64RegisterInfo *>(MF.getTarget().getRegisterInfo());
- const ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
- int FPOffset = MFI->getObjectOffset(FI) + 16;
- int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
- bool isFixed = MFI->isFixedObjectIndex(FI);
-
- // Use frame pointer to reference fixed objects. Use it for locals if
- // there are VLAs (and thus the SP isn't reliable as a base).
- // Make sure useFPForScavengingIndex() does the right thing for the emergency
- // spill slot.
- bool UseFP = false;
- if (AFI->hasStackFrame()) {
- // Note: Keeping the following as multiple 'if' statements rather than
- // merging to a single expression for readability.
- //
- // Argument access should always use the FP.
- if (isFixed) {
- UseFP = hasFP(MF);
- } else if (hasFP(MF) && !RegInfo->hasBasePointer(MF)) {
- // Use SP or FP, whichever gives us the best chance of the offset
- // being in range for direct access. If the FPOffset is positive,
- // that'll always be best, as the SP will be even further away.
- // If the FPOffset is negative, we have to keep in mind that the
- // available offset range for negative offsets is smaller than for
- // positive ones. If we have variable sized objects, we're stuck with
- // using the FP regardless, though, as the SP offset is unknown
- // and we don't have a base pointer available. If an offset is
- // available via the FP and the SP, use whichever is closest.
- if (PreferFP || MFI->hasVarSizedObjects() || FPOffset >= 0 ||
- (FPOffset >= -256 && Offset > -FPOffset))
- UseFP = true;
- }
- }
-
- if (UseFP) {
- FrameReg = RegInfo->getFrameRegister(MF);
- return FPOffset;
- }
-
- // Use the base pointer if we have one.
- if (RegInfo->hasBasePointer(MF))
- FrameReg = RegInfo->getBaseRegister();
- else {
- FrameReg = ARM64::SP;
- // If we're using the red zone for this function, the SP won't actually
- // be adjusted, so the offsets will be negative. They're also all
- // within range of the signed 9-bit immediate instructions.
- if (canUseRedZone(MF))
- Offset -= AFI->getLocalStackSize();
- }
-
- return Offset;
-}
-
-static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) {
- if (Reg != ARM64::LR)
- return getKillRegState(true);
-
- // LR maybe referred to later by an @llvm.returnaddress intrinsic.
- bool LRLiveIn = MF.getRegInfo().isLiveIn(ARM64::LR);
- bool LRKill = !(LRLiveIn && MF.getFrameInfo()->isReturnAddressTaken());
- return getKillRegState(LRKill);
-}
-
-bool ARM64FrameLowering::spillCalleeSavedRegisters(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
- unsigned Count = CSI.size();
- DebugLoc DL;
- assert((Count & 1) == 0 && "Odd number of callee-saved regs to spill!");
-
- if (MI != MBB.end())
- DL = MI->getDebugLoc();
-
- for (unsigned i = 0; i < Count; i += 2) {
- unsigned idx = Count - i - 2;
- unsigned Reg1 = CSI[idx].getReg();
- unsigned Reg2 = CSI[idx + 1].getReg();
- // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
- // list to come in sorted by frame index so that we can issue the store
- // pair instructions directly. Assert if we see anything otherwise.
- //
- // The order of the registers in the list is controlled by
- // getCalleeSavedRegs(), so they will always be in-order, as well.
- assert(CSI[idx].getFrameIdx() + 1 == CSI[idx + 1].getFrameIdx() &&
- "Out of order callee saved regs!");
- unsigned StrOpc;
- assert((Count & 1) == 0 && "Odd number of callee-saved regs to spill!");
- assert((i & 1) == 0 && "Odd index for callee-saved reg spill!");
- // Issue sequence of non-sp increment and pi sp spills for cs regs. The
- // first spill is a pre-increment that allocates the stack.
- // For example:
- // stp x22, x21, [sp, #-48]! // addImm(-6)
- // stp x20, x19, [sp, #16] // addImm(+2)
- // stp fp, lr, [sp, #32] // addImm(+4)
- // Rationale: This sequence saves uop updates compared to a sequence of
- // pre-increment spills like stp xi,xj,[sp,#-16]!
- // Note: Similar rational and sequence for restores in epilog.
- if (ARM64::GPR64RegClass.contains(Reg1)) {
- assert(ARM64::GPR64RegClass.contains(Reg2) &&
- "Expected GPR64 callee-saved register pair!");
- // For first spill use pre-increment store.
- if (i == 0)
- StrOpc = ARM64::STPXpre;
- else
- StrOpc = ARM64::STPXi;
- } else if (ARM64::FPR64RegClass.contains(Reg1)) {
- assert(ARM64::FPR64RegClass.contains(Reg2) &&
- "Expected FPR64 callee-saved register pair!");
- // For first spill use pre-increment store.
- if (i == 0)
- StrOpc = ARM64::STPDpre;
- else
- StrOpc = ARM64::STPDi;
- } else
- llvm_unreachable("Unexpected callee saved register!");
- DEBUG(dbgs() << "CSR spill: (" << TRI->getName(Reg1) << ", "
- << TRI->getName(Reg2) << ") -> fi#(" << CSI[idx].getFrameIdx()
- << ", " << CSI[idx + 1].getFrameIdx() << ")\n");
- // Compute offset: i = 0 => offset = -Count;
- // i = 2 => offset = -(Count - 2) + Count = 2 = i; etc.
- const int Offset = (i == 0) ? -Count : i;
- assert((Offset >= -64 && Offset <= 63) &&
- "Offset out of bounds for STP immediate");
- MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc));
- if (StrOpc == ARM64::STPDpre || StrOpc == ARM64::STPXpre)
- MIB.addReg(ARM64::SP, RegState::Define);
-
- MIB.addReg(Reg2, getPrologueDeath(MF, Reg2))
- .addReg(Reg1, getPrologueDeath(MF, Reg1))
- .addReg(ARM64::SP)
- .addImm(Offset) // [sp, #offset * 8], where factor * 8 is implicit
- .setMIFlag(MachineInstr::FrameSetup);
- }
- return true;
-}
-
-bool ARM64FrameLowering::restoreCalleeSavedRegisters(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
- unsigned Count = CSI.size();
- DebugLoc DL;
- assert((Count & 1) == 0 && "Odd number of callee-saved regs to spill!");
-
- if (MI != MBB.end())
- DL = MI->getDebugLoc();
-
- for (unsigned i = 0; i < Count; i += 2) {
- unsigned Reg1 = CSI[i].getReg();
- unsigned Reg2 = CSI[i + 1].getReg();
- // GPRs and FPRs are saved in pairs of 64-bit regs. We expect the CSI
- // list to come in sorted by frame index so that we can issue the store
- // pair instructions directly. Assert if we see anything otherwise.
- assert(CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx() &&
- "Out of order callee saved regs!");
- // Issue sequence of non-sp increment and sp-pi restores for cs regs. Only
- // the last load is sp-pi post-increment and de-allocates the stack:
- // For example:
- // ldp fp, lr, [sp, #32] // addImm(+4)
- // ldp x20, x19, [sp, #16] // addImm(+2)
- // ldp x22, x21, [sp], #48 // addImm(+6)
- // Note: see comment in spillCalleeSavedRegisters()
- unsigned LdrOpc;
-
- assert((Count & 1) == 0 && "Odd number of callee-saved regs to spill!");
- assert((i & 1) == 0 && "Odd index for callee-saved reg spill!");
- if (ARM64::GPR64RegClass.contains(Reg1)) {
- assert(ARM64::GPR64RegClass.contains(Reg2) &&
- "Expected GPR64 callee-saved register pair!");
- if (i == Count - 2)
- LdrOpc = ARM64::LDPXpost;
- else
- LdrOpc = ARM64::LDPXi;
- } else if (ARM64::FPR64RegClass.contains(Reg1)) {
- assert(ARM64::FPR64RegClass.contains(Reg2) &&
- "Expected FPR64 callee-saved register pair!");
- if (i == Count - 2)
- LdrOpc = ARM64::LDPDpost;
- else
- LdrOpc = ARM64::LDPDi;
- } else
- llvm_unreachable("Unexpected callee saved register!");
- DEBUG(dbgs() << "CSR restore: (" << TRI->getName(Reg1) << ", "
- << TRI->getName(Reg2) << ") -> fi#(" << CSI[i].getFrameIdx()
- << ", " << CSI[i + 1].getFrameIdx() << ")\n");
-
- // Compute offset: i = 0 => offset = Count - 2; i = 2 => offset = Count - 4;
- // etc.
- const int Offset = (i == Count - 2) ? Count : Count - i - 2;
- assert((Offset >= -64 && Offset <= 63) &&
- "Offset out of bounds for LDP immediate");
- MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(LdrOpc));
- if (LdrOpc == ARM64::LDPXpost || LdrOpc == ARM64::LDPDpost)
- MIB.addReg(ARM64::SP, RegState::Define);
-
- MIB.addReg(Reg2, getDefRegState(true))
- .addReg(Reg1, getDefRegState(true))
- .addReg(ARM64::SP)
- .addImm(Offset); // [sp], #offset * 8 or [sp, #offset * 8]
- // where the factor * 8 is implicit
- }
- return true;
-}
-
-void ARM64FrameLowering::processFunctionBeforeCalleeSavedScan(
- MachineFunction &MF, RegScavenger *RS) const {
- const ARM64RegisterInfo *RegInfo =
- static_cast<const ARM64RegisterInfo *>(MF.getTarget().getRegisterInfo());
- ARM64FunctionInfo *AFI = MF.getInfo<ARM64FunctionInfo>();
- MachineRegisterInfo *MRI = &MF.getRegInfo();
- SmallVector<unsigned, 4> UnspilledCSGPRs;
- SmallVector<unsigned, 4> UnspilledCSFPRs;
-
- // The frame record needs to be created by saving the appropriate registers
- if (hasFP(MF)) {
- MRI->setPhysRegUsed(ARM64::FP);
- MRI->setPhysRegUsed(ARM64::LR);
- }
-
- // Spill the BasePtr if it's used. Do this first thing so that the
- // getCalleeSavedRegs() below will get the right answer.
- if (RegInfo->hasBasePointer(MF))
- MRI->setPhysRegUsed(RegInfo->getBaseRegister());
-
- // If any callee-saved registers are used, the frame cannot be eliminated.
- unsigned NumGPRSpilled = 0;
- unsigned NumFPRSpilled = 0;
- bool ExtraCSSpill = false;
- bool CanEliminateFrame = true;
- DEBUG(dbgs() << "*** processFunctionBeforeCalleeSavedScan\nUsed CSRs:");
- const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
-
- // Check pairs of consecutive callee-saved registers.
- for (unsigned i = 0; CSRegs[i]; i += 2) {
- assert(CSRegs[i + 1] && "Odd number of callee-saved registers!");
-
- const unsigned OddReg = CSRegs[i];
- const unsigned EvenReg = CSRegs[i + 1];
- assert((ARM64::GPR64RegClass.contains(OddReg) &&
- ARM64::GPR64RegClass.contains(EvenReg)) ^
- (ARM64::FPR64RegClass.contains(OddReg) &&
- ARM64::FPR64RegClass.contains(EvenReg)) &&
- "Register class mismatch!");
-
- const bool OddRegUsed = MRI->isPhysRegUsed(OddReg);
- const bool EvenRegUsed = MRI->isPhysRegUsed(EvenReg);
-
- // Early exit if none of the registers in the register pair is actually
- // used.
- if (!OddRegUsed && !EvenRegUsed) {
- if (ARM64::GPR64RegClass.contains(OddReg)) {
- UnspilledCSGPRs.push_back(OddReg);
- UnspilledCSGPRs.push_back(EvenReg);
- } else {
- UnspilledCSFPRs.push_back(OddReg);
- UnspilledCSFPRs.push_back(EvenReg);
- }
- continue;
- }
-
- unsigned Reg = ARM64::NoRegister;
- // If only one of the registers of the register pair is used, make sure to
- // mark the other one as used as well.
- if (OddRegUsed ^ EvenRegUsed) {
- // Find out which register is the additional spill.
- Reg = OddRegUsed ? EvenReg : OddReg;
- MRI->setPhysRegUsed(Reg);
- }
-
- DEBUG(dbgs() << ' ' << PrintReg(OddReg, RegInfo));
- DEBUG(dbgs() << ' ' << PrintReg(EvenReg, RegInfo));
-
- assert(((OddReg == ARM64::LR && EvenReg == ARM64::FP) ||
- (RegInfo->getEncodingValue(OddReg) + 1 ==
- RegInfo->getEncodingValue(EvenReg))) &&
- "Register pair of non-adjacent registers!");
- if (ARM64::GPR64RegClass.contains(OddReg)) {
- NumGPRSpilled += 2;
- // If it's not a reserved register, we can use it in lieu of an
- // emergency spill slot for the register scavenger.
- // FIXME: It would be better to instead keep looking and choose another
- // unspilled register that isn't reserved, if there is one.
- if (Reg != ARM64::NoRegister && !RegInfo->isReservedReg(MF, Reg))
- ExtraCSSpill = true;
- } else
- NumFPRSpilled += 2;
-
- CanEliminateFrame = false;
- }
-
- // FIXME: Set BigStack if any stack slot references may be out of range.
- // For now, just conservatively guestimate based on unscaled indexing
- // range. We'll end up allocating an unnecessary spill slot a lot, but
- // realistically that's not a big deal at this stage of the game.
- // The CSR spill slots have not been allocated yet, so estimateStackSize
- // won't include them.
- MachineFrameInfo *MFI = MF.getFrameInfo();
- unsigned CFSize = estimateStackSize(MF) + 8 * (NumGPRSpilled + NumFPRSpilled);
- DEBUG(dbgs() << "Estimated stack frame size: " << CFSize << " bytes.\n");
- bool BigStack = (CFSize >= 256);
- if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF))
- AFI->setHasStackFrame(true);
-
- // Estimate if we might need to scavenge a register at some point in order
- // to materialize a stack offset. If so, either spill one additional
- // callee-saved register or reserve a special spill slot to facilitate
- // register scavenging. If we already spilled an extra callee-saved register
- // above to keep the number of spills even, we don't need to do anything else
- // here.
- if (BigStack && !ExtraCSSpill) {
-
- // If we're adding a register to spill here, we have to add two of them
- // to keep the number of regs to spill even.
- assert(((UnspilledCSGPRs.size() & 1) == 0) && "Odd number of registers!");
- unsigned Count = 0;
- while (!UnspilledCSGPRs.empty() && Count < 2) {
- unsigned Reg = UnspilledCSGPRs.back();
- UnspilledCSGPRs.pop_back();
- DEBUG(dbgs() << "Spilling " << PrintReg(Reg, RegInfo)
- << " to get a scratch register.\n");
- MRI->setPhysRegUsed(Reg);
- ExtraCSSpill = true;
- ++Count;
- }
-
- // If we didn't find an extra callee-saved register to spill, create
- // an emergency spill slot.
- if (!ExtraCSSpill) {
- const TargetRegisterClass *RC = &ARM64::GPR64RegClass;
- int FI = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), false);
- RS->addScavengingFrameIndex(FI);
- DEBUG(dbgs() << "No available CS registers, allocated fi#" << FI
- << " as the emergency spill slot.\n");
- }
- }
-}
Removed: llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.h?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.h (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64FrameLowering.h (removed)
@@ -1,75 +0,0 @@
-//===-- ARM64FrameLowering.h - TargetFrameLowering for ARM64 ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ARM64_FRAMELOWERING_H
-#define ARM64_FRAMELOWERING_H
-
-#include "llvm/Target/TargetFrameLowering.h"
-
-namespace llvm {
-
-class ARM64Subtarget;
-class ARM64TargetMachine;
-
-class ARM64FrameLowering : public TargetFrameLowering {
- const ARM64TargetMachine &TM;
-
-public:
- explicit ARM64FrameLowering(const ARM64TargetMachine &TM,
- const ARM64Subtarget &STI)
- : TargetFrameLowering(StackGrowsDown, 16, 0, 16,
- false /*StackRealignable*/),
- TM(TM) {}
-
- void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned FramePtr) const;
-
- void eliminateCallFramePseudoInstr(MachineFunction &MF,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const override;
-
- /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
- /// the function.
- void emitPrologue(MachineFunction &MF) const override;
- void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
-
- int getFrameIndexOffset(const MachineFunction &MF, int FI) const override;
- int getFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg) const override;
- int resolveFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg,
- bool PreferFP = false) const;
- bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const override;
-
- bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const override;
-
- /// \brief Can this function use the red zone for local allocations.
- bool canUseRedZone(const MachineFunction &MF) const;
-
- bool hasFP(const MachineFunction &MF) const override;
- bool hasReservedCallFrame(const MachineFunction &MF) const override;
-
- void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const override;
-};
-
-} // End llvm namespace
-
-#endif
Removed: llvm/trunk/lib/Target/ARM64/ARM64ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelDAGToDAG.cpp?rev=209576&view=auto
==============================================================================
--- llvm/trunk/lib/Target/ARM64/ARM64ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/ARM64ISelDAGToDAG.cpp (removed)
@@ -1,3030 +0,0 @@
-//===-- ARM64ISelDAGToDAG.cpp - A dag to dag inst selector for ARM64 ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines an instruction selector for the ARM64 target.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ARM64TargetMachine.h"
-#include "MCTargetDesc/ARM64AddressingModes.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/IR/Function.h" // To access function attributes.
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "arm64-isel"
-
-//===--------------------------------------------------------------------===//
-/// ARM64DAGToDAGISel - ARM64 specific code to select ARM64 machine
-/// instructions for SelectionDAG operations.
-///
-namespace {
-
-class ARM64DAGToDAGISel : public SelectionDAGISel {
- ARM64TargetMachine &TM;
-
- /// Subtarget - Keep a pointer to the ARM64Subtarget around so that we can
- /// make the right decision when generating code for different targets.
- const ARM64Subtarget *Subtarget;
-
- bool ForCodeSize;
-
-public:
- explicit ARM64DAGToDAGISel(ARM64TargetMachine &tm, CodeGenOpt::Level OptLevel)
- : SelectionDAGISel(tm, OptLevel), TM(tm),
- Subtarget(nullptr), ForCodeSize(false) {}
-
- const char *getPassName() const override {
- return "ARM64 Instruction Selection";
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override {
- AttributeSet FnAttrs = MF.getFunction()->getAttributes();
- ForCodeSize =
- FnAttrs.hasAttribute(AttributeSet::FunctionIndex,
- Attribute::OptimizeForSize) ||
- FnAttrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::MinSize);
- Subtarget = &TM.getSubtarget<ARM64Subtarget>();
- return SelectionDAGISel::runOnMachineFunction(MF);
- }
-
- SDNode *Select(SDNode *Node) override;
-
- /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
- /// inline asm expressions.
- bool SelectInlineAsmMemoryOperand(const SDValue &Op,
- char ConstraintCode,
- std::vector<SDValue> &OutOps) override;
-
- SDNode *SelectMLAV64LaneV128(SDNode *N);
- SDNode *SelectMULLV64LaneV128(unsigned IntNo, SDNode *N);
- bool SelectArithExtendedRegister(SDValue N, SDValue &Reg, SDValue &Shift);
- bool SelectArithImmed(SDValue N, SDValue &Val, SDValue &Shift);
- bool SelectNegArithImmed(SDValue N, SDValue &Val, SDValue &Shift);
- bool SelectArithShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) {
- return SelectShiftedRegister(N, false, Reg, Shift);
- }
- bool SelectLogicalShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) {
- return SelectShiftedRegister(N, true, Reg, Shift);
- }
- bool SelectAddrModeIndexed8(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeIndexed(N, 1, Base, OffImm);
- }
- bool SelectAddrModeIndexed16(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeIndexed(N, 2, Base, OffImm);
- }
- bool SelectAddrModeIndexed32(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeIndexed(N, 4, Base, OffImm);
- }
- bool SelectAddrModeIndexed64(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeIndexed(N, 8, Base, OffImm);
- }
- bool SelectAddrModeIndexed128(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeIndexed(N, 16, Base, OffImm);
- }
- bool SelectAddrModeUnscaled8(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeUnscaled(N, 1, Base, OffImm);
- }
- bool SelectAddrModeUnscaled16(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeUnscaled(N, 2, Base, OffImm);
- }
- bool SelectAddrModeUnscaled32(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeUnscaled(N, 4, Base, OffImm);
- }
- bool SelectAddrModeUnscaled64(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeUnscaled(N, 8, Base, OffImm);
- }
- bool SelectAddrModeUnscaled128(SDValue N, SDValue &Base, SDValue &OffImm) {
- return SelectAddrModeUnscaled(N, 16, Base, OffImm);
- }
-
- template<int Width>
- bool SelectAddrModeWRO(SDValue N, SDValue &Base, SDValue &Offset,
- SDValue &SignExtend, SDValue &DoShift) {
- return SelectAddrModeWRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
- }
-
- template<int Width>
- bool SelectAddrModeXRO(SDValue N, SDValue &Base, SDValue &Offset,
- SDValue &SignExtend, SDValue &DoShift) {
- return SelectAddrModeXRO(N, Width / 8, Base, Offset, SignExtend, DoShift);
- }
-
-
- /// Form sequences of consecutive 64/128-bit registers for use in NEON
- /// instructions making use of a vector-list (e.g. ldN, tbl). Vecs must have
- /// between 1 and 4 elements. If it contains a single element that is returned
- /// unchanged; otherwise a REG_SEQUENCE value is returned.
- SDValue createDTuple(ArrayRef<SDValue> Vecs);
- SDValue createQTuple(ArrayRef<SDValue> Vecs);
-
- /// Generic helper for the createDTuple/createQTuple
- /// functions. Those should almost always be called instead.
- SDValue createTuple(ArrayRef<SDValue> Vecs, unsigned RegClassIDs[],
- unsigned SubRegs[]);
-
- SDNode *SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, bool isExt);
-
- SDNode *SelectIndexedLoad(SDNode *N, bool &Done);
-
- SDNode *SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
- unsigned SubRegIdx);
- SDNode *SelectPostLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
- unsigned SubRegIdx);
- SDNode *SelectLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc);
- SDNode *SelectPostLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc);
-
- SDNode *SelectStore(SDNode *N, unsigned NumVecs, unsigned Opc);
- SDNode *SelectPostStore(SDNode *N, unsigned NumVecs, unsigned Opc);
- SDNode *SelectStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc);
- SDNode *SelectPostStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc);
-
- SDNode *SelectSIMDAddSubNarrowing(unsigned IntNo, SDNode *Node);
- SDNode *SelectSIMDXtnNarrowing(unsigned IntNo, SDNode *Node);
-
- SDNode *SelectBitfieldExtractOp(SDNode *N);
- SDNode *SelectBitfieldInsertOp(SDNode *N);
-
- SDNode *SelectLIBM(SDNode *N);
-
-// Include the pieces autogenerated from the target description.
-#include "ARM64GenDAGISel.inc"
-
-private:
- bool SelectShiftedRegister(SDValue N, bool AllowROR, SDValue &Reg,
- SDValue &Shift);
- bool SelectAddrModeIndexed(SDValue N, unsigned Size, SDValue &Base,
- SDValue &OffImm);
- bool SelectAddrModeUnscaled(SDValue N, unsigned Size, SDValue &Base,
- SDValue &OffImm);
- bool SelectAddrModeWRO(SDValue N, unsigned Size, SDValue &Base,
- SDValue &Offset, SDValue &SignExtend,
- SDValue &DoShift);
- bool SelectAddrModeXRO(SDValue N, unsigned Size, SDValue &Base,
- SDValue &Offset, SDValue &SignExtend,
- SDValue &DoShift);
- bool isWorthFolding(SDValue V) const;
- bool SelectExtendedSHL(SDValue N, unsigned Size, bool WantExtend,
- SDValue &Offset, SDValue &SignExtend);
-
- template<unsigned RegWidth>
- bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos) {
- return SelectCVTFixedPosOperand(N, FixedPos, RegWidth);
- }
-
- bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos, unsigned Width);
-};
-} // end anonymous namespace
-
-/// isIntImmediate - This method tests to see if the node is a constant
-/// operand. If so Imm will receive the 32-bit value.
-static bool isIntImmediate(const SDNode *N, uint64_t &Imm) {
- if (const ConstantSDNode *C = dyn_cast<const ConstantSDNode>(N)) {
- Imm = C->getZExtValue();
- return true;
- }
- return false;
-}
-
-// isIntImmediate - This method tests to see if a constant operand.
-// If so Imm will receive the value.
-static bool isIntImmediate(SDValue N, uint64_t &Imm) {
- return isIntImmediate(N.getNode(), Imm);
-}
-
-// isOpcWithIntImmediate - This method tests to see if the node is a specific
-// opcode and that it has a immediate integer right operand.
-// If so Imm will receive the 32 bit value.
-static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc,
- uint64_t &Imm) {
- return N->getOpcode() == Opc &&
- isIntImmediate(N->getOperand(1).getNode(), Imm);
-}
-
-bool ARM64DAGToDAGISel::SelectInlineAsmMemoryOperand(
- const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
- assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
- // Require the address to be in a register. That is safe for all ARM64
- // variants and it is hard to do anything much smarter without knowing
- // how the operand is used.
- OutOps.push_back(Op);
- return false;
-}
-
-/// SelectArithImmed - Select an immediate value that can be represented as
-/// a 12-bit value shifted left by either 0 or 12. If so, return true with
-/// Val set to the 12-bit value and Shift set to the shifter operand.
-bool ARM64DAGToDAGISel::SelectArithImmed(SDValue N, SDValue &Val,
- SDValue &Shift) {
- // This function is called from the addsub_shifted_imm ComplexPattern,
- // which lists [imm] as the list of opcode it's interested in, however
- // we still need to check whether the operand is actually an immediate
- // here because the ComplexPattern opcode list is only used in
- // root-level opcode matching.
- if (!isa<ConstantSDNode>(N.getNode()))
- return false;
-
- uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue();
- unsigned ShiftAmt;
-
- if (Immed >> 12 == 0) {
- ShiftAmt = 0;
- } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) {
- ShiftAmt = 12;
- Immed = Immed >> 12;
- } else
- return false;
-
- unsigned ShVal = ARM64_AM::getShifterImm(ARM64_AM::LSL, ShiftAmt);
- Val = CurDAG->getTargetConstant(Immed, MVT::i32);
- Shift = CurDAG->getTargetConstant(ShVal, MVT::i32);
- return true;
-}
-
-/// SelectNegArithImmed - As above, but negates the value before trying to
-/// select it.
-bool ARM64DAGToDAGISel::SelectNegArithImmed(SDValue N, SDValue &Val,
- SDValue &Shift) {
- // This function is called from the addsub_shifted_imm ComplexPattern,
- // which lists [imm] as the list of opcode it's interested in, however
- // we still need to check whether the operand is actually an immediate
- // here because the ComplexPattern opcode list is only used in
- // root-level opcode matching.
- if (!isa<ConstantSDNode>(N.getNode()))
- return false;
-
- // The immediate operand must be a 24-bit zero-extended immediate.
- uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue();
-
- // This negation is almost always valid, but "cmp wN, #0" and "cmn wN, #0"
- // have the opposite effect on the C flag, so this pattern mustn't match under
- // those circumstances.
- if (Immed == 0)
- return false;
-
- if (N.getValueType() == MVT::i32)
- Immed = ~((uint32_t)Immed) + 1;
- else
- Immed = ~Immed + 1ULL;
- if (Immed & 0xFFFFFFFFFF000000ULL)
- return false;
-
- Immed &= 0xFFFFFFULL;
- return SelectArithImmed(CurDAG->getConstant(Immed, MVT::i32), Val, Shift);
-}
-
-/// getShiftTypeForNode - Translate a shift node to the corresponding
-/// ShiftType value.
-static ARM64_AM::ShiftExtendType getShiftTypeForNode(SDValue N) {
- switch (N.getOpcode()) {
- default:
- return ARM64_AM::InvalidShiftExtend;
- case ISD::SHL:
- return ARM64_AM::LSL;
- case ISD::SRL:
- return ARM64_AM::LSR;
- case ISD::SRA:
- return ARM64_AM::ASR;
- case ISD::ROTR:
- return ARM64_AM::ROR;
- }
-}
-
-/// \brief Determine wether it is worth to fold V into an extended register.
-bool ARM64DAGToDAGISel::isWorthFolding(SDValue V) const {
- // it hurts if the a value is used at least twice, unless we are optimizing
- // for code size.
- if (ForCodeSize || V.hasOneUse())
- return true;
- return false;
-}
-
-/// SelectShiftedRegister - Select a "shifted register" operand. If the value
-/// is not shifted, set the Shift operand to default of "LSL 0". The logical
-/// instructions allow the shifted register to be rotated, but the arithmetic
-/// instructions do not. The AllowROR parameter specifies whether ROR is
-/// supported.
-bool ARM64DAGToDAGISel::SelectShiftedRegister(SDValue N, bool AllowROR,
- SDValue &Reg, SDValue &Shift) {
- ARM64_AM::ShiftExtendType ShType = getShiftTypeForNode(N);
- if (ShType == ARM64_AM::InvalidShiftExtend)
- return false;
- if (!AllowROR && ShType == ARM64_AM::ROR)
- return false;
-
- if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
- unsigned BitSize = N.getValueType().getSizeInBits();
- unsigned Val = RHS->getZExtValue() & (BitSize - 1);
- unsigned ShVal = ARM64_AM::getShifterImm(ShType, Val);
-
- Reg = N.getOperand(0);
- Shift = CurDAG->getTargetConstant(ShVal, MVT::i32);
- return isWorthFolding(N);
- }
-
- return false;
-}
-
-/// getExtendTypeForNode - Translate an extend node to the corresponding
-/// ExtendType value.
-static ARM64_AM::ShiftExtendType
-getExtendTypeForNode(SDValue N, bool IsLoadStore = false) {
- if (N.getOpcode() == ISD::SIGN_EXTEND ||
- N.getOpcode() == ISD::SIGN_EXTEND_INREG) {
- EVT SrcVT;
- if (N.getOpcode() == ISD::SIGN_EXTEND_INREG)
- SrcVT = cast<VTSDNode>(N.getOperand(1))->getVT();
- else
- SrcVT = N.getOperand(0).getValueType();
-
- if (!IsLoadStore && SrcVT == MVT::i8)
- return ARM64_AM::SXTB;
- else if (!IsLoadStore && SrcVT == MVT::i16)
- return ARM64_AM::SXTH;
- else if (SrcVT == MVT::i32)
- return ARM64_AM::SXTW;
- assert(SrcVT != MVT::i64 && "extend from 64-bits?");
-
- return ARM64_AM::InvalidShiftExtend;
- } else if (N.getOpcode() == ISD::ZERO_EXTEND ||
- N.getOpcode() == ISD::ANY_EXTEND) {
- EVT SrcVT = N.getOperand(0).getValueType();
- if (!IsLoadStore && SrcVT == MVT::i8)
- return ARM64_AM::UXTB;
- else if (!IsLoadStore && SrcVT == MVT::i16)
- return ARM64_AM::UXTH;
- else if (SrcVT == MVT::i32)
- return ARM64_AM::UXTW;
- assert(SrcVT != MVT::i64 && "extend from 64-bits?");
-
- return ARM64_AM::InvalidShiftExtend;
- } else if (N.getOpcode() == ISD::AND) {
- ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
- if (!CSD)
- return ARM64_AM::InvalidShiftExtend;
- uint64_t AndMask = CSD->getZExtValue();
-
- switch (AndMask) {
- default:
- return ARM64_AM::InvalidShiftExtend;
- case 0xFF:
- return !IsLoadStore ? ARM64_AM::UXTB : ARM64_AM::InvalidShiftExtend;
- case 0xFFFF:
- return !IsLoadStore ? ARM64_AM::UXTH : ARM64_AM::InvalidShiftExtend;
- case 0xFFFFFFFF:
- return ARM64_AM::UXTW;
- }
- }
-
- return ARM64_AM::InvalidShiftExtend;
-}
-
-// Helper for SelectMLAV64LaneV128 - Recognize high lane extracts.
-static bool checkHighLaneIndex(SDNode *DL, SDValue &LaneOp, int &LaneIdx) {
- if (DL->getOpcode() != ARM64ISD::DUPLANE16 &&
- DL->getOpcode() != ARM64ISD::DUPLANE32)
- return false;
-
- SDValue SV = DL->getOperand(0);
- if (SV.getOpcode() != ISD::INSERT_SUBVECTOR)
- return false;
-
- SDValue EV = SV.getOperand(1);
- if (EV.getOpcode() != ISD::EXTRACT_SUBVECTOR)
- return false;
-
- ConstantSDNode *DLidx = cast<ConstantSDNode>(DL->getOperand(1).getNode());
- ConstantSDNode *EVidx = cast<ConstantSDNode>(EV.getOperand(1).getNode());
- LaneIdx = DLidx->getSExtValue() + EVidx->getSExtValue();
- LaneOp = EV.getOperand(0);
-
- return true;
-}
-
-// Helper for SelectOpcV64LaneV128 - Recogzine operatinos where one operand is a
-// high lane extract.
-static bool checkV64LaneV128(SDValue Op0, SDValue Op1, SDValue &StdOp,
- SDValue &LaneOp, int &LaneIdx) {
-
- if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx)) {
- std::swap(Op0, Op1);
- if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx))
- return false;
- }
- StdOp = Op1;
- return true;
-}
-
-/// SelectMLAV64LaneV128 - ARM64 supports vector MLAs where one multiplicand is
-/// a lane in the upper half of a 128-bit vector. Recognize and select this so
-/// that we don't emit unnecessary lane extracts.
-SDNode *ARM64DAGToDAGISel::SelectMLAV64LaneV128(SDNode *N) {
- SDValue Op0 = N->getOperand(0);
- SDValue Op1 = N->getOperand(1);
- SDValue MLAOp1; // Will hold ordinary multiplicand for MLA.
- SDValue MLAOp2; // Will hold lane-accessed multiplicand for MLA.
- int LaneIdx = -1; // Will hold the lane index.
-
- if (Op1.getOpcode() != ISD::MUL ||
- !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2,
- LaneIdx)) {
- std::swap(Op0, Op1);
- if (Op1.getOpcode() != ISD::MUL ||
- !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2,
- LaneIdx))
- return nullptr;
- }
-
- SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, MVT::i64);
-
- SDValue Ops[] = { Op0, MLAOp1, MLAOp2, LaneIdxVal };
-
- unsigned MLAOpc = ~0U;
-
- switch (N->getSimpleValueType(0).SimpleTy) {
- default:
- llvm_unreachable("Unrecognized MLA.");
- case MVT::v4i16:
- MLAOpc = ARM64::MLAv4i16_indexed;
- break;
- case MVT::v8i16:
- MLAOpc = ARM64::MLAv8i16_indexed;
- break;
- case MVT::v2i32:
- MLAOpc = ARM64::MLAv2i32_indexed;
- break;
- case MVT::v4i32:
- MLAOpc = ARM64::MLAv4i32_indexed;
- break;
- }
-
- return CurDAG->getMachineNode(MLAOpc, SDLoc(N), N->getValueType(0), Ops);
-}
-
-SDNode *ARM64DAGToDAGISel::SelectMULLV64LaneV128(unsigned IntNo, SDNode *N) {
- SDValue SMULLOp0;
- SDValue SMULLOp1;
- int LaneIdx;
-
- if (!checkV64LaneV128(N->getOperand(1), N->getOperand(2), SMULLOp0, SMULLOp1,
- LaneIdx))
- return nullptr;
-
- SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, MVT::i64);
-
- SDValue Ops[] = { SMULLOp0, SMULLOp1, LaneIdxVal };
-
- unsigned SMULLOpc = ~0U;
-
- if (IntNo == Intrinsic::arm64_neon_smull) {
- switch (N->getSimpleValueType(0).SimpleTy) {
- default:
- llvm_unreachable("Unrecognized SMULL.");
- case MVT::v4i32:
- SMULLOpc = ARM64::SMULLv4i16_indexed;
- break;
- case MVT::v2i64:
- SMULLOpc = ARM64::SMULLv2i32_indexed;
- break;
- }
- } else if (IntNo == Intrinsic::arm64_neon_umull) {
- switch (N->getSimpleValueType(0).SimpleTy) {
- default:
- llvm_unreachable("Unrecognized SMULL.");
- case MVT::v4i32:
- SMULLOpc = ARM64::UMULLv4i16_indexed;
- break;
- case MVT::v2i64:
- SMULLOpc = ARM64::UMULLv2i32_indexed;
- break;
- }
- } else
- llvm_unreachable("Unrecognized intrinsic.");
-
- return CurDAG->getMachineNode(SMULLOpc, SDLoc(N), N->getValueType(0), Ops);
-}
-
-/// Instructions that accept extend modifiers like UXTW expect the register
-/// being extended to be a GPR32, but the incoming DAG might be acting on a
-/// GPR64 (either via SEXT_INREG or AND). Extract the appropriate low bits if
-/// this is the case.
-static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N) {
- if (N.getValueType() == MVT::i32)
- return N;
-
- SDValue SubReg = CurDAG->getTargetConstant(ARM64::sub_32, MVT::i32);
- MachineSDNode *Node = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
- SDLoc(N), MVT::i32, N, SubReg);
- return SDValue(Node, 0);
-}
-
-
-/// SelectArithExtendedRegister - Select a "extended register" operand. This
-/// operand folds in an extend followed by an optional left shift.
-bool ARM64DAGToDAGISel::SelectArithExtendedRegister(SDValue N, SDValue &Reg,
- SDValue &Shift) {
- unsigned ShiftVal = 0;
- ARM64_AM::ShiftExtendType Ext;
-
- if (N.getOpcode() == ISD::SHL) {
- ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
- if (!CSD)
- return false;
- ShiftVal = CSD->getZExtValue();
- if (ShiftVal > 4)
- return false;
-
- Ext = getExtendTypeForNode(N.getOperand(0));
- if (Ext == ARM64_AM::InvalidShiftExtend)
- return false;
-
- Reg = N.getOperand(0).getOperand(0);
- } else {
- Ext = getExtendTypeForNode(N);
- if (Ext == ARM64_AM::InvalidShiftExtend)
- return false;
-
- Reg = N.getOperand(0);
- }
-
- // ARM64 mandates that the RHS of the operation must use the smallest
- // register classs that could contain the size being extended from. Thus,
- // if we're folding a (sext i8), we need the RHS to be a GPR32, even though
- // there might not be an actual 32-bit value in the program. We can
- // (harmlessly) synthesize one by injected an EXTRACT_SUBREG here.
- assert(Ext != ARM64_AM::UXTX && Ext != ARM64_AM::SXTX);
- Reg = narrowIfNeeded(CurDAG, Reg);
- Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), MVT::i32);
- return isWorthFolding(N);
-}
-
-/// SelectAddrModeIndexed - Select a "register plus scaled unsigned 12-bit
-/// immediate" address. The "Size" argument is the size in bytes of the memory
-/// reference, which determines the scale.
-bool ARM64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size,
- SDValue &Base, SDValue &OffImm) {
- const TargetLowering *TLI = getTargetLowering();
- if (N.getOpcode() == ISD::FrameIndex) {
- int FI = cast<FrameIndexSDNode>(N)->getIndex();
- Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy());
- OffImm = CurDAG->getTargetConstant(0, MVT::i64);
- return true;
- }
-
- if (N.getOpcode() == ARM64ISD::ADDlow) {
- GlobalAddressSDNode *GAN =
- dyn_cast<GlobalAddressSDNode>(N.getOperand(1).getNode());
- Base = N.getOperand(0);
- OffImm = N.getOperand(1);
- if (!GAN)
- return true;
-
- const GlobalValue *GV = GAN->getGlobal();
- unsigned Alignment = GV->getAlignment();
- const DataLayout *DL = TLI->getDataLayout();
- if (Alignment == 0 && !Subtarget->isTargetDarwin())
- Alignment = DL->getABITypeAlignment(GV->getType()->getElementType());
-
- if (Alignment >= Size)
- return true;
- }
-
- if (CurDAG->isBaseWithConstantOffset(N)) {
- if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
- int64_t RHSC = (int64_t)RHS->getZExtValue();
- unsigned Scale = Log2_32(Size);
- if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) {
- Base = N.getOperand(0);
- if (Base.getOpcode() == ISD::FrameIndex) {
- int FI = cast<FrameIndexSDNode>(Base)->getIndex();
- Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy());
- }
- OffImm = CurDAG->getTargetConstant(RHSC >> Scale, MVT::i64);
- return true;
- }
- }
- }
-
- // Before falling back to our general case, check if the unscaled
- // instructions can handle this. If so, that's preferable.
- if (SelectAddrModeUnscaled(N, Size, Base, OffImm))
- return false;
-
- // Base only. The address will be materialized into a register before
- // the memory is accessed.
- // add x0, Xbase, #offset
- // ldr x0, [x0]
- Base = N;
- OffImm = CurDAG->getTargetConstant(0, MVT::i64);
- return true;
-}
-
-/// SelectAddrModeUnscaled - Select a "register plus unscaled signed 9-bit
-/// immediate" address. This should only match when there is an offset that
-/// is not valid for a scaled immediate addressing mode. The "Size" argument
-/// is the size in bytes of the memory reference, which is needed here to know
-/// what is valid for a scaled immediate.
-bool ARM64DAGToDAGISel::SelectAddrModeUnscaled(SDValue N, unsigned Size,
- SDValue &Base, SDValue &OffImm) {
- if (!CurDAG->isBaseWithConstantOffset(N))
- return false;
- if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
- int64_t RHSC = RHS->getSExtValue();
- // If the offset is valid as a scaled immediate, don't match here.
- if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 &&
- RHSC < (0x1000 << Log2_32(Size)))
- return false;
- if (RHSC >= -256 && RHSC < 256) {
- Base = N.getOperand(0);
- if (Base.getOpcode() == ISD::FrameIndex) {
- int FI = cast<FrameIndexSDNode>(Base)->getIndex();
- const TargetLowering *TLI = getTargetLowering();
- Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy());
- }
- OffImm = CurDAG->getTargetConstant(RHSC, MVT::i64);
- return true;
- }
- }
- return false;
-}
-
-static SDValue Widen(SelectionDAG *CurDAG, SDValue N) {
- SDValue SubReg = CurDAG->getTargetConstant(ARM64::sub_32, MVT::i32);
- SDValue ImpDef = SDValue(
- CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, SDLoc(N), MVT::i64),
- 0);
- MachineSDNode *Node = CurDAG->getMachineNode(
- TargetOpcode::INSERT_SUBREG, SDLoc(N), MVT::i64, ImpDef, N, SubReg);
- return SDValue(Node, 0);
-}
-
-/// \brief Check if the given SHL node (\p N), can be used to form an
-/// extended register for an addressing mode.
-bool ARM64DAGToDAGISel::SelectExtendedSHL(SDValue N, unsigned Size,
- bool WantExtend, SDValue &Offset,
- SDValue &SignExtend) {
- assert(N.getOpcode() == ISD::SHL && "Invalid opcode.");
- ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1));
- if (!CSD || (CSD->getZExtValue() & 0x7) != CSD->getZExtValue())
- return false;
-
- if (WantExtend) {
- ARM64_AM::ShiftExtendType Ext = getExtendTypeForNode(N.getOperand(0), true);
- if (Ext == ARM64_AM::InvalidShiftExtend)
- return false;
-
- Offset = narrowIfNeeded(CurDAG, N.getOperand(0).getOperand(0));
- SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
- } else {
- Offset = N.getOperand(0);
- SignExtend = CurDAG->getTargetConstant(0, MVT::i32);
- }
-
- unsigned LegalShiftVal = Log2_32(Size);
- unsigned ShiftVal = CSD->getZExtValue();
-
- if (ShiftVal != 0 && ShiftVal != LegalShiftVal)
- return false;
-
- if (isWorthFolding(N))
- return true;
-
- return false;
-}
-
-bool ARM64DAGToDAGISel::SelectAddrModeWRO(SDValue N, unsigned Size,
- SDValue &Base, SDValue &Offset,
- SDValue &SignExtend,
- SDValue &DoShift) {
- if (N.getOpcode() != ISD::ADD)
- return false;
- SDValue LHS = N.getOperand(0);
- SDValue RHS = N.getOperand(1);
-
- // We don't want to match immediate adds here, because they are better lowered
- // to the register-immediate addressing modes.
- if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
- return false;
-
- // Check if this particular node is reused in any non-memory related
- // operation. If yes, do not try to fold this node into the address
- // computation, since the computation will be kept.
- const SDNode *Node = N.getNode();
- for (SDNode *UI : Node->uses()) {
- if (!isa<MemSDNode>(*UI))
- return false;
- }
-
- // Remember if it is worth folding N when it produces extended register.
- bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
-
- // Try to match a shifted extend on the RHS.
- if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
- SelectExtendedSHL(RHS, Size, true, Offset, SignExtend)) {
- Base = LHS;
- DoShift = CurDAG->getTargetConstant(true, MVT::i32);
- return true;
- }
-
- // Try to match a shifted extend on the LHS.
- if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
- SelectExtendedSHL(LHS, Size, true, Offset, SignExtend)) {
- Base = RHS;
- DoShift = CurDAG->getTargetConstant(true, MVT::i32);
- return true;
- }
-
- // There was no shift, whatever else we find.
- DoShift = CurDAG->getTargetConstant(false, MVT::i32);
-
- ARM64_AM::ShiftExtendType Ext = ARM64_AM::InvalidShiftExtend;
- // Try to match an unshifted extend on the LHS.
- if (IsExtendedRegisterWorthFolding &&
- (Ext = getExtendTypeForNode(LHS, true)) != ARM64_AM::InvalidShiftExtend) {
- Base = RHS;
- Offset = narrowIfNeeded(CurDAG, LHS.getOperand(0));
- SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
- if (isWorthFolding(LHS))
- return true;
- }
-
- // Try to match an unshifted extend on the RHS.
- if (IsExtendedRegisterWorthFolding &&
- (Ext = getExtendTypeForNode(RHS, true)) != ARM64_AM::InvalidShiftExtend) {
- Base = LHS;
- Offset = narrowIfNeeded(CurDAG, RHS.getOperand(0));
- SignExtend = CurDAG->getTargetConstant(Ext == ARM64_AM::SXTW, MVT::i32);
- if (isWorthFolding(RHS))
- return true;
- }
-
- return false;
-}
-
-bool ARM64DAGToDAGISel::SelectAddrModeXRO(SDValue N, unsigned Size,
- SDValue &Base, SDValue &Offset,
- SDValue &SignExtend,
- SDValue &DoShift) {
- if (N.getOpcode() != ISD::ADD)
- return false;
- SDValue LHS = N.getOperand(0);
- SDValue RHS = N.getOperand(1);
-
- // We don't want to match immediate adds here, because they are better lowered
- // to the register-immediate addressing modes.
- if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS))
- return false;
-
- // Check if this particular node is reused in any non-memory related
- // operation. If yes, do not try to fold this node into the address
- // computation, since the computation will be kept.
- const SDNode *Node = N.getNode();
- for (SDNode *UI : Node->uses()) {
- if (!isa<MemSDNode>(*UI))
- return false;
- }
-
- // Remember if it is worth folding N when it produces extended register.
- bool IsExtendedRegisterWorthFolding = isWorthFolding(N);
-
- // Try to match a shifted extend on the RHS.
- if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL &&
- SelectExtendedSHL(RHS, Size, false, Offset, SignExtend)) {
- Base = LHS;
- DoShift = CurDAG->getTargetConstant(true, MVT::i32);
- return true;
- }
-
- // Try to match a shifted extend on the LHS.
- if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL &&
- SelectExtendedSHL(LHS, Size, false, Offset, SignExtend)) {
- Base = RHS;
- DoShift = CurDAG->getTargetConstant(true, MVT::i32);
- return true;
- }
-
- // Match any non-shifted, non-extend, non-immediate add expression.
- Base = LHS;
- Offset = RHS;
- SignExtend = CurDAG->getTargetConstant(false, MVT::i32);
- DoShift = CurDAG->getTargetConstant(false, MVT::i32);
- // Reg1 + Reg2 is free: no check needed.
- return true;
-}
-
-SDValue ARM64DAGToDAGISel::createDTuple(ArrayRef<SDValue> Regs) {
- static unsigned RegClassIDs[] = { ARM64::DDRegClassID, ARM64::DDDRegClassID,
- ARM64::DDDDRegClassID };
- static unsigned SubRegs[] = { ARM64::dsub0, ARM64::dsub1,
- ARM64::dsub2, ARM64::dsub3 };
-
- return createTuple(Regs, RegClassIDs, SubRegs);
-}
-
-SDValue ARM64DAGToDAGISel::createQTuple(ArrayRef<SDValue> Regs) {
- static unsigned RegClassIDs[] = { ARM64::QQRegClassID, ARM64::QQQRegClassID,
- ARM64::QQQQRegClassID };
- static unsigned SubRegs[] = { ARM64::qsub0, ARM64::qsub1,
- ARM64::qsub2, ARM64::qsub3 };
-
- return createTuple(Regs, RegClassIDs, SubRegs);
-}
-
-SDValue ARM64DAGToDAGISel::createTuple(ArrayRef<SDValue> Regs,
- unsigned RegClassIDs[],
- unsigned SubRegs[]) {
- // There's no special register-class for a vector-list of 1 element: it's just
- // a vector.
- if (Regs.size() == 1)
- return Regs[0];
-
- assert(Regs.size() >= 2 && Regs.size() <= 4);
-
- SDLoc DL(Regs[0].getNode());
-
- SmallVector<SDValue, 4> Ops;
-
- // First operand of REG_SEQUENCE is the desired RegClass.
- Ops.push_back(
- CurDAG->getTargetConstant(RegClassIDs[Regs.size() - 2], MVT::i32));
-
- // Then we get pairs of source & subregister-position for the components.
- for (unsigned i = 0; i < Regs.size(); ++i) {
- Ops.push_back(Regs[i]);
- Ops.push_back(CurDAG->getTargetConstant(SubRegs[i], MVT::i32));
- }
-
- SDNode *N =
- CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops);
- return SDValue(N, 0);
-}
-
-SDNode *ARM64DAGToDAGISel::SelectTable(SDNode *N, unsigned NumVecs,
- unsigned Opc, bool isExt) {
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
-
- unsigned ExtOff = isExt;
-
- // Form a REG_SEQUENCE to force register allocation.
- unsigned Vec0Off = ExtOff + 1;
- SmallVector<SDValue, 4> Regs(N->op_begin() + Vec0Off,
- N->op_begin() + Vec0Off + NumVecs);
- SDValue RegSeq = createQTuple(Regs);
-
- SmallVector<SDValue, 6> Ops;
- if (isExt)
- Ops.push_back(N->getOperand(1));
- Ops.push_back(RegSeq);
- Ops.push_back(N->getOperand(NumVecs + ExtOff + 1));
- return CurDAG->getMachineNode(Opc, dl, VT, Ops);
-}
-
-SDNode *ARM64DAGToDAGISel::SelectIndexedLoad(SDNode *N, bool &Done) {
- LoadSDNode *LD = cast<LoadSDNode>(N);
- if (LD->isUnindexed())
- return nullptr;
- EVT VT = LD->getMemoryVT();
- EVT DstVT = N->getValueType(0);
- ISD::MemIndexedMode AM = LD->getAddressingMode();
- bool IsPre = AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
-
- // We're not doing validity checking here. That was done when checking
- // if we should mark the load as indexed or not. We're just selecting
- // the right instruction.
- unsigned Opcode = 0;
-
- ISD::LoadExtType ExtType = LD->getExtensionType();
- bool InsertTo64 = false;
- if (VT == MVT::i64)
- Opcode = IsPre ? ARM64::LDRXpre : ARM64::LDRXpost;
- else if (VT == MVT::i32) {
- if (ExtType == ISD::NON_EXTLOAD)
- Opcode = IsPre ? ARM64::LDRWpre : ARM64::LDRWpost;
- else if (ExtType == ISD::SEXTLOAD)
- Opcode = IsPre ? ARM64::LDRSWpre : ARM64::LDRSWpost;
- else {
- Opcode = IsPre ? ARM64::LDRWpre : ARM64::LDRWpost;
- InsertTo64 = true;
- // The result of the load is only i32. It's the subreg_to_reg that makes
- // it into an i64.
- DstVT = MVT::i32;
- }
- } else if (VT == MVT::i16) {
- if (ExtType == ISD::SEXTLOAD) {
- if (DstVT == MVT::i64)
- Opcode = IsPre ? ARM64::LDRSHXpre : ARM64::LDRSHXpost;
- else
- Opcode = IsPre ? ARM64::LDRSHWpre : ARM64::LDRSHWpost;
- } else {
- Opcode = IsPre ? ARM64::LDRHHpre : ARM64::LDRHHpost;
- InsertTo64 = DstVT == MVT::i64;
- // The result of the load is only i32. It's the subreg_to_reg that makes
- // it into an i64.
- DstVT = MVT::i32;
- }
- } else if (VT == MVT::i8) {
- if (ExtType == ISD::SEXTLOAD) {
- if (DstVT == MVT::i64)
- Opcode = IsPre ? ARM64::LDRSBXpre : ARM64::LDRSBXpost;
- else
- Opcode = IsPre ? ARM64::LDRSBWpre : ARM64::LDRSBWpost;
- } else {
- Opcode = IsPre ? ARM64::LDRBBpre : ARM64::LDRBBpost;
- InsertTo64 = DstVT == MVT::i64;
- // The result of the load is only i32. It's the subreg_to_reg that makes
- // it into an i64.
- DstVT = MVT::i32;
- }
- } else if (VT == MVT::f32) {
- Opcode = IsPre ? ARM64::LDRSpre : ARM64::LDRSpost;
- } else if (VT == MVT::f64 || VT.is64BitVector()) {
- Opcode = IsPre ? ARM64::LDRDpre : ARM64::LDRDpost;
- } else if (VT.is128BitVector()) {
- Opcode = IsPre ? ARM64::LDRQpre : ARM64::LDRQpost;
- } else
- return nullptr;
- SDValue Chain = LD->getChain();
- SDValue Base = LD->getBasePtr();
- ConstantSDNode *OffsetOp = cast<ConstantSDNode>(LD->getOffset());
- int OffsetVal = (int)OffsetOp->getZExtValue();
- SDValue Offset = CurDAG->getTargetConstant(OffsetVal, MVT::i64);
- SDValue Ops[] = { Base, Offset, Chain };
- SDNode *Res = CurDAG->getMachineNode(Opcode, SDLoc(N), MVT::i64, DstVT,
- MVT::Other, Ops);
- // Either way, we're replacing the node, so tell the caller that.
- Done = true;
- SDValue LoadedVal = SDValue(Res, 1);
- if (InsertTo64) {
- SDValue SubReg = CurDAG->getTargetConstant(ARM64::sub_32, MVT::i32);
- LoadedVal =
- SDValue(CurDAG->getMachineNode(ARM64::SUBREG_TO_REG, SDLoc(N), MVT::i64,
- CurDAG->getTargetConstant(0, MVT::i64),
- LoadedVal, SubReg),
- 0);
- }
-
- ReplaceUses(SDValue(N, 0), LoadedVal);
- ReplaceUses(SDValue(N, 1), SDValue(Res, 0));
- ReplaceUses(SDValue(N, 2), SDValue(Res, 2));
-
- return nullptr;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc,
- unsigned SubRegIdx) {
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
- SDValue Chain = N->getOperand(0);
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(N->getOperand(2)); // Mem operand;
- Ops.push_back(Chain);
-
- std::vector<EVT> ResTys;
- ResTys.push_back(MVT::Untyped);
- ResTys.push_back(MVT::Other);
-
- SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
- SDValue SuperReg = SDValue(Ld, 0);
- for (unsigned i = 0; i < NumVecs; ++i)
- ReplaceUses(SDValue(N, i),
- CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
-
- ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1));
- return nullptr;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectPostLoad(SDNode *N, unsigned NumVecs,
- unsigned Opc, unsigned SubRegIdx) {
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
- SDValue Chain = N->getOperand(0);
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(N->getOperand(1)); // Mem operand
- Ops.push_back(N->getOperand(2)); // Incremental
- Ops.push_back(Chain);
-
- std::vector<EVT> ResTys;
- ResTys.push_back(MVT::i64); // Type of the write back register
- ResTys.push_back(MVT::Untyped);
- ResTys.push_back(MVT::Other);
-
- SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
-
- // Update uses of write back register
- ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0));
-
- // Update uses of vector list
- SDValue SuperReg = SDValue(Ld, 1);
- if (NumVecs == 1)
- ReplaceUses(SDValue(N, 0), SuperReg);
- else
- for (unsigned i = 0; i < NumVecs; ++i)
- ReplaceUses(SDValue(N, i),
- CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg));
-
- // Update the chain
- ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2));
- return nullptr;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectStore(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getOperand(2)->getValueType(0);
-
- // Form a REG_SEQUENCE to force register allocation.
- bool Is128Bit = VT.getSizeInBits() == 128;
- SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
- SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(N->getOperand(NumVecs + 2));
- Ops.push_back(N->getOperand(0));
- SDNode *St = CurDAG->getMachineNode(Opc, dl, N->getValueType(0), Ops);
-
- return St;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectPostStore(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getOperand(2)->getValueType(0);
- SmallVector<EVT, 2> ResTys;
- ResTys.push_back(MVT::i64); // Type of the write back register
- ResTys.push_back(MVT::Other); // Type for the Chain
-
- // Form a REG_SEQUENCE to force register allocation.
- bool Is128Bit = VT.getSizeInBits() == 128;
- SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
- SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs);
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(N->getOperand(NumVecs + 1)); // base register
- Ops.push_back(N->getOperand(NumVecs + 2)); // Incremental
- Ops.push_back(N->getOperand(0)); // Chain
- SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
-
- return St;
-}
-
-/// WidenVector - Given a value in the V64 register class, produce the
-/// equivalent value in the V128 register class.
-class WidenVector {
- SelectionDAG &DAG;
-
-public:
- WidenVector(SelectionDAG &DAG) : DAG(DAG) {}
-
- SDValue operator()(SDValue V64Reg) {
- EVT VT = V64Reg.getValueType();
- unsigned NarrowSize = VT.getVectorNumElements();
- MVT EltTy = VT.getVectorElementType().getSimpleVT();
- MVT WideTy = MVT::getVectorVT(EltTy, 2 * NarrowSize);
- SDLoc DL(V64Reg);
-
- SDValue Undef =
- SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, WideTy), 0);
- return DAG.getTargetInsertSubreg(ARM64::dsub, DL, WideTy, Undef, V64Reg);
- }
-};
-
-/// NarrowVector - Given a value in the V128 register class, produce the
-/// equivalent value in the V64 register class.
-static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG) {
- EVT VT = V128Reg.getValueType();
- unsigned WideSize = VT.getVectorNumElements();
- MVT EltTy = VT.getVectorElementType().getSimpleVT();
- MVT NarrowTy = MVT::getVectorVT(EltTy, WideSize / 2);
-
- return DAG.getTargetExtractSubreg(ARM64::dsub, SDLoc(V128Reg), NarrowTy,
- V128Reg);
-}
-
-SDNode *ARM64DAGToDAGISel::SelectLoadLane(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
- bool Narrow = VT.getSizeInBits() == 64;
-
- // Form a REG_SEQUENCE to force register allocation.
- SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
-
- if (Narrow)
- std::transform(Regs.begin(), Regs.end(), Regs.begin(),
- WidenVector(*CurDAG));
-
- SDValue RegSeq = createQTuple(Regs);
-
- std::vector<EVT> ResTys;
- ResTys.push_back(MVT::Untyped);
- ResTys.push_back(MVT::Other);
-
- unsigned LaneNo =
- cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue();
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(CurDAG->getTargetConstant(LaneNo, MVT::i64));
- Ops.push_back(N->getOperand(NumVecs + 3));
- Ops.push_back(N->getOperand(0));
- SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
- SDValue SuperReg = SDValue(Ld, 0);
-
- EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
- static unsigned QSubs[] = { ARM64::qsub0, ARM64::qsub1, ARM64::qsub2,
- ARM64::qsub3 };
- for (unsigned i = 0; i < NumVecs; ++i) {
- SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg);
- if (Narrow)
- NV = NarrowVector(NV, *CurDAG);
- ReplaceUses(SDValue(N, i), NV);
- }
-
- ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1));
-
- return Ld;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectPostLoadLane(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getValueType(0);
- bool Narrow = VT.getSizeInBits() == 64;
-
- // Form a REG_SEQUENCE to force register allocation.
- SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
-
- if (Narrow)
- std::transform(Regs.begin(), Regs.end(), Regs.begin(),
- WidenVector(*CurDAG));
-
- SDValue RegSeq = createQTuple(Regs);
-
- std::vector<EVT> ResTys;
- ResTys.push_back(MVT::i64); // Type of the write back register
- ResTys.push_back(MVT::Untyped);
- ResTys.push_back(MVT::Other);
-
- unsigned LaneNo =
- cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue();
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(CurDAG->getTargetConstant(LaneNo, MVT::i64)); // Lane Number
- Ops.push_back(N->getOperand(NumVecs + 2)); // Base register
- Ops.push_back(N->getOperand(NumVecs + 3)); // Incremental
- Ops.push_back(N->getOperand(0));
- SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
-
- // Update uses of the write back register
- ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0));
-
- // Update uses of the vector list
- SDValue SuperReg = SDValue(Ld, 1);
- if (NumVecs == 1) {
- ReplaceUses(SDValue(N, 0),
- Narrow ? NarrowVector(SuperReg, *CurDAG) : SuperReg);
- } else {
- EVT WideVT = RegSeq.getOperand(1)->getValueType(0);
- static unsigned QSubs[] = { ARM64::qsub0, ARM64::qsub1, ARM64::qsub2,
- ARM64::qsub3 };
- for (unsigned i = 0; i < NumVecs; ++i) {
- SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT,
- SuperReg);
- if (Narrow)
- NV = NarrowVector(NV, *CurDAG);
- ReplaceUses(SDValue(N, i), NV);
- }
- }
-
- // Update the Chain
- ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2));
-
- return Ld;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectStoreLane(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getOperand(2)->getValueType(0);
- bool Narrow = VT.getSizeInBits() == 64;
-
- // Form a REG_SEQUENCE to force register allocation.
- SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs);
-
- if (Narrow)
- std::transform(Regs.begin(), Regs.end(), Regs.begin(),
- WidenVector(*CurDAG));
-
- SDValue RegSeq = createQTuple(Regs);
-
- unsigned LaneNo =
- cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue();
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(CurDAG->getTargetConstant(LaneNo, MVT::i64));
- Ops.push_back(N->getOperand(NumVecs + 3));
- Ops.push_back(N->getOperand(0));
- SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops);
-
- // Transfer memoperands.
- MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
- MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
- cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1);
-
- return St;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectPostStoreLane(SDNode *N, unsigned NumVecs,
- unsigned Opc) {
- SDLoc dl(N);
- EVT VT = N->getOperand(2)->getValueType(0);
- bool Narrow = VT.getSizeInBits() == 64;
-
- // Form a REG_SEQUENCE to force register allocation.
- SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs);
-
- if (Narrow)
- std::transform(Regs.begin(), Regs.end(), Regs.begin(),
- WidenVector(*CurDAG));
-
- SDValue RegSeq = createQTuple(Regs);
-
- SmallVector<EVT, 2> ResTys;
- ResTys.push_back(MVT::i64); // Type of the write back register
- ResTys.push_back(MVT::Other);
-
- unsigned LaneNo =
- cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue();
-
- SmallVector<SDValue, 6> Ops;
- Ops.push_back(RegSeq);
- Ops.push_back(CurDAG->getTargetConstant(LaneNo, MVT::i64));
- Ops.push_back(N->getOperand(NumVecs + 2)); // Base Register
- Ops.push_back(N->getOperand(NumVecs + 3)); // Incremental
- Ops.push_back(N->getOperand(0));
- SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops);
-
- // Transfer memoperands.
- MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
- MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
- cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1);
-
- return St;
-}
-
-static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N,
- unsigned &Opc, SDValue &Opd0,
- unsigned &LSB, unsigned &MSB,
- unsigned NumberOfIgnoredLowBits,
- bool BiggerPattern) {
- assert(N->getOpcode() == ISD::AND &&
- "N must be a AND operation to call this function");
-
- EVT VT = N->getValueType(0);
-
- // Here we can test the type of VT and return false when the type does not
- // match, but since it is done prior to that call in the current context
- // we turned that into an assert to avoid redundant code.
- assert((VT == MVT::i32 || VT == MVT::i64) &&
- "Type checking must have been done before calling this function");
-
- // FIXME: simplify-demanded-bits in DAGCombine will probably have
- // changed the AND node to a 32-bit mask operation. We'll have to
- // undo that as part of the transform here if we want to catch all
- // the opportunities.
- // Currently the NumberOfIgnoredLowBits argument helps to recover
- // form these situations when matching bigger pattern (bitfield insert).
-
- // For unsigned extracts, check for a shift right and mask
- uint64_t And_imm = 0;
- if (!isOpcWithIntImmediate(N, ISD::AND, And_imm))
- return false;
-
- const SDNode *Op0 = N->getOperand(0).getNode();
-
- // Because of simplify-demanded-bits in DAGCombine, the mask may have been
- // simplified. Try to undo that
- And_imm |= (1 << NumberOfIgnoredLowBits) - 1;
-
- // The immediate is a mask of the low bits iff imm & (imm+1) == 0
- if (And_imm & (And_imm + 1))
- return false;
-
- bool ClampMSB = false;
- uint64_t Srl_imm = 0;
- // Handle the SRL + ANY_EXTEND case.
- if (VT == MVT::i64 && Op0->getOpcode() == ISD::ANY_EXTEND &&
- isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL, Srl_imm)) {
- // Extend the incoming operand of the SRL to 64-bit.
- Opd0 = Widen(CurDAG, Op0->getOperand(0).getOperand(0));
- // Make sure to clamp the MSB so that we preserve the semantics of the
- // original operations.
- ClampMSB = true;
- } else if (VT == MVT::i32 && Op0->getOpcode() == ISD::TRUNCATE &&
- isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL,
- Srl_imm)) {
- // If the shift result was truncated, we can still combine them.
- Opd0 = Op0->getOperand(0).getOperand(0);
-
- // Use the type of SRL node.
- VT = Opd0->getValueType(0);
- } else if (isOpcWithIntImmediate(Op0, ISD::SRL, Srl_imm)) {
- Opd0 = Op0->getOperand(0);
- } else if (BiggerPattern) {
- // Let's pretend a 0 shift right has been performed.
- // The resulting code will be at least as good as the original one
- // plus it may expose more opportunities for bitfield insert pattern.
- // FIXME: Currently we limit this to the bigger pattern, because
- // some optimizations expect AND and not UBFM
- Opd0 = N->getOperand(0);
- } else
- return false;
-
- assert((BiggerPattern || (Srl_imm > 0 && Srl_imm < VT.getSizeInBits())) &&
- "bad amount in shift node!");
-
- LSB = Srl_imm;
- MSB = Srl_imm + (VT == MVT::i32 ? CountTrailingOnes_32(And_imm)
- : CountTrailingOnes_64(And_imm)) -
- 1;
- if (ClampMSB)
- // Since we're moving the extend before the right shift operation, we need
- // to clamp the MSB to make sure we don't shift in undefined bits instead of
- // the zeros which would get shifted in with the original right shift
- // operation.
- MSB = MSB > 31 ? 31 : MSB;
-
- Opc = VT == MVT::i32 ? ARM64::UBFMWri : ARM64::UBFMXri;
- return true;
-}
-
-static bool isOneBitExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0,
- unsigned &LSB, unsigned &MSB) {
- // We are looking for the following pattern which basically extracts a single
- // bit from the source value and places it in the LSB of the destination
- // value, all other bits of the destination value or set to zero:
- //
- // Value2 = AND Value, MaskImm
- // SRL Value2, ShiftImm
- //
- // with MaskImm >> ShiftImm == 1.
- //
- // This gets selected into a single UBFM:
- //
- // UBFM Value, ShiftImm, ShiftImm
- //
-
- if (N->getOpcode() != ISD::SRL)
- return false;
-
- uint64_t And_mask = 0;
- if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, And_mask))
- return false;
-
- Opd0 = N->getOperand(0).getOperand(0);
-
- uint64_t Srl_imm = 0;
- if (!isIntImmediate(N->getOperand(1), Srl_imm))
- return false;
-
- // Check whether we really have a one bit extract here.
- if (And_mask >> Srl_imm == 0x1) {
- if (N->getValueType(0) == MVT::i32)
- Opc = ARM64::UBFMWri;
- else
- Opc = ARM64::UBFMXri;
-
- LSB = MSB = Srl_imm;
-
- return true;
- }
-
- return false;
-}
-
-static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0,
- unsigned &LSB, unsigned &MSB,
- bool BiggerPattern) {
- assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) &&
- "N must be a SHR/SRA operation to call this function");
-
- EVT VT = N->getValueType(0);
-
- // Here we can test the type of VT and return false when the type does not
- // match, but since it is done prior to that call in the current context
- // we turned that into an assert to avoid redundant code.
- assert((VT == MVT::i32 || VT == MVT::i64) &&
- "Type checking must have been done before calling this function");
-
- // Check for AND + SRL doing a one bit extract.
- if (isOneBitExtractOpFromShr(N, Opc, Opd0, LSB, MSB))
- return true;
-
- // we're looking for a shift of a shift
- uint64_t Shl_imm = 0;
- uint64_t Trunc_bits = 0;
- if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) {
- Opd0 = N->getOperand(0).getOperand(0);
- } else if (VT == MVT::i32 && N->getOpcode() == ISD::SRL &&
- N->getOperand(0).getNode()->getOpcode() == ISD::TRUNCATE) {
- // We are looking for a shift of truncate. Truncate from i64 to i32 could
- // be considered as setting high 32 bits as zero. Our strategy here is to
- // always generate 64bit UBFM. This consistency will help the CSE pass
- // later find more redundancy.
- Opd0 = N->getOperand(0).getOperand(0);
- Trunc_bits = Opd0->getValueType(0).getSizeInBits() - VT.getSizeInBits();
- VT = Opd0->getValueType(0);
- assert(VT == MVT::i64 && "the promoted type should be i64");
- } else if (BiggerPattern) {
- // Let's pretend a 0 shift left has been performed.
- // FIXME: Currently we limit this to the bigger pattern case,
- // because some optimizations expect AND and not UBFM
- Opd0 = N->getOperand(0);
- } else
- return false;
-
- assert(Shl_imm < VT.getSizeInBits() && "bad amount in shift node!");
- uint64_t Srl_imm = 0;
- if (!isIntImmediate(N->getOperand(1), Srl_imm))
- return false;
-
- assert(Srl_imm > 0 && Srl_imm < VT.getSizeInBits() &&
- "bad amount in shift node!");
- // Note: The width operand is encoded as width-1.
- unsigned Width = VT.getSizeInBits() - Trunc_bits - Srl_imm - 1;
- int sLSB = Srl_imm - Shl_imm;
- if (sLSB < 0)
- return false;
- LSB = sLSB;
- MSB = LSB + Width;
- // SRA requires a signed extraction
- if (VT == MVT::i32)
- Opc = N->getOpcode() == ISD::SRA ? ARM64::SBFMWri : ARM64::UBFMWri;
- else
- Opc = N->getOpcode() == ISD::SRA ? ARM64::SBFMXri : ARM64::UBFMXri;
- return true;
-}
-
-static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc,
- SDValue &Opd0, unsigned &LSB, unsigned &MSB,
- unsigned NumberOfIgnoredLowBits = 0,
- bool BiggerPattern = false) {
- if (N->getValueType(0) != MVT::i32 && N->getValueType(0) != MVT::i64)
- return false;
-
- switch (N->getOpcode()) {
- default:
- if (!N->isMachineOpcode())
- return false;
- break;
- case ISD::AND:
- return isBitfieldExtractOpFromAnd(CurDAG, N, Opc, Opd0, LSB, MSB,
- NumberOfIgnoredLowBits, BiggerPattern);
- case ISD::SRL:
- case ISD::SRA:
- return isBitfieldExtractOpFromShr(N, Opc, Opd0, LSB, MSB, BiggerPattern);
- }
-
- unsigned NOpc = N->getMachineOpcode();
- switch (NOpc) {
- default:
- return false;
- case ARM64::SBFMWri:
- case ARM64::UBFMWri:
- case ARM64::SBFMXri:
- case ARM64::UBFMXri:
- Opc = NOpc;
- Opd0 = N->getOperand(0);
- LSB = cast<ConstantSDNode>(N->getOperand(1).getNode())->getZExtValue();
- MSB = cast<ConstantSDNode>(N->getOperand(2).getNode())->getZExtValue();
- return true;
- }
- // Unreachable
- return false;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectBitfieldExtractOp(SDNode *N) {
- unsigned Opc, LSB, MSB;
- SDValue Opd0;
- if (!isBitfieldExtractOp(CurDAG, N, Opc, Opd0, LSB, MSB))
- return nullptr;
-
- EVT VT = N->getValueType(0);
-
- // If the bit extract operation is 64bit but the original type is 32bit, we
- // need to add one EXTRACT_SUBREG.
- if ((Opc == ARM64::SBFMXri || Opc == ARM64::UBFMXri) && VT == MVT::i32) {
- SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(LSB, MVT::i64),
- CurDAG->getTargetConstant(MSB, MVT::i64)};
-
- SDNode *BFM = CurDAG->getMachineNode(Opc, SDLoc(N), MVT::i64, Ops64);
- SDValue SubReg = CurDAG->getTargetConstant(ARM64::sub_32, MVT::i32);
- MachineSDNode *Node =
- CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, SDLoc(N), MVT::i32,
- SDValue(BFM, 0), SubReg);
- return Node;
- }
-
- SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(LSB, VT),
- CurDAG->getTargetConstant(MSB, VT)};
- return CurDAG->SelectNodeTo(N, Opc, VT, Ops);
-}
-
-/// Does DstMask form a complementary pair with the mask provided by
-/// BitsToBeInserted, suitable for use in a BFI instruction. Roughly speaking,
-/// this asks whether DstMask zeroes precisely those bits that will be set by
-/// the other half.
-static bool isBitfieldDstMask(uint64_t DstMask, APInt BitsToBeInserted,
- unsigned NumberOfIgnoredHighBits, EVT VT) {
- assert((VT == MVT::i32 || VT == MVT::i64) &&
- "i32 or i64 mask type expected!");
- unsigned BitWidth = VT.getSizeInBits() - NumberOfIgnoredHighBits;
-
- APInt SignificantDstMask = APInt(BitWidth, DstMask);
- APInt SignificantBitsToBeInserted = BitsToBeInserted.zextOrTrunc(BitWidth);
-
- return (SignificantDstMask & SignificantBitsToBeInserted) == 0 &&
- (SignificantDstMask | SignificantBitsToBeInserted).isAllOnesValue();
-}
-
-// Look for bits that will be useful for later uses.
-// A bit is consider useless as soon as it is dropped and never used
-// before it as been dropped.
-// E.g., looking for useful bit of x
-// 1. y = x & 0x7
-// 2. z = y >> 2
-// After #1, x useful bits are 0x7, then the useful bits of x, live through
-// y.
-// After #2, the useful bits of x are 0x4.
-// However, if x is used on an unpredicatable instruction, then all its bits
-// are useful.
-// E.g.
-// 1. y = x & 0x7
-// 2. z = y >> 2
-// 3. str x, [@x]
-static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth = 0);
-
-static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits,
- unsigned Depth) {
- uint64_t Imm =
- cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue();
- Imm = ARM64_AM::decodeLogicalImmediate(Imm, UsefulBits.getBitWidth());
- UsefulBits &= APInt(UsefulBits.getBitWidth(), Imm);
- getUsefulBits(Op, UsefulBits, Depth + 1);
-}
-
-static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits,
- uint64_t Imm, uint64_t MSB,
- unsigned Depth) {
- // inherit the bitwidth value
- APInt OpUsefulBits(UsefulBits);
- OpUsefulBits = 1;
-
- if (MSB >= Imm) {
- OpUsefulBits = OpUsefulBits.shl(MSB - Imm + 1);
- --OpUsefulBits;
- // The interesting part will be in the lower part of the result
- getUsefulBits(Op, OpUsefulBits, Depth + 1);
- // The interesting part was starting at Imm in the argument
- OpUsefulBits = OpUsefulBits.shl(Imm);
- } else {
- OpUsefulBits = OpUsefulBits.shl(MSB + 1);
- --OpUsefulBits;
- // The interesting part will be shifted in the result
- OpUsefulBits = OpUsefulBits.shl(OpUsefulBits.getBitWidth() - Imm);
- getUsefulBits(Op, OpUsefulBits, Depth + 1);
- // The interesting part was at zero in the argument
- OpUsefulBits = OpUsefulBits.lshr(OpUsefulBits.getBitWidth() - Imm);
- }
-
- UsefulBits &= OpUsefulBits;
-}
-
-static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits,
- unsigned Depth) {
- uint64_t Imm =
- cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue();
- uint64_t MSB =
- cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
-
- getUsefulBitsFromBitfieldMoveOpd(Op, UsefulBits, Imm, MSB, Depth);
-}
-
-static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits,
- unsigned Depth) {
- uint64_t ShiftTypeAndValue =
- cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
- APInt Mask(UsefulBits);
- Mask.clearAllBits();
- Mask.flipAllBits();
-
- if (ARM64_AM::getShiftType(ShiftTypeAndValue) == ARM64_AM::LSL) {
- // Shift Left
- uint64_t ShiftAmt = ARM64_AM::getShiftValue(ShiftTypeAndValue);
- Mask = Mask.shl(ShiftAmt);
- getUsefulBits(Op, Mask, Depth + 1);
- Mask = Mask.lshr(ShiftAmt);
- } else if (ARM64_AM::getShiftType(ShiftTypeAndValue) == ARM64_AM::LSR) {
- // Shift Right
- // We do not handle ARM64_AM::ASR, because the sign will change the
- // number of useful bits
- uint64_t ShiftAmt = ARM64_AM::getShiftValue(ShiftTypeAndValue);
- Mask = Mask.lshr(ShiftAmt);
- getUsefulBits(Op, Mask, Depth + 1);
- Mask = Mask.shl(ShiftAmt);
- } else
- return;
-
- UsefulBits &= Mask;
-}
-
-static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits,
- unsigned Depth) {
- uint64_t Imm =
- cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
- uint64_t MSB =
- cast<const ConstantSDNode>(Op.getOperand(3).getNode())->getZExtValue();
-
- if (Op.getOperand(1) == Orig)
- return getUsefulBitsFromBitfieldMoveOpd(Op, UsefulBits, Imm, MSB, Depth);
-
- APInt OpUsefulBits(UsefulBits);
- OpUsefulBits = 1;
-
- if (MSB >= Imm) {
- OpUsefulBits = OpUsefulBits.shl(MSB - Imm + 1);
- --OpUsefulBits;
- UsefulBits &= ~OpUsefulBits;
- getUsefulBits(Op, UsefulBits, Depth + 1);
- } else {
- OpUsefulBits = OpUsefulBits.shl(MSB + 1);
- --OpUsefulBits;
- UsefulBits = ~(OpUsefulBits.shl(OpUsefulBits.getBitWidth() - Imm));
- getUsefulBits(Op, UsefulBits, Depth + 1);
- }
-}
-
-static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits,
- SDValue Orig, unsigned Depth) {
-
- // Users of this node should have already been instruction selected
- // FIXME: Can we turn that into an assert?
- if (!UserNode->isMachineOpcode())
- return;
-
- switch (UserNode->getMachineOpcode()) {
- default:
- return;
- case ARM64::ANDSWri:
- case ARM64::ANDSXri:
- case ARM64::ANDWri:
- case ARM64::ANDXri:
- // We increment Depth only when we call the getUsefulBits
- return getUsefulBitsFromAndWithImmediate(SDValue(UserNode, 0), UsefulBits,
- Depth);
- case ARM64::UBFMWri:
- case ARM64::UBFMXri:
- return getUsefulBitsFromUBFM(SDValue(UserNode, 0), UsefulBits, Depth);
-
- case ARM64::ORRWrs:
- case ARM64::ORRXrs:
- if (UserNode->getOperand(1) != Orig)
- return;
- return getUsefulBitsFromOrWithShiftedReg(SDValue(UserNode, 0), UsefulBits,
- Depth);
- case ARM64::BFMWri:
- case ARM64::BFMXri:
- return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth);
- }
-}
-
-static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth) {
- if (Depth >= 6)
- return;
- // Initialize UsefulBits
- if (!Depth) {
- unsigned Bitwidth = Op.getValueType().getScalarType().getSizeInBits();
- // At the beginning, assume every produced bits is useful
- UsefulBits = APInt(Bitwidth, 0);
- UsefulBits.flipAllBits();
- }
- APInt UsersUsefulBits(UsefulBits.getBitWidth(), 0);
-
- for (SDNode *Node : Op.getNode()->uses()) {
- // A use cannot produce useful bits
- APInt UsefulBitsForUse = APInt(UsefulBits);
- getUsefulBitsForUse(Node, UsefulBitsForUse, Op, Depth);
- UsersUsefulBits |= UsefulBitsForUse;
- }
- // UsefulBits contains the produced bits that are meaningful for the
- // current definition, thus a user cannot make a bit meaningful at
- // this point
- UsefulBits &= UsersUsefulBits;
-}
-
-/// Create a machine node performing a notional SHL of Op by ShlAmount. If
-/// ShlAmount is negative, do a (logical) right-shift instead. If ShlAmount is
-/// 0, return Op unchanged.
-static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount) {
- if (ShlAmount == 0)
- return Op;
-
- EVT VT = Op.getValueType();
- unsigned BitWidth = VT.getSizeInBits();
- unsigned UBFMOpc = BitWidth == 32 ? ARM64::UBFMWri : ARM64::UBFMXri;
-
- SDNode *ShiftNode;
- if (ShlAmount > 0) {
- // LSL wD, wN, #Amt == UBFM wD, wN, #32-Amt, #31-Amt
- ShiftNode = CurDAG->getMachineNode(
- UBFMOpc, SDLoc(Op), VT, Op,
- CurDAG->getTargetConstant(BitWidth - ShlAmount, VT),
- CurDAG->getTargetConstant(BitWidth - 1 - ShlAmount, VT));
- } else {
- // LSR wD, wN, #Amt == UBFM wD, wN, #Amt, #32-1
- assert(ShlAmount < 0 && "expected right shift");
- int ShrAmount = -ShlAmount;
- ShiftNode = CurDAG->getMachineNode(
- UBFMOpc, SDLoc(Op), VT, Op, CurDAG->getTargetConstant(ShrAmount, VT),
- CurDAG->getTargetConstant(BitWidth - 1, VT));
- }
-
- return SDValue(ShiftNode, 0);
-}
-
-/// Does this tree qualify as an attempt to move a bitfield into position,
-/// essentially "(and (shl VAL, N), Mask)".
-static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op,
- SDValue &Src, int &ShiftAmount,
- int &MaskWidth) {
- EVT VT = Op.getValueType();
- unsigned BitWidth = VT.getSizeInBits();
- (void)BitWidth;
- assert(BitWidth == 32 || BitWidth == 64);
-
- APInt KnownZero, KnownOne;
- CurDAG->computeKnownBits(Op, KnownZero, KnownOne);
-
- // Non-zero in the sense that they're not provably zero, which is the key
- // point if we want to use this value
- uint64_t NonZeroBits = (~KnownZero).getZExtValue();
-
- // Discard a constant AND mask if present. It's safe because the node will
- // already have been factored into the computeKnownBits calculation above.
- uint64_t AndImm;
- if (isOpcWithIntImmediate(Op.getNode(), ISD::AND, AndImm)) {
- assert((~APInt(BitWidth, AndImm) & ~KnownZero) == 0);
- Op = Op.getOperand(0);
- }
-
- uint64_t ShlImm;
- if (!isOpcWithIntImmediate(Op.getNode(), ISD::SHL, ShlImm))
- return false;
- Op = Op.getOperand(0);
-
- if (!isShiftedMask_64(NonZeroBits))
- return false;
-
- ShiftAmount = countTrailingZeros(NonZeroBits);
- MaskWidth = CountTrailingOnes_64(NonZeroBits >> ShiftAmount);
-
- // BFI encompasses sufficiently many nodes that it's worth inserting an extra
- // LSL/LSR if the mask in NonZeroBits doesn't quite match up with the ISD::SHL
- // amount.
- Src = getLeftShift(CurDAG, Op, ShlImm - ShiftAmount);
-
- return true;
-}
-
-// Given a OR operation, check if we have the following pattern
-// ubfm c, b, imm, imm2 (or something that does the same jobs, see
-// isBitfieldExtractOp)
-// d = e & mask2 ; where mask is a binary sequence of 1..10..0 and
-// countTrailingZeros(mask2) == imm2 - imm + 1
-// f = d | c
-// if yes, given reference arguments will be update so that one can replace
-// the OR instruction with:
-// f = Opc Opd0, Opd1, LSB, MSB ; where Opc is a BFM, LSB = imm, and MSB = imm2
-static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
- SDValue &Src, unsigned &ImmR,
- unsigned &ImmS, SelectionDAG *CurDAG) {
- assert(N->getOpcode() == ISD::OR && "Expect a OR operation");
-
- // Set Opc
- EVT VT = N->getValueType(0);
- if (VT == MVT::i32)
- Opc = ARM64::BFMWri;
- else if (VT == MVT::i64)
- Opc = ARM64::BFMXri;
- else
- return false;
-
- // Because of simplify-demanded-bits in DAGCombine, involved masks may not
- // have the expected shape. Try to undo that.
- APInt UsefulBits;
- getUsefulBits(SDValue(N, 0), UsefulBits);
-
- unsigned NumberOfIgnoredLowBits = UsefulBits.countTrailingZeros();
- unsigned NumberOfIgnoredHighBits = UsefulBits.countLeadingZeros();
-
- // OR is commutative, check both possibilities (does llvm provide a
- // way to do that directely, e.g., via code matcher?)
- SDValue OrOpd1Val = N->getOperand(1);
- SDNode *OrOpd0 = N->getOperand(0).getNode();
- SDNode *OrOpd1 = N->getOperand(1).getNode();
- for (int i = 0; i < 2;
- ++i, std::swap(OrOpd0, OrOpd1), OrOpd1Val = N->getOperand(0)) {
- unsigned BFXOpc;
- int DstLSB, Width;
- if (isBitfieldExtractOp(CurDAG, OrOpd0, BFXOpc, Src, ImmR, ImmS,
- NumberOfIgnoredLowBits, true)) {
- // Check that the returned opcode is compatible with the pattern,
- // i.e., same type and zero extended (U and not S)
- if ((BFXOpc != ARM64::UBFMXri && VT == MVT::i64) ||
- (BFXOpc != ARM64::UBFMWri && VT == MVT::i32))
- continue;
-
- // Compute the width of the bitfield insertion
- DstLSB = 0;
- Width = ImmS - ImmR + 1;
- // FIXME: This constraint is to catch bitfield insertion we may
- // want to widen the pattern if we want to grab general bitfied
- // move case
- if (Width <= 0)
- continue;
-
- // If the mask on the insertee is correct, we have a BFXIL operation. We
- // can share the ImmR and ImmS values from the already-computed UBFM.
- } else if (isBitfieldPositioningOp(CurDAG, SDValue(OrOpd0, 0), Src,
- DstLSB, Width)) {
- ImmR = (VT.getSizeInBits() - DstLSB) % VT.getSizeInBits();
- ImmS = Width - 1;
- } else
- continue;
-
- // Check the second part of the pattern
- EVT VT = OrOpd1->getValueType(0);
- assert((VT == MVT::i32 || VT == MVT::i64) && "unexpected OR operand");
-
- // Compute the Known Zero for the candidate of the first operand.
- // This allows to catch more general case than just looking for
- // AND with imm. Indeed, simplify-demanded-bits may have removed
- // the AND instruction because it proves it was useless.
- APInt KnownZero, KnownOne;
- CurDAG->computeKnownBits(OrOpd1Val, KnownZero, KnownOne);
-
- // Check if there is enough room for the second operand to appear
- // in the first one
- APInt BitsToBeInserted =
- APInt::getBitsSet(KnownZero.getBitWidth(), DstLSB, DstLSB + Width);
-
- if ((BitsToBeInserted & ~KnownZero) != 0)
- continue;
-
- // Set the first operand
- uint64_t Imm;
- if (isOpcWithIntImmediate(OrOpd1, ISD::AND, Imm) &&
- isBitfieldDstMask(Imm, BitsToBeInserted, NumberOfIgnoredHighBits, VT))
- // In that case, we can eliminate the AND
- Dst = OrOpd1->getOperand(0);
- else
- // Maybe the AND has been removed by simplify-demanded-bits
- // or is useful because it discards more bits
- Dst = OrOpd1Val;
-
- // both parts match
- return true;
- }
-
- return false;
-}
-
-SDNode *ARM64DAGToDAGISel::SelectBitfieldInsertOp(SDNode *N) {
- if (N->getOpcode() != ISD::OR)
- return nullptr;
-
- unsigned Opc;
- unsigned LSB, MSB;
- SDValue Opd0, Opd1;
-
- if (!isBitfieldInsertOpFromOr(N, Opc, Opd0, Opd1, LSB, MSB, CurDAG))
- return nullptr;
-
- EVT VT = N->getValueType(0);
- SDValue Ops[] = { Opd0,
- Opd1,
- CurDAG->getTargetConstant(LSB, VT),
- CurDAG->getTargetConstant(MSB, VT) };
- return CurDAG->SelectNodeTo(N, Opc, VT, Ops);
-}
-
-SDNode *ARM64DAGToDAGISel::SelectLIBM(SDNode *N) {
- EVT VT = N->getValueType(0);
- unsigned Variant;
- unsigned Opc;
- unsigned FRINTXOpcs[] = { ARM64::FRINTXSr, ARM64::FRINTXDr };
-
- if (VT == MVT::f32) {
- Variant = 0;
- } else if (VT == MVT::f64) {
- Variant = 1;
- } else
- return nullptr; // Unrecognized argument type. Fall back on default codegen.
-
- // Pick the FRINTX variant needed to set the flags.
- unsigned FRINTXOpc = FRINTXOpcs[Variant];
-
- switch (N->getOpcode()) {
- default:
- return nullptr; // Unrecognized libm ISD node. Fall back on default codegen.
- case ISD::FCEIL: {
- unsigned FRINTPOpcs[] = { ARM64::FRINTPSr, ARM64::FRINTPDr };
- Opc = FRINTPOpcs[Variant];
- break;
- }
- case ISD::FFLOOR: {
- unsigned FRINTMOpcs[] = { ARM64::FRINTMSr, ARM64::FRINTMDr };
- Opc = FRINTMOpcs[Variant];
- break;
- }
- case ISD::FTRUNC: {
- unsigned FRINTZOpcs[] = { ARM64::FRINTZSr, ARM64::FRINTZDr };
- Opc = FRINTZOpcs[Variant];
- break;
- }
- case ISD::FROUND: {
- unsigned FRINTAOpcs[] = { ARM64::FRINTASr, ARM64::FRINTADr };
- Opc = FRINTAOpcs[Variant];
- break;
- }
- }
-
- SDLoc dl(N);
- SDValue In = N->getOperand(0);
- SmallVector<SDValue, 2> Ops;
- Ops.push_back(In);
-
- if (!TM.Options.UnsafeFPMath) {
- SDNode *FRINTX = CurDAG->getMachineNode(FRINTXOpc, dl, VT, MVT::Glue, In);
- Ops.push_back(SDValue(FRINTX, 1));
- }
-
- return CurDAG->getMachineNode(Opc, dl, VT, Ops);
-}
-
-bool
-ARM64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos,
- unsigned RegWidth) {
- APFloat FVal(0.0);
- if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N))
- FVal = CN->getValueAPF();
- else if (LoadSDNode *LN = dyn_cast<LoadSDNode>(N)) {
- // Some otherwise illegal constants are allowed in this case.
- if (LN->getOperand(1).getOpcode() != ARM64ISD::ADDlow ||
- !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)))
- return false;
-
- ConstantPoolSDNode *CN =
- dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1));
- FVal = cast<ConstantFP>(CN->getConstVal())->getValueAPF();
- } else
- return false;
-
- // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits
- // is between 1 and 32 for a destination w-register, or 1 and 64 for an
- // x-register.
- //
- // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we
- // want THIS_NODE to be 2^fbits. This is much easier to deal with using
- // integers.
- bool IsExact;
-
- // fbits is between 1 and 64 in the worst-case, which means the fmul
- // could have 2^64 as an actual operand. Need 65 bits of precision.
- APSInt IntVal(65, true);
- FVal.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact);
-
- // N.b. isPowerOf2 also checks for > 0.
- if (!IsExact || !IntVal.isPowerOf2()) return false;
- unsigned FBits = IntVal.logBase2();
-
- // Checks above should have guaranteed that we haven't lost information in
- // finding FBits, but it must still be in range.
- if (FBits == 0 || FBits > RegWidth) return false;
-
- FixedPos = CurDAG->getTargetConstant(FBits, MVT::i32);
- return true;
-}
-
-SDNode *ARM64DAGToDAGISel::Select(SDNode *Node) {
- // Dump information about the Node being selected
- DEBUG(errs() << "Selecting: ");
- DEBUG(Node->dump(CurDAG));
- DEBUG(errs() << "\n");
-
- // If we have a custom node, we already have selected!
- if (Node->isMachineOpcode()) {
- DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
- Node->setNodeId(-1);
- return nullptr;
- }
-
- // Few custom selection stuff.
- SDNode *ResNode = nullptr;
- EVT VT = Node->getValueType(0);
-
- switch (Node->getOpcode()) {
- default:
- break;
-
- case ISD::ADD:
- if (SDNode *I = SelectMLAV64LaneV128(Node))
- return I;
- break;
-
- case ISD::LOAD: {
- // Try to select as an indexed load. Fall through to normal processing
- // if we can't.
- bool Done = false;
- SDNode *I = SelectIndexedLoad(Node, Done);
- if (Done)
- return I;
- break;
- }
-
- case ISD::SRL:
- case ISD::AND:
- case ISD::SRA:
- if (SDNode *I = SelectBitfieldExtractOp(Node))
- return I;
- break;
-
- case ISD::OR:
- if (SDNode *I = SelectBitfieldInsertOp(Node))
- return I;
- break;
-
- case ISD::EXTRACT_VECTOR_ELT: {
- // Extracting lane zero is a special case where we can just use a plain
- // EXTRACT_SUBREG instruction, which will become FMOV. This is easier for
- // the rest of the compiler, especially the register allocator and copyi
- // propagation, to reason about, so is preferred when it's possible to
- // use it.
- ConstantSDNode *LaneNode = cast<ConstantSDNode>(Node->getOperand(1));
- // Bail and use the default Select() for non-zero lanes.
- if (LaneNode->getZExtValue() != 0)
- break;
- // If the element type is not the same as the result type, likewise
- // bail and use the default Select(), as there's more to do than just
- // a cross-class COPY. This catches extracts of i8 and i16 elements
- // since they will need an explicit zext.
- if (VT != Node->getOperand(0).getValueType().getVectorElementType())
- break;
- unsigned SubReg;
- switch (Node->getOperand(0)
- .getValueType()
- .getVectorElementType()
- .getSizeInBits()) {
- default:
- assert(0 && "Unexpected vector element type!");
- case 64:
- SubReg = ARM64::dsub;
- break;
- case 32:
- SubReg = ARM64::ssub;
- break;
- case 16: // FALLTHROUGH
- case 8:
- llvm_unreachable("unexpected zext-requiring extract element!");
- }
- SDValue Extract = CurDAG->getTargetExtractSubreg(SubReg, SDLoc(Node), VT,
- Node->getOperand(0));
- DEBUG(dbgs() << "ISEL: Custom selection!\n=> ");
- DEBUG(Extract->dumpr(CurDAG));
- DEBUG(dbgs() << "\n");
- return Extract.getNode();
- }
- case ISD::Constant: {
- // Materialize zero constants as copies from WZR/XZR. This allows
- // the coalescer to propagate these into other instructions.
- ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node);
- if (ConstNode->isNullValue()) {
- if (VT == MVT::i32)
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node),
- ARM64::WZR, MVT::i32).getNode();
- else if (VT == MVT::i64)
- return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node),
- ARM64::XZR, MVT::i64).getNode();
- }
- break;
- }
-
- case ISD::FrameIndex: {
- // Selects to ADDXri FI, 0 which in turn will become ADDXri SP, imm.
- int FI = cast<FrameIndexSDNode>(Node)->getIndex();
- unsigned Shifter = ARM64_AM::getShifterImm(ARM64_AM::LSL, 0);
- const TargetLowering *TLI = getTargetLowering();
- SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy());
- SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
- CurDAG->getTargetConstant(Shifter, MVT::i32) };
- return CurDAG->SelectNodeTo(Node, ARM64::ADDXri, MVT::i64, Ops);
- }
- case ISD::INTRINSIC_W_CHAIN: {
- unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
- switch (IntNo) {
- default:
- break;
- case Intrinsic::arm64_ldaxp:
- case Intrinsic::arm64_ldxp: {
- unsigned Op =
- IntNo == Intrinsic::arm64_ldaxp ? ARM64::LDAXPX : ARM64::LDXPX;
- SDValue MemAddr = Node->getOperand(2);
- SDLoc DL(Node);
- SDValue Chain = Node->getOperand(0);
-
- SDNode *Ld = CurDAG->getMachineNode(Op, DL, MVT::i64, MVT::i64,
- MVT::Other, MemAddr, Chain);
-
- // Transfer memoperands.
- MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
- MemOp[0] = cast<MemIntrinsicSDNode>(Node)->getMemOperand();
- cast<MachineSDNode>(Ld)->setMemRefs(MemOp, MemOp + 1);
- return Ld;
- }
- case Intrinsic::arm64_stlxp:
- case Intrinsic::arm64_stxp: {
- unsigned Op =
- IntNo == Intrinsic::arm64_stlxp ? ARM64::STLXPX : ARM64::STXPX;
- SDLoc DL(Node);
- SDValue Chain = Node->getOperand(0);
- SDValue ValLo = Node->getOperand(2);
- SDValue ValHi = Node->getOperand(3);
- SDValue MemAddr = Node->getOperand(4);
-
- // Place arguments in the right order.
- SmallVector<SDValue, 7> Ops;
- Ops.push_back(ValLo);
- Ops.push_back(ValHi);
- Ops.push_back(MemAddr);
- Ops.push_back(Chain);
-
- SDNode *St = CurDAG->getMachineNode(Op, DL, MVT::i32, MVT::Other, Ops);
- // Transfer memoperands.
- MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
- MemOp[0] = cast<MemIntrinsicSDNode>(Node)->getMemOperand();
- cast<MachineSDNode>(St)->setMemRefs(MemOp, MemOp + 1);
-
- return St;
- }
- case Intrinsic::arm64_neon_ld1x2:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 2, ARM64::LD1Twov8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 2, ARM64::LD1Twov16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 2, ARM64::LD1Twov4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 2, ARM64::LD1Twov8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 2, ARM64::LD1Twov2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 2, ARM64::LD1Twov4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 2, ARM64::LD1Twov1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 2, ARM64::LD1Twov2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld1x3:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 3, ARM64::LD1Threev8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 3, ARM64::LD1Threev16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 3, ARM64::LD1Threev4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 3, ARM64::LD1Threev8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 3, ARM64::LD1Threev2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 3, ARM64::LD1Threev4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 3, ARM64::LD1Threev1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 3, ARM64::LD1Threev2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld1x4:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 4, ARM64::LD1Fourv8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 4, ARM64::LD1Fourv16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 4, ARM64::LD1Fourv4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 4, ARM64::LD1Fourv8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 4, ARM64::LD1Fourv2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 4, ARM64::LD1Fourv4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 4, ARM64::LD1Fourv1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 4, ARM64::LD1Fourv2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld2:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 2, ARM64::LD2Twov8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 2, ARM64::LD2Twov16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 2, ARM64::LD2Twov4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 2, ARM64::LD2Twov8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 2, ARM64::LD2Twov2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 2, ARM64::LD2Twov4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 2, ARM64::LD1Twov1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 2, ARM64::LD2Twov2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld3:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 3, ARM64::LD3Threev8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 3, ARM64::LD3Threev16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 3, ARM64::LD3Threev4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 3, ARM64::LD3Threev8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 3, ARM64::LD3Threev2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 3, ARM64::LD3Threev4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 3, ARM64::LD1Threev1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 3, ARM64::LD3Threev2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld4:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 4, ARM64::LD4Fourv8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 4, ARM64::LD4Fourv16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 4, ARM64::LD4Fourv4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 4, ARM64::LD4Fourv8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 4, ARM64::LD4Fourv2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 4, ARM64::LD4Fourv4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 4, ARM64::LD1Fourv1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 4, ARM64::LD4Fourv2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld2r:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 2, ARM64::LD2Rv8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 2, ARM64::LD2Rv16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 2, ARM64::LD2Rv4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 2, ARM64::LD2Rv8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 2, ARM64::LD2Rv2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 2, ARM64::LD2Rv4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 2, ARM64::LD2Rv1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 2, ARM64::LD2Rv2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld3r:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 3, ARM64::LD3Rv8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 3, ARM64::LD3Rv16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 3, ARM64::LD3Rv4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 3, ARM64::LD3Rv8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 3, ARM64::LD3Rv2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 3, ARM64::LD3Rv4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 3, ARM64::LD3Rv1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 3, ARM64::LD3Rv2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld4r:
- if (VT == MVT::v8i8)
- return SelectLoad(Node, 4, ARM64::LD4Rv8b, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectLoad(Node, 4, ARM64::LD4Rv16b, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectLoad(Node, 4, ARM64::LD4Rv4h, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectLoad(Node, 4, ARM64::LD4Rv8h, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectLoad(Node, 4, ARM64::LD4Rv2s, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectLoad(Node, 4, ARM64::LD4Rv4s, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectLoad(Node, 4, ARM64::LD4Rv1d, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectLoad(Node, 4, ARM64::LD4Rv2d, ARM64::qsub0);
- break;
- case Intrinsic::arm64_neon_ld2lane:
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectLoadLane(Node, 2, ARM64::LD2i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectLoadLane(Node, 2, ARM64::LD2i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectLoadLane(Node, 2, ARM64::LD2i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectLoadLane(Node, 2, ARM64::LD2i64);
- break;
- case Intrinsic::arm64_neon_ld3lane:
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectLoadLane(Node, 3, ARM64::LD3i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectLoadLane(Node, 3, ARM64::LD3i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectLoadLane(Node, 3, ARM64::LD3i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectLoadLane(Node, 3, ARM64::LD3i64);
- break;
- case Intrinsic::arm64_neon_ld4lane:
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectLoadLane(Node, 4, ARM64::LD4i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectLoadLane(Node, 4, ARM64::LD4i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectLoadLane(Node, 4, ARM64::LD4i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectLoadLane(Node, 4, ARM64::LD4i64);
- break;
- }
- } break;
- case ISD::INTRINSIC_WO_CHAIN: {
- unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
- switch (IntNo) {
- default:
- break;
- case Intrinsic::arm64_neon_tbl2:
- return SelectTable(Node, 2, VT == MVT::v8i8 ? ARM64::TBLv8i8Two
- : ARM64::TBLv16i8Two,
- false);
- case Intrinsic::arm64_neon_tbl3:
- return SelectTable(Node, 3, VT == MVT::v8i8 ? ARM64::TBLv8i8Three
- : ARM64::TBLv16i8Three,
- false);
- case Intrinsic::arm64_neon_tbl4:
- return SelectTable(Node, 4, VT == MVT::v8i8 ? ARM64::TBLv8i8Four
- : ARM64::TBLv16i8Four,
- false);
- case Intrinsic::arm64_neon_tbx2:
- return SelectTable(Node, 2, VT == MVT::v8i8 ? ARM64::TBXv8i8Two
- : ARM64::TBXv16i8Two,
- true);
- case Intrinsic::arm64_neon_tbx3:
- return SelectTable(Node, 3, VT == MVT::v8i8 ? ARM64::TBXv8i8Three
- : ARM64::TBXv16i8Three,
- true);
- case Intrinsic::arm64_neon_tbx4:
- return SelectTable(Node, 4, VT == MVT::v8i8 ? ARM64::TBXv8i8Four
- : ARM64::TBXv16i8Four,
- true);
- case Intrinsic::arm64_neon_smull:
- case Intrinsic::arm64_neon_umull:
- if (SDNode *N = SelectMULLV64LaneV128(IntNo, Node))
- return N;
- break;
- }
- break;
- }
- case ISD::INTRINSIC_VOID: {
- unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
- if (Node->getNumOperands() >= 3)
- VT = Node->getOperand(2)->getValueType(0);
- switch (IntNo) {
- default:
- break;
- case Intrinsic::arm64_neon_st1x2: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 2, ARM64::ST1Twov8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 2, ARM64::ST1Twov16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 2, ARM64::ST1Twov4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 2, ARM64::ST1Twov8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 2, ARM64::ST1Twov2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 2, ARM64::ST1Twov4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 2, ARM64::ST1Twov2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 2, ARM64::ST1Twov1d);
- break;
- }
- case Intrinsic::arm64_neon_st1x3: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 3, ARM64::ST1Threev8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 3, ARM64::ST1Threev16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 3, ARM64::ST1Threev4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 3, ARM64::ST1Threev8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 3, ARM64::ST1Threev2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 3, ARM64::ST1Threev4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 3, ARM64::ST1Threev2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 3, ARM64::ST1Threev1d);
- break;
- }
- case Intrinsic::arm64_neon_st1x4: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 4, ARM64::ST1Fourv8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 4, ARM64::ST1Fourv16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 4, ARM64::ST1Fourv4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 4, ARM64::ST1Fourv8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 4, ARM64::ST1Fourv2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 4, ARM64::ST1Fourv4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 4, ARM64::ST1Fourv2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 4, ARM64::ST1Fourv1d);
- break;
- }
- case Intrinsic::arm64_neon_st2: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 2, ARM64::ST2Twov8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 2, ARM64::ST2Twov16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 2, ARM64::ST2Twov4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 2, ARM64::ST2Twov8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 2, ARM64::ST2Twov2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 2, ARM64::ST2Twov4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 2, ARM64::ST2Twov2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 2, ARM64::ST1Twov1d);
- break;
- }
- case Intrinsic::arm64_neon_st3: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 3, ARM64::ST3Threev8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 3, ARM64::ST3Threev16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 3, ARM64::ST3Threev4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 3, ARM64::ST3Threev8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 3, ARM64::ST3Threev2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 3, ARM64::ST3Threev4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 3, ARM64::ST3Threev2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 3, ARM64::ST1Threev1d);
- break;
- }
- case Intrinsic::arm64_neon_st4: {
- if (VT == MVT::v8i8)
- return SelectStore(Node, 4, ARM64::ST4Fourv8b);
- else if (VT == MVT::v16i8)
- return SelectStore(Node, 4, ARM64::ST4Fourv16b);
- else if (VT == MVT::v4i16)
- return SelectStore(Node, 4, ARM64::ST4Fourv4h);
- else if (VT == MVT::v8i16)
- return SelectStore(Node, 4, ARM64::ST4Fourv8h);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectStore(Node, 4, ARM64::ST4Fourv2s);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectStore(Node, 4, ARM64::ST4Fourv4s);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectStore(Node, 4, ARM64::ST4Fourv2d);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectStore(Node, 4, ARM64::ST1Fourv1d);
- break;
- }
- case Intrinsic::arm64_neon_st2lane: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectStoreLane(Node, 2, ARM64::ST2i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectStoreLane(Node, 2, ARM64::ST2i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectStoreLane(Node, 2, ARM64::ST2i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectStoreLane(Node, 2, ARM64::ST2i64);
- break;
- }
- case Intrinsic::arm64_neon_st3lane: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectStoreLane(Node, 3, ARM64::ST3i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectStoreLane(Node, 3, ARM64::ST3i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectStoreLane(Node, 3, ARM64::ST3i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectStoreLane(Node, 3, ARM64::ST3i64);
- break;
- }
- case Intrinsic::arm64_neon_st4lane: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectStoreLane(Node, 4, ARM64::ST4i8);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectStoreLane(Node, 4, ARM64::ST4i16);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectStoreLane(Node, 4, ARM64::ST4i32);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectStoreLane(Node, 4, ARM64::ST4i64);
- break;
- }
- }
- }
- case ARM64ISD::LD2post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 2, ARM64::LD2Twov2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD3post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 3, ARM64::LD3Threev2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD4post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 4, ARM64::LD4Fourv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD1x2post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 2, ARM64::LD1Twov2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD1x3post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 3, ARM64::LD1Threev2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD1x4post: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 4, ARM64::LD1Fourv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD1DUPpost: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 1, ARM64::LD1Rv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD2DUPpost: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 2, ARM64::LD2Rv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD3DUPpost: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 3, ARM64::LD3Rv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD4DUPpost: {
- if (VT == MVT::v8i8)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv8b_POST, ARM64::dsub0);
- else if (VT == MVT::v16i8)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv16b_POST, ARM64::qsub0);
- else if (VT == MVT::v4i16)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv4h_POST, ARM64::dsub0);
- else if (VT == MVT::v8i16)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv8h_POST, ARM64::qsub0);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv2s_POST, ARM64::dsub0);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv4s_POST, ARM64::qsub0);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv1d_POST, ARM64::dsub0);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostLoad(Node, 4, ARM64::LD4Rv2d_POST, ARM64::qsub0);
- break;
- }
- case ARM64ISD::LD1LANEpost: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostLoadLane(Node, 1, ARM64::LD1i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostLoadLane(Node, 1, ARM64::LD1i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostLoadLane(Node, 1, ARM64::LD1i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostLoadLane(Node, 1, ARM64::LD1i64_POST);
- break;
- }
- case ARM64ISD::LD2LANEpost: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostLoadLane(Node, 2, ARM64::LD2i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostLoadLane(Node, 2, ARM64::LD2i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostLoadLane(Node, 2, ARM64::LD2i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostLoadLane(Node, 2, ARM64::LD2i64_POST);
- break;
- }
- case ARM64ISD::LD3LANEpost: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostLoadLane(Node, 3, ARM64::LD3i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostLoadLane(Node, 3, ARM64::LD3i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostLoadLane(Node, 3, ARM64::LD3i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostLoadLane(Node, 3, ARM64::LD3i64_POST);
- break;
- }
- case ARM64ISD::LD4LANEpost: {
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostLoadLane(Node, 4, ARM64::LD4i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostLoadLane(Node, 4, ARM64::LD4i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostLoadLane(Node, 4, ARM64::LD4i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostLoadLane(Node, 4, ARM64::LD4i64_POST);
- break;
- }
- case ARM64ISD::ST2post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 2, ARM64::ST2Twov8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 2, ARM64::ST2Twov16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 2, ARM64::ST2Twov4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 2, ARM64::ST2Twov8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 2, ARM64::ST2Twov2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 2, ARM64::ST2Twov4s_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 2, ARM64::ST2Twov2d_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 2, ARM64::ST1Twov1d_POST);
- break;
- }
- case ARM64ISD::ST3post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 3, ARM64::ST3Threev8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 3, ARM64::ST3Threev16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 3, ARM64::ST3Threev4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 3, ARM64::ST3Threev8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 3, ARM64::ST3Threev2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 3, ARM64::ST3Threev4s_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 3, ARM64::ST3Threev2d_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 3, ARM64::ST1Threev1d_POST);
- break;
- }
- case ARM64ISD::ST4post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv4s_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 4, ARM64::ST4Fourv2d_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv1d_POST);
- break;
- }
- case ARM64ISD::ST1x2post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 2, ARM64::ST1Twov8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 2, ARM64::ST1Twov16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 2, ARM64::ST1Twov4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 2, ARM64::ST1Twov8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 2, ARM64::ST1Twov2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 2, ARM64::ST1Twov4s_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 2, ARM64::ST1Twov1d_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 2, ARM64::ST1Twov2d_POST);
- break;
- }
- case ARM64ISD::ST1x3post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 3, ARM64::ST1Threev8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 3, ARM64::ST1Threev16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 3, ARM64::ST1Threev4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 3, ARM64::ST1Threev8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 3, ARM64::ST1Threev2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 3, ARM64::ST1Threev4s_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 3, ARM64::ST1Threev1d_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 3, ARM64::ST1Threev2d_POST);
- break;
- }
- case ARM64ISD::ST1x4post: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v8i8)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv8b_POST);
- else if (VT == MVT::v16i8)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv16b_POST);
- else if (VT == MVT::v4i16)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv4h_POST);
- else if (VT == MVT::v8i16)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv8h_POST);
- else if (VT == MVT::v2i32 || VT == MVT::v2f32)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv2s_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v4f32)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv4s_POST);
- else if (VT == MVT::v1i64 || VT == MVT::v1f64)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv1d_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v2f64)
- return SelectPostStore(Node, 4, ARM64::ST1Fourv2d_POST);
- break;
- }
- case ARM64ISD::ST2LANEpost: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostStoreLane(Node, 2, ARM64::ST2i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostStoreLane(Node, 2, ARM64::ST2i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostStoreLane(Node, 2, ARM64::ST2i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostStoreLane(Node, 2, ARM64::ST2i64_POST);
- break;
- }
- case ARM64ISD::ST3LANEpost: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostStoreLane(Node, 3, ARM64::ST3i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostStoreLane(Node, 3, ARM64::ST3i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostStoreLane(Node, 3, ARM64::ST3i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostStoreLane(Node, 3, ARM64::ST3i64_POST);
- break;
- }
- case ARM64ISD::ST4LANEpost: {
- VT = Node->getOperand(1).getValueType();
- if (VT == MVT::v16i8 || VT == MVT::v8i8)
- return SelectPostStoreLane(Node, 4, ARM64::ST4i8_POST);
- else if (VT == MVT::v8i16 || VT == MVT::v4i16)
- return SelectPostStoreLane(Node, 4, ARM64::ST4i16_POST);
- else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 ||
- VT == MVT::v2f32)
- return SelectPostStoreLane(Node, 4, ARM64::ST4i32_POST);
- else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 ||
- VT == MVT::v1f64)
- return SelectPostStoreLane(Node, 4, ARM64::ST4i64_POST);
- break;
- }
-
- case ISD::FCEIL:
- case ISD::FFLOOR:
- case ISD::FTRUNC:
- case ISD::FROUND:
- if (SDNode *I = SelectLIBM(Node))
- return I;
- break;
- }
-
- // Select the default instruction
- ResNode = SelectCode(Node);
-
- DEBUG(errs() << "=> ");
- if (ResNode == nullptr || ResNode == Node)
- DEBUG(Node->dump(CurDAG));
- else
- DEBUG(ResNode->dump(CurDAG));
- DEBUG(errs() << "\n");
-
- return ResNode;
-}
-
-/// createARM64ISelDag - This pass converts a legalized DAG into a
-/// ARM64-specific DAG, ready for instruction scheduling.
-FunctionPass *llvm::createARM64ISelDag(ARM64TargetMachine &TM,
- CodeGenOpt::Level OptLevel) {
- return new ARM64DAGToDAGISel(TM, OptLevel);
-}
More information about the llvm-commits
mailing list