aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/AArch64
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AArch64')
-rw-r--r--lib/Target/AArch64/AArch64FrameLowering.cpp7
-rw-r--r--lib/Target/AArch64/AArch64ISelDAGToDAG.cpp106
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp140
-rw-r--r--lib/Target/AArch64/AArch64InstrFormats.td2
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.cpp6
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.td1071
-rw-r--r--lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp9
-rw-r--r--lib/Target/AArch64/Utils/AArch64BaseInfo.cpp306
-rw-r--r--lib/Target/AArch64/Utils/AArch64BaseInfo.h290
9 files changed, 1271 insertions, 666 deletions
diff --git a/lib/Target/AArch64/AArch64FrameLowering.cpp b/lib/Target/AArch64/AArch64FrameLowering.cpp
index 572617c..daa7f1d 100644
--- a/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -367,9 +367,8 @@ AArch64FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// shoving a base register and an offset into the instruction then we may well
// need to scavenge registers. We should either specifically add an
// callee-save register for this purpose or allocate an extra spill slot.
-
bool BigStack =
- (RS && MFI->estimateStackSize(MF) >= TII.estimateRSStackLimit(MF))
+ MFI->estimateStackSize(MF) >= TII.estimateRSStackLimit(MF)
|| MFI->hasVarSizedObjects() // Access will be from X29: messes things up
|| (MFI->adjustsStack() && !hasReservedCallFrame(MF));
@@ -392,11 +391,13 @@ AArch64FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
if (ExtraReg != 0) {
MF.getRegInfo().setPhysRegUsed(ExtraReg);
} else {
+ assert(RS && "Expect register scavenger to be available");
+
// Create a stack slot for scavenging purposes. PrologEpilogInserter
// helpfully places it near either SP or FP for us to avoid
// infinitely-regression during scavenging.
const TargetRegisterClass *RC = &AArch64::GPR64RegClass;
- RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
+ RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
diff --git a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 46b8221..468c561 100644
--- a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -88,6 +88,8 @@ public:
bool SelectTSTBOperand(SDValue N, SDValue &FixedPos, unsigned RegWidth);
+ SDNode *SelectAtomic(SDNode *N, unsigned Op8, unsigned Op16, unsigned Op32, unsigned Op64);
+
SDNode *TrySelectToMoveImm(SDNode *N);
SDNode *LowerToFPLitPool(SDNode *Node);
SDNode *SelectToLitPool(SDNode *N);
@@ -318,6 +320,38 @@ AArch64DAGToDAGISel::SelectTSTBOperand(SDValue N, SDValue &FixedPos,
return true;
}
+SDNode *AArch64DAGToDAGISel::SelectAtomic(SDNode *Node, unsigned Op8,
+ unsigned Op16,unsigned Op32,
+ unsigned Op64) {
+ // Mostly direct translation to the given operations, except that we preserve
+ // the AtomicOrdering for use later on.
+ AtomicSDNode *AN = cast<AtomicSDNode>(Node);
+ EVT VT = AN->getMemoryVT();
+
+ unsigned Op;
+ if (VT == MVT::i8)
+ Op = Op8;
+ else if (VT == MVT::i16)
+ Op = Op16;
+ else if (VT == MVT::i32)
+ Op = Op32;
+ else if (VT == MVT::i64)
+ Op = Op64;
+ else
+ llvm_unreachable("Unexpected atomic operation");
+
+ SmallVector<SDValue, 4> Ops;
+ for (unsigned i = 1; i < AN->getNumOperands(); ++i)
+ Ops.push_back(AN->getOperand(i));
+
+ Ops.push_back(CurDAG->getTargetConstant(AN->getOrdering(), MVT::i32));
+ Ops.push_back(AN->getOperand(0)); // Chain moves to the end
+
+ return CurDAG->SelectNodeTo(Node, Op,
+ AN->getValueType(0), MVT::Other,
+ &Ops[0], Ops.size());
+}
+
SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) {
// Dump information about the Node being selected
DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n");
@@ -328,6 +362,78 @@ SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) {
}
switch (Node->getOpcode()) {
+ case ISD::ATOMIC_LOAD_ADD:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_ADD_I8,
+ AArch64::ATOMIC_LOAD_ADD_I16,
+ AArch64::ATOMIC_LOAD_ADD_I32,
+ AArch64::ATOMIC_LOAD_ADD_I64);
+ case ISD::ATOMIC_LOAD_SUB:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_SUB_I8,
+ AArch64::ATOMIC_LOAD_SUB_I16,
+ AArch64::ATOMIC_LOAD_SUB_I32,
+ AArch64::ATOMIC_LOAD_SUB_I64);
+ case ISD::ATOMIC_LOAD_AND:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_AND_I8,
+ AArch64::ATOMIC_LOAD_AND_I16,
+ AArch64::ATOMIC_LOAD_AND_I32,
+ AArch64::ATOMIC_LOAD_AND_I64);
+ case ISD::ATOMIC_LOAD_OR:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_OR_I8,
+ AArch64::ATOMIC_LOAD_OR_I16,
+ AArch64::ATOMIC_LOAD_OR_I32,
+ AArch64::ATOMIC_LOAD_OR_I64);
+ case ISD::ATOMIC_LOAD_XOR:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_XOR_I8,
+ AArch64::ATOMIC_LOAD_XOR_I16,
+ AArch64::ATOMIC_LOAD_XOR_I32,
+ AArch64::ATOMIC_LOAD_XOR_I64);
+ case ISD::ATOMIC_LOAD_NAND:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_NAND_I8,
+ AArch64::ATOMIC_LOAD_NAND_I16,
+ AArch64::ATOMIC_LOAD_NAND_I32,
+ AArch64::ATOMIC_LOAD_NAND_I64);
+ case ISD::ATOMIC_LOAD_MIN:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_MIN_I8,
+ AArch64::ATOMIC_LOAD_MIN_I16,
+ AArch64::ATOMIC_LOAD_MIN_I32,
+ AArch64::ATOMIC_LOAD_MIN_I64);
+ case ISD::ATOMIC_LOAD_MAX:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_MAX_I8,
+ AArch64::ATOMIC_LOAD_MAX_I16,
+ AArch64::ATOMIC_LOAD_MAX_I32,
+ AArch64::ATOMIC_LOAD_MAX_I64);
+ case ISD::ATOMIC_LOAD_UMIN:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_UMIN_I8,
+ AArch64::ATOMIC_LOAD_UMIN_I16,
+ AArch64::ATOMIC_LOAD_UMIN_I32,
+ AArch64::ATOMIC_LOAD_UMIN_I64);
+ case ISD::ATOMIC_LOAD_UMAX:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_LOAD_UMAX_I8,
+ AArch64::ATOMIC_LOAD_UMAX_I16,
+ AArch64::ATOMIC_LOAD_UMAX_I32,
+ AArch64::ATOMIC_LOAD_UMAX_I64);
+ case ISD::ATOMIC_SWAP:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_SWAP_I8,
+ AArch64::ATOMIC_SWAP_I16,
+ AArch64::ATOMIC_SWAP_I32,
+ AArch64::ATOMIC_SWAP_I64);
+ case ISD::ATOMIC_CMP_SWAP:
+ return SelectAtomic(Node,
+ AArch64::ATOMIC_CMP_SWAP_I8,
+ AArch64::ATOMIC_CMP_SWAP_I16,
+ AArch64::ATOMIC_CMP_SWAP_I32,
+ AArch64::ATOMIC_CMP_SWAP_I64);
case ISD::FrameIndex: {
int FI = cast<FrameIndexSDNode>(Node)->getIndex();
EVT PtrTy = TLI.getPointerTy();
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp
index e9f4497..786b1ba 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -59,13 +59,6 @@ AArch64TargetLowering::AArch64TargetLowering(AArch64TargetMachine &TM)
computeRegisterProperties();
- // Some atomic operations can be folded into load-acquire or store-release
- // instructions on AArch64. It's marginally simpler to let LLVM expand
- // everything out to a barrier and then recombine the (few) barriers we can.
- setInsertFencesForAtomic(true);
- setTargetDAGCombine(ISD::ATOMIC_FENCE);
- setTargetDAGCombine(ISD::ATOMIC_STORE);
-
// We combine OR nodes for bitfield and NEON BSL operations.
setTargetDAGCombine(ISD::OR);
@@ -275,27 +268,34 @@ EVT AArch64TargetLowering::getSetCCResultType(EVT VT) const {
return VT.changeVectorElementTypeToInteger();
}
-static void getExclusiveOperation(unsigned Size, unsigned &ldrOpc,
- unsigned &strOpc) {
- switch (Size) {
- default: llvm_unreachable("unsupported size for atomic binary op!");
- case 1:
- ldrOpc = AArch64::LDXR_byte;
- strOpc = AArch64::STXR_byte;
- break;
- case 2:
- ldrOpc = AArch64::LDXR_hword;
- strOpc = AArch64::STXR_hword;
- break;
- case 4:
- ldrOpc = AArch64::LDXR_word;
- strOpc = AArch64::STXR_word;
- break;
- case 8:
- ldrOpc = AArch64::LDXR_dword;
- strOpc = AArch64::STXR_dword;
- break;
- }
+static void getExclusiveOperation(unsigned Size, AtomicOrdering Ord,
+ unsigned &LdrOpc,
+ unsigned &StrOpc) {
+ static unsigned LoadBares[] = {AArch64::LDXR_byte, AArch64::LDXR_hword,
+ AArch64::LDXR_word, AArch64::LDXR_dword};
+ static unsigned LoadAcqs[] = {AArch64::LDAXR_byte, AArch64::LDAXR_hword,
+ AArch64::LDAXR_word, AArch64::LDAXR_dword};
+ static unsigned StoreBares[] = {AArch64::STXR_byte, AArch64::STXR_hword,
+ AArch64::STXR_word, AArch64::STXR_dword};
+ static unsigned StoreRels[] = {AArch64::STLXR_byte, AArch64::STLXR_hword,
+ AArch64::STLXR_word, AArch64::STLXR_dword};
+
+ unsigned *LoadOps, *StoreOps;
+ if (Ord == Acquire || Ord == AcquireRelease || Ord == SequentiallyConsistent)
+ LoadOps = LoadAcqs;
+ else
+ LoadOps = LoadBares;
+
+ if (Ord == Release || Ord == AcquireRelease || Ord == SequentiallyConsistent)
+ StoreOps = StoreRels;
+ else
+ StoreOps = StoreBares;
+
+ assert(isPowerOf2_32(Size) && Size <= 8 &&
+ "unsupported size for atomic binary op!");
+
+ LdrOpc = LoadOps[Log2_32(Size)];
+ StrOpc = StoreOps[Log2_32(Size)];
}
MachineBasicBlock *
@@ -313,12 +313,13 @@ AArch64TargetLowering::emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
unsigned dest = MI->getOperand(0).getReg();
unsigned ptr = MI->getOperand(1).getReg();
unsigned incr = MI->getOperand(2).getReg();
+ AtomicOrdering Ord = static_cast<AtomicOrdering>(MI->getOperand(3).getImm());
DebugLoc dl = MI->getDebugLoc();
MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();
unsigned ldrOpc, strOpc;
- getExclusiveOperation(Size, ldrOpc, strOpc);
+ getExclusiveOperation(Size, Ord, ldrOpc, strOpc);
MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
@@ -397,6 +398,8 @@ AArch64TargetLowering::emitAtomicBinaryMinMax(MachineInstr *MI,
unsigned dest = MI->getOperand(0).getReg();
unsigned ptr = MI->getOperand(1).getReg();
unsigned incr = MI->getOperand(2).getReg();
+ AtomicOrdering Ord = static_cast<AtomicOrdering>(MI->getOperand(3).getImm());
+
unsigned oldval = dest;
DebugLoc dl = MI->getDebugLoc();
@@ -411,7 +414,7 @@ AArch64TargetLowering::emitAtomicBinaryMinMax(MachineInstr *MI,
}
unsigned ldrOpc, strOpc;
- getExclusiveOperation(Size, ldrOpc, strOpc);
+ getExclusiveOperation(Size, Ord, ldrOpc, strOpc);
MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
@@ -479,6 +482,7 @@ AArch64TargetLowering::emitAtomicCmpSwap(MachineInstr *MI,
unsigned ptr = MI->getOperand(1).getReg();
unsigned oldval = MI->getOperand(2).getReg();
unsigned newval = MI->getOperand(3).getReg();
+ AtomicOrdering Ord = static_cast<AtomicOrdering>(MI->getOperand(4).getImm());
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
DebugLoc dl = MI->getDebugLoc();
@@ -487,7 +491,7 @@ AArch64TargetLowering::emitAtomicCmpSwap(MachineInstr *MI,
TRCsp = Size == 8 ? &AArch64::GPR64xspRegClass : &AArch64::GPR32wspRegClass;
unsigned ldrOpc, strOpc;
- getExclusiveOperation(Size, ldrOpc, strOpc);
+ getExclusiveOperation(Size, Ord, ldrOpc, strOpc);
MachineFunction *MF = BB->getParent();
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -2377,78 +2381,6 @@ static SDValue PerformANDCombine(SDNode *N,
DAG.getConstant(LSB + Width - 1, MVT::i64));
}
-static SDValue PerformATOMIC_FENCECombine(SDNode *FenceNode,
- TargetLowering::DAGCombinerInfo &DCI) {
- // An atomic operation followed by an acquiring atomic fence can be reduced to
- // an acquiring load. The atomic operation provides a convenient pointer to
- // load from. If the original operation was a load anyway we can actually
- // combine the two operations into an acquiring load.
- SelectionDAG &DAG = DCI.DAG;
- SDValue AtomicOp = FenceNode->getOperand(0);
- AtomicSDNode *AtomicNode = dyn_cast<AtomicSDNode>(AtomicOp);
-
- // A fence on its own can't be optimised
- if (!AtomicNode)
- return SDValue();
-
- AtomicOrdering FenceOrder
- = static_cast<AtomicOrdering>(FenceNode->getConstantOperandVal(1));
- SynchronizationScope FenceScope
- = static_cast<SynchronizationScope>(FenceNode->getConstantOperandVal(2));
-
- if (FenceOrder != Acquire || FenceScope != AtomicNode->getSynchScope())
- return SDValue();
-
- // If the original operation was an ATOMIC_LOAD then we'll be replacing it, so
- // the chain we use should be its input, otherwise we'll put our store after
- // it so we use its output chain.
- SDValue Chain = AtomicNode->getOpcode() == ISD::ATOMIC_LOAD ?
- AtomicNode->getChain() : AtomicOp;
-
- // We have an acquire fence with a handy atomic operation nearby, we can
- // convert the fence into a load-acquire, discarding the result.
- DebugLoc DL = FenceNode->getDebugLoc();
- SDValue Op = DAG.getAtomic(ISD::ATOMIC_LOAD, DL, AtomicNode->getMemoryVT(),
- AtomicNode->getValueType(0),
- Chain, // Chain
- AtomicOp.getOperand(1), // Pointer
- AtomicNode->getMemOperand(), Acquire,
- FenceScope);
-
- if (AtomicNode->getOpcode() == ISD::ATOMIC_LOAD)
- DAG.ReplaceAllUsesWith(AtomicNode, Op.getNode());
-
- return Op.getValue(1);
-}
-
-static SDValue PerformATOMIC_STORECombine(SDNode *N,
- TargetLowering::DAGCombinerInfo &DCI) {
- // A releasing atomic fence followed by an atomic store can be combined into a
- // single store operation.
- SelectionDAG &DAG = DCI.DAG;
- AtomicSDNode *AtomicNode = cast<AtomicSDNode>(N);
- SDValue FenceOp = AtomicNode->getOperand(0);
-
- if (FenceOp.getOpcode() != ISD::ATOMIC_FENCE)
- return SDValue();
-
- AtomicOrdering FenceOrder
- = static_cast<AtomicOrdering>(FenceOp->getConstantOperandVal(1));
- SynchronizationScope FenceScope
- = static_cast<SynchronizationScope>(FenceOp->getConstantOperandVal(2));
-
- if (FenceOrder != Release || FenceScope != AtomicNode->getSynchScope())
- return SDValue();
-
- DebugLoc DL = AtomicNode->getDebugLoc();
- return DAG.getAtomic(ISD::ATOMIC_STORE, DL, AtomicNode->getMemoryVT(),
- FenceOp.getOperand(0), // Chain
- AtomicNode->getOperand(1), // Pointer
- AtomicNode->getOperand(2), // Value
- AtomicNode->getMemOperand(), Release,
- FenceScope);
-}
-
/// For a true bitfield insert, the bits getting into that contiguous mask
/// should come from the low part of an existing value: they must be formed from
/// a compatible SHL operation (unless they're already low). This function
@@ -2804,8 +2736,6 @@ AArch64TargetLowering::PerformDAGCombine(SDNode *N,
switch (N->getOpcode()) {
default: break;
case ISD::AND: return PerformANDCombine(N, DCI);
- case ISD::ATOMIC_FENCE: return PerformATOMIC_FENCECombine(N, DCI);
- case ISD::ATOMIC_STORE: return PerformATOMIC_STORECombine(N, DCI);
case ISD::OR: return PerformORCombine(N, DCI, Subtarget);
case ISD::SRA: return PerformSRACombine(N, DCI);
}
diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td
index cb93471..9dd122f 100644
--- a/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/lib/Target/AArch64/AArch64InstrFormats.td
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// This file describes AArch64 instruction formats, down to the level of the
// instruction's overall class.
-// ===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/AArch64/AArch64InstrInfo.cpp b/lib/Target/AArch64/AArch64InstrInfo.cpp
index 7b93463..cf3a2c3 100644
--- a/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -618,11 +618,11 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB,
int64_t NumBytes, MachineInstr::MIFlag MIFlags) {
if (NumBytes == 0 && DstReg == SrcReg)
return;
- else if (abs(NumBytes) & ~0xffffff) {
+ else if (abs64(NumBytes) & ~0xffffff) {
// Generically, we have to materialize the offset into a temporary register
// and subtract it. There are a couple of ways this could be done, for now
// we'll use a movz/movk or movn/movk sequence.
- uint64_t Bits = static_cast<uint64_t>(abs(NumBytes));
+ uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes));
BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
.addImm(0xffff & Bits).addImm(0)
.setMIFlags(MIFlags);
@@ -673,7 +673,7 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB,
} else {
LowOp = AArch64::SUBxxi_lsl0_s;
HighOp = AArch64::SUBxxi_lsl12_s;
- NumBytes = abs(NumBytes);
+ NumBytes = abs64(NumBytes);
}
// If we're here, at the very least a move needs to be produced, which just
diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td
index 319ec97..e3b39ce 100644
--- a/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/lib/Target/AArch64/AArch64InstrInfo.td
@@ -159,53 +159,55 @@ let Defs = [XSP], Uses = [XSP] in {
// Atomic operation pseudo-instructions
//===----------------------------------------------------------------------===//
-let usesCustomInserter = 1 in {
-multiclass AtomicSizes<string opname> {
- def _I8 : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$incr),
- [(set GPR32:$dst, (!cast<SDNode>(opname # "_8") GPR64:$ptr, GPR32:$incr))]>;
- def _I16 : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$incr),
- [(set GPR32:$dst, (!cast<SDNode>(opname # "_16") GPR64:$ptr, GPR32:$incr))]>;
- def _I32 : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$incr),
- [(set GPR32:$dst, (!cast<SDNode>(opname # "_32") GPR64:$ptr, GPR32:$incr))]>;
- def _I64 : PseudoInst<(outs GPR64:$dst), (ins GPR64:$ptr, GPR64:$incr),
- [(set GPR64:$dst, (!cast<SDNode>(opname # "_64") GPR64:$ptr, GPR64:$incr))]>;
-}
-}
-
-defm ATOMIC_LOAD_ADD : AtomicSizes<"atomic_load_add">;
-defm ATOMIC_LOAD_SUB : AtomicSizes<"atomic_load_sub">;
-defm ATOMIC_LOAD_AND : AtomicSizes<"atomic_load_and">;
-defm ATOMIC_LOAD_OR : AtomicSizes<"atomic_load_or">;
-defm ATOMIC_LOAD_XOR : AtomicSizes<"atomic_load_xor">;
-defm ATOMIC_LOAD_NAND : AtomicSizes<"atomic_load_nand">;
-defm ATOMIC_SWAP : AtomicSizes<"atomic_swap">;
+// These get selected from C++ code as a pretty much direct translation from the
+// generic DAG nodes. The one exception is the AtomicOrdering is added as an
+// operand so that the eventual lowering can make use of it and choose
+// acquire/release operations when required.
+
+let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1 in {
+multiclass AtomicSizes {
+ def _I8 : PseudoInst<(outs GPR32:$dst),
+ (ins GPR64xsp:$ptr, GPR32:$incr, i32imm:$ordering), []>;
+ def _I16 : PseudoInst<(outs GPR32:$dst),
+ (ins GPR64xsp:$ptr, GPR32:$incr, i32imm:$ordering), []>;
+ def _I32 : PseudoInst<(outs GPR32:$dst),
+ (ins GPR64xsp:$ptr, GPR32:$incr, i32imm:$ordering), []>;
+ def _I64 : PseudoInst<(outs GPR64:$dst),
+ (ins GPR64xsp:$ptr, GPR64:$incr, i32imm:$ordering), []>;
+}
+}
+
+defm ATOMIC_LOAD_ADD : AtomicSizes;
+defm ATOMIC_LOAD_SUB : AtomicSizes;
+defm ATOMIC_LOAD_AND : AtomicSizes;
+defm ATOMIC_LOAD_OR : AtomicSizes;
+defm ATOMIC_LOAD_XOR : AtomicSizes;
+defm ATOMIC_LOAD_NAND : AtomicSizes;
+defm ATOMIC_SWAP : AtomicSizes;
let Defs = [NZCV] in {
// These operations need a CMP to calculate the correct value
- defm ATOMIC_LOAD_MIN : AtomicSizes<"atomic_load_min">;
- defm ATOMIC_LOAD_MAX : AtomicSizes<"atomic_load_max">;
- defm ATOMIC_LOAD_UMIN : AtomicSizes<"atomic_load_umin">;
- defm ATOMIC_LOAD_UMAX : AtomicSizes<"atomic_load_umax">;
-}
-
-let usesCustomInserter = 1, Defs = [NZCV] in {
-def ATOMIC_CMP_SWAP_I8
- : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$old, GPR32:$new),
- [(set GPR32:$dst,
- (atomic_cmp_swap_8 GPR64:$ptr, GPR32:$old, GPR32:$new))]>;
-def ATOMIC_CMP_SWAP_I16
- : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$old, GPR32:$new),
- [(set GPR32:$dst,
- (atomic_cmp_swap_16 GPR64:$ptr, GPR32:$old, GPR32:$new))]>;
-def ATOMIC_CMP_SWAP_I32
- : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$old, GPR32:$new),
- [(set GPR32:$dst,
- (atomic_cmp_swap_32 GPR64:$ptr, GPR32:$old, GPR32:$new))]>;
-def ATOMIC_CMP_SWAP_I64
- : PseudoInst<(outs GPR64:$dst), (ins GPR64:$ptr, GPR64:$old, GPR64:$new),
- [(set GPR64:$dst,
- (atomic_cmp_swap_64 GPR64:$ptr, GPR64:$old, GPR64:$new))]>;
+ defm ATOMIC_LOAD_MIN : AtomicSizes;
+ defm ATOMIC_LOAD_MAX : AtomicSizes;
+ defm ATOMIC_LOAD_UMIN : AtomicSizes;
+ defm ATOMIC_LOAD_UMAX : AtomicSizes;
}
+class AtomicCmpSwap<RegisterClass GPRData>
+ : PseudoInst<(outs GPRData:$dst),
+ (ins GPR64xsp:$ptr, GPRData:$old, GPRData:$new,
+ i32imm:$ordering), []> {
+ let usesCustomInserter = 1;
+ let hasCtrlDep = 1;
+ let mayLoad = 1;
+ let mayStore = 1;
+ let Defs = [NZCV];
+}
+
+def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<GPR32>;
+def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<GPR32>;
+def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<GPR32>;
+def ATOMIC_CMP_SWAP_I64 : AtomicCmpSwap<GPR64>;
+
//===----------------------------------------------------------------------===//
// Add-subtract (extended register) instructions
//===----------------------------------------------------------------------===//
@@ -264,31 +266,39 @@ def LSL_extoperand : Operand<i64> {
class extend_types {
dag uxtb; dag uxth; dag uxtw; dag uxtx;
dag sxtb; dag sxth; dag sxtw; dag sxtx;
+ ValueType ty;
+ RegisterClass GPR;
}
def extends_to_i64 : extend_types {
- let uxtb = (and (anyext GPR32:$Rm), 255);
- let uxth = (and (anyext GPR32:$Rm), 65535);
- let uxtw = (zext GPR32:$Rm);
- let uxtx = (i64 GPR64:$Rm);
+ let uxtb = (and (anyext i32:$Rm), 255);
+ let uxth = (and (anyext i32:$Rm), 65535);
+ let uxtw = (zext i32:$Rm);
+ let uxtx = (i64 $Rm);
+
+ let sxtb = (sext_inreg (anyext i32:$Rm), i8);
+ let sxth = (sext_inreg (anyext i32:$Rm), i16);
+ let sxtw = (sext i32:$Rm);
+ let sxtx = (i64 $Rm);
- let sxtb = (sext_inreg (anyext GPR32:$Rm), i8);
- let sxth = (sext_inreg (anyext GPR32:$Rm), i16);
- let sxtw = (sext GPR32:$Rm);
- let sxtx = (i64 GPR64:$Rm);
+ let ty = i64;
+ let GPR = GPR64xsp;
}
def extends_to_i32 : extend_types {
- let uxtb = (and GPR32:$Rm, 255);
- let uxth = (and GPR32:$Rm, 65535);
- let uxtw = (i32 GPR32:$Rm);
- let uxtx = (i32 GPR32:$Rm);
+ let uxtb = (and i32:$Rm, 255);
+ let uxth = (and i32:$Rm, 65535);
+ let uxtw = (i32 i32:$Rm);
+ let uxtx = (i32 i32:$Rm);
+
+ let sxtb = (sext_inreg i32:$Rm, i8);
+ let sxth = (sext_inreg i32:$Rm, i16);
+ let sxtw = (i32 i32:$Rm);
+ let sxtx = (i32 i32:$Rm);
- let sxtb = (sext_inreg GPR32:$Rm, i8);
- let sxth = (sext_inreg GPR32:$Rm, i16);
- let sxtw = (i32 GPR32:$Rm);
- let sxtx = (i32 GPR32:$Rm);
+ let ty = i32;
+ let GPR = GPR32wsp;
}
// Now, six of the extensions supported are easy and uniform: if the source size
@@ -303,44 +313,38 @@ def extends_to_i32 : extend_types {
// would probably be the best option).
multiclass addsub_exts<bit sf, bit op, bit S, string asmop,
SDPatternOperator opfrag,
- dag outs, extend_types exts, RegisterClass GPRsp> {
+ dag outs, extend_types exts> {
def w_uxtb : A64I_addsubext<sf, op, S, 0b00, 0b000,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, UXTB_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.uxtb, UXTB_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, UXTB_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.uxtb, UXTB_operand:$Imm3))],
+ NoItinerary>;
def w_uxth : A64I_addsubext<sf, op, S, 0b00, 0b001,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, UXTH_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.uxth, UXTH_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, UXTH_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.uxth, UXTH_operand:$Imm3))],
+ NoItinerary>;
def w_uxtw : A64I_addsubext<sf, op, S, 0b00, 0b010,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, UXTW_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.uxtw, UXTW_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, UXTW_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.uxtw, UXTW_operand:$Imm3))],
+ NoItinerary>;
def w_sxtb : A64I_addsubext<sf, op, S, 0b00, 0b100,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, SXTB_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.sxtb, SXTB_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, SXTB_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.sxtb, SXTB_operand:$Imm3))],
+ NoItinerary>;
def w_sxth : A64I_addsubext<sf, op, S, 0b00, 0b101,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, SXTH_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.sxth, SXTH_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, SXTH_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.sxth, SXTH_operand:$Imm3))],
+ NoItinerary>;
def w_sxtw : A64I_addsubext<sf, op, S, 0b00, 0b110,
- outs,
- (ins GPRsp:$Rn, GPR32:$Rm, SXTW_operand:$Imm3),
- !strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPRsp:$Rn, (shl exts.sxtw, SXTW_operand:$Imm3))],
- NoItinerary>;
+ outs, (ins exts.GPR:$Rn, GPR32:$Rm, SXTW_operand:$Imm3),
+ !strconcat(asmop, "$Rn, $Rm, $Imm3"),
+ [(opfrag exts.ty:$Rn, (shl exts.sxtw, SXTW_operand:$Imm3))],
+ NoItinerary>;
}
// These two could be merge in with the above, but their patterns aren't really
@@ -351,7 +355,7 @@ multiclass addsub_xxtx<bit op, bit S, string asmop, SDPatternOperator opfrag,
outs,
(ins GPR64xsp:$Rn, GPR64:$Rm, UXTX_operand:$Imm3),
!strconcat(asmop, "$Rn, $Rm, $Imm3"),
- [(opfrag GPR64xsp:$Rn, (shl GPR64:$Rm, UXTX_operand:$Imm3))],
+ [(opfrag i64:$Rn, (shl i64:$Rm, UXTX_operand:$Imm3))],
NoItinerary>;
def x_sxtx : A64I_addsubext<0b1, op, S, 0b00, 0b111,
@@ -384,53 +388,53 @@ class SetNZCV<SDPatternOperator op>
: PatFrag<(ops node:$lhs, node:$rhs), (set NZCV, (op node:$lhs, node:$rhs))>;
defm ADDxx :addsub_exts<0b1, 0b0, 0b0, "add\t$Rd, ", SetRD<GPR64xsp, add>,
- (outs GPR64xsp:$Rd), extends_to_i64, GPR64xsp>,
+ (outs GPR64xsp:$Rd), extends_to_i64>,
addsub_xxtx< 0b0, 0b0, "add\t$Rd, ", SetRD<GPR64xsp, add>,
(outs GPR64xsp:$Rd)>;
defm ADDww :addsub_exts<0b0, 0b0, 0b0, "add\t$Rd, ", SetRD<GPR32wsp, add>,
- (outs GPR32wsp:$Rd), extends_to_i32, GPR32wsp>,
+ (outs GPR32wsp:$Rd), extends_to_i32>,
addsub_wxtx< 0b0, 0b0, "add\t$Rd, ",
(outs GPR32wsp:$Rd)>;
defm SUBxx :addsub_exts<0b1, 0b1, 0b0, "sub\t$Rd, ", SetRD<GPR64xsp, sub>,
- (outs GPR64xsp:$Rd), extends_to_i64, GPR64xsp>,
+ (outs GPR64xsp:$Rd), extends_to_i64>,
addsub_xxtx< 0b1, 0b0, "sub\t$Rd, ", SetRD<GPR64xsp, sub>,
(outs GPR64xsp:$Rd)>;
defm SUBww :addsub_exts<0b0, 0b1, 0b0, "sub\t$Rd, ", SetRD<GPR32wsp, sub>,
- (outs GPR32wsp:$Rd), extends_to_i32, GPR32wsp>,
+ (outs GPR32wsp:$Rd), extends_to_i32>,
addsub_wxtx< 0b1, 0b0, "sub\t$Rd, ",
(outs GPR32wsp:$Rd)>;
let Defs = [NZCV] in {
defm ADDSxx :addsub_exts<0b1, 0b0, 0b1, "adds\t$Rd, ", SetRD<GPR64, addc>,
- (outs GPR64:$Rd), extends_to_i64, GPR64xsp>,
+ (outs GPR64:$Rd), extends_to_i64>,
addsub_xxtx< 0b0, 0b1, "adds\t$Rd, ", SetRD<GPR64, addc>,
(outs GPR64:$Rd)>;
defm ADDSww :addsub_exts<0b0, 0b0, 0b1, "adds\t$Rd, ", SetRD<GPR32, addc>,
- (outs GPR32:$Rd), extends_to_i32, GPR32wsp>,
+ (outs GPR32:$Rd), extends_to_i32>,
addsub_wxtx< 0b0, 0b1, "adds\t$Rd, ",
(outs GPR32:$Rd)>;
defm SUBSxx :addsub_exts<0b1, 0b1, 0b1, "subs\t$Rd, ", SetRD<GPR64, subc>,
- (outs GPR64:$Rd), extends_to_i64, GPR64xsp>,
+ (outs GPR64:$Rd), extends_to_i64>,
addsub_xxtx< 0b1, 0b1, "subs\t$Rd, ", SetRD<GPR64, subc>,
(outs GPR64:$Rd)>;
defm SUBSww :addsub_exts<0b0, 0b1, 0b1, "subs\t$Rd, ", SetRD<GPR32, subc>,
- (outs GPR32:$Rd), extends_to_i32, GPR32wsp>,
+ (outs GPR32:$Rd), extends_to_i32>,
addsub_wxtx< 0b1, 0b1, "subs\t$Rd, ",
(outs GPR32:$Rd)>;
let Rd = 0b11111, isCompare = 1 in {
defm CMNx : addsub_exts<0b1, 0b0, 0b1, "cmn\t", SetNZCV<A64cmn>,
- (outs), extends_to_i64, GPR64xsp>,
+ (outs), extends_to_i64>,
addsub_xxtx< 0b0, 0b1, "cmn\t", SetNZCV<A64cmn>, (outs)>;
defm CMNw : addsub_exts<0b0, 0b0, 0b1, "cmn\t", SetNZCV<A64cmn>,
- (outs), extends_to_i32, GPR32wsp>,
+ (outs), extends_to_i32>,
addsub_wxtx< 0b0, 0b1, "cmn\t", (outs)>;
defm CMPx : addsub_exts<0b1, 0b1, 0b1, "cmp\t", SetNZCV<A64cmp>,
- (outs), extends_to_i64, GPR64xsp>,
+ (outs), extends_to_i64>,
addsub_xxtx< 0b1, 0b1, "cmp\t", SetNZCV<A64cmp>, (outs)>;
defm CMPw : addsub_exts<0b0, 0b1, 0b1, "cmp\t", SetNZCV<A64cmp>,
- (outs), extends_to_i32, GPR32wsp>,
+ (outs), extends_to_i32>,
addsub_wxtx< 0b1, 0b1, "cmp\t", (outs)>;
}
}
@@ -439,31 +443,31 @@ defm CMPw : addsub_exts<0b0, 0b1, 0b1, "cmp\t", SetNZCV<A64cmp>,
// created for uxtx/sxtx since they're non-uniform and it's expected that
// add/sub (shifted register) will handle those cases anyway.
multiclass addsubext_noshift_patterns<string prefix, SDPatternOperator nodeop,
- RegisterClass GPRsp, extend_types exts> {
- def : Pat<(nodeop GPRsp:$Rn, exts.uxtb),
- (!cast<Instruction>(prefix # "w_uxtb") GPRsp:$Rn, GPR32:$Rm, 0)>;
- def : Pat<(nodeop GPRsp:$Rn, exts.uxth),
- (!cast<Instruction>(prefix # "w_uxth") GPRsp:$Rn, GPR32:$Rm, 0)>;
- def : Pat<(nodeop GPRsp:$Rn, exts.uxtw),
- (!cast<Instruction>(prefix # "w_uxtw") GPRsp:$Rn, GPR32:$Rm, 0)>;
-
- def : Pat<(nodeop GPRsp:$Rn, exts.sxtb),
- (!cast<Instruction>(prefix # "w_sxtb") GPRsp:$Rn, GPR32:$Rm, 0)>;
- def : Pat<(nodeop GPRsp:$Rn, exts.sxth),
- (!cast<Instruction>(prefix # "w_sxth") GPRsp:$Rn, GPR32:$Rm, 0)>;
- def : Pat<(nodeop GPRsp:$Rn, exts.sxtw),
- (!cast<Instruction>(prefix # "w_sxtw") GPRsp:$Rn, GPR32:$Rm, 0)>;
-}
-
-defm : addsubext_noshift_patterns<"ADDxx", add, GPR64xsp, extends_to_i64>;
-defm : addsubext_noshift_patterns<"ADDww", add, GPR32wsp, extends_to_i32>;
-defm : addsubext_noshift_patterns<"SUBxx", sub, GPR64xsp, extends_to_i64>;
-defm : addsubext_noshift_patterns<"SUBww", sub, GPR32wsp, extends_to_i32>;
-
-defm : addsubext_noshift_patterns<"CMNx", A64cmn, GPR64xsp, extends_to_i64>;
-defm : addsubext_noshift_patterns<"CMNw", A64cmn, GPR32wsp, extends_to_i32>;
-defm : addsubext_noshift_patterns<"CMPx", A64cmp, GPR64xsp, extends_to_i64>;
-defm : addsubext_noshift_patterns<"CMPw", A64cmp, GPR32wsp, extends_to_i32>;
+ extend_types exts> {
+ def : Pat<(nodeop exts.ty:$Rn, exts.uxtb),
+ (!cast<Instruction>(prefix # "w_uxtb") $Rn, $Rm, 0)>;
+ def : Pat<(nodeop exts.ty:$Rn, exts.uxth),
+ (!cast<Instruction>(prefix # "w_uxth") $Rn, $Rm, 0)>;
+ def : Pat<(nodeop exts.ty:$Rn, exts.uxtw),
+ (!cast<Instruction>(prefix # "w_uxtw") $Rn, $Rm, 0)>;
+
+ def : Pat<(nodeop exts.ty:$Rn, exts.sxtb),
+ (!cast<Instruction>(prefix # "w_sxtb") $Rn, $Rm, 0)>;
+ def : Pat<(nodeop exts.ty:$Rn, exts.sxth),
+ (!cast<Instruction>(prefix # "w_sxth") $Rn, $Rm, 0)>;
+ def : Pat<(nodeop exts.ty:$Rn, exts.sxtw),
+ (!cast<Instruction>(prefix # "w_sxtw") $Rn, $Rm, 0)>;
+}
+
+defm : addsubext_noshift_patterns<"ADDxx", add, extends_to_i64>;
+defm : addsubext_noshift_patterns<"ADDww", add, extends_to_i32>;
+defm : addsubext_noshift_patterns<"SUBxx", sub, extends_to_i64>;
+defm : addsubext_noshift_patterns<"SUBww", sub, extends_to_i32>;
+
+defm : addsubext_noshift_patterns<"CMNx", A64cmn, extends_to_i64>;
+defm : addsubext_noshift_patterns<"CMNw", A64cmn, extends_to_i32>;
+defm : addsubext_noshift_patterns<"CMPx", A64cmp, extends_to_i64>;
+defm : addsubext_noshift_patterns<"CMPw", A64cmp, extends_to_i32>;
// An extend of "lsl #imm" is valid if and only if one of Rn and Rd is
// sp/wsp. It is synonymous with uxtx/uxtw depending on the size of the
@@ -614,14 +618,13 @@ multiclass addsubimm_varieties<string prefix, bit sf, bit op, bits<2> shift,
string asmop, string cmpasmop,
Operand imm_operand, Operand cmp_imm_operand,
RegisterClass GPR, RegisterClass GPRsp,
- AArch64Reg ZR> {
+ AArch64Reg ZR, ValueType Ty> {
// All registers for non-S variants allow SP
def _s : A64I_addsubimm<sf, op, 0b0, shift,
(outs GPRsp:$Rd),
(ins GPRsp:$Rn, imm_operand:$Imm12),
!strconcat(asmop, "\t$Rd, $Rn, $Imm12"),
- [(set GPRsp:$Rd,
- (add GPRsp:$Rn, imm_operand:$Imm12))],
+ [(set Ty:$Rd, (add Ty:$Rn, imm_operand:$Imm12))],
NoItinerary>;
@@ -630,7 +633,7 @@ multiclass addsubimm_varieties<string prefix, bit sf, bit op, bits<2> shift,
(outs GPR:$Rd),
(ins GPRsp:$Rn, imm_operand:$Imm12),
!strconcat(asmop, "s\t$Rd, $Rn, $Imm12"),
- [(set GPR:$Rd, (addc GPRsp:$Rn, imm_operand:$Imm12))],
+ [(set Ty:$Rd, (addc Ty:$Rn, imm_operand:$Imm12))],
NoItinerary> {
let Defs = [NZCV];
}
@@ -642,7 +645,7 @@ multiclass addsubimm_varieties<string prefix, bit sf, bit op, bits<2> shift,
(outs), (ins GPRsp:$Rn, imm_operand:$Imm12),
!strconcat(cmpasmop, " $Rn, $Imm12"),
[(set NZCV,
- (A64cmp GPRsp:$Rn, cmp_imm_operand:$Imm12))],
+ (A64cmp Ty:$Rn, cmp_imm_operand:$Imm12))],
NoItinerary> {
let Rd = 0b11111;
let Defs = [NZCV];
@@ -653,36 +656,37 @@ multiclass addsubimm_varieties<string prefix, bit sf, bit op, bits<2> shift,
multiclass addsubimm_shifts<string prefix, bit sf, bit op,
string asmop, string cmpasmop, string operand, string cmpoperand,
- RegisterClass GPR, RegisterClass GPRsp, AArch64Reg ZR> {
+ RegisterClass GPR, RegisterClass GPRsp, AArch64Reg ZR,
+ ValueType Ty> {
defm _lsl0 : addsubimm_varieties<prefix # "_lsl0", sf, op, 0b00,
asmop, cmpasmop,
!cast<Operand>(operand # "_lsl0"),
!cast<Operand>(cmpoperand # "_lsl0"),
- GPR, GPRsp, ZR>;
+ GPR, GPRsp, ZR, Ty>;
defm _lsl12 : addsubimm_varieties<prefix # "_lsl12", sf, op, 0b01,
asmop, cmpasmop,
!cast<Operand>(operand # "_lsl12"),
!cast<Operand>(cmpoperand # "_lsl12"),
- GPR, GPRsp, ZR>;
+ GPR, GPRsp, ZR, Ty>;
}
defm ADDwwi : addsubimm_shifts<"ADDwi", 0b0, 0b0, "add", "cmn",
"addsubimm_operand_i32_posimm",
"addsubimm_operand_i32_negimm",
- GPR32, GPR32wsp, WZR>;
+ GPR32, GPR32wsp, WZR, i32>;
defm ADDxxi : addsubimm_shifts<"ADDxi", 0b1, 0b0, "add", "cmn",
"addsubimm_operand_i64_posimm",
"addsubimm_operand_i64_negimm",
- GPR64, GPR64xsp, XZR>;
+ GPR64, GPR64xsp, XZR, i64>;
defm SUBwwi : addsubimm_shifts<"SUBwi", 0b0, 0b1, "sub", "cmp",
"addsubimm_operand_i32_negimm",
"addsubimm_operand_i32_posimm",
- GPR32, GPR32wsp, WZR>;
+ GPR32, GPR32wsp, WZR, i32>;
defm SUBxxi : addsubimm_shifts<"SUBxi", 0b1, 0b1, "sub", "cmp",
"addsubimm_operand_i64_negimm",
"addsubimm_operand_i64_posimm",
- GPR64, GPR64xsp, XZR>;
+ GPR64, GPR64xsp, XZR, i64>;
multiclass MOVsp<RegisterClass GPRsp, RegisterClass SP, Instruction addop> {
def _fromsp : InstAlias<"mov $Rd, $Rn",
@@ -753,36 +757,36 @@ defm ror_operand : shift_operands<"ror_operand", "ROR">;
// N.b. the commutable parameter is just !N. It will be first against the wall
// when the revolution comes.
multiclass addsub_shifts<string prefix, bit sf, bit op, bit s, bit commutable,
- string asmop, SDPatternOperator opfrag, string sty,
+ string asmop, SDPatternOperator opfrag, ValueType ty,
RegisterClass GPR, list<Register> defs> {
let isCommutable = commutable, Defs = defs in {
def _lsl : A64I_addsubshift<sf, op, s, 0b00,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6),
+ !cast<Operand>("lsl_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (shl GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6))
+ [(set GPR:$Rd, (opfrag ty:$Rn, (shl ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _lsr : A64I_addsubshift<sf, op, s, 0b01,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6),
+ !cast<Operand>("lsr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (srl GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (srl ty:$Rm,
+ !cast<Operand>("lsr_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _asr : A64I_addsubshift<sf, op, s, 0b10,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6),
+ !cast<Operand>("asr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (sra GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (sra ty:$Rm,
+ !cast<Operand>("asr_operand_" # ty):$Imm6))
)],
NoItinerary>;
}
@@ -792,17 +796,17 @@ multiclass addsub_shifts<string prefix, bit sf, bit op, bit s, bit commutable,
(!cast<Instruction>(prefix # "_lsl") GPR:$Rd, GPR:$Rn,
GPR:$Rm, 0)>;
- def : Pat<(opfrag GPR:$Rn, GPR:$Rm),
- (!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
+ def : Pat<(opfrag ty:$Rn, ty:$Rm),
+ (!cast<Instruction>(prefix # "_lsl") $Rn, $Rm, 0)>;
}
multiclass addsub_sizes<string prefix, bit op, bit s, bit commutable,
string asmop, SDPatternOperator opfrag,
list<Register> defs> {
defm xxx : addsub_shifts<prefix # "xxx", 0b1, op, s,
- commutable, asmop, opfrag, "i64", GPR64, defs>;
+ commutable, asmop, opfrag, i64, GPR64, defs>;
defm www : addsub_shifts<prefix # "www", 0b0, op, s,
- commutable, asmop, opfrag, "i32", GPR32, defs>;
+ commutable, asmop, opfrag, i32, GPR32, defs>;
}
@@ -816,26 +820,26 @@ defm SUBS : addsub_sizes<"SUBS", 0b1, 0b1, 0b0, "subs", subc, [NZCV]>;
// 1. The NEG/NEGS aliases
//===-------------------------------
-multiclass neg_alias<Instruction INST, RegisterClass GPR,
- Register ZR, Operand shift_operand, SDNode shiftop> {
+multiclass neg_alias<Instruction INST, RegisterClass GPR, Register ZR,
+ ValueType ty, Operand shift_operand, SDNode shiftop> {
def : InstAlias<"neg $Rd, $Rm, $Imm6",
(INST GPR:$Rd, ZR, GPR:$Rm, shift_operand:$Imm6)>;
- def : Pat<(sub 0, (shiftop GPR:$Rm, shift_operand:$Imm6)),
- (INST ZR, GPR:$Rm, shift_operand:$Imm6)>;
+ def : Pat<(sub 0, (shiftop ty:$Rm, shift_operand:$Imm6)),
+ (INST ZR, $Rm, shift_operand:$Imm6)>;
}
-defm : neg_alias<SUBwww_lsl, GPR32, WZR, lsl_operand_i32, shl>;
-defm : neg_alias<SUBwww_lsr, GPR32, WZR, lsr_operand_i32, srl>;
-defm : neg_alias<SUBwww_asr, GPR32, WZR, asr_operand_i32, sra>;
+defm : neg_alias<SUBwww_lsl, GPR32, WZR, i32, lsl_operand_i32, shl>;
+defm : neg_alias<SUBwww_lsr, GPR32, WZR, i32, lsr_operand_i32, srl>;
+defm : neg_alias<SUBwww_asr, GPR32, WZR, i32, asr_operand_i32, sra>;
def : InstAlias<"neg $Rd, $Rm", (SUBwww_lsl GPR32:$Rd, WZR, GPR32:$Rm, 0)>;
-def : Pat<(sub 0, GPR32:$Rm), (SUBwww_lsl WZR, GPR32:$Rm, 0)>;
+def : Pat<(sub 0, i32:$Rm), (SUBwww_lsl WZR, $Rm, 0)>;
-defm : neg_alias<SUBxxx_lsl, GPR64, XZR, lsl_operand_i64, shl>;
-defm : neg_alias<SUBxxx_lsr, GPR64, XZR, lsr_operand_i64, srl>;
-defm : neg_alias<SUBxxx_asr, GPR64, XZR, asr_operand_i64, sra>;
+defm : neg_alias<SUBxxx_lsl, GPR64, XZR, i64, lsl_operand_i64, shl>;
+defm : neg_alias<SUBxxx_lsr, GPR64, XZR, i64, lsr_operand_i64, srl>;
+defm : neg_alias<SUBxxx_asr, GPR64, XZR, i64, asr_operand_i64, sra>;
def : InstAlias<"neg $Rd, $Rm", (SUBxxx_lsl GPR64:$Rd, XZR, GPR64:$Rm, 0)>;
-def : Pat<(sub 0, GPR64:$Rm), (SUBxxx_lsl XZR, GPR64:$Rm, 0)>;
+def : Pat<(sub 0, i64:$Rm), (SUBxxx_lsl XZR, $Rm, 0)>;
// NEGS doesn't get any patterns yet: defining multiple outputs means C++ has to
// be involved.
@@ -859,36 +863,36 @@ def : InstAlias<"negs $Rd, $Rm", (SUBSxxx_lsl GPR64:$Rd, XZR, GPR64:$Rm, 0)>;
//===-------------------------------
multiclass cmp_shifts<string prefix, bit sf, bit op, bit commutable,
- string asmop, SDPatternOperator opfrag, string sty,
+ string asmop, SDPatternOperator opfrag, ValueType ty,
RegisterClass GPR> {
let isCommutable = commutable, Rd = 0b11111, Defs = [NZCV] in {
def _lsl : A64I_addsubshift<sf, op, 0b1, 0b00,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6),
+ !cast<Operand>("lsl_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rn, $Rm, $Imm6"),
- [(set NZCV, (opfrag GPR:$Rn, (shl GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6))
+ [(set NZCV, (opfrag ty:$Rn, (shl ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _lsr : A64I_addsubshift<sf, op, 0b1, 0b01,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6),
+ !cast<Operand>("lsr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rn, $Rm, $Imm6"),
- [(set NZCV, (opfrag GPR:$Rn, (srl GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6))
+ [(set NZCV, (opfrag ty:$Rn, (srl ty:$Rm,
+ !cast<Operand>("lsr_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _asr : A64I_addsubshift<sf, op, 0b1, 0b10,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6),
+ !cast<Operand>("asr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rn, $Rm, $Imm6"),
- [(set NZCV, (opfrag GPR:$Rn, (sra GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6))
+ [(set NZCV, (opfrag ty:$Rn, (sra ty:$Rm,
+ !cast<Operand>("asr_operand_" # ty):$Imm6))
)],
NoItinerary>;
}
@@ -897,15 +901,15 @@ multiclass cmp_shifts<string prefix, bit sf, bit op, bit commutable,
: InstAlias<!strconcat(asmop, " $Rn, $Rm"),
(!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
- def : Pat<(opfrag GPR:$Rn, GPR:$Rm),
- (!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
+ def : Pat<(opfrag ty:$Rn, ty:$Rm),
+ (!cast<Instruction>(prefix # "_lsl") $Rn, $Rm, 0)>;
}
-defm CMPww : cmp_shifts<"CMPww", 0b0, 0b1, 0b0, "cmp", A64cmp, "i32", GPR32>;
-defm CMPxx : cmp_shifts<"CMPxx", 0b1, 0b1, 0b0, "cmp", A64cmp, "i64", GPR64>;
+defm CMPww : cmp_shifts<"CMPww", 0b0, 0b1, 0b0, "cmp", A64cmp, i32, GPR32>;
+defm CMPxx : cmp_shifts<"CMPxx", 0b1, 0b1, 0b0, "cmp", A64cmp, i64, GPR64>;
-defm CMNww : cmp_shifts<"CMNww", 0b0, 0b0, 0b1, "cmn", A64cmn, "i32", GPR32>;
-defm CMNxx : cmp_shifts<"CMNxx", 0b1, 0b0, 0b1, "cmn", A64cmn, "i64", GPR64>;
+defm CMNww : cmp_shifts<"CMNww", 0b0, 0b0, 0b1, "cmn", A64cmn, i32, GPR32>;
+defm CMNxx : cmp_shifts<"CMNxx", 0b1, 0b0, 0b1, "cmn", A64cmn, i64, GPR64>;
//===----------------------------------------------------------------------===//
// Add-subtract (with carry) instructions
@@ -947,10 +951,10 @@ def : InstAlias<"ngcs $Rd, $Rm", (SBCSxxx GPR64:$Rd, XZR, GPR64:$Rm)>;
// Note that adde and sube can form a chain longer than two (e.g. for 256-bit
// addition). So the flag-setting instructions are appropriate.
-def : Pat<(adde GPR32:$Rn, GPR32:$Rm), (ADCSwww GPR32:$Rn, GPR32:$Rm)>;
-def : Pat<(adde GPR64:$Rn, GPR64:$Rm), (ADCSxxx GPR64:$Rn, GPR64:$Rm)>;
-def : Pat<(sube GPR32:$Rn, GPR32:$Rm), (SBCSwww GPR32:$Rn, GPR32:$Rm)>;
-def : Pat<(sube GPR64:$Rn, GPR64:$Rm), (SBCSxxx GPR64:$Rn, GPR64:$Rm)>;
+def : Pat<(adde i32:$Rn, i32:$Rm), (ADCSwww $Rn, $Rm)>;
+def : Pat<(adde i64:$Rn, i64:$Rm), (ADCSxxx $Rn, $Rm)>;
+def : Pat<(sube i32:$Rn, i32:$Rm), (SBCSwww $Rn, $Rm)>;
+def : Pat<(sube i64:$Rn, i64:$Rm), (SBCSxxx $Rn, $Rm)>;
//===----------------------------------------------------------------------===//
// Bitfield
@@ -1053,52 +1057,52 @@ def BFMxxii :
// Note that these instructions are strictly more specific than the
// BFM ones (in ImmR) so they can handle their own decoding.
-class A64I_bf_ext<bit sf, bits<2> opc, RegisterClass GPRDest, string asmop,
- bits<6> imms, dag pattern>
+class A64I_bf_ext<bit sf, bits<2> opc, RegisterClass GPRDest, ValueType dty,
+ string asmop, bits<6> imms, dag pattern>
: A64I_bitfield<sf, opc, sf,
(outs GPRDest:$Rd), (ins GPR32:$Rn),
!strconcat(asmop, "\t$Rd, $Rn"),
- [(set GPRDest:$Rd, pattern)], NoItinerary> {
+ [(set dty:$Rd, pattern)], NoItinerary> {
let ImmR = 0b000000;
let ImmS = imms;
}
// Signed extensions
-def SXTBxw : A64I_bf_ext<0b1, 0b00, GPR64, "sxtb", 7,
- (sext_inreg (anyext GPR32:$Rn), i8)>;
-def SXTBww : A64I_bf_ext<0b0, 0b00, GPR32, "sxtb", 7,
- (sext_inreg GPR32:$Rn, i8)>;
-def SXTHxw : A64I_bf_ext<0b1, 0b00, GPR64, "sxth", 15,
- (sext_inreg (anyext GPR32:$Rn), i16)>;
-def SXTHww : A64I_bf_ext<0b0, 0b00, GPR32, "sxth", 15,
- (sext_inreg GPR32:$Rn, i16)>;
-def SXTWxw : A64I_bf_ext<0b1, 0b00, GPR64, "sxtw", 31, (sext GPR32:$Rn)>;
+def SXTBxw : A64I_bf_ext<0b1, 0b00, GPR64, i64, "sxtb", 7,
+ (sext_inreg (anyext i32:$Rn), i8)>;
+def SXTBww : A64I_bf_ext<0b0, 0b00, GPR32, i32, "sxtb", 7,
+ (sext_inreg i32:$Rn, i8)>;
+def SXTHxw : A64I_bf_ext<0b1, 0b00, GPR64, i64, "sxth", 15,
+ (sext_inreg (anyext i32:$Rn), i16)>;
+def SXTHww : A64I_bf_ext<0b0, 0b00, GPR32, i32, "sxth", 15,
+ (sext_inreg i32:$Rn, i16)>;
+def SXTWxw : A64I_bf_ext<0b1, 0b00, GPR64, i64, "sxtw", 31, (sext i32:$Rn)>;
// Unsigned extensions
-def UXTBww : A64I_bf_ext<0b0, 0b10, GPR32, "uxtb", 7,
- (and GPR32:$Rn, 255)>;
-def UXTHww : A64I_bf_ext<0b0, 0b10, GPR32, "uxth", 15,
- (and GPR32:$Rn, 65535)>;
+def UXTBww : A64I_bf_ext<0b0, 0b10, GPR32, i32, "uxtb", 7,
+ (and i32:$Rn, 255)>;
+def UXTHww : A64I_bf_ext<0b0, 0b10, GPR32, i32, "uxth", 15,
+ (and i32:$Rn, 65535)>;
// The 64-bit unsigned variants are not strictly architectural but recommended
// for consistency.
let isAsmParserOnly = 1 in {
- def UXTBxw : A64I_bf_ext<0b0, 0b10, GPR64, "uxtb", 7,
- (and (anyext GPR32:$Rn), 255)>;
- def UXTHxw : A64I_bf_ext<0b0, 0b10, GPR64, "uxth", 15,
- (and (anyext GPR32:$Rn), 65535)>;
+ def UXTBxw : A64I_bf_ext<0b0, 0b10, GPR64, i64, "uxtb", 7,
+ (and (anyext i32:$Rn), 255)>;
+ def UXTHxw : A64I_bf_ext<0b0, 0b10, GPR64, i64, "uxth", 15,
+ (and (anyext i32:$Rn), 65535)>;
}
// Extra patterns for when the source register is actually 64-bits
// too. There's no architectural difference here, it's just LLVM
// shinanigans. There's no need for equivalent zero-extension patterns
// because they'll already be caught by logical (immediate) matching.
-def : Pat<(sext_inreg GPR64:$Rn, i8),
- (SXTBxw (EXTRACT_SUBREG GPR64:$Rn, sub_32))>;
-def : Pat<(sext_inreg GPR64:$Rn, i16),
- (SXTHxw (EXTRACT_SUBREG GPR64:$Rn, sub_32))>;
-def : Pat<(sext_inreg GPR64:$Rn, i32),
- (SXTWxw (EXTRACT_SUBREG GPR64:$Rn, sub_32))>;
+def : Pat<(sext_inreg i64:$Rn, i8),
+ (SXTBxw (EXTRACT_SUBREG $Rn, sub_32))>;
+def : Pat<(sext_inreg i64:$Rn, i16),
+ (SXTHxw (EXTRACT_SUBREG $Rn, sub_32))>;
+def : Pat<(sext_inreg i64:$Rn, i32),
+ (SXTWxw (EXTRACT_SUBREG $Rn, sub_32))>;
//===-------------------------------
@@ -1111,7 +1115,7 @@ multiclass A64I_shift<bits<2> opc, string asmop, SDNode opnode> {
def wwi : A64I_bitfield<0b0, opc, 0b0,
(outs GPR32:$Rd), (ins GPR32:$Rn, bitfield32_imm:$ImmR),
!strconcat(asmop, "\t$Rd, $Rn, $ImmR"),
- [(set GPR32:$Rd, (opnode GPR32:$Rn, bitfield32_imm:$ImmR))],
+ [(set i32:$Rd, (opnode i32:$Rn, bitfield32_imm:$ImmR))],
NoItinerary> {
let ImmS = 31;
}
@@ -1119,7 +1123,7 @@ multiclass A64I_shift<bits<2> opc, string asmop, SDNode opnode> {
def xxi : A64I_bitfield<0b1, opc, 0b1,
(outs GPR64:$Rd), (ins GPR64:$Rn, bitfield64_imm:$ImmR),
!strconcat(asmop, "\t$Rd, $Rn, $ImmR"),
- [(set GPR64:$Rd, (opnode GPR64:$Rn, bitfield64_imm:$ImmR))],
+ [(set i64:$Rd, (opnode i64:$Rn, bitfield64_imm:$ImmR))],
NoItinerary> {
let ImmS = 63;
}
@@ -1156,10 +1160,11 @@ def bitfield64_lsl_imm : Operand<i64>,
let EncoderMethod = "getBitfield64LSLOpValue";
}
-class A64I_bitfield_lsl<bit sf, RegisterClass GPR, Operand operand>
+class A64I_bitfield_lsl<bit sf, RegisterClass GPR, ValueType ty,
+ Operand operand>
: A64I_bitfield<sf, 0b10, sf, (outs GPR:$Rd), (ins GPR:$Rn, operand:$FullImm),
"lsl\t$Rd, $Rn, $FullImm",
- [(set GPR:$Rd, (shl GPR:$Rn, operand:$FullImm))],
+ [(set ty:$Rd, (shl ty:$Rn, operand:$FullImm))],
NoItinerary> {
bits<12> FullImm;
let ImmR = FullImm{5-0};
@@ -1170,8 +1175,8 @@ class A64I_bitfield_lsl<bit sf, RegisterClass GPR, Operand operand>
let isAsmParserOnly = 1;
}
-def LSLwwi : A64I_bitfield_lsl<0b0, GPR32, bitfield32_lsl_imm>;
-def LSLxxi : A64I_bitfield_lsl<0b1, GPR64, bitfield64_lsl_imm>;
+def LSLwwi : A64I_bitfield_lsl<0b0, GPR32, i32, bitfield32_lsl_imm>;
+def LSLxxi : A64I_bitfield_lsl<0b1, GPR64, i64, bitfield64_lsl_imm>;
//===-------------------------------
// 5. Aliases for bitfield extract instructions
@@ -1206,7 +1211,7 @@ multiclass A64I_bitfield_extract<bits<2> opc, string asmop, SDNode op> {
def wwii : A64I_bitfield<0b0, opc, 0b0, (outs GPR32:$Rd),
(ins GPR32:$Rn, bitfield32_imm:$ImmR, bfx32_width:$ImmS),
!strconcat(asmop, "\t$Rd, $Rn, $ImmR, $ImmS"),
- [(set GPR32:$Rd, (op GPR32:$Rn, imm:$ImmR, imm:$ImmS))],
+ [(set i32:$Rd, (op i32:$Rn, imm:$ImmR, imm:$ImmS))],
NoItinerary> {
// As above, no disassembler allowed.
let isAsmParserOnly = 1;
@@ -1215,7 +1220,7 @@ multiclass A64I_bitfield_extract<bits<2> opc, string asmop, SDNode op> {
def xxii : A64I_bitfield<0b1, opc, 0b1, (outs GPR64:$Rd),
(ins GPR64:$Rn, bitfield64_imm:$ImmR, bfx64_width:$ImmS),
!strconcat(asmop, "\t$Rd, $Rn, $ImmR, $ImmS"),
- [(set GPR64:$Rd, (op GPR64:$Rn, imm:$ImmR, imm:$ImmS))],
+ [(set i64:$Rd, (op i64:$Rn, imm:$ImmR, imm:$ImmS))],
NoItinerary> {
// As above, no disassembler allowed.
let isAsmParserOnly = 1;
@@ -1243,15 +1248,15 @@ def BFXILxxii : A64I_bitfield<0b1, 0b01, 0b1, (outs GPR64:$Rd),
}
// SBFX instructions can do a 1-instruction sign-extension of boolean values.
-def : Pat<(sext_inreg GPR64:$Rn, i1), (SBFXxxii GPR64:$Rn, 0, 0)>;
-def : Pat<(sext_inreg GPR32:$Rn, i1), (SBFXwwii GPR32:$Rn, 0, 0)>;
-def : Pat<(i64 (sext_inreg (anyext GPR32:$Rn), i1)),
- (SBFXxxii (SUBREG_TO_REG (i64 0), GPR32:$Rn, sub_32), 0, 0)>;
+def : Pat<(sext_inreg i64:$Rn, i1), (SBFXxxii $Rn, 0, 0)>;
+def : Pat<(sext_inreg i32:$Rn, i1), (SBFXwwii $Rn, 0, 0)>;
+def : Pat<(i64 (sext_inreg (anyext i32:$Rn), i1)),
+ (SBFXxxii (SUBREG_TO_REG (i64 0), $Rn, sub_32), 0, 0)>;
// UBFX makes sense as an implementation of a 64-bit zero-extension too. Could
// use either 64-bit or 32-bit variant, but 32-bit might be more efficient.
-def : Pat<(zext GPR32:$Rn), (SUBREG_TO_REG (i64 0), (UBFXwwii GPR32:$Rn, 0, 31),
- sub_32)>;
+def : Pat<(zext i32:$Rn), (SUBREG_TO_REG (i64 0), (UBFXwwii $Rn, 0, 31),
+ sub_32)>;
//===-------------------------------
// 6. Aliases for bitfield insert instructions
@@ -1380,14 +1385,14 @@ multiclass cmpbr_sizes<bit op, string asmop, ImmLeaf SETOP> {
(outs),
(ins GPR64:$Rt, bcc_target:$Label),
!strconcat(asmop,"\t$Rt, $Label"),
- [(A64br_cc (A64cmp GPR64:$Rt, 0), SETOP, bb:$Label)],
+ [(A64br_cc (A64cmp i64:$Rt, 0), SETOP, bb:$Label)],
NoItinerary>;
def w : A64I_cmpbr<0b0, op,
(outs),
(ins GPR32:$Rt, bcc_target:$Label),
!strconcat(asmop,"\t$Rt, $Label"),
- [(A64br_cc (A64cmp GPR32:$Rt, 0), SETOP, bb:$Label)],
+ [(A64br_cc (A64cmp i32:$Rt, 0), SETOP, bb:$Label)],
NoItinerary>;
}
}
@@ -1530,7 +1535,7 @@ multiclass A64I_condselSizes<bit op, bits<2> op2, string asmop,
(outs GPR32:$Rd),
(ins GPR32:$Rn, GPR32:$Rm, cond_code_op:$Cond),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Cond"),
- [(set GPR32:$Rd, (select GPR32:$Rn, GPR32:$Rm))],
+ [(set i32:$Rd, (select i32:$Rn, i32:$Rm))],
NoItinerary>;
@@ -1538,7 +1543,7 @@ multiclass A64I_condselSizes<bit op, bits<2> op2, string asmop,
(outs GPR64:$Rd),
(ins GPR64:$Rn, GPR64:$Rm, cond_code_op:$Cond),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Cond"),
- [(set GPR64:$Rd, (select GPR64:$Rn, GPR64:$Rm))],
+ [(set i64:$Rd, (select i64:$Rn, i64:$Rm))],
NoItinerary>;
}
}
@@ -1613,24 +1618,22 @@ def : Pat<(A64select_cc NZCV, -1, 0, inv_cond_code:$Cond),
// No commutable pattern for CSEL since the commuted version is isomorphic.
// CSINC
-def :Pat<(A64select_cc NZCV, (add GPR32:$Rm, 1), GPR32:$Rn,
- inv_cond_code:$Cond),
- (CSINCwwwc GPR32:$Rn, GPR32:$Rm, inv_cond_code:$Cond)>;
-def :Pat<(A64select_cc NZCV, (add GPR64:$Rm, 1), GPR64:$Rn,
- inv_cond_code:$Cond),
- (CSINCxxxc GPR64:$Rn, GPR64:$Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (add i32:$Rm, 1), i32:$Rn, inv_cond_code:$Cond),
+ (CSINCwwwc $Rn, $Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (add i64:$Rm, 1), i64:$Rn, inv_cond_code:$Cond),
+ (CSINCxxxc $Rn, $Rm, inv_cond_code:$Cond)>;
// CSINV
-def :Pat<(A64select_cc NZCV, (not GPR32:$Rm), GPR32:$Rn, inv_cond_code:$Cond),
- (CSINVwwwc GPR32:$Rn, GPR32:$Rm, inv_cond_code:$Cond)>;
-def :Pat<(A64select_cc NZCV, (not GPR64:$Rm), GPR64:$Rn, inv_cond_code:$Cond),
- (CSINVxxxc GPR64:$Rn, GPR64:$Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (not i32:$Rm), i32:$Rn, inv_cond_code:$Cond),
+ (CSINVwwwc $Rn, $Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (not i64:$Rm), i64:$Rn, inv_cond_code:$Cond),
+ (CSINVxxxc $Rn, $Rm, inv_cond_code:$Cond)>;
// CSNEG
-def :Pat<(A64select_cc NZCV, (ineg GPR32:$Rm), GPR32:$Rn, inv_cond_code:$Cond),
- (CSNEGwwwc GPR32:$Rn, GPR32:$Rm, inv_cond_code:$Cond)>;
-def :Pat<(A64select_cc NZCV, (ineg GPR64:$Rm), GPR64:$Rn, inv_cond_code:$Cond),
- (CSNEGxxxc GPR64:$Rn, GPR64:$Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (ineg i32:$Rm), i32:$Rn, inv_cond_code:$Cond),
+ (CSNEGwwwc $Rn, $Rm, inv_cond_code:$Cond)>;
+def :Pat<(A64select_cc NZCV, (ineg i64:$Rm), i64:$Rn, inv_cond_code:$Cond),
+ (CSNEGxxxc $Rn, $Rm, inv_cond_code:$Cond)>;
//===----------------------------------------------------------------------===//
// Data Processing (1 source) instructions
@@ -1664,28 +1667,28 @@ defm RBIT : A64I_dp_1src<0b000000, "rbit">;
defm CLS : A64I_dp_1src<0b000101, "cls">;
defm CLZ : A64I_dp_1src<0b000100, "clz">;
-def : Pat<(ctlz GPR32:$Rn), (CLZww GPR32:$Rn)>;
-def : Pat<(ctlz GPR64:$Rn), (CLZxx GPR64:$Rn)>;
-def : Pat<(ctlz_zero_undef GPR32:$Rn), (CLZww GPR32:$Rn)>;
-def : Pat<(ctlz_zero_undef GPR64:$Rn), (CLZxx GPR64:$Rn)>;
+def : Pat<(ctlz i32:$Rn), (CLZww $Rn)>;
+def : Pat<(ctlz i64:$Rn), (CLZxx $Rn)>;
+def : Pat<(ctlz_zero_undef i32:$Rn), (CLZww $Rn)>;
+def : Pat<(ctlz_zero_undef i64:$Rn), (CLZxx $Rn)>;
-def : Pat<(cttz GPR32:$Rn), (CLZww (RBITww GPR32:$Rn))>;
-def : Pat<(cttz GPR64:$Rn), (CLZxx (RBITxx GPR64:$Rn))>;
-def : Pat<(cttz_zero_undef GPR32:$Rn), (CLZww (RBITww GPR32:$Rn))>;
-def : Pat<(cttz_zero_undef GPR64:$Rn), (CLZxx (RBITxx GPR64:$Rn))>;
+def : Pat<(cttz i32:$Rn), (CLZww (RBITww $Rn))>;
+def : Pat<(cttz i64:$Rn), (CLZxx (RBITxx $Rn))>;
+def : Pat<(cttz_zero_undef i32:$Rn), (CLZww (RBITww $Rn))>;
+def : Pat<(cttz_zero_undef i64:$Rn), (CLZxx (RBITxx $Rn))>;
def REVww : A64I_dp_1src_impl<0b0, 0b000010, "rev",
- [(set GPR32:$Rd, (bswap GPR32:$Rn))],
+ [(set i32:$Rd, (bswap i32:$Rn))],
GPR32, NoItinerary>;
def REVxx : A64I_dp_1src_impl<0b1, 0b000011, "rev",
- [(set GPR64:$Rd, (bswap GPR64:$Rn))],
+ [(set i64:$Rd, (bswap i64:$Rn))],
GPR64, NoItinerary>;
def REV32xx : A64I_dp_1src_impl<0b1, 0b000010, "rev32",
- [(set GPR64:$Rd, (bswap (rotr GPR64:$Rn, (i64 32))))],
+ [(set i64:$Rd, (bswap (rotr i64:$Rn, (i64 32))))],
GPR64, NoItinerary>;
def REV16ww : A64I_dp_1src_impl<0b0, 0b000001, "rev16",
- [(set GPR32:$Rd, (bswap (rotr GPR32:$Rn, (i64 16))))],
+ [(set i32:$Rd, (bswap (rotr i32:$Rn, (i64 16))))],
GPR32,
NoItinerary>;
def REV16xx : A64I_dp_1src_impl<0b1, 0b000001, "rev16", [], GPR64, NoItinerary>;
@@ -1726,14 +1729,14 @@ multiclass dp_2src_zext <bits<6> opcode, string asmop, SDPatternOperator op> {
def www : dp_2src_impl<0b0,
opcode,
asmop,
- [(set GPR32:$Rd,
- (op GPR32:$Rn, (i64 (zext GPR32:$Rm))))],
+ [(set i32:$Rd,
+ (op i32:$Rn, (i64 (zext i32:$Rm))))],
GPR32,
NoItinerary>;
def xxx : dp_2src_impl<0b1,
opcode,
asmop,
- [(set GPR64:$Rd, (op GPR64:$Rn, GPR64:$Rm))],
+ [(set i64:$Rd, (op i64:$Rn, i64:$Rm))],
GPR64,
NoItinerary>;
}
@@ -1743,13 +1746,13 @@ multiclass dp_2src <bits<6> opcode, string asmop, SDPatternOperator op> {
def www : dp_2src_impl<0b0,
opcode,
asmop,
- [(set GPR32:$Rd, (op GPR32:$Rn, GPR32:$Rm))],
+ [(set i32:$Rd, (op i32:$Rn, i32:$Rm))],
GPR32,
NoItinerary>;
def xxx : dp_2src_impl<0b1,
opcode,
asmop,
- [(set GPR64:$Rd, (op GPR64:$Rn, GPR64:$Rm))],
+ [(set i64:$Rd, (op i64:$Rn, i64:$Rm))],
GPR64,
NoItinerary>;
}
@@ -1770,14 +1773,14 @@ defm RORV : dp_2src_zext<0b001011, "ror", rotr>;
// operation. Since the LLVM operations are undefined (as in C) if the
// RHS is out of range, it's perfectly permissible to discard the high
// bits of the GPR64.
-def : Pat<(shl GPR32:$Rn, GPR64:$Rm),
- (LSLVwww GPR32:$Rn, (EXTRACT_SUBREG GPR64:$Rm, sub_32))>;
-def : Pat<(srl GPR32:$Rn, GPR64:$Rm),
- (LSRVwww GPR32:$Rn, (EXTRACT_SUBREG GPR64:$Rm, sub_32))>;
-def : Pat<(sra GPR32:$Rn, GPR64:$Rm),
- (ASRVwww GPR32:$Rn, (EXTRACT_SUBREG GPR64:$Rm, sub_32))>;
-def : Pat<(rotr GPR32:$Rn, GPR64:$Rm),
- (RORVwww GPR32:$Rn, (EXTRACT_SUBREG GPR64:$Rm, sub_32))>;
+def : Pat<(shl i32:$Rn, i64:$Rm),
+ (LSLVwww $Rn, (EXTRACT_SUBREG $Rm, sub_32))>;
+def : Pat<(srl i32:$Rn, i64:$Rm),
+ (LSRVwww $Rn, (EXTRACT_SUBREG $Rm, sub_32))>;
+def : Pat<(sra i32:$Rn, i64:$Rm),
+ (ASRVwww $Rn, (EXTRACT_SUBREG $Rm, sub_32))>;
+def : Pat<(rotr i32:$Rn, i64:$Rm),
+ (RORVwww $Rn, (EXTRACT_SUBREG $Rm, sub_32))>;
// Here we define the aliases for the data processing 2 source instructions.
def LSL_mnemonic : MnemonicAlias<"lslv", "lsl">;
@@ -1792,46 +1795,47 @@ def ROR_menmonic : MnemonicAlias<"rorv", "ror">;
// + aliases MUL, MNEG, SMULL, SMNEGL, UMULL, UMNEGL
class A64I_dp3_4operand<bit sf, bits<6> opcode, RegisterClass AccReg,
- RegisterClass SrcReg, string asmop, dag pattern>
+ ValueType AccTy, RegisterClass SrcReg,
+ string asmop, dag pattern>
: A64I_dp3<sf, opcode,
(outs AccReg:$Rd), (ins SrcReg:$Rn, SrcReg:$Rm, AccReg:$Ra),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Ra"),
- [(set AccReg:$Rd, pattern)], NoItinerary> {
+ [(set AccTy:$Rd, pattern)], NoItinerary> {
RegisterClass AccGPR = AccReg;
RegisterClass SrcGPR = SrcReg;
}
-def MADDwwww : A64I_dp3_4operand<0b0, 0b000000, GPR32, GPR32, "madd",
- (add GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm))>;
-def MADDxxxx : A64I_dp3_4operand<0b1, 0b000000, GPR64, GPR64, "madd",
- (add GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm))>;
+def MADDwwww : A64I_dp3_4operand<0b0, 0b000000, GPR32, i32, GPR32, "madd",
+ (add i32:$Ra, (mul i32:$Rn, i32:$Rm))>;
+def MADDxxxx : A64I_dp3_4operand<0b1, 0b000000, GPR64, i64, GPR64, "madd",
+ (add i64:$Ra, (mul i64:$Rn, i64:$Rm))>;
-def MSUBwwww : A64I_dp3_4operand<0b0, 0b000001, GPR32, GPR32, "msub",
- (sub GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm))>;
-def MSUBxxxx : A64I_dp3_4operand<0b1, 0b000001, GPR64, GPR64, "msub",
- (sub GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm))>;
+def MSUBwwww : A64I_dp3_4operand<0b0, 0b000001, GPR32, i32, GPR32, "msub",
+ (sub i32:$Ra, (mul i32:$Rn, i32:$Rm))>;
+def MSUBxxxx : A64I_dp3_4operand<0b1, 0b000001, GPR64, i64, GPR64, "msub",
+ (sub i64:$Ra, (mul i64:$Rn, i64:$Rm))>;
-def SMADDLxwwx : A64I_dp3_4operand<0b1, 0b000010, GPR64, GPR32, "smaddl",
- (add GPR64:$Ra, (mul (i64 (sext GPR32:$Rn)), (sext GPR32:$Rm)))>;
-def SMSUBLxwwx : A64I_dp3_4operand<0b1, 0b000011, GPR64, GPR32, "smsubl",
- (sub GPR64:$Ra, (mul (i64 (sext GPR32:$Rn)), (sext GPR32:$Rm)))>;
+def SMADDLxwwx : A64I_dp3_4operand<0b1, 0b000010, GPR64, i64, GPR32, "smaddl",
+ (add i64:$Ra, (mul (i64 (sext i32:$Rn)), (sext i32:$Rm)))>;
+def SMSUBLxwwx : A64I_dp3_4operand<0b1, 0b000011, GPR64, i64, GPR32, "smsubl",
+ (sub i64:$Ra, (mul (i64 (sext i32:$Rn)), (sext i32:$Rm)))>;
-def UMADDLxwwx : A64I_dp3_4operand<0b1, 0b001010, GPR64, GPR32, "umaddl",
- (add GPR64:$Ra, (mul (i64 (zext GPR32:$Rn)), (zext GPR32:$Rm)))>;
-def UMSUBLxwwx : A64I_dp3_4operand<0b1, 0b001011, GPR64, GPR32, "umsubl",
- (sub GPR64:$Ra, (mul (i64 (zext GPR32:$Rn)), (zext GPR32:$Rm)))>;
+def UMADDLxwwx : A64I_dp3_4operand<0b1, 0b001010, GPR64, i64, GPR32, "umaddl",
+ (add i64:$Ra, (mul (i64 (zext i32:$Rn)), (zext i32:$Rm)))>;
+def UMSUBLxwwx : A64I_dp3_4operand<0b1, 0b001011, GPR64, i64, GPR32, "umsubl",
+ (sub i64:$Ra, (mul (i64 (zext i32:$Rn)), (zext i32:$Rm)))>;
let isCommutable = 1, PostEncoderMethod = "fixMulHigh" in {
def UMULHxxx : A64I_dp3<0b1, 0b001100, (outs GPR64:$Rd),
(ins GPR64:$Rn, GPR64:$Rm),
"umulh\t$Rd, $Rn, $Rm",
- [(set GPR64:$Rd, (mulhu GPR64:$Rn, GPR64:$Rm))],
+ [(set i64:$Rd, (mulhu i64:$Rn, i64:$Rm))],
NoItinerary>;
def SMULHxxx : A64I_dp3<0b1, 0b000100, (outs GPR64:$Rd),
(ins GPR64:$Rn, GPR64:$Rm),
"smulh\t$Rd, $Rn, $Rm",
- [(set GPR64:$Rd, (mulhs GPR64:$Rn, GPR64:$Rm))],
+ [(set i64:$Rd, (mulhs i64:$Rn, i64:$Rm))],
NoItinerary>;
}
@@ -1840,26 +1844,26 @@ multiclass A64I_dp3_3operand<string asmop, A64I_dp3_4operand INST,
def : InstAlias<asmop # " $Rd, $Rn, $Rm",
(INST INST.AccGPR:$Rd, INST.SrcGPR:$Rn, INST.SrcGPR:$Rm, ZR)>;
- def : Pat<pattern, (INST INST.SrcGPR:$Rn, INST.SrcGPR:$Rm, ZR)>;
+ def : Pat<pattern, (INST $Rn, $Rm, ZR)>;
}
-defm : A64I_dp3_3operand<"mul", MADDwwww, WZR, (mul GPR32:$Rn, GPR32:$Rm)>;
-defm : A64I_dp3_3operand<"mul", MADDxxxx, XZR, (mul GPR64:$Rn, GPR64:$Rm)>;
+defm : A64I_dp3_3operand<"mul", MADDwwww, WZR, (mul i32:$Rn, i32:$Rm)>;
+defm : A64I_dp3_3operand<"mul", MADDxxxx, XZR, (mul i64:$Rn, i64:$Rm)>;
defm : A64I_dp3_3operand<"mneg", MSUBwwww, WZR,
- (sub 0, (mul GPR32:$Rn, GPR32:$Rm))>;
+ (sub 0, (mul i32:$Rn, i32:$Rm))>;
defm : A64I_dp3_3operand<"mneg", MSUBxxxx, XZR,
- (sub 0, (mul GPR64:$Rn, GPR64:$Rm))>;
+ (sub 0, (mul i64:$Rn, i64:$Rm))>;
defm : A64I_dp3_3operand<"smull", SMADDLxwwx, XZR,
- (mul (i64 (sext GPR32:$Rn)), (sext GPR32:$Rm))>;
+ (mul (i64 (sext i32:$Rn)), (sext i32:$Rm))>;
defm : A64I_dp3_3operand<"smnegl", SMSUBLxwwx, XZR,
- (sub 0, (mul (i64 (sext GPR32:$Rn)), (sext GPR32:$Rm)))>;
+ (sub 0, (mul (i64 (sext i32:$Rn)), (sext i32:$Rm)))>;
defm : A64I_dp3_3operand<"umull", UMADDLxwwx, XZR,
- (mul (i64 (zext GPR32:$Rn)), (zext GPR32:$Rm))>;
+ (mul (i64 (zext i32:$Rn)), (zext i32:$Rm))>;
defm : A64I_dp3_3operand<"umnegl", UMSUBLxwwx, XZR,
- (sub 0, (mul (i64 (zext GPR32:$Rn)), (zext GPR32:$Rm)))>;
+ (sub 0, (mul (i64 (zext i32:$Rn)), (zext i32:$Rm)))>;
//===----------------------------------------------------------------------===//
@@ -1909,15 +1913,15 @@ def EXTRwwwi : A64I_extract<0b0, 0b000, 0b0,
(outs GPR32:$Rd),
(ins GPR32:$Rn, GPR32:$Rm, bitfield32_imm:$LSB),
"extr\t$Rd, $Rn, $Rm, $LSB",
- [(set GPR32:$Rd,
- (A64Extr GPR32:$Rn, GPR32:$Rm, imm:$LSB))],
+ [(set i32:$Rd,
+ (A64Extr i32:$Rn, i32:$Rm, imm:$LSB))],
NoItinerary>;
def EXTRxxxi : A64I_extract<0b1, 0b000, 0b1,
(outs GPR64:$Rd),
(ins GPR64:$Rn, GPR64:$Rm, bitfield64_imm:$LSB),
"extr\t$Rd, $Rn, $Rm, $LSB",
- [(set GPR64:$Rd,
- (A64Extr GPR64:$Rn, GPR64:$Rm, imm:$LSB))],
+ [(set i64:$Rd,
+ (A64Extr i64:$Rn, i64:$Rm, imm:$LSB))],
NoItinerary>;
def : InstAlias<"ror $Rd, $Rs, $LSB",
@@ -1925,10 +1929,10 @@ def : InstAlias<"ror $Rd, $Rs, $LSB",
def : InstAlias<"ror $Rd, $Rs, $LSB",
(EXTRxxxi GPR64:$Rd, GPR64:$Rs, GPR64:$Rs, bitfield64_imm:$LSB)>;
-def : Pat<(rotr GPR32:$Rn, bitfield32_imm:$LSB),
- (EXTRwwwi GPR32:$Rn, GPR32:$Rn, bitfield32_imm:$LSB)>;
-def : Pat<(rotr GPR64:$Rn, bitfield64_imm:$LSB),
- (EXTRxxxi GPR64:$Rn, GPR64:$Rn, bitfield64_imm:$LSB)>;
+def : Pat<(rotr i32:$Rn, bitfield32_imm:$LSB),
+ (EXTRwwwi $Rn, $Rn, bitfield32_imm:$LSB)>;
+def : Pat<(rotr i64:$Rn, bitfield64_imm:$LSB),
+ (EXTRxxxi $Rn, $Rn, bitfield64_imm:$LSB)>;
//===----------------------------------------------------------------------===//
// Floating-point compare instructions
@@ -1969,17 +1973,17 @@ multiclass A64I_fpcmpSignal<bits<2> type, bit imm, dag ins, dag pattern> {
}
defm FCMPss : A64I_fpcmpSignal<0b00, 0b0, (ins FPR32:$Rn, FPR32:$Rm),
- (set NZCV, (A64cmp (f32 FPR32:$Rn), FPR32:$Rm))>;
+ (set NZCV, (A64cmp f32:$Rn, f32:$Rm))>;
defm FCMPdd : A64I_fpcmpSignal<0b01, 0b0, (ins FPR64:$Rn, FPR64:$Rm),
- (set NZCV, (A64cmp (f64 FPR64:$Rn), FPR64:$Rm))>;
+ (set NZCV, (A64cmp f64:$Rn, f64:$Rm))>;
// What would be Rm should be written as 0; note that even though it's called
// "$Rm" here to fit in with the InstrFormats, it's actually an immediate.
defm FCMPsi : A64I_fpcmpSignal<0b00, 0b1, (ins FPR32:$Rn, fpz32:$Rm),
- (set NZCV, (A64cmp (f32 FPR32:$Rn), fpz32:$Rm))>;
+ (set NZCV, (A64cmp f32:$Rn, fpz32:$Rm))>;
defm FCMPdi : A64I_fpcmpSignal<0b01, 0b1, (ins FPR64:$Rn, fpz64:$Rm),
- (set NZCV, (A64cmp (f64 FPR64:$Rn), fpz64:$Rm))>;
+ (set NZCV, (A64cmp f64:$Rn, fpz64:$Rm))>;
//===----------------------------------------------------------------------===//
@@ -2010,18 +2014,16 @@ let Uses = [NZCV] in {
def FCSELsssc : A64I_fpcondsel<0b0, 0b0, 0b00, (outs FPR32:$Rd),
(ins FPR32:$Rn, FPR32:$Rm, cond_code_op:$Cond),
"fcsel\t$Rd, $Rn, $Rm, $Cond",
- [(set FPR32:$Rd,
- (simple_select (f32 FPR32:$Rn),
- FPR32:$Rm))],
+ [(set f32:$Rd,
+ (simple_select f32:$Rn, f32:$Rm))],
NoItinerary>;
def FCSELdddc : A64I_fpcondsel<0b0, 0b0, 0b01, (outs FPR64:$Rd),
(ins FPR64:$Rn, FPR64:$Rm, cond_code_op:$Cond),
"fcsel\t$Rd, $Rn, $Rm, $Cond",
- [(set FPR64:$Rd,
- (simple_select (f64 FPR64:$Rn),
- FPR64:$Rm))],
+ [(set f64:$Rd,
+ (simple_select f64:$Rn, f64:$Rm))],
NoItinerary>;
}
@@ -2039,12 +2041,12 @@ multiclass A64I_fpdp1sizes<bits<6> opcode, string asmstr,
SDPatternOperator opnode = FPNoUnop> {
def ss : A64I_fpdp1<0b0, 0b0, 0b00, opcode, (outs FPR32:$Rd), (ins FPR32:$Rn),
!strconcat(asmstr, "\t$Rd, $Rn"),
- [(set (f32 FPR32:$Rd), (opnode FPR32:$Rn))],
+ [(set f32:$Rd, (opnode f32:$Rn))],
NoItinerary>;
def dd : A64I_fpdp1<0b0, 0b0, 0b01, opcode, (outs FPR64:$Rd), (ins FPR64:$Rn),
!strconcat(asmstr, "\t$Rd, $Rn"),
- [(set (f64 FPR64:$Rd), (opnode FPR64:$Rn))],
+ [(set f64:$Rd, (opnode f64:$Rn))],
NoItinerary>;
}
@@ -2080,8 +2082,7 @@ class A64I_fpdp1_fcvt<FCVTRegType DestReg, FCVTRegType SrcReg, SDNode opnode>
{0,0,0,1, DestReg.t1, DestReg.t0},
(outs DestReg.Class:$Rd), (ins SrcReg.Class:$Rn),
"fcvt\t$Rd, $Rn",
- [(set (DestReg.VT DestReg.Class:$Rd),
- (opnode (SrcReg.VT SrcReg.Class:$Rn)))], NoItinerary>;
+ [(set DestReg.VT:$Rd, (opnode SrcReg.VT:$Rn))], NoItinerary>;
def FCVTds : A64I_fpdp1_fcvt<FCVT64, FCVT32, fextend>;
def FCVThs : A64I_fpdp1_fcvt<FCVT16, FCVT32, fround>;
@@ -2105,14 +2106,14 @@ multiclass A64I_fpdp2sizes<bits<4> opcode, string asmstr,
(outs FPR32:$Rd),
(ins FPR32:$Rn, FPR32:$Rm),
!strconcat(asmstr, "\t$Rd, $Rn, $Rm"),
- [(set (f32 FPR32:$Rd), (opnode FPR32:$Rn, FPR32:$Rm))],
+ [(set f32:$Rd, (opnode f32:$Rn, f32:$Rm))],
NoItinerary>;
def ddd : A64I_fpdp2<0b0, 0b0, 0b01, opcode,
(outs FPR64:$Rd),
(ins FPR64:$Rn, FPR64:$Rm),
!strconcat(asmstr, "\t$Rd, $Rn, $Rm"),
- [(set (f64 FPR64:$Rd), (opnode FPR64:$Rn, FPR64:$Rm))],
+ [(set f64:$Rd, (opnode f64:$Rn, f64:$Rm))],
NoItinerary>;
}
@@ -2151,7 +2152,7 @@ class A64I_fpdp3Impl<string asmop, RegisterClass FPR, ValueType VT,
: A64I_fpdp3<0b0, 0b0, type, o1, o0, (outs FPR:$Rd),
(ins FPR:$Rn, FPR:$Rm, FPR:$Ra),
!strconcat(asmop,"\t$Rd, $Rn, $Rm, $Ra"),
- [(set FPR:$Rd, (fmakind (VT FPR:$Rn), FPR:$Rm, FPR:$Ra))],
+ [(set VT:$Rd, (fmakind VT:$Rn, VT:$Rm, VT:$Ra))],
NoItinerary>;
def FMADDssss : A64I_fpdp3Impl<"fmadd", FPR32, f32, 0b00, 0b0, 0b0, fma>;
@@ -2208,57 +2209,59 @@ class cvtfix_i64_op<ValueType FloatVT>
// worth going for a multiclass here. Oh well.
class A64I_fptofix<bit sf, bits<2> type, bits<3> opcode,
- RegisterClass GPR, RegisterClass FPR, Operand scale_op,
- string asmop, SDNode cvtop>
+ RegisterClass GPR, RegisterClass FPR,
+ ValueType DstTy, ValueType SrcTy,
+ Operand scale_op, string asmop, SDNode cvtop>
: A64I_fpfixed<sf, 0b0, type, 0b11, opcode,
(outs GPR:$Rd), (ins FPR:$Rn, scale_op:$Scale),
!strconcat(asmop, "\t$Rd, $Rn, $Scale"),
- [(set GPR:$Rd, (cvtop (fmul FPR:$Rn, scale_op:$Scale)))],
+ [(set DstTy:$Rd, (cvtop (fmul SrcTy:$Rn, scale_op:$Scale)))],
NoItinerary>;
-def FCVTZSwsi : A64I_fptofix<0b0, 0b00, 0b000, GPR32, FPR32,
+def FCVTZSwsi : A64I_fptofix<0b0, 0b00, 0b000, GPR32, FPR32, i32, f32,
cvtfix_i32_op<f32>, "fcvtzs", fp_to_sint>;
-def FCVTZSxsi : A64I_fptofix<0b1, 0b00, 0b000, GPR64, FPR32,
+def FCVTZSxsi : A64I_fptofix<0b1, 0b00, 0b000, GPR64, FPR32, i64, f32,
cvtfix_i64_op<f32>, "fcvtzs", fp_to_sint>;
-def FCVTZUwsi : A64I_fptofix<0b0, 0b00, 0b001, GPR32, FPR32,
+def FCVTZUwsi : A64I_fptofix<0b0, 0b00, 0b001, GPR32, FPR32, i32, f32,
cvtfix_i32_op<f32>, "fcvtzu", fp_to_uint>;
-def FCVTZUxsi : A64I_fptofix<0b1, 0b00, 0b001, GPR64, FPR32,
+def FCVTZUxsi : A64I_fptofix<0b1, 0b00, 0b001, GPR64, FPR32, i64, f32,
cvtfix_i64_op<f32>, "fcvtzu", fp_to_uint>;
-def FCVTZSwdi : A64I_fptofix<0b0, 0b01, 0b000, GPR32, FPR64,
+def FCVTZSwdi : A64I_fptofix<0b0, 0b01, 0b000, GPR32, FPR64, i32, f64,
cvtfix_i32_op<f64>, "fcvtzs", fp_to_sint>;
-def FCVTZSxdi : A64I_fptofix<0b1, 0b01, 0b000, GPR64, FPR64,
+def FCVTZSxdi : A64I_fptofix<0b1, 0b01, 0b000, GPR64, FPR64, i64, f64,
cvtfix_i64_op<f64>, "fcvtzs", fp_to_sint>;
-def FCVTZUwdi : A64I_fptofix<0b0, 0b01, 0b001, GPR32, FPR64,
+def FCVTZUwdi : A64I_fptofix<0b0, 0b01, 0b001, GPR32, FPR64, i32, f64,
cvtfix_i32_op<f64>, "fcvtzu", fp_to_uint>;
-def FCVTZUxdi : A64I_fptofix<0b1, 0b01, 0b001, GPR64, FPR64,
+def FCVTZUxdi : A64I_fptofix<0b1, 0b01, 0b001, GPR64, FPR64, i64, f64,
cvtfix_i64_op<f64>, "fcvtzu", fp_to_uint>;
class A64I_fixtofp<bit sf, bits<2> type, bits<3> opcode,
- RegisterClass FPR, RegisterClass GPR, Operand scale_op,
- string asmop, SDNode cvtop>
+ RegisterClass FPR, RegisterClass GPR,
+ ValueType DstTy, ValueType SrcTy,
+ Operand scale_op, string asmop, SDNode cvtop>
: A64I_fpfixed<sf, 0b0, type, 0b00, opcode,
(outs FPR:$Rd), (ins GPR:$Rn, scale_op:$Scale),
!strconcat(asmop, "\t$Rd, $Rn, $Scale"),
- [(set FPR:$Rd, (fdiv (cvtop GPR:$Rn), scale_op:$Scale))],
+ [(set DstTy:$Rd, (fdiv (cvtop SrcTy:$Rn), scale_op:$Scale))],
NoItinerary>;
-def SCVTFswi : A64I_fixtofp<0b0, 0b00, 0b010, FPR32, GPR32,
+def SCVTFswi : A64I_fixtofp<0b0, 0b00, 0b010, FPR32, GPR32, f32, i32,
cvtfix_i32_op<f32>, "scvtf", sint_to_fp>;
-def SCVTFsxi : A64I_fixtofp<0b1, 0b00, 0b010, FPR32, GPR64,
+def SCVTFsxi : A64I_fixtofp<0b1, 0b00, 0b010, FPR32, GPR64, f32, i64,
cvtfix_i64_op<f32>, "scvtf", sint_to_fp>;
-def UCVTFswi : A64I_fixtofp<0b0, 0b00, 0b011, FPR32, GPR32,
+def UCVTFswi : A64I_fixtofp<0b0, 0b00, 0b011, FPR32, GPR32, f32, i32,
cvtfix_i32_op<f32>, "ucvtf", uint_to_fp>;
-def UCVTFsxi : A64I_fixtofp<0b1, 0b00, 0b011, FPR32, GPR64,
+def UCVTFsxi : A64I_fixtofp<0b1, 0b00, 0b011, FPR32, GPR64, f32, i64,
cvtfix_i64_op<f32>, "ucvtf", uint_to_fp>;
-def SCVTFdwi : A64I_fixtofp<0b0, 0b01, 0b010, FPR64, GPR32,
+def SCVTFdwi : A64I_fixtofp<0b0, 0b01, 0b010, FPR64, GPR32, f64, i32,
cvtfix_i32_op<f64>, "scvtf", sint_to_fp>;
-def SCVTFdxi : A64I_fixtofp<0b1, 0b01, 0b010, FPR64, GPR64,
+def SCVTFdxi : A64I_fixtofp<0b1, 0b01, 0b010, FPR64, GPR64, f64, i64,
cvtfix_i64_op<f64>, "scvtf", sint_to_fp>;
-def UCVTFdwi : A64I_fixtofp<0b0, 0b01, 0b011, FPR64, GPR32,
+def UCVTFdwi : A64I_fixtofp<0b0, 0b01, 0b011, FPR64, GPR32, f64, i32,
cvtfix_i32_op<f64>, "ucvtf", uint_to_fp>;
-def UCVTFdxi : A64I_fixtofp<0b1, 0b01, 0b011, FPR64, GPR64,
+def UCVTFdxi : A64I_fixtofp<0b1, 0b01, 0b011, FPR64, GPR64, f64, i64,
cvtfix_i64_op<f64>, "ucvtf", uint_to_fp>;
//===----------------------------------------------------------------------===//
@@ -2297,14 +2300,14 @@ defm FCVTM : A64I_fptointRM<0b10, 0b0, "fcvtm">;
defm FCVTZ : A64I_fptointRM<0b11, 0b0, "fcvtz">;
defm FCVTA : A64I_fptointRM<0b00, 0b1, "fcvta">;
-def : Pat<(i32 (fp_to_sint FPR32:$Rn)), (FCVTZSws FPR32:$Rn)>;
-def : Pat<(i64 (fp_to_sint FPR32:$Rn)), (FCVTZSxs FPR32:$Rn)>;
-def : Pat<(i32 (fp_to_uint FPR32:$Rn)), (FCVTZUws FPR32:$Rn)>;
-def : Pat<(i64 (fp_to_uint FPR32:$Rn)), (FCVTZUxs FPR32:$Rn)>;
-def : Pat<(i32 (fp_to_sint (f64 FPR64:$Rn))), (FCVTZSwd FPR64:$Rn)>;
-def : Pat<(i64 (fp_to_sint (f64 FPR64:$Rn))), (FCVTZSxd FPR64:$Rn)>;
-def : Pat<(i32 (fp_to_uint (f64 FPR64:$Rn))), (FCVTZUwd FPR64:$Rn)>;
-def : Pat<(i64 (fp_to_uint (f64 FPR64:$Rn))), (FCVTZUxd FPR64:$Rn)>;
+def : Pat<(i32 (fp_to_sint f32:$Rn)), (FCVTZSws $Rn)>;
+def : Pat<(i64 (fp_to_sint f32:$Rn)), (FCVTZSxs $Rn)>;
+def : Pat<(i32 (fp_to_uint f32:$Rn)), (FCVTZUws $Rn)>;
+def : Pat<(i64 (fp_to_uint f32:$Rn)), (FCVTZUxs $Rn)>;
+def : Pat<(i32 (fp_to_sint f64:$Rn)), (FCVTZSwd $Rn)>;
+def : Pat<(i64 (fp_to_sint f64:$Rn)), (FCVTZSxd $Rn)>;
+def : Pat<(i32 (fp_to_uint f64:$Rn)), (FCVTZUwd $Rn)>;
+def : Pat<(i64 (fp_to_uint f64:$Rn)), (FCVTZUxd $Rn)>;
multiclass A64I_inttofp<bit o0, string asmop> {
def CVTFsw : A64I_fpintI<0b0, 0b00, 0b00, {0, 1, o0}, FPR32, GPR32, asmop>;
@@ -2316,24 +2319,24 @@ multiclass A64I_inttofp<bit o0, string asmop> {
defm S : A64I_inttofp<0b0, "scvtf">;
defm U : A64I_inttofp<0b1, "ucvtf">;
-def : Pat<(f32 (sint_to_fp GPR32:$Rn)), (SCVTFsw GPR32:$Rn)>;
-def : Pat<(f32 (sint_to_fp GPR64:$Rn)), (SCVTFsx GPR64:$Rn)>;
-def : Pat<(f64 (sint_to_fp GPR32:$Rn)), (SCVTFdw GPR32:$Rn)>;
-def : Pat<(f64 (sint_to_fp GPR64:$Rn)), (SCVTFdx GPR64:$Rn)>;
-def : Pat<(f32 (uint_to_fp GPR32:$Rn)), (UCVTFsw GPR32:$Rn)>;
-def : Pat<(f32 (uint_to_fp GPR64:$Rn)), (UCVTFsx GPR64:$Rn)>;
-def : Pat<(f64 (uint_to_fp GPR32:$Rn)), (UCVTFdw GPR32:$Rn)>;
-def : Pat<(f64 (uint_to_fp GPR64:$Rn)), (UCVTFdx GPR64:$Rn)>;
+def : Pat<(f32 (sint_to_fp i32:$Rn)), (SCVTFsw $Rn)>;
+def : Pat<(f32 (sint_to_fp i64:$Rn)), (SCVTFsx $Rn)>;
+def : Pat<(f64 (sint_to_fp i32:$Rn)), (SCVTFdw $Rn)>;
+def : Pat<(f64 (sint_to_fp i64:$Rn)), (SCVTFdx $Rn)>;
+def : Pat<(f32 (uint_to_fp i32:$Rn)), (UCVTFsw $Rn)>;
+def : Pat<(f32 (uint_to_fp i64:$Rn)), (UCVTFsx $Rn)>;
+def : Pat<(f64 (uint_to_fp i32:$Rn)), (UCVTFdw $Rn)>;
+def : Pat<(f64 (uint_to_fp i64:$Rn)), (UCVTFdx $Rn)>;
def FMOVws : A64I_fpintI<0b0, 0b00, 0b00, 0b110, GPR32, FPR32, "fmov">;
def FMOVsw : A64I_fpintI<0b0, 0b00, 0b00, 0b111, FPR32, GPR32, "fmov">;
def FMOVxd : A64I_fpintI<0b1, 0b01, 0b00, 0b110, GPR64, FPR64, "fmov">;
def FMOVdx : A64I_fpintI<0b1, 0b01, 0b00, 0b111, FPR64, GPR64, "fmov">;
-def : Pat<(i32 (bitconvert (f32 FPR32:$Rn))), (FMOVws FPR32:$Rn)>;
-def : Pat<(f32 (bitconvert (i32 GPR32:$Rn))), (FMOVsw GPR32:$Rn)>;
-def : Pat<(i64 (bitconvert (f64 FPR64:$Rn))), (FMOVxd FPR64:$Rn)>;
-def : Pat<(f64 (bitconvert (i64 GPR64:$Rn))), (FMOVdx GPR64:$Rn)>;
+def : Pat<(i32 (bitconvert f32:$Rn)), (FMOVws $Rn)>;
+def : Pat<(f32 (bitconvert i32:$Rn)), (FMOVsw $Rn)>;
+def : Pat<(i64 (bitconvert f64:$Rn)), (FMOVxd $Rn)>;
+def : Pat<(f64 (bitconvert i64:$Rn)), (FMOVdx $Rn)>;
def lane1_asmoperand : AsmOperandClass {
let Name = "Lane1";
@@ -2397,7 +2400,7 @@ class A64I_fpimm_impl<bits<2> type, RegisterClass Reg, ValueType VT,
(outs Reg:$Rd),
(ins fmov_operand:$Imm8),
"fmov\t$Rd, $Imm8",
- [(set (VT Reg:$Rd), fmov_operand:$Imm8)],
+ [(set VT:$Rd, fmov_operand:$Imm8)],
NoItinerary>;
def FMOVsi : A64I_fpimm_impl<0b00, FPR32, f32, fmov32_operand>;
@@ -2582,7 +2585,8 @@ defm LDAR : A64I_LRex<"ldar", 0b101>;
class acquiring_load<PatFrag base>
: PatFrag<(ops node:$ptr), (base node:$ptr), [{
- return cast<AtomicSDNode>(N)->getOrdering() == Acquire;
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
+ return Ordering == Acquire || Ordering == SequentiallyConsistent;
}]>;
def atomic_load_acquire_8 : acquiring_load<atomic_load_8>;
@@ -2590,10 +2594,10 @@ def atomic_load_acquire_16 : acquiring_load<atomic_load_16>;
def atomic_load_acquire_32 : acquiring_load<atomic_load_32>;
def atomic_load_acquire_64 : acquiring_load<atomic_load_64>;
-def : Pat<(atomic_load_acquire_8 GPR64xsp:$Rn), (LDAR_byte GPR64xsp0:$Rn)>;
-def : Pat<(atomic_load_acquire_16 GPR64xsp:$Rn), (LDAR_hword GPR64xsp0:$Rn)>;
-def : Pat<(atomic_load_acquire_32 GPR64xsp:$Rn), (LDAR_word GPR64xsp0:$Rn)>;
-def : Pat<(atomic_load_acquire_64 GPR64xsp:$Rn), (LDAR_dword GPR64xsp0:$Rn)>;
+def : Pat<(atomic_load_acquire_8 i64:$Rn), (LDAR_byte $Rn)>;
+def : Pat<(atomic_load_acquire_16 i64:$Rn), (LDAR_hword $Rn)>;
+def : Pat<(atomic_load_acquire_32 i64:$Rn), (LDAR_word $Rn)>;
+def : Pat<(atomic_load_acquire_64 i64:$Rn), (LDAR_dword $Rn)>;
//===----------------------------------
// Store-release (no exclusivity)
@@ -2613,7 +2617,8 @@ class A64I_SLexs_impl<bits<2> size, bits<3> opcode, string asm, dag outs,
class releasing_store<PatFrag base>
: PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
- return cast<AtomicSDNode>(N)->getOrdering() == Release;
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
+ return Ordering == Release || Ordering == SequentiallyConsistent;
}]>;
def atomic_store_release_8 : releasing_store<atomic_store_8>;
@@ -2624,22 +2629,22 @@ def atomic_store_release_64 : releasing_store<atomic_store_64>;
multiclass A64I_SLex<string asmstr, bits<3> opcode, string prefix> {
def _byte: A64I_SLexs_impl<0b00, opcode, !strconcat(asmstr, "b"),
(outs), (ins GPR32:$Rt, GPR64xsp0:$Rn),
- [(atomic_store_release_8 GPR64xsp0:$Rn, GPR32:$Rt)],
+ [(atomic_store_release_8 i64:$Rn, i32:$Rt)],
NoItinerary>;
def _hword: A64I_SLexs_impl<0b01, opcode, !strconcat(asmstr, "h"),
(outs), (ins GPR32:$Rt, GPR64xsp0:$Rn),
- [(atomic_store_release_16 GPR64xsp0:$Rn, GPR32:$Rt)],
+ [(atomic_store_release_16 i64:$Rn, i32:$Rt)],
NoItinerary>;
def _word: A64I_SLexs_impl<0b10, opcode, asmstr,
(outs), (ins GPR32:$Rt, GPR64xsp0:$Rn),
- [(atomic_store_release_32 GPR64xsp0:$Rn, GPR32:$Rt)],
+ [(atomic_store_release_32 i64:$Rn, i32:$Rt)],
NoItinerary>;
def _dword: A64I_SLexs_impl<0b11, opcode, asmstr,
(outs), (ins GPR64:$Rt, GPR64xsp0:$Rn),
- [(atomic_store_release_64 GPR64xsp0:$Rn, GPR64:$Rt)],
+ [(atomic_store_release_64 i64:$Rn, i64:$Rt)],
NoItinerary>;
}
@@ -3596,15 +3601,15 @@ multiclass A64I_logimmSizes<bits<2> opc, string asmop, SDNode opnode> {
def wwi : A64I_logicalimm<0b0, opc, (outs GPR32wsp:$Rd),
(ins GPR32:$Rn, logical_imm32_operand:$Imm),
!strconcat(asmop, "\t$Rd, $Rn, $Imm"),
- [(set GPR32wsp:$Rd,
- (opnode GPR32:$Rn, logical_imm32_operand:$Imm))],
+ [(set i32:$Rd,
+ (opnode i32:$Rn, logical_imm32_operand:$Imm))],
NoItinerary>;
def xxi : A64I_logicalimm<0b1, opc, (outs GPR64xsp:$Rd),
(ins GPR64:$Rn, logical_imm64_operand:$Imm),
!strconcat(asmop, "\t$Rd, $Rn, $Imm"),
- [(set GPR64xsp:$Rd,
- (opnode GPR64:$Rn, logical_imm64_operand:$Imm))],
+ [(set i64:$Rd,
+ (opnode i64:$Rn, logical_imm64_operand:$Imm))],
NoItinerary>;
}
@@ -3655,46 +3660,46 @@ def signed_cond : PatLeaf<(cond), [{
// when the revolution comes.
multiclass logical_shifts<string prefix, bit sf, bits<2> opc,
bit N, bit commutable,
- string asmop, SDPatternOperator opfrag, string sty,
+ string asmop, SDPatternOperator opfrag, ValueType ty,
RegisterClass GPR, list<Register> defs> {
let isCommutable = commutable, Defs = defs in {
def _lsl : A64I_logicalshift<sf, opc, 0b00, N,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6),
+ !cast<Operand>("lsl_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (shl GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (shl ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _lsr : A64I_logicalshift<sf, opc, 0b01, N,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6),
+ !cast<Operand>("lsr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (srl GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (srl ty:$Rm,
+ !cast<Operand>("lsr_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _asr : A64I_logicalshift<sf, opc, 0b10, N,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6),
+ !cast<Operand>("asr_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (sra GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (sra ty:$Rm,
+ !cast<Operand>("asr_operand_" # ty):$Imm6))
)],
NoItinerary>;
def _ror : A64I_logicalshift<sf, opc, 0b11, N,
(outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("ror_operand_" # sty):$Imm6),
+ !cast<Operand>("ror_operand_" # ty):$Imm6),
!strconcat(asmop, "\t$Rd, $Rn, $Rm, $Imm6"),
- [(set GPR:$Rd, (opfrag GPR:$Rn, (rotr GPR:$Rm,
- !cast<Operand>("ror_operand_" # sty):$Imm6))
+ [(set ty:$Rd, (opfrag ty:$Rn, (rotr ty:$Rm,
+ !cast<Operand>("ror_operand_" # ty):$Imm6))
)],
NoItinerary>;
}
@@ -3704,17 +3709,17 @@ multiclass logical_shifts<string prefix, bit sf, bits<2> opc,
(!cast<Instruction>(prefix # "_lsl") GPR:$Rd, GPR:$Rn,
GPR:$Rm, 0)>;
- def : Pat<(opfrag GPR:$Rn, GPR:$Rm),
- (!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
+ def : Pat<(opfrag ty:$Rn, ty:$Rm),
+ (!cast<Instruction>(prefix # "_lsl") $Rn, $Rm, 0)>;
}
multiclass logical_sizes<string prefix, bits<2> opc, bit N, bit commutable,
string asmop, SDPatternOperator opfrag,
list<Register> defs> {
defm xxx : logical_shifts<prefix # "xxx", 0b1, opc, N,
- commutable, asmop, opfrag, "i64", GPR64, defs>;
+ commutable, asmop, opfrag, i64, GPR64, defs>;
defm www : logical_shifts<prefix # "www", 0b0, opc, N,
- commutable, asmop, opfrag, "i32", GPR32, defs>;
+ commutable, asmop, opfrag, i32, GPR32, defs>;
}
@@ -3741,15 +3746,15 @@ defm BICS : logical_sizes<"BICS", 0b11, 0b1, 0b0, "bics",
[{ (void)N; return false; }]>,
[NZCV]>;
-multiclass tst_shifts<string prefix, bit sf, string sty, RegisterClass GPR> {
+multiclass tst_shifts<string prefix, bit sf, ValueType ty, RegisterClass GPR> {
let isCommutable = 1, Rd = 0b11111, Defs = [NZCV] in {
def _lsl : A64I_logicalshift<sf, 0b11, 0b00, 0b0,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6),
+ !cast<Operand>("lsl_operand_" # ty):$Imm6),
"tst\t$Rn, $Rm, $Imm6",
- [(set NZCV, (A64setcc (and GPR:$Rn, (shl GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6)),
+ [(set NZCV, (A64setcc (and ty:$Rn, (shl ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6)),
0, signed_cond))],
NoItinerary>;
@@ -3757,30 +3762,30 @@ multiclass tst_shifts<string prefix, bit sf, string sty, RegisterClass GPR> {
def _lsr : A64I_logicalshift<sf, 0b11, 0b01, 0b0,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6),
+ !cast<Operand>("lsr_operand_" # ty):$Imm6),
"tst\t$Rn, $Rm, $Imm6",
- [(set NZCV, (A64setcc (and GPR:$Rn, (srl GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6)),
+ [(set NZCV, (A64setcc (and ty:$Rn, (srl ty:$Rm,
+ !cast<Operand>("lsr_operand_" # ty):$Imm6)),
0, signed_cond))],
NoItinerary>;
def _asr : A64I_logicalshift<sf, 0b11, 0b10, 0b0,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6),
+ !cast<Operand>("asr_operand_" # ty):$Imm6),
"tst\t$Rn, $Rm, $Imm6",
- [(set NZCV, (A64setcc (and GPR:$Rn, (sra GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6)),
+ [(set NZCV, (A64setcc (and ty:$Rn, (sra ty:$Rm,
+ !cast<Operand>("asr_operand_" # ty):$Imm6)),
0, signed_cond))],
NoItinerary>;
def _ror : A64I_logicalshift<sf, 0b11, 0b11, 0b0,
(outs),
(ins GPR:$Rn, GPR:$Rm,
- !cast<Operand>("ror_operand_" # sty):$Imm6),
+ !cast<Operand>("ror_operand_" # ty):$Imm6),
"tst\t$Rn, $Rm, $Imm6",
- [(set NZCV, (A64setcc (and GPR:$Rn, (rotr GPR:$Rm,
- !cast<Operand>("ror_operand_" # sty):$Imm6)),
+ [(set NZCV, (A64setcc (and ty:$Rn, (rotr ty:$Rm,
+ !cast<Operand>("ror_operand_" # ty):$Imm6)),
0, signed_cond))],
NoItinerary>;
}
@@ -3788,63 +3793,63 @@ multiclass tst_shifts<string prefix, bit sf, string sty, RegisterClass GPR> {
def _noshift : InstAlias<"tst $Rn, $Rm",
(!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
- def : Pat<(A64setcc (and GPR:$Rn, GPR:$Rm), 0, signed_cond),
- (!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
+ def : Pat<(A64setcc (and ty:$Rn, ty:$Rm), 0, signed_cond),
+ (!cast<Instruction>(prefix # "_lsl") $Rn, $Rm, 0)>;
}
-defm TSTxx : tst_shifts<"TSTxx", 0b1, "i64", GPR64>;
-defm TSTww : tst_shifts<"TSTww", 0b0, "i32", GPR32>;
+defm TSTxx : tst_shifts<"TSTxx", 0b1, i64, GPR64>;
+defm TSTww : tst_shifts<"TSTww", 0b0, i32, GPR32>;
-multiclass mvn_shifts<string prefix, bit sf, string sty, RegisterClass GPR> {
+multiclass mvn_shifts<string prefix, bit sf, ValueType ty, RegisterClass GPR> {
let isCommutable = 0, Rn = 0b11111 in {
def _lsl : A64I_logicalshift<sf, 0b01, 0b00, 0b1,
(outs GPR:$Rd),
(ins GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6),
+ !cast<Operand>("lsl_operand_" # ty):$Imm6),
"mvn\t$Rd, $Rm, $Imm6",
- [(set GPR:$Rd, (not (shl GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6)))],
+ [(set ty:$Rd, (not (shl ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6)))],
NoItinerary>;
def _lsr : A64I_logicalshift<sf, 0b01, 0b01, 0b1,
(outs GPR:$Rd),
(ins GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6),
+ !cast<Operand>("lsr_operand_" # ty):$Imm6),
"mvn\t$Rd, $Rm, $Imm6",
- [(set GPR:$Rd, (not (srl GPR:$Rm,
- !cast<Operand>("lsr_operand_" # sty):$Imm6)))],
+ [(set ty:$Rd, (not (srl ty:$Rm,
+ !cast<Operand>("lsr_operand_" # ty):$Imm6)))],
NoItinerary>;
def _asr : A64I_logicalshift<sf, 0b01, 0b10, 0b1,
(outs GPR:$Rd),
(ins GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6),
+ !cast<Operand>("asr_operand_" # ty):$Imm6),
"mvn\t$Rd, $Rm, $Imm6",
- [(set GPR:$Rd, (not (sra GPR:$Rm,
- !cast<Operand>("asr_operand_" # sty):$Imm6)))],
+ [(set ty:$Rd, (not (sra ty:$Rm,
+ !cast<Operand>("asr_operand_" # ty):$Imm6)))],
NoItinerary>;
def _ror : A64I_logicalshift<sf, 0b01, 0b11, 0b1,
(outs GPR:$Rd),
(ins GPR:$Rm,
- !cast<Operand>("ror_operand_" # sty):$Imm6),
+ !cast<Operand>("ror_operand_" # ty):$Imm6),
"mvn\t$Rd, $Rm, $Imm6",
- [(set GPR:$Rd, (not (rotr GPR:$Rm,
- !cast<Operand>("lsl_operand_" # sty):$Imm6)))],
+ [(set ty:$Rd, (not (rotr ty:$Rm,
+ !cast<Operand>("lsl_operand_" # ty):$Imm6)))],
NoItinerary>;
}
def _noshift : InstAlias<"mvn $Rn, $Rm",
(!cast<Instruction>(prefix # "_lsl") GPR:$Rn, GPR:$Rm, 0)>;
- def : Pat<(not GPR:$Rm),
- (!cast<Instruction>(prefix # "_lsl") GPR:$Rm, 0)>;
+ def : Pat<(not ty:$Rm),
+ (!cast<Instruction>(prefix # "_lsl") $Rm, 0)>;
}
-defm MVNxx : mvn_shifts<"MVNxx", 0b1, "i64", GPR64>;
-defm MVNww : mvn_shifts<"MVNww", 0b0, "i32", GPR32>;
+defm MVNxx : mvn_shifts<"MVNxx", 0b1, i64, GPR64>;
+defm MVNww : mvn_shifts<"MVNww", 0b0, i32, GPR32>;
def MOVxx :InstAlias<"mov $Rd, $Rm", (ORRxxx_lsl GPR64:$Rd, XZR, GPR64:$Rm, 0)>;
def MOVww :InstAlias<"mov $Rd, $Rm", (ORRwww_lsl GPR32:$Rd, WZR, GPR32:$Rm, 0)>;
@@ -4279,14 +4284,14 @@ let isBranch = 1, isTerminator = 1 in {
def TBZxii : A64I_TBimm<0b0, (outs),
(ins GPR64:$Rt, uimm6:$Imm, tbimm_target:$Label),
"tbz\t$Rt, $Imm, $Label",
- [(A64br_cc (A64cmp (and GPR64:$Rt, tstb64_pat:$Imm), 0),
+ [(A64br_cc (A64cmp (and i64:$Rt, tstb64_pat:$Imm), 0),
A64eq, bb:$Label)],
NoItinerary>;
def TBNZxii : A64I_TBimm<0b1, (outs),
(ins GPR64:$Rt, uimm6:$Imm, tbimm_target:$Label),
"tbnz\t$Rt, $Imm, $Label",
- [(A64br_cc (A64cmp (and GPR64:$Rt, tstb64_pat:$Imm), 0),
+ [(A64br_cc (A64cmp (and i64:$Rt, tstb64_pat:$Imm), 0),
A64ne, bb:$Label)],
NoItinerary>;
@@ -4298,7 +4303,7 @@ let isBranch = 1, isTerminator = 1 in {
def TBZwii : A64I_TBimm<0b0, (outs),
(ins GPR32:$Rt, uimm5:$Imm, tbimm_target:$Label),
"tbz\t$Rt, $Imm, $Label",
- [(A64br_cc (A64cmp (and GPR32:$Rt, tstb32_pat:$Imm), 0),
+ [(A64br_cc (A64cmp (and i32:$Rt, tstb32_pat:$Imm), 0),
A64eq, bb:$Label)],
NoItinerary> {
let Imm{5} = 0b0;
@@ -4307,7 +4312,7 @@ let isBranch = 1, isTerminator = 1 in {
def TBNZwii : A64I_TBimm<0b1, (outs),
(ins GPR32:$Rt, uimm5:$Imm, tbimm_target:$Label),
"tbnz\t$Rt, $Imm, $Label",
- [(A64br_cc (A64cmp (and GPR32:$Rt, tstb32_pat:$Imm), 0),
+ [(A64br_cc (A64cmp (and i32:$Rt, tstb32_pat:$Imm), 0),
A64ne, bb:$Label)],
NoItinerary> {
let Imm{5} = 0b0;
@@ -4383,13 +4388,13 @@ class A64I_BregImpl<bits<4> opc,
let isBranch = 1 in {
def BRx : A64I_BregImpl<0b0000,(outs), (ins GPR64:$Rn),
- "br\t$Rn", [(brind GPR64:$Rn)]> {
+ "br\t$Rn", [(brind i64:$Rn)]> {
let isBarrier = 1;
let isTerminator = 1;
}
def BLRx : A64I_BregImpl<0b0001, (outs), (ins GPR64:$Rn),
- "blr\t$Rn", [(AArch64Call GPR64:$Rn)]> {
+ "blr\t$Rn", [(AArch64Call i64:$Rn)]> {
let isBarrier = 0;
let isCall = 1;
let Defs = [X30];
@@ -4457,8 +4462,6 @@ def : ADRP_ADD<A64WrapperSmall, tjumptable>;
// GOT access patterns
//===----------------------------------------------------------------------===//
-// FIXME: Wibble
-
class GOTLoadSmall<SDNode addrfrag>
: Pat<(A64GOTLoad (A64WrapperSmall addrfrag:$Hi, addrfrag:$Lo12, 8)),
(LS64_LDR (ADRPxi addrfrag:$Hi), addrfrag:$Lo12)>;
@@ -4478,7 +4481,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [XSP] in {
def TC_RETURNxi
: PseudoInst<(outs), (ins tcGPR64:$dst, i32imm:$FPDiff),
- [(AArch64tcret tcGPR64:$dst, (i32 timm:$FPDiff))]>;
+ [(AArch64tcret i64:$dst, (i32 timm:$FPDiff))]>;
}
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
@@ -4510,13 +4513,13 @@ def TLSDESCCALL : PseudoInst<(outs), (ins i64imm:$Lbl), []> {
}
def TLSDESC_BLRx : PseudoInst<(outs), (ins GPR64:$Rn, i64imm:$Var),
- [(A64tlsdesc_blr GPR64:$Rn, tglobaltlsaddr:$Var)]> {
+ [(A64tlsdesc_blr i64:$Rn, tglobaltlsaddr:$Var)]> {
let isCall = 1;
let Defs = [X30];
}
-def : Pat<(A64tlsdesc_blr GPR64:$Rn, texternalsym:$Var),
- (TLSDESC_BLRx GPR64:$Rn, texternalsym:$Var)>;
+def : Pat<(A64tlsdesc_blr i64:$Rn, texternalsym:$Var),
+ (TLSDESC_BLRx $Rn, texternalsym:$Var)>;
//===----------------------------------------------------------------------===//
// Bitfield patterns
@@ -4539,22 +4542,22 @@ def bfi_width_to_imms : SDNodeXForm<imm, [{
// (either all bits are used or the low 32 bits are used).
let AddedComplexity = 10 in {
-def : Pat<(A64Bfi GPR64:$src, GPR64:$Rn, imm:$ImmR, imm:$ImmS),
- (BFIxxii GPR64:$src, GPR64:$Rn,
+def : Pat<(A64Bfi i64:$src, i64:$Rn, imm:$ImmR, imm:$ImmS),
+ (BFIxxii $src, $Rn,
(bfi64_lsb_to_immr (i64 imm:$ImmR)),
(bfi_width_to_imms (i64 imm:$ImmS)))>;
-def : Pat<(A64Bfi GPR32:$src, GPR32:$Rn, imm:$ImmR, imm:$ImmS),
- (BFIwwii GPR32:$src, GPR32:$Rn,
+def : Pat<(A64Bfi i32:$src, i32:$Rn, imm:$ImmR, imm:$ImmS),
+ (BFIwwii $src, $Rn,
(bfi32_lsb_to_immr (i64 imm:$ImmR)),
(bfi_width_to_imms (i64 imm:$ImmS)))>;
-def : Pat<(and (A64Bfi GPR64:$src, GPR64:$Rn, imm:$ImmR, imm:$ImmS),
+def : Pat<(and (A64Bfi i64:$src, i64:$Rn, imm:$ImmR, imm:$ImmS),
(i64 4294967295)),
(SUBREG_TO_REG (i64 0),
- (BFIwwii (EXTRACT_SUBREG GPR64:$src, sub_32),
- (EXTRACT_SUBREG GPR64:$Rn, sub_32),
+ (BFIwwii (EXTRACT_SUBREG $src, sub_32),
+ (EXTRACT_SUBREG $Rn, sub_32),
(bfi32_lsb_to_immr (i64 imm:$ImmR)),
(bfi_width_to_imms (i64 imm:$ImmS))),
sub_32)>;
@@ -4566,20 +4569,19 @@ def : Pat<(and (A64Bfi GPR64:$src, GPR64:$Rn, imm:$ImmR, imm:$ImmS),
//===----------------------------------------------------------------------===//
// Truncation from 64 to 32-bits just involves renaming your register.
-def : Pat<(i32 (trunc (i64 GPR64:$val))), (EXTRACT_SUBREG GPR64:$val, sub_32)>;
+def : Pat<(i32 (trunc i64:$val)), (EXTRACT_SUBREG $val, sub_32)>;
// Similarly, extension where we don't care about the high bits is
// just a rename.
-def : Pat<(i64 (anyext (i32 GPR32:$val))),
- (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$val, sub_32)>;
+def : Pat<(i64 (anyext i32:$val)),
+ (INSERT_SUBREG (IMPLICIT_DEF), $val, sub_32)>;
// SELECT instructions providing f128 types need to be handled by a
// pseudo-instruction since the eventual code will need to introduce basic
// blocks and control flow.
def F128CSEL : PseudoInst<(outs FPR128:$Rd),
- (ins FPR128:$Rn, FPR128:$Rm, cond_code_op:$Cond),
- [(set FPR128:$Rd, (simple_select (f128 FPR128:$Rn),
- FPR128:$Rm))]> {
+ (ins FPR128:$Rn, FPR128:$Rm, cond_code_op:$Cond),
+ [(set f128:$Rd, (simple_select f128:$Rn, f128:$Rm))]> {
let Uses = [NZCV];
let usesCustomInserter = 1;
}
@@ -4691,13 +4693,13 @@ def atomic_store_simple_i64 : simple_store<atomic_store_64>;
// Atomic patterns can be shared between integer operations of all sizes, a
// quick multiclass here allows reuse.
multiclass ls_atomic_pats<Instruction LOAD, Instruction STORE, dag Base,
- dag Offset, dag address, RegisterClass TPR,
+ dag Offset, dag address, ValueType transty,
ValueType sty> {
def : Pat<(!cast<PatFrag>("atomic_load_simple_" # sty) address),
(LOAD Base, Offset)>;
- def : Pat<(!cast<PatFrag>("atomic_store_simple_" # sty) address, TPR:$Rt),
- (STORE TPR:$Rt, Base, Offset)>;
+ def : Pat<(!cast<PatFrag>("atomic_store_simple_" # sty) address, transty:$Rt),
+ (STORE $Rt, Base, Offset)>;
}
// Instructions accessing a memory chunk smaller than a register (or, in a
@@ -4709,7 +4711,7 @@ multiclass ls_atomic_pats<Instruction LOAD, Instruction STORE, dag Base,
multiclass ls_small_pats<Instruction LOAD, Instruction STORE,
dag Base, dag Offset,
dag address, ValueType sty>
- : ls_atomic_pats<LOAD, STORE, Base, Offset, address, GPR32, sty> {
+ : ls_atomic_pats<LOAD, STORE, Base, Offset, address, i32, sty> {
def : Pat<(!cast<SDNode>(zextload # sty) address), (LOAD Base, Offset)>;
def : Pat<(!cast<SDNode>(extload # sty) address), (LOAD Base, Offset)>;
@@ -4722,13 +4724,13 @@ multiclass ls_small_pats<Instruction LOAD, Instruction STORE,
def : Pat<(i64 (!cast<SDNode>(extload # sty) address)),
(SUBREG_TO_REG (i64 0), (LOAD Base, Offset), sub_32)>;
- def : Pat<(!cast<SDNode>(truncstore # sty) GPR32:$Rt, address),
- (STORE GPR32:$Rt, Base, Offset)>;
+ def : Pat<(!cast<SDNode>(truncstore # sty) i32:$Rt, address),
+ (STORE $Rt, Base, Offset)>;
// For truncating store from 64-bits, we have to manually tell LLVM to
// ignore the high bits of the x register.
- def : Pat<(!cast<SDNode>(truncstore # sty) GPR64:$Rt, address),
- (STORE (EXTRACT_SUBREG GPR64:$Rt, sub_32), Base, Offset)>;
+ def : Pat<(!cast<SDNode>(truncstore # sty) i64:$Rt, address),
+ (STORE (EXTRACT_SUBREG $Rt, sub_32), Base, Offset)>;
}
// Next come patterns for sign-extending loads.
@@ -4744,18 +4746,16 @@ multiclass load_signed_pats<string T, string U, dag Base, dag Offset,
// and finally "natural-width" loads and stores come next.
multiclass ls_neutral_pats<Instruction LOAD, Instruction STORE, dag Base,
- dag Offset, dag address, RegisterClass TPR,
- ValueType sty> {
+ dag Offset, dag address, ValueType sty> {
def : Pat<(sty (load address)), (LOAD Base, Offset)>;
- def : Pat<(store (sty TPR:$Rt), address), (STORE TPR:$Rt, Base, Offset)>;
+ def : Pat<(store sty:$Rt, address), (STORE $Rt, Base, Offset)>;
}
// Integer operations also get atomic instructions to select for.
multiclass ls_int_neutral_pats<Instruction LOAD, Instruction STORE, dag Base,
- dag Offset, dag address, RegisterClass TPR,
- ValueType sty>
- : ls_neutral_pats<LOAD, STORE, Base, Offset, address, TPR, sty>,
- ls_atomic_pats<LOAD, STORE, Base, Offset, address, TPR, sty>;
+ dag Offset, dag address, ValueType sty>
+ : ls_neutral_pats<LOAD, STORE, Base, Offset, address, sty>,
+ ls_atomic_pats<LOAD, STORE, Base, Offset, address, sty, sty>;
//===------------------------------
// 2.2. Addressing-mode instantiations
@@ -4790,7 +4790,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, word_uimm12,
!subst(ALIGN, min_align4, decls.pattern))),
- GPR32, i32>;
+ i32>;
defm : ls_int_neutral_pats<LS64_LDR, LS64_STR, Base,
!foreach(decls.pattern, Offset,
@@ -4798,7 +4798,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, dword_uimm12,
!subst(ALIGN, min_align8, decls.pattern))),
- GPR64, i64>;
+ i64>;
defm : ls_neutral_pats<LSFP16_LDR, LSFP16_STR, Base,
!foreach(decls.pattern, Offset,
@@ -4806,7 +4806,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, hword_uimm12,
!subst(ALIGN, min_align2, decls.pattern))),
- FPR16, f16>;
+ f16>;
defm : ls_neutral_pats<LSFP32_LDR, LSFP32_STR, Base,
!foreach(decls.pattern, Offset,
@@ -4814,7 +4814,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, word_uimm12,
!subst(ALIGN, min_align4, decls.pattern))),
- FPR32, f32>;
+ f32>;
defm : ls_neutral_pats<LSFP64_LDR, LSFP64_STR, Base,
!foreach(decls.pattern, Offset,
@@ -4822,7 +4822,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, dword_uimm12,
!subst(ALIGN, min_align8, decls.pattern))),
- FPR64, f64>;
+ f64>;
defm : ls_neutral_pats<LSFP128_LDR, LSFP128_STR, Base,
!foreach(decls.pattern, Offset,
@@ -4830,7 +4830,7 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
!foreach(decls.pattern, address,
!subst(OFFSET, qword_uimm12,
!subst(ALIGN, min_align16, decls.pattern))),
- FPR128, f128>;
+ f128>;
defm : load_signed_pats<"B", "", Base,
!foreach(decls.pattern, Offset,
@@ -4857,13 +4857,13 @@ multiclass uimm12_pats<dag address, dag Base, dag Offset> {
// Straightforward patterns of last resort: a pointer with or without an
// appropriate offset.
-defm : uimm12_pats<(i64 GPR64xsp:$Rn), (i64 GPR64xsp:$Rn), (i64 0)>;
-defm : uimm12_pats<(add GPR64xsp:$Rn, OFFSET:$UImm12),
- (i64 GPR64xsp:$Rn), (i64 OFFSET:$UImm12)>;
+defm : uimm12_pats<(i64 i64:$Rn), (i64 i64:$Rn), (i64 0)>;
+defm : uimm12_pats<(add i64:$Rn, OFFSET:$UImm12),
+ (i64 i64:$Rn), (i64 OFFSET:$UImm12)>;
// The offset could be hidden behind an "or", of course:
-defm : uimm12_pats<(add_like_or GPR64xsp:$Rn, OFFSET:$UImm12),
- (i64 GPR64xsp:$Rn), (i64 OFFSET:$UImm12)>;
+defm : uimm12_pats<(add_like_or i64:$Rn, OFFSET:$UImm12),
+ (i64 i64:$Rn), (i64 OFFSET:$UImm12)>;
// Global addresses under the small-absolute model should use these
// instructions. There are ELF relocations specifically for it.
@@ -4897,36 +4897,31 @@ multiclass simm9_pats<dag address, dag Base, dag Offset> {
defm : ls_small_pats<LS8_LDUR, LS8_STUR, Base, Offset, address, i8>;
defm : ls_small_pats<LS16_LDUR, LS16_STUR, Base, Offset, address, i16>;
- defm : ls_int_neutral_pats<LS32_LDUR, LS32_STUR, Base, Offset, address,
- GPR32, i32>;
- defm : ls_int_neutral_pats<LS64_LDUR, LS64_STUR, Base, Offset, address,
- GPR64, i64>;
-
- defm : ls_neutral_pats<LSFP16_LDUR, LSFP16_STUR, Base, Offset, address,
- FPR16, f16>;
- defm : ls_neutral_pats<LSFP32_LDUR, LSFP32_STUR, Base, Offset, address,
- FPR32, f32>;
- defm : ls_neutral_pats<LSFP64_LDUR, LSFP64_STUR, Base, Offset, address,
- FPR64, f64>;
+ defm : ls_int_neutral_pats<LS32_LDUR, LS32_STUR, Base, Offset, address, i32>;
+ defm : ls_int_neutral_pats<LS64_LDUR, LS64_STUR, Base, Offset, address, i64>;
+
+ defm : ls_neutral_pats<LSFP16_LDUR, LSFP16_STUR, Base, Offset, address, f16>;
+ defm : ls_neutral_pats<LSFP32_LDUR, LSFP32_STUR, Base, Offset, address, f32>;
+ defm : ls_neutral_pats<LSFP64_LDUR, LSFP64_STUR, Base, Offset, address, f64>;
defm : ls_neutral_pats<LSFP128_LDUR, LSFP128_STUR, Base, Offset, address,
- FPR128, f128>;
+ f128>;
def : Pat<(i64 (zextloadi32 address)),
(SUBREG_TO_REG (i64 0), (LS32_LDUR Base, Offset), sub_32)>;
- def : Pat<(truncstorei32 GPR64:$Rt, address),
- (LS32_STUR (EXTRACT_SUBREG GPR64:$Rt, sub_32), Base, Offset)>;
+ def : Pat<(truncstorei32 i64:$Rt, address),
+ (LS32_STUR (EXTRACT_SUBREG $Rt, sub_32), Base, Offset)>;
defm : load_signed_pats<"B", "_U", Base, Offset, address, i8>;
defm : load_signed_pats<"H", "_U", Base, Offset, address, i16>;
def : Pat<(sextloadi32 address), (LDURSWx Base, Offset)>;
}
-defm : simm9_pats<(add GPR64xsp:$Rn, simm9:$SImm9),
- (i64 GPR64xsp:$Rn), (SDXF_simm9 simm9:$SImm9)>;
+defm : simm9_pats<(add i64:$Rn, simm9:$SImm9),
+ (i64 $Rn), (SDXF_simm9 simm9:$SImm9)>;
-defm : simm9_pats<(add_like_or GPR64xsp:$Rn, simm9:$SImm9),
- (i64 GPR64xsp:$Rn), (SDXF_simm9 simm9:$SImm9)>;
+defm : simm9_pats<(add_like_or i64:$Rn, simm9:$SImm9),
+ (i64 $Rn), (SDXF_simm9 simm9:$SImm9)>;
//===------------------------------
@@ -4937,12 +4932,12 @@ defm : simm9_pats<(add_like_or GPR64xsp:$Rn, simm9:$SImm9),
// quick multiclass here allows reuse.
multiclass ro_atomic_pats<Instruction LOAD, Instruction STORE, dag Base,
dag Offset, dag Extend, dag address,
- RegisterClass TPR, ValueType sty> {
+ ValueType transty, ValueType sty> {
def : Pat<(!cast<PatFrag>("atomic_load_simple_" # sty) address),
(LOAD Base, Offset, Extend)>;
- def : Pat<(!cast<PatFrag>("atomic_store_simple_" # sty) address, TPR:$Rt),
- (STORE TPR:$Rt, Base, Offset, Extend)>;
+ def : Pat<(!cast<PatFrag>("atomic_store_simple_" # sty) address, transty:$Rt),
+ (STORE $Rt, Base, Offset, Extend)>;
}
// The register offset instructions take three operands giving the instruction,
@@ -4953,7 +4948,7 @@ multiclass ro_atomic_pats<Instruction LOAD, Instruction STORE, dag Base,
multiclass ro_small_pats<Instruction LOAD, Instruction STORE,
dag Base, dag Offset, dag Extend,
dag address, ValueType sty>
- : ro_atomic_pats<LOAD, STORE, Base, Offset, Extend, address, GPR32, sty> {
+ : ro_atomic_pats<LOAD, STORE, Base, Offset, Extend, address, i32, sty> {
def : Pat<(!cast<SDNode>(zextload # sty) address),
(LOAD Base, Offset, Extend)>;
@@ -4968,13 +4963,13 @@ multiclass ro_small_pats<Instruction LOAD, Instruction STORE,
def : Pat<(i64 (!cast<SDNode>(extload # sty) address)),
(SUBREG_TO_REG (i64 0), (LOAD Base, Offset, Extend), sub_32)>;
- def : Pat<(!cast<SDNode>(truncstore # sty) GPR32:$Rt, address),
- (STORE GPR32:$Rt, Base, Offset, Extend)>;
+ def : Pat<(!cast<SDNode>(truncstore # sty) i32:$Rt, address),
+ (STORE $Rt, Base, Offset, Extend)>;
// For truncating store from 64-bits, we have to manually tell LLVM to
// ignore the high bits of the x register.
- def : Pat<(!cast<SDNode>(truncstore # sty) GPR64:$Rt, address),
- (STORE (EXTRACT_SUBREG GPR64:$Rt, sub_32), Base, Offset, Extend)>;
+ def : Pat<(!cast<SDNode>(truncstore # sty) i64:$Rt, address),
+ (STORE (EXTRACT_SUBREG $Rt, sub_32), Base, Offset, Extend)>;
}
@@ -4993,17 +4988,17 @@ multiclass ro_signed_pats<string T, string Rm, dag Base, dag Offset, dag Extend,
// and finally "natural-width" loads and stores come next.
multiclass ro_neutral_pats<Instruction LOAD, Instruction STORE,
dag Base, dag Offset, dag Extend, dag address,
- RegisterClass TPR, ValueType sty> {
+ ValueType sty> {
def : Pat<(sty (load address)), (LOAD Base, Offset, Extend)>;
- def : Pat<(store (sty TPR:$Rt), address),
- (STORE TPR:$Rt, Base, Offset, Extend)>;
+ def : Pat<(store sty:$Rt, address),
+ (STORE $Rt, Base, Offset, Extend)>;
}
multiclass ro_int_neutral_pats<Instruction LOAD, Instruction STORE,
dag Base, dag Offset, dag Extend, dag address,
- RegisterClass TPR, ValueType sty>
- : ro_neutral_pats<LOAD, STORE, Base, Offset, Extend, address, TPR, sty>,
- ro_atomic_pats<LOAD, STORE, Base, Offset, Extend, address, TPR, sty>;
+ ValueType sty>
+ : ro_neutral_pats<LOAD, STORE, Base, Offset, Extend, address, sty>,
+ ro_atomic_pats<LOAD, STORE, Base, Offset, Extend, address, sty, sty>;
multiclass regoff_pats<string Rm, dag address, dag Base, dag Offset,
dag Extend> {
@@ -5032,7 +5027,7 @@ multiclass regoff_pats<string Rm, dag address, dag Base, dag Offset,
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq2, decls.pattern)),
- GPR32, i32>;
+ i32>;
defm : ro_int_neutral_pats<
!cast<Instruction>("LS64_" # Rm # "_RegOffset_LDR"),
@@ -5040,45 +5035,45 @@ multiclass regoff_pats<string Rm, dag address, dag Base, dag Offset,
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq3, decls.pattern)),
- GPR64, i64>;
+ i64>;
defm : ro_neutral_pats<!cast<Instruction>("LSFP16_" # Rm # "_RegOffset_LDR"),
!cast<Instruction>("LSFP16_" # Rm # "_RegOffset_STR"),
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq1, decls.pattern)),
- FPR16, f16>;
+ f16>;
defm : ro_neutral_pats<!cast<Instruction>("LSFP32_" # Rm # "_RegOffset_LDR"),
!cast<Instruction>("LSFP32_" # Rm # "_RegOffset_STR"),
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq2, decls.pattern)),
- FPR32, f32>;
+ f32>;
defm : ro_neutral_pats<!cast<Instruction>("LSFP64_" # Rm # "_RegOffset_LDR"),
!cast<Instruction>("LSFP64_" # Rm # "_RegOffset_STR"),
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq3, decls.pattern)),
- FPR64, f64>;
+ f64>;
defm : ro_neutral_pats<!cast<Instruction>("LSFP128_" # Rm # "_RegOffset_LDR"),
!cast<Instruction>("LSFP128_" # Rm # "_RegOffset_STR"),
Base, Offset, Extend,
!foreach(decls.pattern, address,
!subst(SHIFT, imm_eq4, decls.pattern)),
- FPR128, f128>;
+ f128>;
defm : ro_signed_pats<"B", Rm, Base, Offset, Extend,
- !foreach(decls.pattern, address,
- !subst(SHIFT, imm_eq0, decls.pattern)),
- i8>;
+ !foreach(decls.pattern, address,
+ !subst(SHIFT, imm_eq0, decls.pattern)),
+ i8>;
defm : ro_signed_pats<"H", Rm, Base, Offset, Extend,
- !foreach(decls.pattern, address,
- !subst(SHIFT, imm_eq1, decls.pattern)),
- i16>;
+ !foreach(decls.pattern, address,
+ !subst(SHIFT, imm_eq1, decls.pattern)),
+ i16>;
def : Pat<(sextloadi32 !foreach(decls.pattern, address,
!subst(SHIFT, imm_eq2, decls.pattern))),
@@ -5091,20 +5086,20 @@ multiclass regoff_pats<string Rm, dag address, dag Base, dag Offset,
// using register-offset instructions. Essentially a base plus a possibly
// extended, possibly shifted (by access size) offset.
-defm : regoff_pats<"Wm", (add GPR64xsp:$Rn, (sext GPR32:$Rm)),
- (i64 GPR64xsp:$Rn), (i32 GPR32:$Rm), (i64 6)>;
+defm : regoff_pats<"Wm", (add i64:$Rn, (sext i32:$Rm)),
+ (i64 i64:$Rn), (i32 i32:$Rm), (i64 6)>;
-defm : regoff_pats<"Wm", (add GPR64xsp:$Rn, (shl (sext GPR32:$Rm), SHIFT)),
- (i64 GPR64xsp:$Rn), (i32 GPR32:$Rm), (i64 7)>;
+defm : regoff_pats<"Wm", (add i64:$Rn, (shl (sext i32:$Rm), SHIFT)),
+ (i64 i64:$Rn), (i32 i32:$Rm), (i64 7)>;
-defm : regoff_pats<"Wm", (add GPR64xsp:$Rn, (zext GPR32:$Rm)),
- (i64 GPR64xsp:$Rn), (i32 GPR32:$Rm), (i64 2)>;
+defm : regoff_pats<"Wm", (add i64:$Rn, (zext i32:$Rm)),
+ (i64 i64:$Rn), (i32 i32:$Rm), (i64 2)>;
-defm : regoff_pats<"Wm", (add GPR64xsp:$Rn, (shl (zext GPR32:$Rm), SHIFT)),
- (i64 GPR64xsp:$Rn), (i32 GPR32:$Rm), (i64 3)>;
+defm : regoff_pats<"Wm", (add i64:$Rn, (shl (zext i32:$Rm), SHIFT)),
+ (i64 i64:$Rn), (i32 i32:$Rm), (i64 3)>;
-defm : regoff_pats<"Xm", (add GPR64xsp:$Rn, GPR64:$Rm),
- (i64 GPR64xsp:$Rn), (i64 GPR64:$Rm), (i64 2)>;
+defm : regoff_pats<"Xm", (add i64:$Rn, i64:$Rm),
+ (i64 i64:$Rn), (i64 i64:$Rm), (i64 2)>;
-defm : regoff_pats<"Xm", (add GPR64xsp:$Rn, (shl GPR64:$Rm, SHIFT)),
- (i64 GPR64xsp:$Rn), (i64 GPR64:$Rm), (i64 3)>;
+defm : regoff_pats<"Xm", (add i64:$Rn, (shl i64:$Rm, SHIFT)),
+ (i64 i64:$Rn), (i64 i64:$Rm), (i64 3)>;
diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index b83577a..3b811df 100644
--- a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -63,14 +63,15 @@ public:
~AArch64ELFStreamer() {}
- virtual void ChangeSection(const MCSection *Section) {
+ virtual void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) {
// We have to keep track of the mapping symbol state of any sections we
// use. Each one should start off as EMS_None, which is provided as the
// default constructor by DenseMap::lookup.
- LastMappingSymbols[getPreviousSection()] = LastEMS;
+ LastMappingSymbols[getPreviousSection().first] = LastEMS;
LastEMS = LastMappingSymbols.lookup(Section);
- MCELFStreamer::ChangeSection(Section);
+ MCELFStreamer::ChangeSection(Section, Subsection);
}
/// This function is the one used to emit instruction data into the ELF
@@ -129,7 +130,7 @@ private:
MCELF::SetType(SD, ELF::STT_NOTYPE);
MCELF::SetBinding(SD, ELF::STB_LOCAL);
SD.setExternal(false);
- Symbol->setSection(*getCurrentSection());
+ Symbol->setSection(*getCurrentSection().first);
const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
Symbol->setVariableValue(Value);
diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index ab9bba1..bedccb5 100644
--- a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -194,7 +194,55 @@ const NamedImmMapper::Mapping A64SysReg::MRSMapper::MRSPairs[] = {
{"rvbar_el3", RVBAR_EL3},
{"isr_el1", ISR_EL1},
{"cntpct_el0", CNTPCT_EL0},
- {"cntvct_el0", CNTVCT_EL0}
+ {"cntvct_el0", CNTVCT_EL0},
+
+ // Trace registers
+ {"trcstatr", TRCSTATR},
+ {"trcidr8", TRCIDR8},
+ {"trcidr9", TRCIDR9},
+ {"trcidr10", TRCIDR10},
+ {"trcidr11", TRCIDR11},
+ {"trcidr12", TRCIDR12},
+ {"trcidr13", TRCIDR13},
+ {"trcidr0", TRCIDR0},
+ {"trcidr1", TRCIDR1},
+ {"trcidr2", TRCIDR2},
+ {"trcidr3", TRCIDR3},
+ {"trcidr4", TRCIDR4},
+ {"trcidr5", TRCIDR5},
+ {"trcidr6", TRCIDR6},
+ {"trcidr7", TRCIDR7},
+ {"trcoslsr", TRCOSLSR},
+ {"trcpdsr", TRCPDSR},
+ {"trcdevaff0", TRCDEVAFF0},
+ {"trcdevaff1", TRCDEVAFF1},
+ {"trclsr", TRCLSR},
+ {"trcauthstatus", TRCAUTHSTATUS},
+ {"trcdevarch", TRCDEVARCH},
+ {"trcdevid", TRCDEVID},
+ {"trcdevtype", TRCDEVTYPE},
+ {"trcpidr4", TRCPIDR4},
+ {"trcpidr5", TRCPIDR5},
+ {"trcpidr6", TRCPIDR6},
+ {"trcpidr7", TRCPIDR7},
+ {"trcpidr0", TRCPIDR0},
+ {"trcpidr1", TRCPIDR1},
+ {"trcpidr2", TRCPIDR2},
+ {"trcpidr3", TRCPIDR3},
+ {"trccidr0", TRCCIDR0},
+ {"trccidr1", TRCCIDR1},
+ {"trccidr2", TRCCIDR2},
+ {"trccidr3", TRCCIDR3},
+
+ // GICv3 registers
+ {"icc_iar1_el1", ICC_IAR1_EL1},
+ {"icc_iar0_el1", ICC_IAR0_EL1},
+ {"icc_hppir1_el1", ICC_HPPIR1_EL1},
+ {"icc_hppir0_el1", ICC_HPPIR0_EL1},
+ {"icc_rpr_el1", ICC_RPR_EL1},
+ {"ich_vtr_el2", ICH_VTR_EL2},
+ {"ich_eisr_el2", ICH_EISR_EL2},
+ {"ich_elsr_el2", ICH_ELSR_EL2}
};
A64SysReg::MRSMapper::MRSMapper() {
@@ -205,7 +253,19 @@ A64SysReg::MRSMapper::MRSMapper() {
const NamedImmMapper::Mapping A64SysReg::MSRMapper::MSRPairs[] = {
{"dbgdtrtx_el0", DBGDTRTX_EL0},
{"oslar_el1", OSLAR_EL1},
- {"pmswinc_el0", PMSWINC_EL0}
+ {"pmswinc_el0", PMSWINC_EL0},
+
+ // Trace registers
+ {"trcoslar", TRCOSLAR},
+ {"trclar", TRCLAR},
+
+ // GICv3 registers
+ {"icc_eoir1_el1", ICC_EOIR1_EL1},
+ {"icc_eoir0_el1", ICC_EOIR0_EL1},
+ {"icc_dir_el1", ICC_DIR_EL1},
+ {"icc_sgi1r_el1", ICC_SGI1R_EL1},
+ {"icc_asgi1r_el1", ICC_ASGI1R_EL1},
+ {"icc_sgi0r_el1", ICC_SGI0R_EL1}
};
A64SysReg::MSRMapper::MSRMapper() {
@@ -467,6 +527,230 @@ const NamedImmMapper::Mapping A64SysReg::SysRegMapper::SysRegPairs[] = {
{"pmevtyper28_el0", PMEVTYPER28_EL0},
{"pmevtyper29_el0", PMEVTYPER29_EL0},
{"pmevtyper30_el0", PMEVTYPER30_EL0},
+
+ // Trace registers
+ {"trcprgctlr", TRCPRGCTLR},
+ {"trcprocselr", TRCPROCSELR},
+ {"trcconfigr", TRCCONFIGR},
+ {"trcauxctlr", TRCAUXCTLR},
+ {"trceventctl0r", TRCEVENTCTL0R},
+ {"trceventctl1r", TRCEVENTCTL1R},
+ {"trcstallctlr", TRCSTALLCTLR},
+ {"trctsctlr", TRCTSCTLR},
+ {"trcsyncpr", TRCSYNCPR},
+ {"trcccctlr", TRCCCCTLR},
+ {"trcbbctlr", TRCBBCTLR},
+ {"trctraceidr", TRCTRACEIDR},
+ {"trcqctlr", TRCQCTLR},
+ {"trcvictlr", TRCVICTLR},
+ {"trcviiectlr", TRCVIIECTLR},
+ {"trcvissctlr", TRCVISSCTLR},
+ {"trcvipcssctlr", TRCVIPCSSCTLR},
+ {"trcvdctlr", TRCVDCTLR},
+ {"trcvdsacctlr", TRCVDSACCTLR},
+ {"trcvdarcctlr", TRCVDARCCTLR},
+ {"trcseqevr0", TRCSEQEVR0},
+ {"trcseqevr1", TRCSEQEVR1},
+ {"trcseqevr2", TRCSEQEVR2},
+ {"trcseqrstevr", TRCSEQRSTEVR},
+ {"trcseqstr", TRCSEQSTR},
+ {"trcextinselr", TRCEXTINSELR},
+ {"trccntrldvr0", TRCCNTRLDVR0},
+ {"trccntrldvr1", TRCCNTRLDVR1},
+ {"trccntrldvr2", TRCCNTRLDVR2},
+ {"trccntrldvr3", TRCCNTRLDVR3},
+ {"trccntctlr0", TRCCNTCTLR0},
+ {"trccntctlr1", TRCCNTCTLR1},
+ {"trccntctlr2", TRCCNTCTLR2},
+ {"trccntctlr3", TRCCNTCTLR3},
+ {"trccntvr0", TRCCNTVR0},
+ {"trccntvr1", TRCCNTVR1},
+ {"trccntvr2", TRCCNTVR2},
+ {"trccntvr3", TRCCNTVR3},
+ {"trcimspec0", TRCIMSPEC0},
+ {"trcimspec1", TRCIMSPEC1},
+ {"trcimspec2", TRCIMSPEC2},
+ {"trcimspec3", TRCIMSPEC3},
+ {"trcimspec4", TRCIMSPEC4},
+ {"trcimspec5", TRCIMSPEC5},
+ {"trcimspec6", TRCIMSPEC6},
+ {"trcimspec7", TRCIMSPEC7},
+ {"trcrsctlr2", TRCRSCTLR2},
+ {"trcrsctlr3", TRCRSCTLR3},
+ {"trcrsctlr4", TRCRSCTLR4},
+ {"trcrsctlr5", TRCRSCTLR5},
+ {"trcrsctlr6", TRCRSCTLR6},
+ {"trcrsctlr7", TRCRSCTLR7},
+ {"trcrsctlr8", TRCRSCTLR8},
+ {"trcrsctlr9", TRCRSCTLR9},
+ {"trcrsctlr10", TRCRSCTLR10},
+ {"trcrsctlr11", TRCRSCTLR11},
+ {"trcrsctlr12", TRCRSCTLR12},
+ {"trcrsctlr13", TRCRSCTLR13},
+ {"trcrsctlr14", TRCRSCTLR14},
+ {"trcrsctlr15", TRCRSCTLR15},
+ {"trcrsctlr16", TRCRSCTLR16},
+ {"trcrsctlr17", TRCRSCTLR17},
+ {"trcrsctlr18", TRCRSCTLR18},
+ {"trcrsctlr19", TRCRSCTLR19},
+ {"trcrsctlr20", TRCRSCTLR20},
+ {"trcrsctlr21", TRCRSCTLR21},
+ {"trcrsctlr22", TRCRSCTLR22},
+ {"trcrsctlr23", TRCRSCTLR23},
+ {"trcrsctlr24", TRCRSCTLR24},
+ {"trcrsctlr25", TRCRSCTLR25},
+ {"trcrsctlr26", TRCRSCTLR26},
+ {"trcrsctlr27", TRCRSCTLR27},
+ {"trcrsctlr28", TRCRSCTLR28},
+ {"trcrsctlr29", TRCRSCTLR29},
+ {"trcrsctlr30", TRCRSCTLR30},
+ {"trcrsctlr31", TRCRSCTLR31},
+ {"trcssccr0", TRCSSCCR0},
+ {"trcssccr1", TRCSSCCR1},
+ {"trcssccr2", TRCSSCCR2},
+ {"trcssccr3", TRCSSCCR3},
+ {"trcssccr4", TRCSSCCR4},
+ {"trcssccr5", TRCSSCCR5},
+ {"trcssccr6", TRCSSCCR6},
+ {"trcssccr7", TRCSSCCR7},
+ {"trcsscsr0", TRCSSCSR0},
+ {"trcsscsr1", TRCSSCSR1},
+ {"trcsscsr2", TRCSSCSR2},
+ {"trcsscsr3", TRCSSCSR3},
+ {"trcsscsr4", TRCSSCSR4},
+ {"trcsscsr5", TRCSSCSR5},
+ {"trcsscsr6", TRCSSCSR6},
+ {"trcsscsr7", TRCSSCSR7},
+ {"trcsspcicr0", TRCSSPCICR0},
+ {"trcsspcicr1", TRCSSPCICR1},
+ {"trcsspcicr2", TRCSSPCICR2},
+ {"trcsspcicr3", TRCSSPCICR3},
+ {"trcsspcicr4", TRCSSPCICR4},
+ {"trcsspcicr5", TRCSSPCICR5},
+ {"trcsspcicr6", TRCSSPCICR6},
+ {"trcsspcicr7", TRCSSPCICR7},
+ {"trcpdcr", TRCPDCR},
+ {"trcacvr0", TRCACVR0},
+ {"trcacvr1", TRCACVR1},
+ {"trcacvr2", TRCACVR2},
+ {"trcacvr3", TRCACVR3},
+ {"trcacvr4", TRCACVR4},
+ {"trcacvr5", TRCACVR5},
+ {"trcacvr6", TRCACVR6},
+ {"trcacvr7", TRCACVR7},
+ {"trcacvr8", TRCACVR8},
+ {"trcacvr9", TRCACVR9},
+ {"trcacvr10", TRCACVR10},
+ {"trcacvr11", TRCACVR11},
+ {"trcacvr12", TRCACVR12},
+ {"trcacvr13", TRCACVR13},
+ {"trcacvr14", TRCACVR14},
+ {"trcacvr15", TRCACVR15},
+ {"trcacatr0", TRCACATR0},
+ {"trcacatr1", TRCACATR1},
+ {"trcacatr2", TRCACATR2},
+ {"trcacatr3", TRCACATR3},
+ {"trcacatr4", TRCACATR4},
+ {"trcacatr5", TRCACATR5},
+ {"trcacatr6", TRCACATR6},
+ {"trcacatr7", TRCACATR7},
+ {"trcacatr8", TRCACATR8},
+ {"trcacatr9", TRCACATR9},
+ {"trcacatr10", TRCACATR10},
+ {"trcacatr11", TRCACATR11},
+ {"trcacatr12", TRCACATR12},
+ {"trcacatr13", TRCACATR13},
+ {"trcacatr14", TRCACATR14},
+ {"trcacatr15", TRCACATR15},
+ {"trcdvcvr0", TRCDVCVR0},
+ {"trcdvcvr1", TRCDVCVR1},
+ {"trcdvcvr2", TRCDVCVR2},
+ {"trcdvcvr3", TRCDVCVR3},
+ {"trcdvcvr4", TRCDVCVR4},
+ {"trcdvcvr5", TRCDVCVR5},
+ {"trcdvcvr6", TRCDVCVR6},
+ {"trcdvcvr7", TRCDVCVR7},
+ {"trcdvcmr0", TRCDVCMR0},
+ {"trcdvcmr1", TRCDVCMR1},
+ {"trcdvcmr2", TRCDVCMR2},
+ {"trcdvcmr3", TRCDVCMR3},
+ {"trcdvcmr4", TRCDVCMR4},
+ {"trcdvcmr5", TRCDVCMR5},
+ {"trcdvcmr6", TRCDVCMR6},
+ {"trcdvcmr7", TRCDVCMR7},
+ {"trccidcvr0", TRCCIDCVR0},
+ {"trccidcvr1", TRCCIDCVR1},
+ {"trccidcvr2", TRCCIDCVR2},
+ {"trccidcvr3", TRCCIDCVR3},
+ {"trccidcvr4", TRCCIDCVR4},
+ {"trccidcvr5", TRCCIDCVR5},
+ {"trccidcvr6", TRCCIDCVR6},
+ {"trccidcvr7", TRCCIDCVR7},
+ {"trcvmidcvr0", TRCVMIDCVR0},
+ {"trcvmidcvr1", TRCVMIDCVR1},
+ {"trcvmidcvr2", TRCVMIDCVR2},
+ {"trcvmidcvr3", TRCVMIDCVR3},
+ {"trcvmidcvr4", TRCVMIDCVR4},
+ {"trcvmidcvr5", TRCVMIDCVR5},
+ {"trcvmidcvr6", TRCVMIDCVR6},
+ {"trcvmidcvr7", TRCVMIDCVR7},
+ {"trccidcctlr0", TRCCIDCCTLR0},
+ {"trccidcctlr1", TRCCIDCCTLR1},
+ {"trcvmidcctlr0", TRCVMIDCCTLR0},
+ {"trcvmidcctlr1", TRCVMIDCCTLR1},
+ {"trcitctrl", TRCITCTRL},
+ {"trcclaimset", TRCCLAIMSET},
+ {"trcclaimclr", TRCCLAIMCLR},
+
+ // GICv3 registers
+ {"icc_bpr1_el1", ICC_BPR1_EL1},
+ {"icc_bpr0_el1", ICC_BPR0_EL1},
+ {"icc_pmr_el1", ICC_PMR_EL1},
+ {"icc_ctlr_el1", ICC_CTLR_EL1},
+ {"icc_ctlr_el3", ICC_CTLR_EL3},
+ {"icc_sre_el1", ICC_SRE_EL1},
+ {"icc_sre_el2", ICC_SRE_EL2},
+ {"icc_sre_el3", ICC_SRE_EL3},
+ {"icc_igrpen0_el1", ICC_IGRPEN0_EL1},
+ {"icc_igrpen1_el1", ICC_IGRPEN1_EL1},
+ {"icc_igrpen1_el3", ICC_IGRPEN1_EL3},
+ {"icc_seien_el1", ICC_SEIEN_EL1},
+ {"icc_ap0r0_el1", ICC_AP0R0_EL1},
+ {"icc_ap0r1_el1", ICC_AP0R1_EL1},
+ {"icc_ap0r2_el1", ICC_AP0R2_EL1},
+ {"icc_ap0r3_el1", ICC_AP0R3_EL1},
+ {"icc_ap1r0_el1", ICC_AP1R0_EL1},
+ {"icc_ap1r1_el1", ICC_AP1R1_EL1},
+ {"icc_ap1r2_el1", ICC_AP1R2_EL1},
+ {"icc_ap1r3_el1", ICC_AP1R3_EL1},
+ {"ich_ap0r0_el2", ICH_AP0R0_EL2},
+ {"ich_ap0r1_el2", ICH_AP0R1_EL2},
+ {"ich_ap0r2_el2", ICH_AP0R2_EL2},
+ {"ich_ap0r3_el2", ICH_AP0R3_EL2},
+ {"ich_ap1r0_el2", ICH_AP1R0_EL2},
+ {"ich_ap1r1_el2", ICH_AP1R1_EL2},
+ {"ich_ap1r2_el2", ICH_AP1R2_EL2},
+ {"ich_ap1r3_el2", ICH_AP1R3_EL2},
+ {"ich_hcr_el2", ICH_HCR_EL2},
+ {"ich_misr_el2", ICH_MISR_EL2},
+ {"ich_vmcr_el2", ICH_VMCR_EL2},
+ {"ich_vseir_el2", ICH_VSEIR_EL2},
+ {"ich_lr0_el2", ICH_LR0_EL2},
+ {"ich_lr1_el2", ICH_LR1_EL2},
+ {"ich_lr2_el2", ICH_LR2_EL2},
+ {"ich_lr3_el2", ICH_LR3_EL2},
+ {"ich_lr4_el2", ICH_LR4_EL2},
+ {"ich_lr5_el2", ICH_LR5_EL2},
+ {"ich_lr6_el2", ICH_LR6_EL2},
+ {"ich_lr7_el2", ICH_LR7_EL2},
+ {"ich_lr8_el2", ICH_LR8_EL2},
+ {"ich_lr9_el2", ICH_LR9_EL2},
+ {"ich_lr10_el2", ICH_LR10_EL2},
+ {"ich_lr11_el2", ICH_LR11_EL2},
+ {"ich_lr12_el2", ICH_LR12_EL2},
+ {"ich_lr13_el2", ICH_LR13_EL2},
+ {"ich_lr14_el2", ICH_LR14_EL2},
+ {"ich_lr15_el2", ICH_LR15_EL2}
};
uint32_t
@@ -697,8 +981,11 @@ bool A64Imms::isLogicalImm(unsigned RegWidth, uint64_t Imm, uint32_t &Bits) {
Rotation = RepeatWidth - Rotation;
}
- uint64_t ReplicatedOnes = (ReplicatedMask >> Rotation)
- | ((ReplicatedMask << (RepeatWidth - Rotation)) & RepeatMask);
+ uint64_t ReplicatedOnes = ReplicatedMask;
+ if (Rotation != 0 && Rotation != 64)
+ ReplicatedOnes = (ReplicatedMask >> Rotation)
+ | ((ReplicatedMask << (RepeatWidth - Rotation)) & RepeatMask);
+
// Of course, they may not actually be ones, so we have to check that:
if (!isMask_64(ReplicatedOnes))
continue;
@@ -767,13 +1054,14 @@ bool A64Imms::isLogicalImmBits(unsigned RegWidth, uint32_t Bits,
int Rotation = (ImmR & (Width - 1));
uint64_t Mask = (1ULL << Num1s) - 1;
uint64_t WidthMask = Width == 64 ? -1 : (1ULL << Width) - 1;
- Mask = (Mask >> Rotation)
- | ((Mask << (Width - Rotation)) & WidthMask);
+ if (Rotation != 0 && Rotation != 64)
+ Mask = (Mask >> Rotation)
+ | ((Mask << (Width - Rotation)) & WidthMask);
- Imm = 0;
- for (unsigned i = 0; i < RegWidth / Width; ++i) {
- Imm |= Mask;
+ Imm = Mask;
+ for (unsigned i = 1; i < RegWidth / Width; ++i) {
Mask <<= Width;
+ Imm |= Mask;
}
return true;
diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 5eebf44..1b773d6 100644
--- a/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -354,13 +354,73 @@ namespace A64SysReg {
RVBAR_EL3 = 0xf601, // 11 110 1100 0000 001
ISR_EL1 = 0xc608, // 11 000 1100 0001 000
CNTPCT_EL0 = 0xdf01, // 11 011 1110 0000 001
- CNTVCT_EL0 = 0xdf02 // 11 011 1110 0000 010
+ CNTVCT_EL0 = 0xdf02, // 11 011 1110 0000 010
+
+ // Trace registers
+ TRCSTATR = 0x8818, // 10 001 0000 0011 000
+ TRCIDR8 = 0x8806, // 10 001 0000 0000 110
+ TRCIDR9 = 0x880e, // 10 001 0000 0001 110
+ TRCIDR10 = 0x8816, // 10 001 0000 0010 110
+ TRCIDR11 = 0x881e, // 10 001 0000 0011 110
+ TRCIDR12 = 0x8826, // 10 001 0000 0100 110
+ TRCIDR13 = 0x882e, // 10 001 0000 0101 110
+ TRCIDR0 = 0x8847, // 10 001 0000 1000 111
+ TRCIDR1 = 0x884f, // 10 001 0000 1001 111
+ TRCIDR2 = 0x8857, // 10 001 0000 1010 111
+ TRCIDR3 = 0x885f, // 10 001 0000 1011 111
+ TRCIDR4 = 0x8867, // 10 001 0000 1100 111
+ TRCIDR5 = 0x886f, // 10 001 0000 1101 111
+ TRCIDR6 = 0x8877, // 10 001 0000 1110 111
+ TRCIDR7 = 0x887f, // 10 001 0000 1111 111
+ TRCOSLSR = 0x888c, // 10 001 0001 0001 100
+ TRCPDSR = 0x88ac, // 10 001 0001 0101 100
+ TRCDEVAFF0 = 0x8bd6, // 10 001 0111 1010 110
+ TRCDEVAFF1 = 0x8bde, // 10 001 0111 1011 110
+ TRCLSR = 0x8bee, // 10 001 0111 1101 110
+ TRCAUTHSTATUS = 0x8bf6, // 10 001 0111 1110 110
+ TRCDEVARCH = 0x8bfe, // 10 001 0111 1111 110
+ TRCDEVID = 0x8b97, // 10 001 0111 0010 111
+ TRCDEVTYPE = 0x8b9f, // 10 001 0111 0011 111
+ TRCPIDR4 = 0x8ba7, // 10 001 0111 0100 111
+ TRCPIDR5 = 0x8baf, // 10 001 0111 0101 111
+ TRCPIDR6 = 0x8bb7, // 10 001 0111 0110 111
+ TRCPIDR7 = 0x8bbf, // 10 001 0111 0111 111
+ TRCPIDR0 = 0x8bc7, // 10 001 0111 1000 111
+ TRCPIDR1 = 0x8bcf, // 10 001 0111 1001 111
+ TRCPIDR2 = 0x8bd7, // 10 001 0111 1010 111
+ TRCPIDR3 = 0x8bdf, // 10 001 0111 1011 111
+ TRCCIDR0 = 0x8be7, // 10 001 0111 1100 111
+ TRCCIDR1 = 0x8bef, // 10 001 0111 1101 111
+ TRCCIDR2 = 0x8bf7, // 10 001 0111 1110 111
+ TRCCIDR3 = 0x8bff, // 10 001 0111 1111 111
+
+ // GICv3 registers
+ ICC_IAR1_EL1 = 0xc660, // 11 000 1100 1100 000
+ ICC_IAR0_EL1 = 0xc640, // 11 000 1100 1000 000
+ ICC_HPPIR1_EL1 = 0xc662, // 11 000 1100 1100 010
+ ICC_HPPIR0_EL1 = 0xc642, // 11 000 1100 1000 010
+ ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011
+ ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001
+ ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011
+ ICH_ELSR_EL2 = 0xe65d // 11 100 1100 1011 101
};
enum SysRegWOValues {
DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000
OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100
- PMSWINC_EL0 = 0xdce4 // 11 011 1001 1100 100
+ PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100
+
+ // Trace Registers
+ TRCOSLAR = 0x8884, // 10 001 0001 0000 100
+ TRCLAR = 0x8be6, // 10 001 0111 1100 110
+
+ // GICv3 registers
+ ICC_EOIR1_EL1 = 0xc661, // 11 000 1100 1100 001
+ ICC_EOIR0_EL1 = 0xc641, // 11 000 1100 1000 001
+ ICC_DIR_EL1 = 0xc659, // 11 000 1100 1011 001
+ ICC_SGI1R_EL1 = 0xc65d, // 11 000 1100 1011 101
+ ICC_ASGI1R_EL1 = 0xc65e, // 11 000 1100 1011 110
+ ICC_SGI0R_EL1 = 0xc65f // 11 000 1100 1011 111
};
enum SysRegValues {
@@ -616,7 +676,231 @@ namespace A64SysReg {
PMEVTYPER27_EL0 = 0xdf7b, // 11 011 1110 1111 011
PMEVTYPER28_EL0 = 0xdf7c, // 11 011 1110 1111 100
PMEVTYPER29_EL0 = 0xdf7d, // 11 011 1110 1111 101
- PMEVTYPER30_EL0 = 0xdf7e // 11 011 1110 1111 110
+ PMEVTYPER30_EL0 = 0xdf7e, // 11 011 1110 1111 110
+
+ // Trace registers
+ TRCPRGCTLR = 0x8808, // 10 001 0000 0001 000
+ TRCPROCSELR = 0x8810, // 10 001 0000 0010 000
+ TRCCONFIGR = 0x8820, // 10 001 0000 0100 000
+ TRCAUXCTLR = 0x8830, // 10 001 0000 0110 000
+ TRCEVENTCTL0R = 0x8840, // 10 001 0000 1000 000
+ TRCEVENTCTL1R = 0x8848, // 10 001 0000 1001 000
+ TRCSTALLCTLR = 0x8858, // 10 001 0000 1011 000
+ TRCTSCTLR = 0x8860, // 10 001 0000 1100 000
+ TRCSYNCPR = 0x8868, // 10 001 0000 1101 000
+ TRCCCCTLR = 0x8870, // 10 001 0000 1110 000
+ TRCBBCTLR = 0x8878, // 10 001 0000 1111 000
+ TRCTRACEIDR = 0x8801, // 10 001 0000 0000 001
+ TRCQCTLR = 0x8809, // 10 001 0000 0001 001
+ TRCVICTLR = 0x8802, // 10 001 0000 0000 010
+ TRCVIIECTLR = 0x880a, // 10 001 0000 0001 010
+ TRCVISSCTLR = 0x8812, // 10 001 0000 0010 010
+ TRCVIPCSSCTLR = 0x881a, // 10 001 0000 0011 010
+ TRCVDCTLR = 0x8842, // 10 001 0000 1000 010
+ TRCVDSACCTLR = 0x884a, // 10 001 0000 1001 010
+ TRCVDARCCTLR = 0x8852, // 10 001 0000 1010 010
+ TRCSEQEVR0 = 0x8804, // 10 001 0000 0000 100
+ TRCSEQEVR1 = 0x880c, // 10 001 0000 0001 100
+ TRCSEQEVR2 = 0x8814, // 10 001 0000 0010 100
+ TRCSEQRSTEVR = 0x8834, // 10 001 0000 0110 100
+ TRCSEQSTR = 0x883c, // 10 001 0000 0111 100
+ TRCEXTINSELR = 0x8844, // 10 001 0000 1000 100
+ TRCCNTRLDVR0 = 0x8805, // 10 001 0000 0000 101
+ TRCCNTRLDVR1 = 0x880d, // 10 001 0000 0001 101
+ TRCCNTRLDVR2 = 0x8815, // 10 001 0000 0010 101
+ TRCCNTRLDVR3 = 0x881d, // 10 001 0000 0011 101
+ TRCCNTCTLR0 = 0x8825, // 10 001 0000 0100 101
+ TRCCNTCTLR1 = 0x882d, // 10 001 0000 0101 101
+ TRCCNTCTLR2 = 0x8835, // 10 001 0000 0110 101
+ TRCCNTCTLR3 = 0x883d, // 10 001 0000 0111 101
+ TRCCNTVR0 = 0x8845, // 10 001 0000 1000 101
+ TRCCNTVR1 = 0x884d, // 10 001 0000 1001 101
+ TRCCNTVR2 = 0x8855, // 10 001 0000 1010 101
+ TRCCNTVR3 = 0x885d, // 10 001 0000 1011 101
+ TRCIMSPEC0 = 0x8807, // 10 001 0000 0000 111
+ TRCIMSPEC1 = 0x880f, // 10 001 0000 0001 111
+ TRCIMSPEC2 = 0x8817, // 10 001 0000 0010 111
+ TRCIMSPEC3 = 0x881f, // 10 001 0000 0011 111
+ TRCIMSPEC4 = 0x8827, // 10 001 0000 0100 111
+ TRCIMSPEC5 = 0x882f, // 10 001 0000 0101 111
+ TRCIMSPEC6 = 0x8837, // 10 001 0000 0110 111
+ TRCIMSPEC7 = 0x883f, // 10 001 0000 0111 111
+ TRCRSCTLR2 = 0x8890, // 10 001 0001 0010 000
+ TRCRSCTLR3 = 0x8898, // 10 001 0001 0011 000
+ TRCRSCTLR4 = 0x88a0, // 10 001 0001 0100 000
+ TRCRSCTLR5 = 0x88a8, // 10 001 0001 0101 000
+ TRCRSCTLR6 = 0x88b0, // 10 001 0001 0110 000
+ TRCRSCTLR7 = 0x88b8, // 10 001 0001 0111 000
+ TRCRSCTLR8 = 0x88c0, // 10 001 0001 1000 000
+ TRCRSCTLR9 = 0x88c8, // 10 001 0001 1001 000
+ TRCRSCTLR10 = 0x88d0, // 10 001 0001 1010 000
+ TRCRSCTLR11 = 0x88d8, // 10 001 0001 1011 000
+ TRCRSCTLR12 = 0x88e0, // 10 001 0001 1100 000
+ TRCRSCTLR13 = 0x88e8, // 10 001 0001 1101 000
+ TRCRSCTLR14 = 0x88f0, // 10 001 0001 1110 000
+ TRCRSCTLR15 = 0x88f8, // 10 001 0001 1111 000
+ TRCRSCTLR16 = 0x8881, // 10 001 0001 0000 001
+ TRCRSCTLR17 = 0x8889, // 10 001 0001 0001 001
+ TRCRSCTLR18 = 0x8891, // 10 001 0001 0010 001
+ TRCRSCTLR19 = 0x8899, // 10 001 0001 0011 001
+ TRCRSCTLR20 = 0x88a1, // 10 001 0001 0100 001
+ TRCRSCTLR21 = 0x88a9, // 10 001 0001 0101 001
+ TRCRSCTLR22 = 0x88b1, // 10 001 0001 0110 001
+ TRCRSCTLR23 = 0x88b9, // 10 001 0001 0111 001
+ TRCRSCTLR24 = 0x88c1, // 10 001 0001 1000 001
+ TRCRSCTLR25 = 0x88c9, // 10 001 0001 1001 001
+ TRCRSCTLR26 = 0x88d1, // 10 001 0001 1010 001
+ TRCRSCTLR27 = 0x88d9, // 10 001 0001 1011 001
+ TRCRSCTLR28 = 0x88e1, // 10 001 0001 1100 001
+ TRCRSCTLR29 = 0x88e9, // 10 001 0001 1101 001
+ TRCRSCTLR30 = 0x88f1, // 10 001 0001 1110 001
+ TRCRSCTLR31 = 0x88f9, // 10 001 0001 1111 001
+ TRCSSCCR0 = 0x8882, // 10 001 0001 0000 010
+ TRCSSCCR1 = 0x888a, // 10 001 0001 0001 010
+ TRCSSCCR2 = 0x8892, // 10 001 0001 0010 010
+ TRCSSCCR3 = 0x889a, // 10 001 0001 0011 010
+ TRCSSCCR4 = 0x88a2, // 10 001 0001 0100 010
+ TRCSSCCR5 = 0x88aa, // 10 001 0001 0101 010
+ TRCSSCCR6 = 0x88b2, // 10 001 0001 0110 010
+ TRCSSCCR7 = 0x88ba, // 10 001 0001 0111 010
+ TRCSSCSR0 = 0x88c2, // 10 001 0001 1000 010
+ TRCSSCSR1 = 0x88ca, // 10 001 0001 1001 010
+ TRCSSCSR2 = 0x88d2, // 10 001 0001 1010 010
+ TRCSSCSR3 = 0x88da, // 10 001 0001 1011 010
+ TRCSSCSR4 = 0x88e2, // 10 001 0001 1100 010
+ TRCSSCSR5 = 0x88ea, // 10 001 0001 1101 010
+ TRCSSCSR6 = 0x88f2, // 10 001 0001 1110 010
+ TRCSSCSR7 = 0x88fa, // 10 001 0001 1111 010
+ TRCSSPCICR0 = 0x8883, // 10 001 0001 0000 011
+ TRCSSPCICR1 = 0x888b, // 10 001 0001 0001 011
+ TRCSSPCICR2 = 0x8893, // 10 001 0001 0010 011
+ TRCSSPCICR3 = 0x889b, // 10 001 0001 0011 011
+ TRCSSPCICR4 = 0x88a3, // 10 001 0001 0100 011
+ TRCSSPCICR5 = 0x88ab, // 10 001 0001 0101 011
+ TRCSSPCICR6 = 0x88b3, // 10 001 0001 0110 011
+ TRCSSPCICR7 = 0x88bb, // 10 001 0001 0111 011
+ TRCPDCR = 0x88a4, // 10 001 0001 0100 100
+ TRCACVR0 = 0x8900, // 10 001 0010 0000 000
+ TRCACVR1 = 0x8910, // 10 001 0010 0010 000
+ TRCACVR2 = 0x8920, // 10 001 0010 0100 000
+ TRCACVR3 = 0x8930, // 10 001 0010 0110 000
+ TRCACVR4 = 0x8940, // 10 001 0010 1000 000
+ TRCACVR5 = 0x8950, // 10 001 0010 1010 000
+ TRCACVR6 = 0x8960, // 10 001 0010 1100 000
+ TRCACVR7 = 0x8970, // 10 001 0010 1110 000
+ TRCACVR8 = 0x8901, // 10 001 0010 0000 001
+ TRCACVR9 = 0x8911, // 10 001 0010 0010 001
+ TRCACVR10 = 0x8921, // 10 001 0010 0100 001
+ TRCACVR11 = 0x8931, // 10 001 0010 0110 001
+ TRCACVR12 = 0x8941, // 10 001 0010 1000 001
+ TRCACVR13 = 0x8951, // 10 001 0010 1010 001
+ TRCACVR14 = 0x8961, // 10 001 0010 1100 001
+ TRCACVR15 = 0x8971, // 10 001 0010 1110 001
+ TRCACATR0 = 0x8902, // 10 001 0010 0000 010
+ TRCACATR1 = 0x8912, // 10 001 0010 0010 010
+ TRCACATR2 = 0x8922, // 10 001 0010 0100 010
+ TRCACATR3 = 0x8932, // 10 001 0010 0110 010
+ TRCACATR4 = 0x8942, // 10 001 0010 1000 010
+ TRCACATR5 = 0x8952, // 10 001 0010 1010 010
+ TRCACATR6 = 0x8962, // 10 001 0010 1100 010
+ TRCACATR7 = 0x8972, // 10 001 0010 1110 010
+ TRCACATR8 = 0x8903, // 10 001 0010 0000 011
+ TRCACATR9 = 0x8913, // 10 001 0010 0010 011
+ TRCACATR10 = 0x8923, // 10 001 0010 0100 011
+ TRCACATR11 = 0x8933, // 10 001 0010 0110 011
+ TRCACATR12 = 0x8943, // 10 001 0010 1000 011
+ TRCACATR13 = 0x8953, // 10 001 0010 1010 011
+ TRCACATR14 = 0x8963, // 10 001 0010 1100 011
+ TRCACATR15 = 0x8973, // 10 001 0010 1110 011
+ TRCDVCVR0 = 0x8904, // 10 001 0010 0000 100
+ TRCDVCVR1 = 0x8924, // 10 001 0010 0100 100
+ TRCDVCVR2 = 0x8944, // 10 001 0010 1000 100
+ TRCDVCVR3 = 0x8964, // 10 001 0010 1100 100
+ TRCDVCVR4 = 0x8905, // 10 001 0010 0000 101
+ TRCDVCVR5 = 0x8925, // 10 001 0010 0100 101
+ TRCDVCVR6 = 0x8945, // 10 001 0010 1000 101
+ TRCDVCVR7 = 0x8965, // 10 001 0010 1100 101
+ TRCDVCMR0 = 0x8906, // 10 001 0010 0000 110
+ TRCDVCMR1 = 0x8926, // 10 001 0010 0100 110
+ TRCDVCMR2 = 0x8946, // 10 001 0010 1000 110
+ TRCDVCMR3 = 0x8966, // 10 001 0010 1100 110
+ TRCDVCMR4 = 0x8907, // 10 001 0010 0000 111
+ TRCDVCMR5 = 0x8927, // 10 001 0010 0100 111
+ TRCDVCMR6 = 0x8947, // 10 001 0010 1000 111
+ TRCDVCMR7 = 0x8967, // 10 001 0010 1100 111
+ TRCCIDCVR0 = 0x8980, // 10 001 0011 0000 000
+ TRCCIDCVR1 = 0x8990, // 10 001 0011 0010 000
+ TRCCIDCVR2 = 0x89a0, // 10 001 0011 0100 000
+ TRCCIDCVR3 = 0x89b0, // 10 001 0011 0110 000
+ TRCCIDCVR4 = 0x89c0, // 10 001 0011 1000 000
+ TRCCIDCVR5 = 0x89d0, // 10 001 0011 1010 000
+ TRCCIDCVR6 = 0x89e0, // 10 001 0011 1100 000
+ TRCCIDCVR7 = 0x89f0, // 10 001 0011 1110 000
+ TRCVMIDCVR0 = 0x8981, // 10 001 0011 0000 001
+ TRCVMIDCVR1 = 0x8991, // 10 001 0011 0010 001
+ TRCVMIDCVR2 = 0x89a1, // 10 001 0011 0100 001
+ TRCVMIDCVR3 = 0x89b1, // 10 001 0011 0110 001
+ TRCVMIDCVR4 = 0x89c1, // 10 001 0011 1000 001
+ TRCVMIDCVR5 = 0x89d1, // 10 001 0011 1010 001
+ TRCVMIDCVR6 = 0x89e1, // 10 001 0011 1100 001
+ TRCVMIDCVR7 = 0x89f1, // 10 001 0011 1110 001
+ TRCCIDCCTLR0 = 0x8982, // 10 001 0011 0000 010
+ TRCCIDCCTLR1 = 0x898a, // 10 001 0011 0001 010
+ TRCVMIDCCTLR0 = 0x8992, // 10 001 0011 0010 010
+ TRCVMIDCCTLR1 = 0x899a, // 10 001 0011 0011 010
+ TRCITCTRL = 0x8b84, // 10 001 0111 0000 100
+ TRCCLAIMSET = 0x8bc6, // 10 001 0111 1000 110
+ TRCCLAIMCLR = 0x8bce, // 10 001 0111 1001 110
+
+ // GICv3 registers
+ ICC_BPR1_EL1 = 0xc663, // 11 000 1100 1100 011
+ ICC_BPR0_EL1 = 0xc643, // 11 000 1100 1000 011
+ ICC_PMR_EL1 = 0xc230, // 11 000 0100 0110 000
+ ICC_CTLR_EL1 = 0xc664, // 11 000 1100 1100 100
+ ICC_CTLR_EL3 = 0xf664, // 11 110 1100 1100 100
+ ICC_SRE_EL1 = 0xc665, // 11 000 1100 1100 101
+ ICC_SRE_EL2 = 0xe64d, // 11 100 1100 1001 101
+ ICC_SRE_EL3 = 0xf665, // 11 110 1100 1100 101
+ ICC_IGRPEN0_EL1 = 0xc666, // 11 000 1100 1100 110
+ ICC_IGRPEN1_EL1 = 0xc667, // 11 000 1100 1100 111
+ ICC_IGRPEN1_EL3 = 0xf667, // 11 110 1100 1100 111
+ ICC_SEIEN_EL1 = 0xc668, // 11 000 1100 1101 000
+ ICC_AP0R0_EL1 = 0xc644, // 11 000 1100 1000 100
+ ICC_AP0R1_EL1 = 0xc645, // 11 000 1100 1000 101
+ ICC_AP0R2_EL1 = 0xc646, // 11 000 1100 1000 110
+ ICC_AP0R3_EL1 = 0xc647, // 11 000 1100 1000 111
+ ICC_AP1R0_EL1 = 0xc648, // 11 000 1100 1001 000
+ ICC_AP1R1_EL1 = 0xc649, // 11 000 1100 1001 001
+ ICC_AP1R2_EL1 = 0xc64a, // 11 000 1100 1001 010
+ ICC_AP1R3_EL1 = 0xc64b, // 11 000 1100 1001 011
+ ICH_AP0R0_EL2 = 0xe640, // 11 100 1100 1000 000
+ ICH_AP0R1_EL2 = 0xe641, // 11 100 1100 1000 001
+ ICH_AP0R2_EL2 = 0xe642, // 11 100 1100 1000 010
+ ICH_AP0R3_EL2 = 0xe643, // 11 100 1100 1000 011
+ ICH_AP1R0_EL2 = 0xe648, // 11 100 1100 1001 000
+ ICH_AP1R1_EL2 = 0xe649, // 11 100 1100 1001 001
+ ICH_AP1R2_EL2 = 0xe64a, // 11 100 1100 1001 010
+ ICH_AP1R3_EL2 = 0xe64b, // 11 100 1100 1001 011
+ ICH_HCR_EL2 = 0xe658, // 11 100 1100 1011 000
+ ICH_MISR_EL2 = 0xe65a, // 11 100 1100 1011 010
+ ICH_VMCR_EL2 = 0xe65f, // 11 100 1100 1011 111
+ ICH_VSEIR_EL2 = 0xe64c, // 11 100 1100 1001 100
+ ICH_LR0_EL2 = 0xe660, // 11 100 1100 1100 000
+ ICH_LR1_EL2 = 0xe661, // 11 100 1100 1100 001
+ ICH_LR2_EL2 = 0xe662, // 11 100 1100 1100 010
+ ICH_LR3_EL2 = 0xe663, // 11 100 1100 1100 011
+ ICH_LR4_EL2 = 0xe664, // 11 100 1100 1100 100
+ ICH_LR5_EL2 = 0xe665, // 11 100 1100 1100 101
+ ICH_LR6_EL2 = 0xe666, // 11 100 1100 1100 110
+ ICH_LR7_EL2 = 0xe667, // 11 100 1100 1100 111
+ ICH_LR8_EL2 = 0xe668, // 11 100 1100 1101 000
+ ICH_LR9_EL2 = 0xe669, // 11 100 1100 1101 001
+ ICH_LR10_EL2 = 0xe66a, // 11 100 1100 1101 010
+ ICH_LR11_EL2 = 0xe66b, // 11 100 1100 1101 011
+ ICH_LR12_EL2 = 0xe66c, // 11 100 1100 1101 100
+ ICH_LR13_EL2 = 0xe66d, // 11 100 1100 1101 101
+ ICH_LR14_EL2 = 0xe66e, // 11 100 1100 1101 110
+ ICH_LR15_EL2 = 0xe66f // 11 100 1100 1101 111
};
// Note that these do not inherit from NamedImmMapper. This class is