1*0b57cec5SDimitry Andric//===-- AVRRegisterInfo.td - AVR Register defs -------------*- tablegen -*-===// 2*0b57cec5SDimitry Andric// 3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric// 7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 10*0b57cec5SDimitry Andric// Declarations that describe the AVR register file 11*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric// 8-bit General purpose register definition. 14*0b57cec5SDimitry Andricclass AVRReg<bits<16> num, 15*0b57cec5SDimitry Andric string name, 16*0b57cec5SDimitry Andric list<Register> subregs = [], 17*0b57cec5SDimitry Andric list<string> altNames = []> 18*0b57cec5SDimitry Andric : RegisterWithSubRegs<name, subregs> 19*0b57cec5SDimitry Andric{ 20*0b57cec5SDimitry Andric field bits<16> Num = num; 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric let HWEncoding = num; 23*0b57cec5SDimitry Andric let Namespace = "AVR"; 24*0b57cec5SDimitry Andric let SubRegs = subregs; 25*0b57cec5SDimitry Andric let AltNames = altNames; 26*0b57cec5SDimitry Andric} 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric// Subregister indices. 29*0b57cec5SDimitry Andriclet Namespace = "AVR" in 30*0b57cec5SDimitry Andric{ 31*0b57cec5SDimitry Andric def sub_lo : SubRegIndex<8>; 32*0b57cec5SDimitry Andric def sub_hi : SubRegIndex<8, 8>; 33*0b57cec5SDimitry Andric} 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andriclet Namespace = "AVR" in { 36*0b57cec5SDimitry Andric def ptr : RegAltNameIndex; 37*0b57cec5SDimitry Andric} 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 41*0b57cec5SDimitry Andric// 8-bit general purpose registers 42*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andricdef R0 : AVRReg<0, "r0">, DwarfRegNum<[0]>; 45*0b57cec5SDimitry Andricdef R1 : AVRReg<1, "r1">, DwarfRegNum<[1]>; 46*0b57cec5SDimitry Andricdef R2 : AVRReg<2, "r2">, DwarfRegNum<[2]>; 47*0b57cec5SDimitry Andricdef R3 : AVRReg<3, "r3">, DwarfRegNum<[3]>; 48*0b57cec5SDimitry Andricdef R4 : AVRReg<4, "r4">, DwarfRegNum<[4]>; 49*0b57cec5SDimitry Andricdef R5 : AVRReg<5, "r5">, DwarfRegNum<[5]>; 50*0b57cec5SDimitry Andricdef R6 : AVRReg<6, "r6">, DwarfRegNum<[6]>; 51*0b57cec5SDimitry Andricdef R7 : AVRReg<7, "r7">, DwarfRegNum<[7]>; 52*0b57cec5SDimitry Andricdef R8 : AVRReg<8, "r8">, DwarfRegNum<[8]>; 53*0b57cec5SDimitry Andricdef R9 : AVRReg<9, "r9">, DwarfRegNum<[9]>; 54*0b57cec5SDimitry Andricdef R10 : AVRReg<10, "r10">, DwarfRegNum<[10]>; 55*0b57cec5SDimitry Andricdef R11 : AVRReg<11, "r11">, DwarfRegNum<[11]>; 56*0b57cec5SDimitry Andricdef R12 : AVRReg<12, "r12">, DwarfRegNum<[12]>; 57*0b57cec5SDimitry Andricdef R13 : AVRReg<13, "r13">, DwarfRegNum<[13]>; 58*0b57cec5SDimitry Andricdef R14 : AVRReg<14, "r14">, DwarfRegNum<[14]>; 59*0b57cec5SDimitry Andricdef R15 : AVRReg<15, "r15">, DwarfRegNum<[15]>; 60*0b57cec5SDimitry Andricdef R16 : AVRReg<16, "r16">, DwarfRegNum<[16]>; 61*0b57cec5SDimitry Andricdef R17 : AVRReg<17, "r17">, DwarfRegNum<[17]>; 62*0b57cec5SDimitry Andricdef R18 : AVRReg<18, "r18">, DwarfRegNum<[18]>; 63*0b57cec5SDimitry Andricdef R19 : AVRReg<19, "r19">, DwarfRegNum<[19]>; 64*0b57cec5SDimitry Andricdef R20 : AVRReg<20, "r20">, DwarfRegNum<[20]>; 65*0b57cec5SDimitry Andricdef R21 : AVRReg<21, "r21">, DwarfRegNum<[21]>; 66*0b57cec5SDimitry Andricdef R22 : AVRReg<22, "r22">, DwarfRegNum<[22]>; 67*0b57cec5SDimitry Andricdef R23 : AVRReg<23, "r23">, DwarfRegNum<[23]>; 68*0b57cec5SDimitry Andricdef R24 : AVRReg<24, "r24">, DwarfRegNum<[24]>; 69*0b57cec5SDimitry Andricdef R25 : AVRReg<25, "r25">, DwarfRegNum<[25]>; 70*0b57cec5SDimitry Andricdef R26 : AVRReg<26, "r26">, DwarfRegNum<[26]>; 71*0b57cec5SDimitry Andricdef R27 : AVRReg<27, "r27">, DwarfRegNum<[27]>; 72*0b57cec5SDimitry Andricdef R28 : AVRReg<28, "r28">, DwarfRegNum<[28]>; 73*0b57cec5SDimitry Andricdef R29 : AVRReg<29, "r29">, DwarfRegNum<[29]>; 74*0b57cec5SDimitry Andricdef R30 : AVRReg<30, "r30">, DwarfRegNum<[30]>; 75*0b57cec5SDimitry Andricdef R31 : AVRReg<31, "r31">, DwarfRegNum<[31]>; 76*0b57cec5SDimitry Andricdef SPL : AVRReg<32, "SPL">, DwarfRegNum<[32]>; 77*0b57cec5SDimitry Andricdef SPH : AVRReg<33, "SPH">, DwarfRegNum<[33]>; 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andriclet SubRegIndices = [sub_lo, sub_hi], 80*0b57cec5SDimitry AndricCoveredBySubRegs = 1 in 81*0b57cec5SDimitry Andric{ 82*0b57cec5SDimitry Andric // 16 bit GPR pairs. 83*0b57cec5SDimitry Andric def SP : AVRReg<32, "SP", [SPL, SPH]>, DwarfRegNum<[32]>; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric // The pointer registers (X,Y,Z) are a special case because they 86*0b57cec5SDimitry Andric // are printed as a `high:low` pair when a DREG is expected, 87*0b57cec5SDimitry Andric // but printed using `X`, `Y`, `Z` when a pointer register is expected. 88*0b57cec5SDimitry Andric let RegAltNameIndices = [ptr] in { 89*0b57cec5SDimitry Andric def R31R30 : AVRReg<30, "r31:r30", [R30, R31], ["Z"]>, DwarfRegNum<[30]>; 90*0b57cec5SDimitry Andric def R29R28 : AVRReg<28, "r29:r28", [R28, R29], ["Y"]>, DwarfRegNum<[28]>; 91*0b57cec5SDimitry Andric def R27R26 : AVRReg<26, "r27:r26", [R26, R27], ["X"]>, DwarfRegNum<[26]>; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric def R25R24 : AVRReg<24, "r25:r24", [R24, R25]>, DwarfRegNum<[24]>; 94*0b57cec5SDimitry Andric def R23R22 : AVRReg<22, "r23:r22", [R22, R23]>, DwarfRegNum<[22]>; 95*0b57cec5SDimitry Andric def R21R20 : AVRReg<20, "r21:r20", [R20, R21]>, DwarfRegNum<[20]>; 96*0b57cec5SDimitry Andric def R19R18 : AVRReg<18, "r19:r18", [R18, R19]>, DwarfRegNum<[18]>; 97*0b57cec5SDimitry Andric def R17R16 : AVRReg<16, "r17:r16", [R16, R17]>, DwarfRegNum<[16]>; 98*0b57cec5SDimitry Andric def R15R14 : AVRReg<14, "r15:r14", [R14, R15]>, DwarfRegNum<[14]>; 99*0b57cec5SDimitry Andric def R13R12 : AVRReg<12, "r13:r12", [R12, R13]>, DwarfRegNum<[12]>; 100*0b57cec5SDimitry Andric def R11R10 : AVRReg<10, "r11:r10", [R10, R11]>, DwarfRegNum<[10]>; 101*0b57cec5SDimitry Andric def R9R8 : AVRReg<8, "r9:r8", [R8, R9]>, DwarfRegNum<[8]>; 102*0b57cec5SDimitry Andric def R7R6 : AVRReg<6, "r7:r6", [R6, R7]>, DwarfRegNum<[6]>; 103*0b57cec5SDimitry Andric def R5R4 : AVRReg<4, "r5:r4", [R4, R5]>, DwarfRegNum<[4]>; 104*0b57cec5SDimitry Andric def R3R2 : AVRReg<2, "r3:r2", [R2, R3]>, DwarfRegNum<[2]>; 105*0b57cec5SDimitry Andric def R1R0 : AVRReg<0, "r1:r0", [R0, R1]>, DwarfRegNum<[0]>; 106*0b57cec5SDimitry Andric} 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 109*0b57cec5SDimitry Andric// Register Classes 110*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric// Main 8-bit register class. 113*0b57cec5SDimitry Andricdef GPR8 : RegisterClass<"AVR", [i8], 8, 114*0b57cec5SDimitry Andric ( 115*0b57cec5SDimitry Andric // Return value and argument registers. 116*0b57cec5SDimitry Andric add R24, R25, R18, R19, R20, R21, R22, R23, 117*0b57cec5SDimitry Andric // Scratch registers. 118*0b57cec5SDimitry Andric R30, R31, R26, R27, 119*0b57cec5SDimitry Andric // Callee saved registers. 120*0b57cec5SDimitry Andric R28, R29, R17, R16, R15, R14, R13, R12, R11, R10, 121*0b57cec5SDimitry Andric R9, R8, R7, R6, R5, R4, R3, R2, R0, R1 122*0b57cec5SDimitry Andric )>; 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric// Simple lower registers r0..r15 125*0b57cec5SDimitry Andricdef GPR8lo : RegisterClass<"AVR", [i8], 8, 126*0b57cec5SDimitry Andric ( 127*0b57cec5SDimitry Andric add R15, R14, R13, R12, R11, R10, R9, R8, R7, R6, R5, R4, R3, R2, R0, R1 128*0b57cec5SDimitry Andric )>; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric// 8-bit register class for instructions which take immediates. 131*0b57cec5SDimitry Andricdef LD8 : RegisterClass<"AVR", [i8], 8, 132*0b57cec5SDimitry Andric ( 133*0b57cec5SDimitry Andric // Return value and arguments. 134*0b57cec5SDimitry Andric add R24, R25, R18, R19, R20, R21, R22, R23, 135*0b57cec5SDimitry Andric // Scratch registers. 136*0b57cec5SDimitry Andric R30, R31, R26, R27, 137*0b57cec5SDimitry Andric // Callee saved registers. 138*0b57cec5SDimitry Andric R28, R29, R17, R16 139*0b57cec5SDimitry Andric )>; 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric// Simple lower registers r16..r23 142*0b57cec5SDimitry Andricdef LD8lo : RegisterClass<"AVR", [i8], 8, 143*0b57cec5SDimitry Andric ( 144*0b57cec5SDimitry Andric add R23, R22, R21, R20, R19, R18, R17, R16 145*0b57cec5SDimitry Andric )>; 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric// Main 16-bit pair register class. 148*0b57cec5SDimitry Andricdef DREGS : RegisterClass<"AVR", [i16], 8, 149*0b57cec5SDimitry Andric ( 150*0b57cec5SDimitry Andric // Return value and arguments. 151*0b57cec5SDimitry Andric add R25R24, R19R18, R21R20, R23R22, 152*0b57cec5SDimitry Andric // Scratch registers. 153*0b57cec5SDimitry Andric R31R30, R27R26, 154*0b57cec5SDimitry Andric // Callee saved registers. 155*0b57cec5SDimitry Andric R29R28, R17R16, R15R14, R13R12, R11R10, 156*0b57cec5SDimitry Andric R9R8, R7R6, R5R4, R3R2, R1R0 157*0b57cec5SDimitry Andric )>; 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric// The 16-bit DREGS register class, excluding the Z pointer register. 160*0b57cec5SDimitry Andric// 161*0b57cec5SDimitry Andric// This is used by instructions which cause high pointer register 162*0b57cec5SDimitry Andric// contention which leads to an assertion in the register allocator. 163*0b57cec5SDimitry Andric// 164*0b57cec5SDimitry Andric// There is no technical reason why instructions that use this class 165*0b57cec5SDimitry Andric// cannot use Z; it's simply a workaround a regalloc bug. 166*0b57cec5SDimitry Andric// 167*0b57cec5SDimitry Andric// More information can be found in PR39553. 168*0b57cec5SDimitry Andricdef DREGS_WITHOUT_YZ_WORKAROUND : RegisterClass<"AVR", [i16], 8, 169*0b57cec5SDimitry Andric ( 170*0b57cec5SDimitry Andric // Return value and arguments. 171*0b57cec5SDimitry Andric add R25R24, R19R18, R21R20, R23R22, 172*0b57cec5SDimitry Andric // Scratch registers. 173*0b57cec5SDimitry Andric R27R26, 174*0b57cec5SDimitry Andric // Callee saved registers. 175*0b57cec5SDimitry Andric R17R16, R15R14, R13R12, R11R10, 176*0b57cec5SDimitry Andric R9R8, R7R6, R5R4, R3R2, R1R0 177*0b57cec5SDimitry Andric )>; 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric// 16-bit register class for immediate instructions. 180*0b57cec5SDimitry Andricdef DLDREGS : RegisterClass<"AVR", [i16], 8, 181*0b57cec5SDimitry Andric ( 182*0b57cec5SDimitry Andric // Return value and arguments. 183*0b57cec5SDimitry Andric add R25R24, R19R18, R21R20, R23R22, 184*0b57cec5SDimitry Andric // Scratch registers. 185*0b57cec5SDimitry Andric R31R30, R27R26, 186*0b57cec5SDimitry Andric // Callee saved registers. 187*0b57cec5SDimitry Andric R29R28, R17R16 188*0b57cec5SDimitry Andric )>; 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric// 16-bit register class for the adiw/sbiw instructions. 191*0b57cec5SDimitry Andricdef IWREGS : RegisterClass<"AVR", [i16], 8, 192*0b57cec5SDimitry Andric ( 193*0b57cec5SDimitry Andric // Return value and arguments. 194*0b57cec5SDimitry Andric add R25R24, 195*0b57cec5SDimitry Andric // Scratch registers. 196*0b57cec5SDimitry Andric R31R30, R27R26, 197*0b57cec5SDimitry Andric // Callee saved registers. 198*0b57cec5SDimitry Andric R29R28 199*0b57cec5SDimitry Andric )>; 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric// 16-bit register class for the ld and st instructions. 202*0b57cec5SDimitry Andric// AKA X,Y, and Z 203*0b57cec5SDimitry Andricdef PTRREGS : RegisterClass<"AVR", [i16], 8, 204*0b57cec5SDimitry Andric ( 205*0b57cec5SDimitry Andric add R27R26, // X 206*0b57cec5SDimitry Andric R29R28, // Y 207*0b57cec5SDimitry Andric R31R30 // Z 208*0b57cec5SDimitry Andric ), ptr>; 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric// 16-bit register class for the ldd and std instructions. 211*0b57cec5SDimitry Andric// AKA Y and Z. 212*0b57cec5SDimitry Andricdef PTRDISPREGS : RegisterClass<"AVR", [i16], 8, 213*0b57cec5SDimitry Andric ( 214*0b57cec5SDimitry Andric add R31R30, R29R28 215*0b57cec5SDimitry Andric ), ptr>; 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric// We have a bunch of instructions with an explicit Z register argument. We 218*0b57cec5SDimitry Andric// model this using a register class containing only the Z register. 219*0b57cec5SDimitry Andricdef ZREG : RegisterClass<"AVR", [i16], 8, (add R31R30)>; 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric// Register class used for the stack read pseudo instruction. 222*0b57cec5SDimitry Andricdef GPRSP: RegisterClass<"AVR", [i16], 8, (add SP)>; 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric// Status register. 225*0b57cec5SDimitry Andricdef SREG : AVRReg<14, "FLAGS">, DwarfRegNum<[88]>; 226*0b57cec5SDimitry Andricdef CCR : RegisterClass<"AVR", [i8], 8, (add SREG)> 227*0b57cec5SDimitry Andric{ 228*0b57cec5SDimitry Andric let CopyCost = -1; // Don't allow copying of status registers 229*0b57cec5SDimitry Andric} 230*0b57cec5SDimitry Andric 231