1//===-- PPCRegisterInfo.td - The PowerPC Register File -----*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// 10//===----------------------------------------------------------------------===// 11 12let Namespace = "PPC" in { 13def sub_lt : SubRegIndex<1>; 14def sub_gt : SubRegIndex<1, 1>; 15def sub_eq : SubRegIndex<1, 2>; 16def sub_un : SubRegIndex<1, 3>; 17def sub_32 : SubRegIndex<32>; 18def sub_64 : SubRegIndex<64>; 19def sub_vsx0 : SubRegIndex<128>; 20def sub_vsx1 : SubRegIndex<128, 128>; 21def sub_gp8_x0 : SubRegIndex<64>; 22def sub_gp8_x1 : SubRegIndex<64, 64>; 23} 24 25 26class PPCReg<string n> : Register<n> { 27 let Namespace = "PPC"; 28} 29 30// We identify all our registers with a 5-bit ID, for consistency's sake. 31 32// GPR - One of the 32 32-bit general-purpose registers 33class GPR<bits<5> num, string n> : PPCReg<n> { 34 let HWEncoding{4-0} = num; 35} 36 37// GP8 - One of the 32 64-bit general-purpose registers 38class GP8<GPR SubReg, string n> : PPCReg<n> { 39 let HWEncoding = SubReg.HWEncoding; 40 let SubRegs = [SubReg]; 41 let SubRegIndices = [sub_32]; 42} 43 44// SPE - One of the 32 64-bit general-purpose registers (SPE) 45class SPE<GPR SubReg, string n> : PPCReg<n> { 46 let HWEncoding = SubReg.HWEncoding; 47 let SubRegs = [SubReg]; 48 let SubRegIndices = [sub_32]; 49} 50 51// SPR - One of the 32-bit special-purpose registers 52class SPR<bits<10> num, string n> : PPCReg<n> { 53 let HWEncoding{9-0} = num; 54} 55 56// FPR - One of the 32 64-bit floating-point registers 57class FPR<bits<5> num, string n> : PPCReg<n> { 58 let HWEncoding{4-0} = num; 59} 60 61// VF - One of the 32 64-bit floating-point subregisters of the vector 62// registers (used by VSX). 63class VF<bits<5> num, string n> : PPCReg<n> { 64 let HWEncoding{4-0} = num; 65 let HWEncoding{5} = 1; 66} 67 68// VR - One of the 32 128-bit vector registers 69class VR<VF SubReg, string n> : PPCReg<n> { 70 let HWEncoding{4-0} = SubReg.HWEncoding{4-0}; 71 let HWEncoding{5} = 0; 72 let SubRegs = [SubReg]; 73 let SubRegIndices = [sub_64]; 74} 75 76// VSRL - One of the 32 128-bit VSX registers that overlap with the scalar 77// floating-point registers. 78class VSRL<FPR SubReg, string n> : PPCReg<n> { 79 let HWEncoding = SubReg.HWEncoding; 80 let SubRegs = [SubReg]; 81 let SubRegIndices = [sub_64]; 82} 83 84// VSXReg - One of the VSX registers in the range vs32-vs63 with numbering 85// and encoding to match. 86class VSXReg<bits<6> num, string n> : PPCReg<n> { 87 let HWEncoding{5-0} = num; 88} 89 90// CR - One of the 8 4-bit condition registers 91class CR<bits<3> num, string n, list<Register> subregs> : PPCReg<n> { 92 let HWEncoding{2-0} = num; 93 let SubRegs = subregs; 94} 95 96// CRBIT - One of the 32 1-bit condition register fields 97class CRBIT<bits<5> num, string n> : PPCReg<n> { 98 let HWEncoding{4-0} = num; 99} 100 101// VSR Pairs - One of the 32 paired even-odd consecutive VSRs. 102class VSRPair<bits<5> num, string n, list<Register> subregs> : PPCReg<n> { 103 let HWEncoding{4-0} = num; 104 let SubRegs = subregs; 105} 106 107// GP8Pair - Consecutive even-odd paired GP8. 108class GP8Pair<string n, bits<5> EvenIndex> : PPCReg<n> { 109 assert !eq(EvenIndex{0}, 0), "Index should be even."; 110 let HWEncoding{4-0} = EvenIndex; 111 let SubRegs = [!cast<GP8>("X"#EvenIndex), !cast<GP8>("X"#!add(EvenIndex, 1))]; 112 let DwarfNumbers = [-1, -1]; 113 let SubRegIndices = [sub_gp8_x0, sub_gp8_x1]; 114} 115 116// General-purpose registers 117foreach Index = 0-31 in { 118 def R#Index : GPR<Index, "r"#Index>, DwarfRegNum<[-2, Index]>; 119} 120 121// 64-bit General-purpose registers 122foreach Index = 0-31 in { 123 def X#Index : GP8<!cast<GPR>("R"#Index), "r"#Index>, 124 DwarfRegNum<[Index, -2]>; 125} 126 127// SPE registers 128foreach Index = 0-31 in { 129 def S#Index : SPE<!cast<GPR>("R"#Index), "r"#Index>, 130 DwarfRegNum<[!add(Index, 1200), !add(Index, 1200)]>; 131} 132 133// Floating-point registers 134foreach Index = 0-31 in { 135 def F#Index : FPR<Index, "f"#Index>, 136 DwarfRegNum<[!add(Index, 32), !add(Index, 32)]>; 137} 138 139// 64-bit Floating-point subregisters of Altivec registers 140// Note: the register names are v0-v31 or vs32-vs63 depending on the use. 141// Custom C++ code is used to produce the correct name and encoding. 142foreach Index = 0-31 in { 143 def VF#Index : VF<Index, "v" #Index>, 144 DwarfRegNum<[!add(Index, 77), !add(Index, 77)]>; 145} 146 147// Vector registers 148foreach Index = 0-31 in { 149 def V#Index : VR<!cast<VF>("VF"#Index), "v"#Index>, 150 DwarfRegNum<[!add(Index, 77), !add(Index, 77)]>; 151} 152 153// VSX registers 154foreach Index = 0-31 in { 155 def VSL#Index : VSRL<!cast<FPR>("F"#Index), "vs"#Index>, 156 DwarfRegAlias<!cast<FPR>("F"#Index)>; 157} 158 159// Dummy VSX registers, this defines string: "vs32"-"vs63", and is only used for 160// asm printing. 161foreach Index = 32-63 in { 162 def VSX#Index : VSXReg<Index, "vs"#Index>; 163} 164 165let SubRegIndices = [sub_vsx0, sub_vsx1] in { 166 // VSR pairs 0 - 15 (corresponding to VSRs 0 - 30 paired with 1 - 31). 167 foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 168 def VSRp#!srl(Index, 1) : VSRPair<!srl(Index, 1), "vsp"#Index, 169 [!cast<VSRL>("VSL"#Index), !cast<VSRL>("VSL"#!add(Index, 1))]>, 170 DwarfRegNum<[-1, -1]>; 171 } 172 173 // VSR pairs 16 - 31 (corresponding to VSRs 32 - 62 paired with 33 - 63). 174 foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 175 def VSRp#!add(!srl(Index, 1), 16) : 176 VSRPair<!add(!srl(Index, 1), 16), "vsp"#!add(Index, 32), 177 [!cast<VR>("V"#Index), !cast<VR>("V"#!add(Index, 1))]>, 178 DwarfRegNum<[-1, -1]>; 179 } 180} 181 182// 16 paired even-odd consecutive GP8s. 183foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 184 def G8p#!srl(Index, 1) : GP8Pair<"r"#Index, Index>; 185} 186 187// The representation of r0 when treated as the constant 0. 188def ZERO : GPR<0, "0">, DwarfRegAlias<R0>; 189def ZERO8 : GP8<ZERO, "0">, DwarfRegAlias<X0>; 190 191// Representations of the frame pointer used by ISD::FRAMEADDR. 192def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">; 193def FP8 : GP8<FP, "**FRAME POINTER**">; 194 195// Representations of the base pointer used by setjmp. 196def BP : GPR<0 /* arbitrary */, "**BASE POINTER**">; 197def BP8 : GP8<BP, "**BASE POINTER**">; 198 199// Condition register bits 200def CR0LT : CRBIT< 0, "0">; 201def CR0GT : CRBIT< 1, "1">; 202def CR0EQ : CRBIT< 2, "2">; 203def CR0UN : CRBIT< 3, "3">; 204def CR1LT : CRBIT< 4, "4">; 205def CR1GT : CRBIT< 5, "5">; 206def CR1EQ : CRBIT< 6, "6">; 207def CR1UN : CRBIT< 7, "7">; 208def CR2LT : CRBIT< 8, "8">; 209def CR2GT : CRBIT< 9, "9">; 210def CR2EQ : CRBIT<10, "10">; 211def CR2UN : CRBIT<11, "11">; 212def CR3LT : CRBIT<12, "12">; 213def CR3GT : CRBIT<13, "13">; 214def CR3EQ : CRBIT<14, "14">; 215def CR3UN : CRBIT<15, "15">; 216def CR4LT : CRBIT<16, "16">; 217def CR4GT : CRBIT<17, "17">; 218def CR4EQ : CRBIT<18, "18">; 219def CR4UN : CRBIT<19, "19">; 220def CR5LT : CRBIT<20, "20">; 221def CR5GT : CRBIT<21, "21">; 222def CR5EQ : CRBIT<22, "22">; 223def CR5UN : CRBIT<23, "23">; 224def CR6LT : CRBIT<24, "24">; 225def CR6GT : CRBIT<25, "25">; 226def CR6EQ : CRBIT<26, "26">; 227def CR6UN : CRBIT<27, "27">; 228def CR7LT : CRBIT<28, "28">; 229def CR7GT : CRBIT<29, "29">; 230def CR7EQ : CRBIT<30, "30">; 231def CR7UN : CRBIT<31, "31">; 232 233// Condition registers 234let SubRegIndices = [sub_lt, sub_gt, sub_eq, sub_un] in { 235def CR0 : CR<0, "cr0", [CR0LT, CR0GT, CR0EQ, CR0UN]>, DwarfRegNum<[68, 68]>; 236def CR1 : CR<1, "cr1", [CR1LT, CR1GT, CR1EQ, CR1UN]>, DwarfRegNum<[69, 69]>; 237def CR2 : CR<2, "cr2", [CR2LT, CR2GT, CR2EQ, CR2UN]>, DwarfRegNum<[70, 70]>; 238def CR3 : CR<3, "cr3", [CR3LT, CR3GT, CR3EQ, CR3UN]>, DwarfRegNum<[71, 71]>; 239def CR4 : CR<4, "cr4", [CR4LT, CR4GT, CR4EQ, CR4UN]>, DwarfRegNum<[72, 72]>; 240def CR5 : CR<5, "cr5", [CR5LT, CR5GT, CR5EQ, CR5UN]>, DwarfRegNum<[73, 73]>; 241def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74, 74]>; 242def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75, 75]>; 243} 244 245// Link register 246def LR : SPR<8, "lr">, DwarfRegNum<[-2, 65]>; 247//let Aliases = [LR] in 248def LR8 : SPR<8, "lr">, DwarfRegNum<[65, -2]>; 249 250// Count register 251def CTR : SPR<9, "ctr">, DwarfRegNum<[-2, 66]>; 252def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66, -2]>; 253 254// VRsave register 255def VRSAVE: SPR<256, "vrsave">, DwarfRegNum<[109]>; 256 257// SPE extra registers 258def SPEFSCR: SPR<512, "spefscr">, DwarfRegNum<[612, 112]>; 259 260def XER: SPR<1, "xer">, DwarfRegNum<[76]>; 261 262// Carry bit. In the architecture this is really bit 0 of the XER register 263// (which really is SPR register 1); this is the only bit interesting to a 264// compiler. 265def CARRY: SPR<1, "xer">, DwarfRegNum<[76]> { 266 let Aliases = [XER]; 267} 268 269// FP rounding mode: bits 30 and 31 of the FP status and control register 270// This is not allocated as a normal register; it appears only in 271// Uses and Defs. The ABI says it needs to be preserved by a function, 272// but this is not achieved by saving and restoring it as with 273// most registers, it has to be done in code; to make this work all the 274// return and call instructions are described as Uses of RM, so instructions 275// that do nothing but change RM will not get deleted. 276def RM: PPCReg<"**ROUNDING MODE**">; 277 278/// Register classes 279// Allocate volatiles first 280// then nonvolatiles in reverse order since stmw/lmw save from rN to r31 281def GPRC : RegisterClass<"PPC", [i32,f32], 32, (add (sequence "R%u", 2, 12), 282 (sequence "R%u", 30, 13), 283 R31, R0, R1, FP, BP)> { 284 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 285 // put it at the end of the list. 286 // On AIX, CSRs are allocated starting from R31 according to: 287 // https://www.ibm.com/docs/en/ssw_aix_72/assembler/assembler_pdf.pdf. 288 // This also helps setting the correct `NumOfGPRsSaved' in traceback table. 289 let AltOrders = [(add (sub GPRC, R2), R2), 290 (add (sequence "R%u", 2, 12), 291 (sequence "R%u", 31, 13), R0, R1, FP, BP)]; 292 let AltOrderSelect = [{ 293 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 294 }]; 295} 296 297def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12), 298 (sequence "X%u", 30, 14), 299 X31, X13, X0, X1, FP8, BP8)> { 300 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 301 // put it at the end of the list. 302 let AltOrders = [(add (sub G8RC, X2), X2), 303 (add (sequence "X%u", 2, 12), 304 (sequence "X%u", 31, 13), X0, X1, FP8, BP8)]; 305 let AltOrderSelect = [{ 306 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 307 }]; 308} 309 310// For some instructions r0 is special (representing the value 0 instead of 311// the value in the r0 register), and we use these register subclasses to 312// prevent r0 from being allocated for use by those instructions. 313def GPRC_NOR0 : RegisterClass<"PPC", [i32,f32], 32, (add (sub GPRC, R0), ZERO)> { 314 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 315 // put it at the end of the list. 316 let AltOrders = [(add (sub GPRC_NOR0, R2), R2), 317 (add (sequence "R%u", 2, 12), 318 (sequence "R%u", 31, 13), R1, FP, BP, ZERO)]; 319 let AltOrderSelect = [{ 320 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 321 }]; 322} 323 324def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)> { 325 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 326 // put it at the end of the list. 327 let AltOrders = [(add (sub G8RC_NOX0, X2), X2), 328 (add (sequence "X%u", 2, 12), 329 (sequence "X%u", 31, 13), X1, FP8, BP8, ZERO8)]; 330 let AltOrderSelect = [{ 331 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 332 }]; 333} 334 335def SPERC : RegisterClass<"PPC", [f64], 64, (add (sequence "S%u", 2, 12), 336 (sequence "S%u", 30, 13), 337 S31, S0, S1)>; 338 339// Allocate volatiles first, then non-volatiles in reverse order. With the SVR4 340// ABI the size of the Floating-point register save area is determined by the 341// allocated non-volatile register with the lowest register number, as FP 342// register N is spilled to offset 8 * (32 - N) below the back chain word of the 343// previous stack frame. By allocating non-volatiles in reverse order we make 344// sure that the Floating-point register save area is always as small as 345// possible because there aren't any unused spill slots. 346def F8RC : RegisterClass<"PPC", [f64], 64, (add (sequence "F%u", 0, 13), 347 (sequence "F%u", 31, 14))>; 348def F4RC : RegisterClass<"PPC", [f32], 32, (add F8RC)>; 349 350def VRRC : RegisterClass<"PPC", 351 [v16i8,v8i16,v4i32,v2i64,v1i128,v4f32,v2f64, f128], 352 128, 353 (add V2, V3, V4, V5, V0, V1, V6, V7, V8, V9, V10, V11, 354 V12, V13, V14, V15, V16, V17, V18, V19, V31, V30, 355 V29, V28, V27, V26, V25, V24, V23, V22, V21, V20)>; 356 357// VSX register classes (the allocation order mirrors that of the corresponding 358// subregister classes). 359def VSLRC : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128, 360 (add (sequence "VSL%u", 0, 13), 361 (sequence "VSL%u", 31, 14))>; 362def VSRC : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128, 363 (add VSLRC, VRRC)>; 364 365// Register classes for the 64-bit "scalar" VSX subregisters. 366def VFRC : RegisterClass<"PPC", [f64], 64, 367 (add VF2, VF3, VF4, VF5, VF0, VF1, VF6, VF7, 368 VF8, VF9, VF10, VF11, VF12, VF13, VF14, 369 VF15, VF16, VF17, VF18, VF19, VF31, VF30, 370 VF29, VF28, VF27, VF26, VF25, VF24, VF23, 371 VF22, VF21, VF20)>; 372def VSFRC : RegisterClass<"PPC", [f64], 64, (add F8RC, VFRC)>; 373 374// Allow spilling GPR's into caller-saved VSR's. 375def SPILLTOVSRRC : RegisterClass<"PPC", [i64, f64], 64, (add G8RC, (sub VSFRC, 376 (sequence "VF%u", 31, 20), 377 (sequence "F%u", 31, 14)))>; 378 379// Register class for single precision scalars in VSX registers 380def VSSRC : RegisterClass<"PPC", [f32], 32, (add VSFRC)>; 381 382def CRBITRC : RegisterClass<"PPC", [i1], 32, 383 (add CR2LT, CR2GT, CR2EQ, CR2UN, 384 CR3LT, CR3GT, CR3EQ, CR3UN, 385 CR4LT, CR4GT, CR4EQ, CR4UN, 386 CR5LT, CR5GT, CR5EQ, CR5UN, 387 CR6LT, CR6GT, CR6EQ, CR6UN, 388 CR7LT, CR7GT, CR7EQ, CR7UN, 389 CR1LT, CR1GT, CR1EQ, CR1UN, 390 CR0LT, CR0GT, CR0EQ, CR0UN)> { 391 let Size = 32; 392 let AltOrders = [(sub CRBITRC, CR2LT, CR2GT, CR2EQ, CR2UN, CR3LT, CR3GT, 393 CR3EQ, CR3UN, CR4LT, CR4GT, CR4EQ, CR4UN)]; 394 let AltOrderSelect = [{ 395 return MF.getSubtarget<PPCSubtarget>().isELFv2ABI() && 396 MF.getInfo<PPCFunctionInfo>()->isNonVolatileCRDisabled(); 397 }]; 398} 399 400def CRRC : RegisterClass<"PPC", [i32], 32, 401 (add CR0, CR1, CR5, CR6, 402 CR7, CR2, CR3, CR4)> { 403 let AltOrders = [(sub CRRC, CR2, CR3, CR4)]; 404 let AltOrderSelect = [{ 405 return MF.getSubtarget<PPCSubtarget>().isELFv2ABI() && 406 MF.getInfo<PPCFunctionInfo>()->isNonVolatileCRDisabled(); 407 }]; 408} 409// The CTR registers are not allocatable because they're used by the 410// decrement-and-branch instructions, and thus need to stay live across 411// multiple basic blocks. 412def CTRRC : RegisterClass<"PPC", [i32], 32, (add CTR)> { 413 let isAllocatable = 0; 414} 415def CTRRC8 : RegisterClass<"PPC", [i64], 64, (add CTR8)> { 416 let isAllocatable = 0; 417} 418 419def LRRC : RegisterClass<"PPC", [i32], 32, (add LR)> { 420 let isAllocatable = 0; 421} 422def LR8RC : RegisterClass<"PPC", [i64], 64, (add LR8)> { 423 let isAllocatable = 0; 424} 425 426def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>; 427def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY, XER)> { 428 let CopyCost = -1; 429} 430 431// Make AllocationOrder as similar as G8RC's to avoid potential spilling. 432// Similarly, we have an AltOrder for 64-bit ELF ABI which r2 is allocated 433// at last. 434def G8pRC : 435 RegisterClass<"PPC", [i128], 128, 436 (add (sequence "G8p%u", 1, 5), 437 (sequence "G8p%u", 14, 7), 438 G8p15, G8p6, G8p0)> { 439 let AltOrders = [(add (sub G8pRC, G8p1), G8p1)]; 440 let AltOrderSelect = [{ 441 return MF.getSubtarget<PPCSubtarget>().is64BitELFABI(); 442 }]; 443 let Size = 128; 444} 445 446include "PPCRegisterInfoMMA.td" 447