10b57cec5SDimitry Andric//===-- ARMRegisterInfo.td - ARM Register defs -------------*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andricinclude "ARMSystemRegister.td" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric// Declarations that describe the ARM register file 130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric// Registers are identified with 4-bit ID numbers. 160b57cec5SDimitry Andricclass ARMReg<bits<16> Enc, string n, list<Register> subregs = [], 170b57cec5SDimitry Andric list<string> altNames = []> : Register<n, altNames> { 180b57cec5SDimitry Andric let HWEncoding = Enc; 190b57cec5SDimitry Andric let Namespace = "ARM"; 200b57cec5SDimitry Andric let SubRegs = subregs; 210b57cec5SDimitry Andric // All bits of ARM registers with sub-registers are covered by sub-registers. 220b57cec5SDimitry Andric let CoveredBySubRegs = 1; 230b57cec5SDimitry Andric} 240b57cec5SDimitry Andric 250b57cec5SDimitry Andricclass ARMFReg<bits<16> Enc, string n> : Register<n> { 260b57cec5SDimitry Andric let HWEncoding = Enc; 270b57cec5SDimitry Andric let Namespace = "ARM"; 280b57cec5SDimitry Andric} 290b57cec5SDimitry Andric 300b57cec5SDimitry Andriclet Namespace = "ARM", 310b57cec5SDimitry Andric FallbackRegAltNameIndex = NoRegAltName in { 320b57cec5SDimitry Andric def RegNamesRaw : RegAltNameIndex; 330b57cec5SDimitry Andric} 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric// Subregister indices. 360b57cec5SDimitry Andriclet Namespace = "ARM" in { 370b57cec5SDimitry Andricdef qqsub_0 : SubRegIndex<256>; 380b57cec5SDimitry Andricdef qqsub_1 : SubRegIndex<256, 256>; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric// Note: Code depends on these having consecutive numbers. 410b57cec5SDimitry Andricdef qsub_0 : SubRegIndex<128>; 420b57cec5SDimitry Andricdef qsub_1 : SubRegIndex<128, 128>; 430b57cec5SDimitry Andricdef qsub_2 : ComposedSubRegIndex<qqsub_1, qsub_0>; 440b57cec5SDimitry Andricdef qsub_3 : ComposedSubRegIndex<qqsub_1, qsub_1>; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andricdef dsub_0 : SubRegIndex<64>; 470b57cec5SDimitry Andricdef dsub_1 : SubRegIndex<64, 64>; 480b57cec5SDimitry Andricdef dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>; 490b57cec5SDimitry Andricdef dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>; 500b57cec5SDimitry Andricdef dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>; 510b57cec5SDimitry Andricdef dsub_5 : ComposedSubRegIndex<qsub_2, dsub_1>; 520b57cec5SDimitry Andricdef dsub_6 : ComposedSubRegIndex<qsub_3, dsub_0>; 530b57cec5SDimitry Andricdef dsub_7 : ComposedSubRegIndex<qsub_3, dsub_1>; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andricdef ssub_0 : SubRegIndex<32>; 560b57cec5SDimitry Andricdef ssub_1 : SubRegIndex<32, 32>; 570b57cec5SDimitry Andricdef ssub_2 : ComposedSubRegIndex<dsub_1, ssub_0>; 580b57cec5SDimitry Andricdef ssub_3 : ComposedSubRegIndex<dsub_1, ssub_1>; 590b57cec5SDimitry Andricdef ssub_4 : ComposedSubRegIndex<dsub_2, ssub_0>; 600b57cec5SDimitry Andricdef ssub_5 : ComposedSubRegIndex<dsub_2, ssub_1>; 610b57cec5SDimitry Andricdef ssub_6 : ComposedSubRegIndex<dsub_3, ssub_0>; 620b57cec5SDimitry Andricdef ssub_7 : ComposedSubRegIndex<dsub_3, ssub_1>; 630b57cec5SDimitry Andricdef ssub_8 : ComposedSubRegIndex<dsub_4, ssub_0>; 640b57cec5SDimitry Andricdef ssub_9 : ComposedSubRegIndex<dsub_4, ssub_1>; 650b57cec5SDimitry Andricdef ssub_10 : ComposedSubRegIndex<dsub_5, ssub_0>; 660b57cec5SDimitry Andricdef ssub_11 : ComposedSubRegIndex<dsub_5, ssub_1>; 670b57cec5SDimitry Andricdef ssub_12 : ComposedSubRegIndex<dsub_6, ssub_0>; 680b57cec5SDimitry Andricdef ssub_13 : ComposedSubRegIndex<dsub_6, ssub_1>; 69349cc55cSDimitry Andricdef ssub_14 : ComposedSubRegIndex<dsub_7, ssub_0>; 70349cc55cSDimitry Andricdef ssub_15 : ComposedSubRegIndex<dsub_7, ssub_1>; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andricdef gsub_0 : SubRegIndex<32>; 730b57cec5SDimitry Andricdef gsub_1 : SubRegIndex<32, 32>; 740b57cec5SDimitry Andric// Let TableGen synthesize the remaining 12 ssub_* indices. 750b57cec5SDimitry Andric// We don't need to name them. 760b57cec5SDimitry Andric} 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric// Integer registers 790b57cec5SDimitry Andricdef R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>; 800b57cec5SDimitry Andricdef R1 : ARMReg< 1, "r1">, DwarfRegNum<[1]>; 810b57cec5SDimitry Andricdef R2 : ARMReg< 2, "r2">, DwarfRegNum<[2]>; 820b57cec5SDimitry Andricdef R3 : ARMReg< 3, "r3">, DwarfRegNum<[3]>; 830b57cec5SDimitry Andricdef R4 : ARMReg< 4, "r4">, DwarfRegNum<[4]>; 840b57cec5SDimitry Andricdef R5 : ARMReg< 5, "r5">, DwarfRegNum<[5]>; 850b57cec5SDimitry Andricdef R6 : ARMReg< 6, "r6">, DwarfRegNum<[6]>; 860b57cec5SDimitry Andricdef R7 : ARMReg< 7, "r7">, DwarfRegNum<[7]>; 870b57cec5SDimitry Andric// These require 32-bit instructions. 88fe6060f1SDimitry Andriclet CostPerUse = [1] in { 890b57cec5SDimitry Andricdef R8 : ARMReg< 8, "r8">, DwarfRegNum<[8]>; 900b57cec5SDimitry Andricdef R9 : ARMReg< 9, "r9">, DwarfRegNum<[9]>; 910b57cec5SDimitry Andricdef R10 : ARMReg<10, "r10">, DwarfRegNum<[10]>; 920b57cec5SDimitry Andricdef R11 : ARMReg<11, "r11">, DwarfRegNum<[11]>; 930b57cec5SDimitry Andricdef R12 : ARMReg<12, "r12">, DwarfRegNum<[12]>; 940b57cec5SDimitry Andriclet RegAltNameIndices = [RegNamesRaw] in { 950b57cec5SDimitry Andricdef SP : ARMReg<13, "sp", [], ["r13"]>, DwarfRegNum<[13]>; 960b57cec5SDimitry Andricdef LR : ARMReg<14, "lr", [], ["r14"]>, DwarfRegNum<[14]>; 970b57cec5SDimitry Andricdef PC : ARMReg<15, "pc", [], ["r15"]>, DwarfRegNum<[15]>; 980b57cec5SDimitry Andric} 990b57cec5SDimitry Andric} 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric// Float registers 1020b57cec5SDimitry Andricdef S0 : ARMFReg< 0, "s0">; def S1 : ARMFReg< 1, "s1">; 1030b57cec5SDimitry Andricdef S2 : ARMFReg< 2, "s2">; def S3 : ARMFReg< 3, "s3">; 1040b57cec5SDimitry Andricdef S4 : ARMFReg< 4, "s4">; def S5 : ARMFReg< 5, "s5">; 1050b57cec5SDimitry Andricdef S6 : ARMFReg< 6, "s6">; def S7 : ARMFReg< 7, "s7">; 1060b57cec5SDimitry Andricdef S8 : ARMFReg< 8, "s8">; def S9 : ARMFReg< 9, "s9">; 1070b57cec5SDimitry Andricdef S10 : ARMFReg<10, "s10">; def S11 : ARMFReg<11, "s11">; 1080b57cec5SDimitry Andricdef S12 : ARMFReg<12, "s12">; def S13 : ARMFReg<13, "s13">; 1090b57cec5SDimitry Andricdef S14 : ARMFReg<14, "s14">; def S15 : ARMFReg<15, "s15">; 1100b57cec5SDimitry Andricdef S16 : ARMFReg<16, "s16">; def S17 : ARMFReg<17, "s17">; 1110b57cec5SDimitry Andricdef S18 : ARMFReg<18, "s18">; def S19 : ARMFReg<19, "s19">; 1120b57cec5SDimitry Andricdef S20 : ARMFReg<20, "s20">; def S21 : ARMFReg<21, "s21">; 1130b57cec5SDimitry Andricdef S22 : ARMFReg<22, "s22">; def S23 : ARMFReg<23, "s23">; 1140b57cec5SDimitry Andricdef S24 : ARMFReg<24, "s24">; def S25 : ARMFReg<25, "s25">; 1150b57cec5SDimitry Andricdef S26 : ARMFReg<26, "s26">; def S27 : ARMFReg<27, "s27">; 1160b57cec5SDimitry Andricdef S28 : ARMFReg<28, "s28">; def S29 : ARMFReg<29, "s29">; 1170b57cec5SDimitry Andricdef S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric// Aliases of the F* registers used to hold 64-bit fp values (doubles) 1200b57cec5SDimitry Andriclet SubRegIndices = [ssub_0, ssub_1] in { 1210b57cec5SDimitry Andricdef D0 : ARMReg< 0, "d0", [S0, S1]>, DwarfRegNum<[256]>; 1220b57cec5SDimitry Andricdef D1 : ARMReg< 1, "d1", [S2, S3]>, DwarfRegNum<[257]>; 1230b57cec5SDimitry Andricdef D2 : ARMReg< 2, "d2", [S4, S5]>, DwarfRegNum<[258]>; 1240b57cec5SDimitry Andricdef D3 : ARMReg< 3, "d3", [S6, S7]>, DwarfRegNum<[259]>; 1250b57cec5SDimitry Andricdef D4 : ARMReg< 4, "d4", [S8, S9]>, DwarfRegNum<[260]>; 1260b57cec5SDimitry Andricdef D5 : ARMReg< 5, "d5", [S10, S11]>, DwarfRegNum<[261]>; 1270b57cec5SDimitry Andricdef D6 : ARMReg< 6, "d6", [S12, S13]>, DwarfRegNum<[262]>; 1280b57cec5SDimitry Andricdef D7 : ARMReg< 7, "d7", [S14, S15]>, DwarfRegNum<[263]>; 1290b57cec5SDimitry Andricdef D8 : ARMReg< 8, "d8", [S16, S17]>, DwarfRegNum<[264]>; 1300b57cec5SDimitry Andricdef D9 : ARMReg< 9, "d9", [S18, S19]>, DwarfRegNum<[265]>; 1310b57cec5SDimitry Andricdef D10 : ARMReg<10, "d10", [S20, S21]>, DwarfRegNum<[266]>; 1320b57cec5SDimitry Andricdef D11 : ARMReg<11, "d11", [S22, S23]>, DwarfRegNum<[267]>; 1330b57cec5SDimitry Andricdef D12 : ARMReg<12, "d12", [S24, S25]>, DwarfRegNum<[268]>; 1340b57cec5SDimitry Andricdef D13 : ARMReg<13, "d13", [S26, S27]>, DwarfRegNum<[269]>; 1350b57cec5SDimitry Andricdef D14 : ARMReg<14, "d14", [S28, S29]>, DwarfRegNum<[270]>; 1360b57cec5SDimitry Andricdef D15 : ARMReg<15, "d15", [S30, S31]>, DwarfRegNum<[271]>; 1370b57cec5SDimitry Andric} 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric// VFP3 defines 16 additional double registers 1400b57cec5SDimitry Andricdef D16 : ARMFReg<16, "d16">, DwarfRegNum<[272]>; 1410b57cec5SDimitry Andricdef D17 : ARMFReg<17, "d17">, DwarfRegNum<[273]>; 1420b57cec5SDimitry Andricdef D18 : ARMFReg<18, "d18">, DwarfRegNum<[274]>; 1430b57cec5SDimitry Andricdef D19 : ARMFReg<19, "d19">, DwarfRegNum<[275]>; 1440b57cec5SDimitry Andricdef D20 : ARMFReg<20, "d20">, DwarfRegNum<[276]>; 1450b57cec5SDimitry Andricdef D21 : ARMFReg<21, "d21">, DwarfRegNum<[277]>; 1460b57cec5SDimitry Andricdef D22 : ARMFReg<22, "d22">, DwarfRegNum<[278]>; 1470b57cec5SDimitry Andricdef D23 : ARMFReg<23, "d23">, DwarfRegNum<[279]>; 1480b57cec5SDimitry Andricdef D24 : ARMFReg<24, "d24">, DwarfRegNum<[280]>; 1490b57cec5SDimitry Andricdef D25 : ARMFReg<25, "d25">, DwarfRegNum<[281]>; 1500b57cec5SDimitry Andricdef D26 : ARMFReg<26, "d26">, DwarfRegNum<[282]>; 1510b57cec5SDimitry Andricdef D27 : ARMFReg<27, "d27">, DwarfRegNum<[283]>; 1520b57cec5SDimitry Andricdef D28 : ARMFReg<28, "d28">, DwarfRegNum<[284]>; 1530b57cec5SDimitry Andricdef D29 : ARMFReg<29, "d29">, DwarfRegNum<[285]>; 1540b57cec5SDimitry Andricdef D30 : ARMFReg<30, "d30">, DwarfRegNum<[286]>; 1550b57cec5SDimitry Andricdef D31 : ARMFReg<31, "d31">, DwarfRegNum<[287]>; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric// Advanced SIMD (NEON) defines 16 quad-word aliases 1580b57cec5SDimitry Andriclet SubRegIndices = [dsub_0, dsub_1] in { 1590b57cec5SDimitry Andricdef Q0 : ARMReg< 0, "q0", [D0, D1]>; 1600b57cec5SDimitry Andricdef Q1 : ARMReg< 1, "q1", [D2, D3]>; 1610b57cec5SDimitry Andricdef Q2 : ARMReg< 2, "q2", [D4, D5]>; 1620b57cec5SDimitry Andricdef Q3 : ARMReg< 3, "q3", [D6, D7]>; 1630b57cec5SDimitry Andricdef Q4 : ARMReg< 4, "q4", [D8, D9]>; 1640b57cec5SDimitry Andricdef Q5 : ARMReg< 5, "q5", [D10, D11]>; 1650b57cec5SDimitry Andricdef Q6 : ARMReg< 6, "q6", [D12, D13]>; 1660b57cec5SDimitry Andricdef Q7 : ARMReg< 7, "q7", [D14, D15]>; 1670b57cec5SDimitry Andric} 1680b57cec5SDimitry Andriclet SubRegIndices = [dsub_0, dsub_1] in { 1690b57cec5SDimitry Andricdef Q8 : ARMReg< 8, "q8", [D16, D17]>; 1700b57cec5SDimitry Andricdef Q9 : ARMReg< 9, "q9", [D18, D19]>; 1710b57cec5SDimitry Andricdef Q10 : ARMReg<10, "q10", [D20, D21]>; 1720b57cec5SDimitry Andricdef Q11 : ARMReg<11, "q11", [D22, D23]>; 1730b57cec5SDimitry Andricdef Q12 : ARMReg<12, "q12", [D24, D25]>; 1740b57cec5SDimitry Andricdef Q13 : ARMReg<13, "q13", [D26, D27]>; 1750b57cec5SDimitry Andricdef Q14 : ARMReg<14, "q14", [D28, D29]>; 1760b57cec5SDimitry Andricdef Q15 : ARMReg<15, "q15", [D30, D31]>; 1770b57cec5SDimitry Andric} 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric// Current Program Status Register. 1800b57cec5SDimitry Andric// We model fpscr with two registers: FPSCR models the control bits and will be 1810b57cec5SDimitry Andric// reserved. FPSCR_NZCV models the flag bits and will be unreserved. APSR_NZCV 1820b57cec5SDimitry Andric// models the APSR when it's accessed by some special instructions. In such cases 1830b57cec5SDimitry Andric// it has the same encoding as PC. 1840b57cec5SDimitry Andricdef CPSR : ARMReg<0, "cpsr">; 1858bcb0991SDimitry Andricdef APSR : ARMReg<15, "apsr">; 1860b57cec5SDimitry Andricdef APSR_NZCV : ARMReg<15, "apsr_nzcv">; 1870b57cec5SDimitry Andricdef SPSR : ARMReg<2, "spsr">; 1880b57cec5SDimitry Andricdef FPSCR : ARMReg<3, "fpscr">; 1890b57cec5SDimitry Andricdef FPSCR_NZCV : ARMReg<3, "fpscr_nzcv"> { 1900b57cec5SDimitry Andric let Aliases = [FPSCR]; 1910b57cec5SDimitry Andric} 1920b57cec5SDimitry Andricdef ITSTATE : ARMReg<4, "itstate">; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric// Special Registers - only available in privileged mode. 1950b57cec5SDimitry Andricdef FPSID : ARMReg<0, "fpsid">; 1960b57cec5SDimitry Andricdef MVFR2 : ARMReg<5, "mvfr2">; 1970b57cec5SDimitry Andricdef MVFR1 : ARMReg<6, "mvfr1">; 1980b57cec5SDimitry Andricdef MVFR0 : ARMReg<7, "mvfr0">; 1990b57cec5SDimitry Andricdef FPEXC : ARMReg<8, "fpexc">; 2000b57cec5SDimitry Andricdef FPINST : ARMReg<9, "fpinst">; 2010b57cec5SDimitry Andricdef FPINST2 : ARMReg<10, "fpinst2">; 2020b57cec5SDimitry Andric// These encodings aren't actual instruction encodings, their encoding depends 2030b57cec5SDimitry Andric// on the instruction they are used in and for VPR 32 was chosen such that it 2040b57cec5SDimitry Andric// always comes last in spr_reglist_with_vpr. 2050b57cec5SDimitry Andricdef VPR : ARMReg<32, "vpr">; 2060b57cec5SDimitry Andricdef FPSCR_NZCVQC 2070b57cec5SDimitry Andric : ARMReg<2, "fpscr_nzcvqc">; 2080b57cec5SDimitry Andricdef P0 : ARMReg<13, "p0">; 2090b57cec5SDimitry Andricdef FPCXTNS : ARMReg<14, "fpcxtns">; 2100b57cec5SDimitry Andricdef FPCXTS : ARMReg<15, "fpcxts">; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andricdef ZR : ARMReg<15, "zr">, DwarfRegNum<[15]>; 2130b57cec5SDimitry Andric 2140eae32dcSDimitry Andricdef RA_AUTH_CODE : ARMReg<12, "ra_auth_code">, DwarfRegNum<[143]>; 2150eae32dcSDimitry Andric 2160b57cec5SDimitry Andric// Register classes. 2170b57cec5SDimitry Andric// 2180b57cec5SDimitry Andric// pc == Program Counter 2190b57cec5SDimitry Andric// lr == Link Register 2200b57cec5SDimitry Andric// sp == Stack Pointer 2210b57cec5SDimitry Andric// r12 == ip (scratch) 2220b57cec5SDimitry Andric// r7 == Frame Pointer (thumb-style backtraces) 2230b57cec5SDimitry Andric// r9 == May be reserved as Thread Register 2240b57cec5SDimitry Andric// r11 == Frame Pointer (arm-style backtraces) 2250b57cec5SDimitry Andric// r10 == Stack Limit 2260b57cec5SDimitry Andric// 2270b57cec5SDimitry Andricdef GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), 2280b57cec5SDimitry Andric SP, LR, PC)> { 2290b57cec5SDimitry Andric // Allocate LR as the first CSR since it is always saved anyway. 2300b57cec5SDimitry Andric // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't 2310b57cec5SDimitry Andric // know how to spill them. If we make our prologue/epilogue code smarter at 2320b57cec5SDimitry Andric // some point, we can go back to using the above allocation orders for the 2330b57cec5SDimitry Andric // Thumb1 instructions that know how to use hi regs. 2340b57cec5SDimitry Andric let AltOrders = [(add LR, GPR), (trunc GPR, 8), 2350b57cec5SDimitry Andric (add (trunc GPR, 8), R12, LR, (shl GPR, 8))]; 2360b57cec5SDimitry Andric let AltOrderSelect = [{ 2370b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF); 2380b57cec5SDimitry Andric }]; 2390b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r15]"; 2400b57cec5SDimitry Andric} 2410b57cec5SDimitry Andric 242e8d8bef9SDimitry Andric// Register set that excludes registers that are reserved for procedure calls. 243e8d8bef9SDimitry Andric// This is used for pseudo-instructions that are actually implemented using a 244e8d8bef9SDimitry Andric// procedure call. 245e8d8bef9SDimitry Andricdef GPRnoip : RegisterClass<"ARM", [i32], 32, (sub GPR, R12, LR)> { 246e8d8bef9SDimitry Andric // Allocate LR as the first CSR since it is always saved anyway. 247e8d8bef9SDimitry Andric // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't 248e8d8bef9SDimitry Andric // know how to spill them. If we make our prologue/epilogue code smarter at 249e8d8bef9SDimitry Andric // some point, we can go back to using the above allocation orders for the 250e8d8bef9SDimitry Andric // Thumb1 instructions that know how to use hi regs. 251e8d8bef9SDimitry Andric let AltOrders = [(add GPRnoip, GPRnoip), (trunc GPRnoip, 8), 252e8d8bef9SDimitry Andric (add (trunc GPRnoip, 8), (shl GPRnoip, 8))]; 253e8d8bef9SDimitry Andric let AltOrderSelect = [{ 254e8d8bef9SDimitry Andric return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF); 255e8d8bef9SDimitry Andric }]; 256e8d8bef9SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r14]"; 257e8d8bef9SDimitry Andric} 258e8d8bef9SDimitry Andric 2590b57cec5SDimitry Andric// GPRs without the PC. Some ARM instructions do not allow the PC in 2600b57cec5SDimitry Andric// certain operand slots, particularly as the destination. Primarily 2610b57cec5SDimitry Andric// useful for disassembly. 2620b57cec5SDimitry Andricdef GPRnopc : RegisterClass<"ARM", [i32], 32, (sub GPR, PC)> { 2630b57cec5SDimitry Andric let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8), 2640b57cec5SDimitry Andric (add (trunc GPRnopc, 8), R12, LR, (shl GPRnopc, 8))]; 2650b57cec5SDimitry Andric let AltOrderSelect = [{ 2660b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF); 2670b57cec5SDimitry Andric }]; 2680b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r14]"; 2690b57cec5SDimitry Andric} 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric// GPRs without the PC but with APSR. Some instructions allow accessing the 2720b57cec5SDimitry Andric// APSR, while actually encoding PC in the register field. This is useful 2730b57cec5SDimitry Andric// for assembly and disassembly only. 2740b57cec5SDimitry Andricdef GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)> { 2750b57cec5SDimitry Andric let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)]; 2760b57cec5SDimitry Andric let AltOrderSelect = [{ 2770b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 2780b57cec5SDimitry Andric }]; 2790b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r14] or apsr_nzcv"; 2800b57cec5SDimitry Andric} 2810b57cec5SDimitry Andric 2824824e7fdSDimitry Andric// GPRs without the SP register. Used for BXAUT and AUTG 2834824e7fdSDimitry Andricdef GPRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, PC)> { 2844824e7fdSDimitry Andric let AltOrders = [(add LR, GPRnosp), (trunc GPRnosp, 8), 2854824e7fdSDimitry Andric (add (trunc GPRnosp, 8), R12, LR, (shl GPRnosp, 8))]; 2864824e7fdSDimitry Andric let AltOrderSelect = [{ 2874824e7fdSDimitry Andric return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF); 2884824e7fdSDimitry Andric }]; 2894824e7fdSDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r12] or LR or PC"; 2904824e7fdSDimitry Andric} 2914824e7fdSDimitry Andric 2920b57cec5SDimitry Andric// GPRs without the PC and SP registers but with APSR. Used by CLRM instruction. 2930b57cec5SDimitry Andricdef GPRwithAPSRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, APSR)> { 2940b57cec5SDimitry Andric let isAllocatable = 0; 2950b57cec5SDimitry Andric} 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andricdef GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), ZR)> { 2980b57cec5SDimitry Andric let AltOrders = [(add LR, GPRwithZR), (trunc GPRwithZR, 8)]; 2990b57cec5SDimitry Andric let AltOrderSelect = [{ 3000b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 3010b57cec5SDimitry Andric }]; 3020b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r14] or zr"; 3030b57cec5SDimitry Andric} 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andricdef GPRwithZRnosp : RegisterClass<"ARM", [i32], 32, (sub GPRwithZR, SP)> { 3060b57cec5SDimitry Andric let AltOrders = [(add LR, GPRwithZRnosp), (trunc GPRwithZRnosp, 8)]; 3070b57cec5SDimitry Andric let AltOrderSelect = [{ 3080b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 3090b57cec5SDimitry Andric }]; 3100b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r12] or r14 or zr"; 3110b57cec5SDimitry Andric} 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric// GPRsp - Only the SP is legal. Used by Thumb1 instructions that want the 3140b57cec5SDimitry Andric// implied SP argument list. 3150b57cec5SDimitry Andric// FIXME: It would be better to not use this at all and refactor the 3160b57cec5SDimitry Andric// instructions to not have SP an an explicit argument. That makes 3170b57cec5SDimitry Andric// frame index resolution a bit trickier, though. 3180b57cec5SDimitry Andricdef GPRsp : RegisterClass<"ARM", [i32], 32, (add SP)> { 3190b57cec5SDimitry Andric let DiagnosticString = "operand must be a register sp"; 3200b57cec5SDimitry Andric} 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric// GPRlr - Only LR is legal. Used by ARMv8.1-M Low Overhead Loop instructions 3230b57cec5SDimitry Andric// where LR is the only legal loop counter register. 3240b57cec5SDimitry Andricdef GPRlr : RegisterClass<"ARM", [i32], 32, (add LR)>; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric// restricted GPR register class. Many Thumb2 instructions allow the full 3270b57cec5SDimitry Andric// register range for operands, but have undefined behaviours when PC 3280b57cec5SDimitry Andric// or SP (R13 or R15) are used. The ARM ISA refers to these operands 3290b57cec5SDimitry Andric// via the BadReg() pseudo-code description. 3300b57cec5SDimitry Andricdef rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> { 3310b57cec5SDimitry Andric let AltOrders = [(add LR, rGPR), (trunc rGPR, 8), 3320b57cec5SDimitry Andric (add (trunc rGPR, 8), R12, LR, (shl rGPR, 8))]; 3330b57cec5SDimitry Andric let AltOrderSelect = [{ 3340b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF); 3350b57cec5SDimitry Andric }]; 3360b57cec5SDimitry Andric let DiagnosticType = "rGPR"; 3370b57cec5SDimitry Andric} 3380b57cec5SDimitry Andric 3395ffd83dbSDimitry Andric// GPRs without the PC and SP but with APSR_NZCV.Some instructions allow 3405ffd83dbSDimitry Andric// accessing the APSR_NZCV, while actually encoding PC in the register field. 3415ffd83dbSDimitry Andric// This is useful for assembly and disassembly only. 3425ffd83dbSDimitry Andric// Currently used by the CDE extension. 3435ffd83dbSDimitry Andricdef GPRwithAPSR_NZCVnosp 3445ffd83dbSDimitry Andric : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, APSR_NZCV)> { 3455ffd83dbSDimitry Andric let isAllocatable = 0; 3465ffd83dbSDimitry Andric let DiagnosticString = 3475ffd83dbSDimitry Andric "operand must be a register in the range [r0, r12], r14 or apsr_nzcv"; 3485ffd83dbSDimitry Andric} 3495ffd83dbSDimitry Andric 3500b57cec5SDimitry Andric// Thumb registers are R0-R7 normally. Some instructions can still use 3510b57cec5SDimitry Andric// the general GPR register class above (MOV, e.g.) 3520b57cec5SDimitry Andricdef tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)> { 3530b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r0, r7]"; 3540b57cec5SDimitry Andric} 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric// Thumb registers R0-R7 and the PC. Some instructions like TBB or THH allow 3570b57cec5SDimitry Andric// the PC to be used as a destination operand as well. 3580b57cec5SDimitry Andricdef tGPRwithpc : RegisterClass<"ARM", [i32], 32, (add tGPR, PC)>; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric// The high registers in thumb mode, R8-R15. 3610b57cec5SDimitry Andricdef hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)> { 3620b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [r8, r15]"; 3630b57cec5SDimitry Andric} 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric// For tail calls, we can't use callee-saved registers, as they are restored 3660b57cec5SDimitry Andric// to the saved value before the tail call, which would clobber a call address. 3670b57cec5SDimitry Andric// Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of 3680b57cec5SDimitry Andric// this class and the preceding one(!) This is what we want. 3690b57cec5SDimitry Andricdef tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R12)> { 3700b57cec5SDimitry Andric let AltOrders = [(and tcGPR, tGPR)]; 3710b57cec5SDimitry Andric let AltOrderSelect = [{ 3720b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 3730b57cec5SDimitry Andric }]; 3740b57cec5SDimitry Andric} 3750b57cec5SDimitry Andric 376*0fca6ea1SDimitry Andric// Some pointer authentication instructions require the use of R12. When return 377*0fca6ea1SDimitry Andric// address signing is enabled, authentication of the caller's return address 378*0fca6ea1SDimitry Andric// must be performed before a tail call is made. Therefore, indirect tail call 379*0fca6ea1SDimitry Andric// jump cannot be from R12. 380*0fca6ea1SDimitry Andric// FIXME: All PACBTI instruction currently implemented in the compiler 381*0fca6ea1SDimitry Andric// implicitly use R12. When instructions that allow PAC to be placed in a 382*0fca6ea1SDimitry Andric// specific register are implemented the restriction needs to be updated to 383*0fca6ea1SDimitry Andric// make sure that PACBTI signature and indirect tail call both use a different register. 384*0fca6ea1SDimitry Andricdef tcGPRnotr12 : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3)>; 385*0fca6ea1SDimitry Andric 3860b57cec5SDimitry Andricdef tGPROdd : RegisterClass<"ARM", [i32], 32, (add R1, R3, R5, R7, R9, R11)> { 3870b57cec5SDimitry Andric let AltOrders = [(and tGPROdd, tGPR)]; 3880b57cec5SDimitry Andric let AltOrderSelect = [{ 3890b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 3900b57cec5SDimitry Andric }]; 3910b57cec5SDimitry Andric let DiagnosticString = 3920b57cec5SDimitry Andric "operand must be an odd-numbered register in range [r1,r11]"; 3930b57cec5SDimitry Andric} 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andricdef tGPREven : RegisterClass<"ARM", [i32], 32, (add R0, R2, R4, R6, R8, R10, R12, LR)> { 3960b57cec5SDimitry Andric let AltOrders = [(and tGPREven, tGPR)]; 3970b57cec5SDimitry Andric let AltOrderSelect = [{ 3980b57cec5SDimitry Andric return MF.getSubtarget<ARMSubtarget>().isThumb1Only(); 3990b57cec5SDimitry Andric }]; 4000b57cec5SDimitry Andric let DiagnosticString = "operand must be an even-numbered register"; 4010b57cec5SDimitry Andric} 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric// Condition code registers. 4040b57cec5SDimitry Andricdef CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> { 4050b57cec5SDimitry Andric let CopyCost = -1; // Don't allow copying of status registers. 4060b57cec5SDimitry Andric let isAllocatable = 0; 4070b57cec5SDimitry Andric} 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric// MVE Condition code register. 4100eae32dcSDimitry Andricdef VCCR : RegisterClass<"ARM", [i32, v16i1, v8i1, v4i1, v2i1], 32, (add VPR)> { 4110b57cec5SDimitry Andric// let CopyCost = -1; // Don't allow copying of status registers. 4120b57cec5SDimitry Andric} 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric// FPSCR, when the flags at the top of it are used as the input or 4150b57cec5SDimitry Andric// output to an instruction such as MVE VADC. 4160b57cec5SDimitry Andricdef cl_FPSCR_NZCV : RegisterClass<"ARM", [i32], 32, (add FPSCR_NZCV)>; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric// Scalar single precision floating point register class.. 4190b57cec5SDimitry Andric// FIXME: Allocation order changed to s0, s2, ... or s0, s4, ... as a quick hack 4200b57cec5SDimitry Andric// to avoid partial-write dependencies on D or Q (depending on platform) 4210b57cec5SDimitry Andric// registers (S registers are renamed as portions of D/Q registers). 4220b57cec5SDimitry Andricdef SPR : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 31)> { 4230b57cec5SDimitry Andric let AltOrders = [(add (decimate SPR, 2), SPR), 4240b57cec5SDimitry Andric (add (decimate SPR, 4), 4250b57cec5SDimitry Andric (decimate SPR, 2), 4260b57cec5SDimitry Andric (decimate (rotl SPR, 1), 4), 4270b57cec5SDimitry Andric (decimate (rotl SPR, 1), 2))]; 4280b57cec5SDimitry Andric let AltOrderSelect = [{ 4290b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs(); 4300b57cec5SDimitry Andric }]; 4310b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [s0, s31]"; 4320b57cec5SDimitry Andric} 4330b57cec5SDimitry Andric 4345ffd83dbSDimitry Andricdef HPR : RegisterClass<"ARM", [f16, bf16], 32, (sequence "S%u", 0, 31)> { 4350b57cec5SDimitry Andric let AltOrders = [(add (decimate HPR, 2), SPR), 4360b57cec5SDimitry Andric (add (decimate HPR, 4), 4370b57cec5SDimitry Andric (decimate HPR, 2), 4380b57cec5SDimitry Andric (decimate (rotl HPR, 1), 4), 4390b57cec5SDimitry Andric (decimate (rotl HPR, 1), 2))]; 4400b57cec5SDimitry Andric let AltOrderSelect = [{ 4410b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs(); 4420b57cec5SDimitry Andric }]; 4430b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [s0, s31]"; 4440b57cec5SDimitry Andric} 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric// Subset of SPR which can be used as a source of NEON scalars for 16-bit 4470b57cec5SDimitry Andric// operations 4480b57cec5SDimitry Andricdef SPR_8 : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 15)> { 4490b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [s0, s15]"; 4500b57cec5SDimitry Andric} 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric// Scalar double precision floating point / generic 64-bit vector register 4530b57cec5SDimitry Andric// class. 4540b57cec5SDimitry Andric// ARM requires only word alignment for double. It's more performant if it 4550b57cec5SDimitry Andric// is double-word alignment though. 4565ffd83dbSDimitry Andricdef DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64, 4570b57cec5SDimitry Andric (sequence "D%u", 0, 31)> { 4580b57cec5SDimitry Andric // Allocate non-VFP2 registers D16-D31 first, and prefer even registers on 4590b57cec5SDimitry Andric // Darwin platforms. 4600b57cec5SDimitry Andric let AltOrders = [(rotl DPR, 16), 4610b57cec5SDimitry Andric (add (decimate (rotl DPR, 16), 2), (rotl DPR, 16))]; 4620b57cec5SDimitry Andric let AltOrderSelect = [{ 4630b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs(); 4640b57cec5SDimitry Andric }]; 4650b57cec5SDimitry Andric let DiagnosticType = "DPR"; 4660b57cec5SDimitry Andric} 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric// Scalar single and double precision floating point and VPR register class, 4690b57cec5SDimitry Andric// this is only used for parsing, don't use it anywhere else as the size and 4700b57cec5SDimitry Andric// types don't match! 4710b57cec5SDimitry Andricdef FPWithVPR : RegisterClass<"ARM", [f32], 32, (add SPR, DPR, VPR)> { 4720b57cec5SDimitry Andric let isAllocatable = 0; 4730b57cec5SDimitry Andric} 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric// Subset of DPR that are accessible with VFP2 (and so that also have 4760b57cec5SDimitry Andric// 32-bit SPR subregs). 4775ffd83dbSDimitry Andricdef DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64, 4780b57cec5SDimitry Andric (trunc DPR, 16)> { 4790b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [d0, d15]"; 4800b57cec5SDimitry Andric} 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric// Subset of DPR which can be used as a source of NEON scalars for 16-bit 4830b57cec5SDimitry Andric// operations 4845ffd83dbSDimitry Andricdef DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64, 4850b57cec5SDimitry Andric (trunc DPR, 8)> { 4860b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [d0, d7]"; 4870b57cec5SDimitry Andric} 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric// Generic 128-bit vector register class. 4905ffd83dbSDimitry Andricdef QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16, v8bf16], 128, 4910b57cec5SDimitry Andric (sequence "Q%u", 0, 15)> { 4920b57cec5SDimitry Andric // Allocate non-VFP2 aliases Q8-Q15 first. 4930b57cec5SDimitry Andric let AltOrders = [(rotl QPR, 8), (trunc QPR, 8)]; 4940b57cec5SDimitry Andric let AltOrderSelect = [{ 4950b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps(); 4960b57cec5SDimitry Andric }]; 4970b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [q0, q15]"; 4980b57cec5SDimitry Andric} 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric// Subset of QPR that have 32-bit SPR subregs. 5010b57cec5SDimitry Andricdef QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 5020b57cec5SDimitry Andric 128, (trunc QPR, 8)> { 5030b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [q0, q7]"; 5040b57cec5SDimitry Andric} 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric// Subset of QPR that have DPR_8 and SPR_8 subregs. 5070b57cec5SDimitry Andricdef QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 5080b57cec5SDimitry Andric 128, (trunc QPR, 4)> { 5090b57cec5SDimitry Andric let DiagnosticString = "operand must be a register in range [q0, q3]"; 5100b57cec5SDimitry Andric} 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric// MVE 128-bit vector register class. This class is only really needed for 5130b57cec5SDimitry Andric// parsing assembly, since we still have to truncate the register set in the QPR 5140b57cec5SDimitry Andric// class anyway. 5150b57cec5SDimitry Andricdef MQPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 5160b57cec5SDimitry Andric 128, (trunc QPR, 8)>; 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric// Pseudo-registers representing odd-even pairs of D registers. The even-odd 5190b57cec5SDimitry Andric// pairs are already represented by the Q registers. 5200b57cec5SDimitry Andric// These are needed by NEON instructions requiring two consecutive D registers. 5210b57cec5SDimitry Andric// There is no D31_D0 register as that is always an UNPREDICTABLE encoding. 5220b57cec5SDimitry Andricdef TuplesOE2D : RegisterTuples<[dsub_0, dsub_1], 5230b57cec5SDimitry Andric [(decimate (shl DPR, 1), 2), 5240b57cec5SDimitry Andric (decimate (shl DPR, 2), 2)]>; 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric// Register class representing a pair of consecutive D registers. 5270b57cec5SDimitry Andric// Use the Q registers for the even-odd pairs. 5280b57cec5SDimitry Andricdef DPair : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 5290b57cec5SDimitry Andric 128, (interleave QPR, TuplesOE2D)> { 5300b57cec5SDimitry Andric // Allocate starting at non-VFP2 registers D16-D31 first. 5310b57cec5SDimitry Andric // Prefer even-odd pairs as they are easier to copy. 5320b57cec5SDimitry Andric let AltOrders = [(add (rotl QPR, 8), (rotl DPair, 16)), 5330b57cec5SDimitry Andric (add (trunc QPR, 8), (trunc DPair, 16))]; 5340b57cec5SDimitry Andric let AltOrderSelect = [{ 5350b57cec5SDimitry Andric return 1 + MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps(); 5360b57cec5SDimitry Andric }]; 5370b57cec5SDimitry Andric} 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric// Pseudo-registers representing even-odd pairs of GPRs from R1 to R13/SP. 5400b57cec5SDimitry Andric// These are needed by instructions (e.g. ldrexd/strexd) requiring even-odd GPRs. 5418bcb0991SDimitry Andricdef Tuples2Rnosp : RegisterTuples<[gsub_0, gsub_1], 5428bcb0991SDimitry Andric [(add R0, R2, R4, R6, R8, R10), 5438bcb0991SDimitry Andric (add R1, R3, R5, R7, R9, R11)]>; 5448bcb0991SDimitry Andric 5458bcb0991SDimitry Andricdef Tuples2Rsp : RegisterTuples<[gsub_0, gsub_1], 5468bcb0991SDimitry Andric [(add R12), (add SP)]>; 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric// Register class representing a pair of even-odd GPRs. 5498bcb0991SDimitry Andricdef GPRPair : RegisterClass<"ARM", [untyped], 64, (add Tuples2Rnosp, Tuples2Rsp)> { 5508bcb0991SDimitry Andric let Size = 64; // 2 x 32 bits, we have no predefined type of that size. 5518bcb0991SDimitry Andric} 5528bcb0991SDimitry Andric 5538bcb0991SDimitry Andric// Register class representing a pair of even-odd GPRs, except (R12, SP). 5548bcb0991SDimitry Andricdef GPRPairnosp : RegisterClass<"ARM", [untyped], 64, (add Tuples2Rnosp)> { 5550b57cec5SDimitry Andric let Size = 64; // 2 x 32 bits, we have no predefined type of that size. 5560b57cec5SDimitry Andric} 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric// Pseudo-registers representing 3 consecutive D registers. 5590b57cec5SDimitry Andricdef Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2], 5600b57cec5SDimitry Andric [(shl DPR, 0), 5610b57cec5SDimitry Andric (shl DPR, 1), 5620b57cec5SDimitry Andric (shl DPR, 2)]>; 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric// 3 consecutive D registers. 5650b57cec5SDimitry Andricdef DTriple : RegisterClass<"ARM", [untyped], 64, (add Tuples3D)> { 5660b57cec5SDimitry Andric let Size = 192; // 3 x 64 bits, we have no predefined type of that size. 5670b57cec5SDimitry Andric} 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric// Pseudo 256-bit registers to represent pairs of Q registers. These should 5700b57cec5SDimitry Andric// never be present in the emitted code. 5710b57cec5SDimitry Andric// These are used for NEON load / store instructions, e.g., vld4, vst3. 5720b57cec5SDimitry Andricdef Tuples2Q : RegisterTuples<[qsub_0, qsub_1], [(shl QPR, 0), (shl QPR, 1)]>; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric// Pseudo 256-bit vector register class to model pairs of Q registers 5750b57cec5SDimitry Andric// (4 consecutive D registers). 5760b57cec5SDimitry Andricdef QQPR : RegisterClass<"ARM", [v4i64], 256, (add Tuples2Q)> { 5770b57cec5SDimitry Andric // Allocate non-VFP2 aliases first. 5780b57cec5SDimitry Andric let AltOrders = [(rotl QQPR, 8)]; 5790b57cec5SDimitry Andric let AltOrderSelect = [{ return 1; }]; 5800b57cec5SDimitry Andric} 5810b57cec5SDimitry Andric 582349cc55cSDimitry Andric// Same as QQPR but for MVE, containing the 7 register pairs made up from Q0-Q7. 583349cc55cSDimitry Andricdef MQQPR : RegisterClass<"ARM", [v4i64], 256, (trunc QQPR, 7)>; 584349cc55cSDimitry Andric 5850b57cec5SDimitry Andric// Tuples of 4 D regs that isn't also a pair of Q regs. 5860b57cec5SDimitry Andricdef TuplesOE4D : RegisterTuples<[dsub_0, dsub_1, dsub_2, dsub_3], 5870b57cec5SDimitry Andric [(decimate (shl DPR, 1), 2), 5880b57cec5SDimitry Andric (decimate (shl DPR, 2), 2), 5890b57cec5SDimitry Andric (decimate (shl DPR, 3), 2), 5900b57cec5SDimitry Andric (decimate (shl DPR, 4), 2)]>; 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric// 4 consecutive D registers. 5930b57cec5SDimitry Andricdef DQuad : RegisterClass<"ARM", [v4i64], 256, 5940b57cec5SDimitry Andric (interleave Tuples2Q, TuplesOE4D)>; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric// Pseudo 512-bit registers to represent four consecutive Q registers. 5970b57cec5SDimitry Andricdef Tuples2QQ : RegisterTuples<[qqsub_0, qqsub_1], 5980b57cec5SDimitry Andric [(shl QQPR, 0), (shl QQPR, 2)]>; 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric// Pseudo 512-bit vector register class to model 4 consecutive Q registers 6010b57cec5SDimitry Andric// (8 consecutive D registers). 6020b57cec5SDimitry Andricdef QQQQPR : RegisterClass<"ARM", [v8i64], 256, (add Tuples2QQ)> { 6030b57cec5SDimitry Andric // Allocate non-VFP2 aliases first. 6040b57cec5SDimitry Andric let AltOrders = [(rotl QQQQPR, 8)]; 6050b57cec5SDimitry Andric let AltOrderSelect = [{ return 1; }]; 6060b57cec5SDimitry Andric} 6070b57cec5SDimitry Andric 608349cc55cSDimitry Andric// Same as QQPR but for MVE, containing the 5 register quads made up from Q0-Q7. 609349cc55cSDimitry Andricdef MQQQQPR : RegisterClass<"ARM", [v8i64], 256, (trunc QQQQPR, 5)>; 610349cc55cSDimitry Andric 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric// Pseudo-registers representing 2-spaced consecutive D registers. 6130b57cec5SDimitry Andricdef Tuples2DSpc : RegisterTuples<[dsub_0, dsub_2], 6140b57cec5SDimitry Andric [(shl DPR, 0), 6150b57cec5SDimitry Andric (shl DPR, 2)]>; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric// Spaced pairs of D registers. 6180b57cec5SDimitry Andricdef DPairSpc : RegisterClass<"ARM", [v2i64], 64, (add Tuples2DSpc)>; 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andricdef Tuples3DSpc : RegisterTuples<[dsub_0, dsub_2, dsub_4], 6210b57cec5SDimitry Andric [(shl DPR, 0), 6220b57cec5SDimitry Andric (shl DPR, 2), 6230b57cec5SDimitry Andric (shl DPR, 4)]>; 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric// Spaced triples of D registers. 6260b57cec5SDimitry Andricdef DTripleSpc : RegisterClass<"ARM", [untyped], 64, (add Tuples3DSpc)> { 6270b57cec5SDimitry Andric let Size = 192; // 3 x 64 bits, we have no predefined type of that size. 6280b57cec5SDimitry Andric} 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andricdef Tuples4DSpc : RegisterTuples<[dsub_0, dsub_2, dsub_4, dsub_6], 6310b57cec5SDimitry Andric [(shl DPR, 0), 6320b57cec5SDimitry Andric (shl DPR, 2), 6330b57cec5SDimitry Andric (shl DPR, 4), 6340b57cec5SDimitry Andric (shl DPR, 6)]>; 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric// Spaced quads of D registers. 6370b57cec5SDimitry Andricdef DQuadSpc : RegisterClass<"ARM", [v4i64], 64, (add Tuples3DSpc)>; 6385ffd83dbSDimitry Andric 6395ffd83dbSDimitry Andric// FP context payload 6405ffd83dbSDimitry Andricdef FPCXTRegs : RegisterClass<"ARM", [i32], 32, (add FPCXTNS)>; 641