diff options
Diffstat (limited to 'lib/Target/AArch64')
-rw-r--r-- | lib/Target/AArch64/AArch64FrameLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 106 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.cpp | 140 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrFormats.td | 2 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.td | 1071 | ||||
-rw-r--r-- | lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp | 9 | ||||
-rw-r--r-- | lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 306 | ||||
-rw-r--r-- | lib/Target/AArch64/Utils/AArch64BaseInfo.h | 290 |
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 |