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_32_hi_phony : SubRegIndex<32,32>; 19def sub_64 : SubRegIndex<64>; 20def sub_64_hi_phony : SubRegIndex<64,64>; 21def sub_vsx0 : SubRegIndex<128>; 22def sub_vsx1 : SubRegIndex<128, 128>; 23def sub_gp8_x0 : SubRegIndex<64>; 24def sub_gp8_x1 : SubRegIndex<64, 64>; 25def sub_fp0 : SubRegIndex<64>; 26def sub_fp1 : SubRegIndex<64, 64>; 27} 28 29 30class PPCReg<string n> : Register<n> { 31 let Namespace = "PPC"; 32} 33 34// We identify all our registers with a 5-bit ID, for consistency's sake. 35 36// GPR - One of the 32 32-bit general-purpose registers 37class GPR<bits<5> num, string n> : PPCReg<n> { 38 let HWEncoding{4-0} = num; 39} 40 41// GP8 - One of the 32 64-bit general-purpose registers 42class GP8<GPR SubReg, string n> : PPCReg<n> { 43 let HWEncoding = SubReg.HWEncoding; 44 let SubRegs = [SubReg]; 45 let SubRegIndices = [sub_32]; 46} 47 48class SPE<string n, bits<5> Enc, list<Register> subregs = []> : PPCReg<n> { 49 let HWEncoding{4-0} = Enc; 50 let SubRegs = subregs; 51 let SubRegIndices = [sub_32, sub_32_hi_phony]; 52 let CoveredBySubRegs = 1; 53} 54// SPR - One of the 32-bit special-purpose registers 55class SPR<bits<10> num, string n> : PPCReg<n> { 56 let HWEncoding{9-0} = num; 57} 58 59// FPR - One of the 32 64-bit floating-point registers 60class FPR<bits<5> num, string n> : PPCReg<n> { 61 let HWEncoding{4-0} = num; 62} 63 64// FPPair - A pair of 64-bit floating-point registers. 65class FPPair<string n, bits<5> EvenIndex> : PPCReg<n> { 66 assert !eq(EvenIndex{0}, 0), "Index should be even."; 67 let HWEncoding{4-0} = EvenIndex; 68 let SubRegs = [!cast<FPR>("F"#EvenIndex), !cast<FPR>("F"#!add(EvenIndex, 1))]; 69 let DwarfNumbers = [-1, -1]; 70 let SubRegIndices = [sub_fp0, sub_fp1]; 71} 72 73// VF - One of the 32 64-bit floating-point subregisters of the vector 74// registers (used by VSX). 75class VF<bits<5> num, string n> : PPCReg<n> { 76 let HWEncoding{4-0} = num; 77 let HWEncoding{5} = 1; 78} 79 80// VR - One of the 32 128-bit vector registers 81class VR<VF SubReg, VF SubRegH, string n> : PPCReg<n> { 82 let HWEncoding{4-0} = SubReg.HWEncoding{4-0}; 83 let HWEncoding{5} = 0; 84 let SubRegs = [SubReg, SubRegH]; 85 let SubRegIndices = [sub_64, sub_64_hi_phony]; 86} 87 88// VSRL - One of the 32 128-bit VSX registers that overlap with the scalar 89// floating-point registers. 90class VSRL<FPR SubReg, FPR SubRegH, string n> : PPCReg<n> { 91 let HWEncoding = SubReg.HWEncoding; 92 let SubRegs = [SubReg, SubRegH]; 93 let SubRegIndices = [sub_64, sub_64_hi_phony]; 94} 95 96// VSXReg - One of the VSX registers in the range vs32-vs63 with numbering 97// and encoding to match. 98class VSXReg<bits<6> num, string n> : PPCReg<n> { 99 let HWEncoding{5-0} = num; 100} 101 102// CR - One of the 8 4-bit condition registers 103class CR<bits<3> num, string n, list<Register> subregs> : PPCReg<n> { 104 let HWEncoding{2-0} = num; 105 let SubRegs = subregs; 106} 107 108// CRBIT - One of the 32 1-bit condition register fields 109class CRBIT<bits<5> num, string n> : PPCReg<n> { 110 let HWEncoding{4-0} = num; 111} 112 113// VSR Pairs - One of the 32 paired even-odd consecutive VSRs. 114class VSRPair<bits<5> num, string n, list<Register> subregs> : PPCReg<n> { 115 let HWEncoding{4-0} = num; 116 let SubRegs = subregs; 117} 118 119// GP8Pair - Consecutive even-odd paired GP8. 120class GP8Pair<string n, bits<5> EvenIndex> : PPCReg<n> { 121 assert !eq(EvenIndex{0}, 0), "Index should be even."; 122 let HWEncoding{4-0} = EvenIndex; 123 let SubRegs = [!cast<GP8>("X"#EvenIndex), !cast<GP8>("X"#!add(EvenIndex, 1))]; 124 let DwarfNumbers = [-1, -1]; 125 let SubRegIndices = [sub_gp8_x0, sub_gp8_x1]; 126} 127 128// General-purpose registers 129foreach Index = 0-31 in { 130 def R#Index : GPR<Index, "r"#Index>, DwarfRegNum<[-2, Index]>; 131} 132 133let isArtificial = 1 in { 134 foreach Index = 0-31 in { 135 def H#Index : GPR<-1,"">; 136 } 137} 138 139// 64-bit General-purpose registers 140foreach Index = 0-31 in { 141 def X#Index : GP8<!cast<GPR>("R"#Index), "r"#Index>, 142 DwarfRegNum<[Index, -2]>; 143} 144 145// SPE registers 146foreach Index = 0-31 in { 147 def S#Index : SPE<"r"#Index, Index, [!cast<GPR>("R"#Index), !cast<GPR>("H"#Index)]>, 148 DwarfRegNum<[!add(Index, 1200), !add(Index, 1200)]>; 149 150} 151 152 153// Floating-point registers 154foreach Index = 0-31 in { 155 def F#Index : FPR<Index, "f"#Index>, 156 DwarfRegNum<[!add(Index, 32), !add(Index, 32)]>; 157} 158 159// The FH and VFH registers have been marked as Artifical because there are no 160// instructions on PowerPC that use those register classes. They only exist 161// in order to ensure that the super registers (V and VSL) are covered by their 162// subregisters and have correct subregister lane masks. 163let isArtificial = 1 in { 164 foreach Index = 0-31 in { 165 def FH#Index : FPR<-1, "">; 166 def VFH#Index : VF<-1, "">; 167 } 168} 169 170let isAllocatable = 0, CopyCost = -1 in { 171 def VFHRC : RegisterClass<"PPC", [f64], 64, (sequence "VFH%u", 0, 31)>; 172 def FHRC : RegisterClass<"PPC", [f64], 64, (sequence "FH%u", 0, 31)>; 173} 174 175// Floating-point pair registers 176foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 177 def Fpair#Index : FPPair<"fp"#Index, Index>; 178} 179 180// 64-bit Floating-point subregisters of Altivec registers 181// Note: the register names are v0-v31 or vs32-vs63 depending on the use. 182// Custom C++ code is used to produce the correct name and encoding. 183foreach Index = 0-31 in { 184 def VF#Index : VF<Index, "v" #Index>, 185 DwarfRegNum<[!add(Index, 77), !add(Index, 77)]>; 186} 187 188let CoveredBySubRegs = 1 in { 189// Vector registers 190foreach Index = 0-31 in { 191 def V#Index : VR<!cast<VF>("VF"#Index), !cast<VF>("VFH"#Index), "v"#Index>, 192 DwarfRegNum<[!add(Index, 77), !add(Index, 77)]>; 193} 194 195// VSX registers 196foreach Index = 0-31 in { 197 def VSL#Index : VSRL<!cast<FPR>("F"#Index), !cast<FPR>("FH"#Index), "vs"#Index>, 198 DwarfRegAlias<!cast<FPR>("F"#Index)>; 199} 200} 201 202// Dummy VSX registers, this defines string: "vs32"-"vs63", and is only used for 203// asm printing. 204foreach Index = 32-63 in { 205 def VSX#Index : VSXReg<Index, "vs"#Index>; 206} 207 208let SubRegIndices = [sub_vsx0, sub_vsx1] in { 209 // VSR pairs 0 - 15 (corresponding to VSRs 0 - 30 paired with 1 - 31). 210 foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 211 def VSRp#!srl(Index, 1) : VSRPair<!srl(Index, 1), "vsp"#Index, 212 [!cast<VSRL>("VSL"#Index), !cast<VSRL>("VSL"#!add(Index, 1))]>, 213 DwarfRegNum<[-1, -1]>; 214 } 215 216 // VSR pairs 16 - 31 (corresponding to VSRs 32 - 62 paired with 33 - 63). 217 foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 218 def VSRp#!add(!srl(Index, 1), 16) : 219 VSRPair<!add(!srl(Index, 1), 16), "vsp"#!add(Index, 32), 220 [!cast<VR>("V"#Index), !cast<VR>("V"#!add(Index, 1))]>, 221 DwarfRegAlias<!cast<VR>("V"#Index)>; 222 } 223} 224 225// 16 paired even-odd consecutive GP8s. 226foreach Index = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 } in { 227 def G8p#!srl(Index, 1) : GP8Pair<"r"#Index, Index>; 228} 229 230// The representation of r0 when treated as the constant 0. 231let isConstant = true in { 232def ZERO : GPR<0, "0">, DwarfRegAlias<R0>; 233def ZERO8 : GP8<ZERO, "0">, DwarfRegAlias<X0>; 234} // isConstant = true 235 236// Representations of the frame pointer used by ISD::FRAMEADDR. 237def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">; 238def FP8 : GP8<FP, "**FRAME POINTER**">; 239 240// Representations of the base pointer used by setjmp. 241def BP : GPR<0 /* arbitrary */, "**BASE POINTER**">; 242def BP8 : GP8<BP, "**BASE POINTER**">; 243 244// Condition register bits 245def CR0LT : CRBIT< 0, "0">; 246def CR0GT : CRBIT< 1, "1">; 247def CR0EQ : CRBIT< 2, "2">; 248def CR0UN : CRBIT< 3, "3">; 249def CR1LT : CRBIT< 4, "4">; 250def CR1GT : CRBIT< 5, "5">; 251def CR1EQ : CRBIT< 6, "6">; 252def CR1UN : CRBIT< 7, "7">; 253def CR2LT : CRBIT< 8, "8">; 254def CR2GT : CRBIT< 9, "9">; 255def CR2EQ : CRBIT<10, "10">; 256def CR2UN : CRBIT<11, "11">; 257def CR3LT : CRBIT<12, "12">; 258def CR3GT : CRBIT<13, "13">; 259def CR3EQ : CRBIT<14, "14">; 260def CR3UN : CRBIT<15, "15">; 261def CR4LT : CRBIT<16, "16">; 262def CR4GT : CRBIT<17, "17">; 263def CR4EQ : CRBIT<18, "18">; 264def CR4UN : CRBIT<19, "19">; 265def CR5LT : CRBIT<20, "20">; 266def CR5GT : CRBIT<21, "21">; 267def CR5EQ : CRBIT<22, "22">; 268def CR5UN : CRBIT<23, "23">; 269def CR6LT : CRBIT<24, "24">; 270def CR6GT : CRBIT<25, "25">; 271def CR6EQ : CRBIT<26, "26">; 272def CR6UN : CRBIT<27, "27">; 273def CR7LT : CRBIT<28, "28">; 274def CR7GT : CRBIT<29, "29">; 275def CR7EQ : CRBIT<30, "30">; 276def CR7UN : CRBIT<31, "31">; 277 278// Condition registers 279let SubRegIndices = [sub_lt, sub_gt, sub_eq, sub_un] in { 280def CR0 : CR<0, "cr0", [CR0LT, CR0GT, CR0EQ, CR0UN]>, DwarfRegNum<[68, 68]>; 281def CR1 : CR<1, "cr1", [CR1LT, CR1GT, CR1EQ, CR1UN]>, DwarfRegNum<[69, 69]>; 282def CR2 : CR<2, "cr2", [CR2LT, CR2GT, CR2EQ, CR2UN]>, DwarfRegNum<[70, 70]>; 283def CR3 : CR<3, "cr3", [CR3LT, CR3GT, CR3EQ, CR3UN]>, DwarfRegNum<[71, 71]>; 284def CR4 : CR<4, "cr4", [CR4LT, CR4GT, CR4EQ, CR4UN]>, DwarfRegNum<[72, 72]>; 285def CR5 : CR<5, "cr5", [CR5LT, CR5GT, CR5EQ, CR5UN]>, DwarfRegNum<[73, 73]>; 286def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74, 74]>; 287def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75, 75]>; 288} 289 290// Link register 291def LR : SPR<8, "lr">, DwarfRegNum<[-2, 65]>; 292def LR8 : SPR<8, "lr">, DwarfRegNum<[65, -2]> { 293 let Aliases = [LR]; 294} 295 296// Count register 297def CTR : SPR<9, "ctr">, DwarfRegNum<[-2, 66]>; 298def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66, -2]> { 299 let Aliases = [CTR]; 300} 301 302// VRsave register 303def VRSAVE: SPR<256, "vrsave">, DwarfRegNum<[109]>; 304 305// SPE extra registers 306def SPEFSCR: SPR<512, "spefscr">, DwarfRegNum<[612, 112]>; 307 308def XER: SPR<1, "xer">, DwarfRegNum<[76]>; 309 310// Carry bit. In the architecture this is really bit 0 of the XER register 311// (which really is SPR register 1); this is the only bit interesting to a 312// compiler. 313def CARRY: SPR<1, "xer">, DwarfRegNum<[76]> { 314 let Aliases = [XER]; 315} 316 317// FP rounding mode: bits 30 and 31 of the FP status and control register 318// This is not allocated as a normal register; it appears only in 319// Uses and Defs. The ABI says it needs to be preserved by a function, 320// but this is not achieved by saving and restoring it as with 321// most registers, it has to be done in code; to make this work all the 322// return and call instructions are described as Uses of RM, so instructions 323// that do nothing but change RM will not get deleted. 324def RM: PPCReg<"**ROUNDING MODE**">; 325 326let isAllocatable = 0 in 327def GPRC32 : RegisterClass<"PPC", [i32,f32], 32, (add (sequence "H%u", 2, 12), 328 (sequence "H%u", 30, 13), 329 H31, H0, H1)>; 330 331/// Register classes 332// Allocate volatiles first 333// then nonvolatiles in reverse order since stmw/lmw save from rN to r31 334def GPRC : RegisterClass<"PPC", [i32,f32], 32, (add (sequence "R%u", 2, 12), 335 (sequence "R%u", 30, 13), 336 R31, R0, R1, FP, BP)> { 337 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 338 // put it at the end of the list. 339 // On AIX, CSRs are allocated starting from R31 according to: 340 // https://www.ibm.com/docs/en/ssw_aix_72/assembler/assembler_pdf.pdf. 341 // This also helps setting the correct `NumOfGPRsSaved' in traceback table. 342 let AltOrders = [(add (sub GPRC, R2), R2), 343 (add (sequence "R%u", 2, 12), 344 (sequence "R%u", 31, 13), R0, R1, FP, BP)]; 345 let AltOrderSelect = [{ 346 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 347 }]; 348} 349 350def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12), 351 (sequence "X%u", 30, 14), 352 X31, X13, X0, X1, FP8, BP8)> { 353 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 354 // put it at the end of the list. 355 let AltOrders = [(add (sub G8RC, X2), X2), 356 (add (sequence "X%u", 2, 12), 357 (sequence "X%u", 31, 13), X0, X1, FP8, BP8)]; 358 let AltOrderSelect = [{ 359 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 360 }]; 361} 362 363// For some instructions r0 is special (representing the value 0 instead of 364// the value in the r0 register), and we use these register subclasses to 365// prevent r0 from being allocated for use by those instructions. 366def GPRC_NOR0 : RegisterClass<"PPC", [i32,f32], 32, (add (sub GPRC, R0), ZERO)> { 367 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 368 // put it at the end of the list. 369 let AltOrders = [(add (sub GPRC_NOR0, R2), R2), 370 (add (sequence "R%u", 2, 12), 371 (sequence "R%u", 31, 13), R1, FP, BP, ZERO)]; 372 let AltOrderSelect = [{ 373 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 374 }]; 375} 376 377def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)> { 378 // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so 379 // put it at the end of the list. 380 let AltOrders = [(add (sub G8RC_NOX0, X2), X2), 381 (add (sequence "X%u", 2, 12), 382 (sequence "X%u", 31, 13), X1, FP8, BP8, ZERO8)]; 383 let AltOrderSelect = [{ 384 return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx(); 385 }]; 386} 387 388def SPERC : RegisterClass<"PPC", [f64], 64, (add (sequence "S%u", 2, 12), 389 (sequence "S%u", 30, 13), 390 S31, S0, S1)>; 391 392// Allocate volatiles first, then non-volatiles in reverse order. With the SVR4 393// ABI the size of the Floating-point register save area is determined by the 394// allocated non-volatile register with the lowest register number, as FP 395// register N is spilled to offset 8 * (32 - N) below the back chain word of the 396// previous stack frame. By allocating non-volatiles in reverse order we make 397// sure that the Floating-point register save area is always as small as 398// possible because there aren't any unused spill slots. 399def F8RC : RegisterClass<"PPC", [f64], 64, (add (sequence "F%u", 0, 13), 400 (sequence "F%u", 31, 14))>; 401def F4RC : RegisterClass<"PPC", [f32], 32, (add F8RC)>; 402 403// Floating point pair registers. 404// Note that the type used for this register class is ppcf128. This is not 405// completely correct. However, since we are not pattern matching any 406// instructions for these registers and we are not register allocating or 407// scheduling any of these instructions it should be safe to do this. 408// The reason we didn't use the correct type (Decimal Floating Point) is that 409// at the time of this implementation the correct type was not available. 410def FpRC : 411 RegisterClass<"PPC", [ppcf128], 128, 412 (add Fpair0, Fpair2, Fpair4, Fpair6, Fpair8, Fpair10, Fpair12, 413 Fpair14, Fpair16, Fpair18, Fpair20, Fpair22, Fpair24, 414 Fpair26, Fpair28, Fpair30)> { 415 let Size = 128; 416} 417 418def VRRC : RegisterClass<"PPC", 419 [v16i8,v8i16,v4i32,v2i64,v1i128,v4f32,v2f64, f128], 420 128, 421 (add V2, V3, V4, V5, V0, V1, V6, V7, V8, V9, V10, V11, 422 V12, V13, V14, V15, V16, V17, V18, V19, V31, V30, 423 V29, V28, V27, V26, V25, V24, V23, V22, V21, V20)>; 424 425// VSX register classes (the allocation order mirrors that of the corresponding 426// subregister classes). 427def VSLRC : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128, 428 (add (sequence "VSL%u", 0, 13), 429 (sequence "VSL%u", 31, 14))>; 430def VSRC : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128, 431 (add VSLRC, VRRC)>; 432 433// Register classes for the 64-bit "scalar" VSX subregisters. 434def VFRC : RegisterClass<"PPC", [f64], 64, 435 (add VF2, VF3, VF4, VF5, VF0, VF1, VF6, VF7, 436 VF8, VF9, VF10, VF11, VF12, VF13, VF14, 437 VF15, VF16, VF17, VF18, VF19, VF31, VF30, 438 VF29, VF28, VF27, VF26, VF25, VF24, VF23, 439 VF22, VF21, VF20)>; 440def VSFRC : RegisterClass<"PPC", [f64], 64, (add F8RC, VFRC)>; 441 442// Allow spilling GPR's into caller-saved VSR's. 443def SPILLTOVSRRC : RegisterClass<"PPC", [i64, f64], 64, (add G8RC, (sub VSFRC, 444 (sequence "VF%u", 31, 20), 445 (sequence "F%u", 31, 14)))>; 446 447// Register class for single precision scalars in VSX registers 448def VSSRC : RegisterClass<"PPC", [f32], 32, (add VSFRC)>; 449 450def CRBITRC : RegisterClass<"PPC", [i1], 32, 451 (add CR2LT, CR2GT, CR2EQ, CR2UN, 452 CR3LT, CR3GT, CR3EQ, CR3UN, 453 CR4LT, CR4GT, CR4EQ, CR4UN, 454 CR5LT, CR5GT, CR5EQ, CR5UN, 455 CR6LT, CR6GT, CR6EQ, CR6UN, 456 CR7LT, CR7GT, CR7EQ, CR7UN, 457 CR1LT, CR1GT, CR1EQ, CR1UN, 458 CR0LT, CR0GT, CR0EQ, CR0UN)> { 459 let Size = 32; 460 let AltOrders = [(sub CRBITRC, CR2LT, CR2GT, CR2EQ, CR2UN, CR3LT, CR3GT, 461 CR3EQ, CR3UN, CR4LT, CR4GT, CR4EQ, CR4UN)]; 462 let AltOrderSelect = [{ 463 return MF.getSubtarget<PPCSubtarget>().isELFv2ABI() && 464 MF.getInfo<PPCFunctionInfo>()->isNonVolatileCRDisabled(); 465 }]; 466} 467 468def CRRC : RegisterClass<"PPC", [i32], 32, 469 (add CR0, CR1, CR5, CR6, 470 CR7, CR2, CR3, CR4)> { 471 let AltOrders = [(sub CRRC, CR2, CR3, CR4)]; 472 let AltOrderSelect = [{ 473 return MF.getSubtarget<PPCSubtarget>().isELFv2ABI() && 474 MF.getInfo<PPCFunctionInfo>()->isNonVolatileCRDisabled(); 475 }]; 476} 477// The CTR registers are not allocatable because they're used by the 478// decrement-and-branch instructions, and thus need to stay live across 479// multiple basic blocks. 480def CTRRC : RegisterClass<"PPC", [i32], 32, (add CTR)> { 481 let isAllocatable = 0; 482} 483def CTRRC8 : RegisterClass<"PPC", [i64], 64, (add CTR8)> { 484 let isAllocatable = 0; 485} 486 487def LRRC : RegisterClass<"PPC", [i32], 32, (add LR)> { 488 let isAllocatable = 0; 489} 490def LR8RC : RegisterClass<"PPC", [i64], 64, (add LR8)> { 491 let isAllocatable = 0; 492} 493 494def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>; 495def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY, XER)> { 496 let CopyCost = -1; 497 let isAllocatable = 0; 498} 499 500// Make AllocationOrder as similar as G8RC's to avoid potential spilling. 501// Similarly, we have an AltOrder for 64-bit ELF ABI which r2 is allocated 502// at last. 503def G8pRC : 504 RegisterClass<"PPC", [i128], 128, 505 (add (sequence "G8p%u", 1, 5), 506 (sequence "G8p%u", 14, 7), 507 G8p15, G8p6, G8p0)> { 508 let AltOrders = [(add (sub G8pRC, G8p1), G8p1)]; 509 let AltOrderSelect = [{ 510 return MF.getSubtarget<PPCSubtarget>().is64BitELFABI(); 511 }]; 512 let Size = 128; 513} 514 515include "PPCRegisterInfoMMA.td" 516include "PPCRegisterInfoDMR.td" 517 518//===----------------------------------------------------------------------===// 519// PowerPC Operand Definitions. 520 521// In the default PowerPC assembler syntax, registers are specified simply 522// by number, so they cannot be distinguished from immediate values (without 523// looking at the opcode). This means that the default operand matching logic 524// for the asm parser does not work, and we need to specify custom matchers. 525// Since those can only be specified with RegisterOperand classes and not 526// directly on the RegisterClass, all instructions patterns used by the asm 527// parser need to use a RegisterOperand (instead of a RegisterClass) for 528// all their register operands. 529// For this purpose, we define one RegisterOperand for each RegisterClass, 530// using the same name as the class, just in lower case. 531 532def PPCRegGPRCAsmOperand : AsmOperandClass { 533 let Name = "RegGPRC"; let PredicateMethod = "isRegNumber"; 534} 535def gprc : RegisterOperand<GPRC> { 536 let ParserMatchClass = PPCRegGPRCAsmOperand; 537} 538def PPCRegG8RCAsmOperand : AsmOperandClass { 539 let Name = "RegG8RC"; let PredicateMethod = "isRegNumber"; 540} 541def g8rc : RegisterOperand<G8RC> { 542 let ParserMatchClass = PPCRegG8RCAsmOperand; 543} 544def PPCRegG8pRCAsmOperand : AsmOperandClass { 545 let Name = "RegG8pRC"; let PredicateMethod = "isEvenRegNumber"; 546} 547def g8prc : RegisterOperand<G8pRC> { 548 let ParserMatchClass = PPCRegG8pRCAsmOperand; 549} 550def PPCRegGPRCNoR0AsmOperand : AsmOperandClass { 551 let Name = "RegGPRCNoR0"; let PredicateMethod = "isRegNumber"; 552} 553def gprc_nor0 : RegisterOperand<GPRC_NOR0> { 554 let ParserMatchClass = PPCRegGPRCNoR0AsmOperand; 555} 556def PPCRegG8RCNoX0AsmOperand : AsmOperandClass { 557 let Name = "RegG8RCNoX0"; let PredicateMethod = "isRegNumber"; 558} 559def g8rc_nox0 : RegisterOperand<G8RC_NOX0> { 560 let ParserMatchClass = PPCRegG8RCNoX0AsmOperand; 561} 562def PPCRegF8RCAsmOperand : AsmOperandClass { 563 let Name = "RegF8RC"; let PredicateMethod = "isRegNumber"; 564} 565def f8rc : RegisterOperand<F8RC> { 566 let ParserMatchClass = PPCRegF8RCAsmOperand; 567} 568def PPCRegF4RCAsmOperand : AsmOperandClass { 569 let Name = "RegF4RC"; let PredicateMethod = "isRegNumber"; 570} 571def f4rc : RegisterOperand<F4RC> { 572 let ParserMatchClass = PPCRegF4RCAsmOperand; 573} 574def PPCRegFpRCAsmOperand : AsmOperandClass { 575 let Name = "RegFpRC"; let PredicateMethod = "isEvenRegNumber"; 576} 577def fpairrc : RegisterOperand<FpRC> { 578 let ParserMatchClass = PPCRegFpRCAsmOperand; 579} 580def PPCRegVRRCAsmOperand : AsmOperandClass { 581 let Name = "RegVRRC"; let PredicateMethod = "isRegNumber"; 582} 583def vrrc : RegisterOperand<VRRC> { 584 let ParserMatchClass = PPCRegVRRCAsmOperand; 585} 586def PPCRegVFRCAsmOperand : AsmOperandClass { 587 let Name = "RegVFRC"; let PredicateMethod = "isRegNumber"; 588} 589def vfrc : RegisterOperand<VFRC> { 590 let ParserMatchClass = PPCRegVFRCAsmOperand; 591} 592def PPCRegCRBITRCAsmOperand : AsmOperandClass { 593 let Name = "RegCRBITRC"; let PredicateMethod = "isCRBitNumber"; 594} 595def crbitrc : RegisterOperand<CRBITRC> { 596 let ParserMatchClass = PPCRegCRBITRCAsmOperand; 597} 598def PPCRegCRRCAsmOperand : AsmOperandClass { 599 let Name = "RegCRRC"; let PredicateMethod = "isCCRegNumber"; 600} 601def crrc : RegisterOperand<CRRC> { 602 let ParserMatchClass = PPCRegCRRCAsmOperand; 603} 604def PPCRegSPERCAsmOperand : AsmOperandClass { 605 let Name = "RegSPERC"; let PredicateMethod = "isRegNumber"; 606} 607def sperc : RegisterOperand<SPERC> { 608 let ParserMatchClass = PPCRegSPERCAsmOperand; 609} 610def PPCRegSPE4RCAsmOperand : AsmOperandClass { 611 let Name = "RegSPE4RC"; let PredicateMethod = "isRegNumber"; 612} 613def spe4rc : RegisterOperand<GPRC> { 614 let ParserMatchClass = PPCRegSPE4RCAsmOperand; 615} 616 617def PPCU1ImmAsmOperand : AsmOperandClass { 618 let Name = "U1Imm"; let PredicateMethod = "isU1Imm"; 619 let RenderMethod = "addImmOperands"; 620} 621def u1imm : Operand<i32> { 622 let PrintMethod = "printU1ImmOperand"; 623 let ParserMatchClass = PPCU1ImmAsmOperand; 624 let DecoderMethod = "decodeUImmOperand<1>"; 625 let OperandType = "OPERAND_IMMEDIATE"; 626} 627 628def PPCU2ImmAsmOperand : AsmOperandClass { 629 let Name = "U2Imm"; let PredicateMethod = "isU2Imm"; 630 let RenderMethod = "addImmOperands"; 631} 632def u2imm : Operand<i32> { 633 let PrintMethod = "printU2ImmOperand"; 634 let ParserMatchClass = PPCU2ImmAsmOperand; 635 let DecoderMethod = "decodeUImmOperand<2>"; 636 let OperandType = "OPERAND_IMMEDIATE"; 637} 638 639def PPCATBitsAsHintAsmOperand : AsmOperandClass { 640 let Name = "ATBitsAsHint"; let PredicateMethod = "isATBitsAsHint"; 641 let RenderMethod = "addImmOperands"; // Irrelevant, predicate always fails. 642} 643def atimm : Operand<i32> { 644 let PrintMethod = "printATBitsAsHint"; 645 let ParserMatchClass = PPCATBitsAsHintAsmOperand; 646 let OperandType = "OPERAND_IMMEDIATE"; 647} 648 649def PPCU3ImmAsmOperand : AsmOperandClass { 650 let Name = "U3Imm"; let PredicateMethod = "isU3Imm"; 651 let RenderMethod = "addImmOperands"; 652} 653def u3imm : Operand<i32> { 654 let PrintMethod = "printU3ImmOperand"; 655 let ParserMatchClass = PPCU3ImmAsmOperand; 656 let DecoderMethod = "decodeUImmOperand<3>"; 657 let OperandType = "OPERAND_IMMEDIATE"; 658} 659 660def PPCU4ImmAsmOperand : AsmOperandClass { 661 let Name = "U4Imm"; let PredicateMethod = "isU4Imm"; 662 let RenderMethod = "addImmOperands"; 663} 664def u4imm : Operand<i32> { 665 let PrintMethod = "printU4ImmOperand"; 666 let ParserMatchClass = PPCU4ImmAsmOperand; 667 let DecoderMethod = "decodeUImmOperand<4>"; 668 let OperandType = "OPERAND_IMMEDIATE"; 669} 670def PPCS5ImmAsmOperand : AsmOperandClass { 671 let Name = "S5Imm"; let PredicateMethod = "isS5Imm"; 672 let RenderMethod = "addImmOperands"; 673} 674def s5imm : Operand<i32> { 675 let PrintMethod = "printS5ImmOperand"; 676 let ParserMatchClass = PPCS5ImmAsmOperand; 677 let DecoderMethod = "decodeSImmOperand<5>"; 678 let OperandType = "OPERAND_IMMEDIATE"; 679} 680def PPCU5ImmAsmOperand : AsmOperandClass { 681 let Name = "U5Imm"; let PredicateMethod = "isU5Imm"; 682 let RenderMethod = "addImmOperands"; 683} 684def u5imm : Operand<i32> { 685 let PrintMethod = "printU5ImmOperand"; 686 let ParserMatchClass = PPCU5ImmAsmOperand; 687 let DecoderMethod = "decodeUImmOperand<5>"; 688 let OperandType = "OPERAND_IMMEDIATE"; 689} 690def PPCU6ImmAsmOperand : AsmOperandClass { 691 let Name = "U6Imm"; let PredicateMethod = "isU6Imm"; 692 let RenderMethod = "addImmOperands"; 693} 694def u6imm : Operand<i32> { 695 let PrintMethod = "printU6ImmOperand"; 696 let ParserMatchClass = PPCU6ImmAsmOperand; 697 let DecoderMethod = "decodeUImmOperand<6>"; 698 let OperandType = "OPERAND_IMMEDIATE"; 699} 700def PPCU7ImmAsmOperand : AsmOperandClass { 701 let Name = "U7Imm"; let PredicateMethod = "isU7Imm"; 702 let RenderMethod = "addImmOperands"; 703} 704def u7imm : Operand<i32> { 705 let PrintMethod = "printU7ImmOperand"; 706 let ParserMatchClass = PPCU7ImmAsmOperand; 707 let DecoderMethod = "decodeUImmOperand<7>"; 708 let OperandType = "OPERAND_IMMEDIATE"; 709} 710def PPCU8ImmAsmOperand : AsmOperandClass { 711 let Name = "U8Imm"; let PredicateMethod = "isU8Imm"; 712 let RenderMethod = "addImmOperands"; 713} 714def u8imm : Operand<i32> { 715 let PrintMethod = "printU8ImmOperand"; 716 let ParserMatchClass = PPCU8ImmAsmOperand; 717 let DecoderMethod = "decodeUImmOperand<8>"; 718 let OperandType = "OPERAND_IMMEDIATE"; 719} 720def PPCU10ImmAsmOperand : AsmOperandClass { 721 let Name = "U10Imm"; let PredicateMethod = "isU10Imm"; 722 let RenderMethod = "addImmOperands"; 723} 724def u10imm : Operand<i32> { 725 let PrintMethod = "printU10ImmOperand"; 726 let ParserMatchClass = PPCU10ImmAsmOperand; 727 let DecoderMethod = "decodeUImmOperand<10>"; 728 let OperandType = "OPERAND_IMMEDIATE"; 729} 730def PPCU12ImmAsmOperand : AsmOperandClass { 731 let Name = "U12Imm"; let PredicateMethod = "isU12Imm"; 732 let RenderMethod = "addImmOperands"; 733} 734def u12imm : Operand<i32> { 735 let PrintMethod = "printU12ImmOperand"; 736 let ParserMatchClass = PPCU12ImmAsmOperand; 737 let DecoderMethod = "decodeUImmOperand<12>"; 738 let OperandType = "OPERAND_IMMEDIATE"; 739} 740def PPCS16ImmAsmOperand : AsmOperandClass { 741 let Name = "S16Imm"; let PredicateMethod = "isS16Imm"; 742 let RenderMethod = "addS16ImmOperands"; 743} 744def s16imm : Operand<i32> { 745 let PrintMethod = "printS16ImmOperand"; 746 let EncoderMethod = "getImm16Encoding"; 747 let ParserMatchClass = PPCS16ImmAsmOperand; 748 let DecoderMethod = "decodeSImmOperand<16>"; 749 let OperandType = "OPERAND_IMMEDIATE"; 750} 751def PPCU16ImmAsmOperand : AsmOperandClass { 752 let Name = "U16Imm"; let PredicateMethod = "isU16Imm"; 753 let RenderMethod = "addU16ImmOperands"; 754} 755def u16imm : Operand<i32> { 756 let PrintMethod = "printU16ImmOperand"; 757 let EncoderMethod = "getImm16Encoding"; 758 let ParserMatchClass = PPCU16ImmAsmOperand; 759 let DecoderMethod = "decodeUImmOperand<16>"; 760 let OperandType = "OPERAND_IMMEDIATE"; 761} 762def PPCS17ImmAsmOperand : AsmOperandClass { 763 let Name = "S17Imm"; let PredicateMethod = "isS17Imm"; 764 let RenderMethod = "addS16ImmOperands"; 765} 766def s17imm : Operand<i32> { 767 // This operand type is used for addis/lis to allow the assembler parser 768 // to accept immediates in the range -65536..65535 for compatibility with 769 // the GNU assembler. The operand is treated as 16-bit otherwise. 770 let PrintMethod = "printS16ImmOperand"; 771 let EncoderMethod = "getImm16Encoding"; 772 let ParserMatchClass = PPCS17ImmAsmOperand; 773 let DecoderMethod = "decodeSImmOperand<16>"; 774 let OperandType = "OPERAND_IMMEDIATE"; 775} 776def PPCS34ImmAsmOperand : AsmOperandClass { 777 let Name = "S34Imm"; 778 let PredicateMethod = "isS34Imm"; 779 let RenderMethod = "addImmOperands"; 780} 781def s34imm : Operand<i64> { 782 let PrintMethod = "printS34ImmOperand"; 783 let EncoderMethod = "getImm34EncodingNoPCRel"; 784 let ParserMatchClass = PPCS34ImmAsmOperand; 785 let DecoderMethod = "decodeSImmOperand<34>"; 786 let OperandType = "OPERAND_IMMEDIATE"; 787} 788def s34imm_pcrel : Operand<i64> { 789 let PrintMethod = "printS34ImmOperand"; 790 let EncoderMethod = "getImm34EncodingPCRel"; 791 let ParserMatchClass = PPCS34ImmAsmOperand; 792 let DecoderMethod = "decodeSImmOperand<34>"; 793 let OperandType = "OPERAND_IMMEDIATE"; 794} 795def PPCImmZeroAsmOperand : AsmOperandClass { 796 let Name = "ImmZero"; 797 let PredicateMethod = "isImmZero"; 798 let RenderMethod = "addImmOperands"; 799} 800def immZero : Operand<i32> { 801 let PrintMethod = "printImmZeroOperand"; 802 let ParserMatchClass = PPCImmZeroAsmOperand; 803 let DecoderMethod = "decodeImmZeroOperand"; 804 let OperandType = "OPERAND_IMMEDIATE"; 805} 806 807def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>; 808def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; 809 810def PPCDirectBrAsmOperand : AsmOperandClass { 811 let Name = "DirectBr"; let PredicateMethod = "isDirectBr"; 812 let RenderMethod = "addBranchTargetOperands"; 813} 814def directbrtarget : Operand<OtherVT> { 815 let PrintMethod = "printBranchOperand"; 816 let EncoderMethod = "getDirectBrEncoding"; 817 let DecoderMethod = "decodeDirectBrTarget"; 818 let ParserMatchClass = PPCDirectBrAsmOperand; 819 let OperandType = "OPERAND_PCREL"; 820} 821def absdirectbrtarget : Operand<OtherVT> { 822 let PrintMethod = "printAbsBranchOperand"; 823 let EncoderMethod = "getAbsDirectBrEncoding"; 824 let DecoderMethod = "decodeDirectBrTarget"; 825 let ParserMatchClass = PPCDirectBrAsmOperand; 826} 827def PPCCondBrAsmOperand : AsmOperandClass { 828 let Name = "CondBr"; let PredicateMethod = "isCondBr"; 829 let RenderMethod = "addBranchTargetOperands"; 830} 831def condbrtarget : Operand<OtherVT> { 832 let PrintMethod = "printBranchOperand"; 833 let EncoderMethod = "getCondBrEncoding"; 834 let DecoderMethod = "decodeCondBrTarget"; 835 let ParserMatchClass = PPCCondBrAsmOperand; 836 let OperandType = "OPERAND_PCREL"; 837} 838def abscondbrtarget : Operand<OtherVT> { 839 let PrintMethod = "printAbsBranchOperand"; 840 let EncoderMethod = "getAbsCondBrEncoding"; 841 let DecoderMethod = "decodeCondBrTarget"; 842 let ParserMatchClass = PPCCondBrAsmOperand; 843} 844def calltarget : Operand<iPTR> { 845 let PrintMethod = "printBranchOperand"; 846 let EncoderMethod = "getDirectBrEncoding"; 847 let DecoderMethod = "decodeDirectBrTarget"; 848 let ParserMatchClass = PPCDirectBrAsmOperand; 849 let OperandType = "OPERAND_PCREL"; 850} 851def abscalltarget : Operand<iPTR> { 852 let PrintMethod = "printAbsBranchOperand"; 853 let EncoderMethod = "getAbsDirectBrEncoding"; 854 let DecoderMethod = "decodeDirectBrTarget"; 855 let ParserMatchClass = PPCDirectBrAsmOperand; 856} 857def PPCCRBitMaskOperand : AsmOperandClass { 858 let Name = "CRBitMask"; let PredicateMethod = "isCRBitMask"; 859} 860def crbitm: Operand<i8> { 861 let PrintMethod = "printcrbitm"; 862 let EncoderMethod = "get_crbitm_encoding"; 863 let DecoderMethod = "decodeCRBitMOperand"; 864 let ParserMatchClass = PPCCRBitMaskOperand; 865} 866// Address operands 867// A version of ptr_rc which excludes R0 (or X0 in 64-bit mode). 868def PPCRegGxRCNoR0Operand : AsmOperandClass { 869 let Name = "RegGxRCNoR0"; let PredicateMethod = "isRegNumber"; 870} 871def ptr_rc_nor0 : Operand<iPTR>, PointerLikeRegClass<1> { 872 let ParserMatchClass = PPCRegGxRCNoR0Operand; 873} 874 875// New addressing modes with 34 bit immediates. 876def PPCDispRI34Operand : AsmOperandClass { 877 let Name = "DispRI34"; let PredicateMethod = "isS34Imm"; 878 let RenderMethod = "addImmOperands"; 879} 880def dispRI34 : Operand<iPTR> { 881 let ParserMatchClass = PPCDispRI34Operand; 882 let EncoderMethod = "getDispRI34Encoding"; 883 let DecoderMethod = "decodeSImmOperand<34>"; 884} 885def dispRI34_pcrel : Operand<iPTR> { 886 let ParserMatchClass = PPCDispRI34Operand; 887 let EncoderMethod = "getDispRI34PCRelEncoding"; 888 let DecoderMethod = "decodeSImmOperand<34>"; 889} 890def memri34 : Operand<iPTR> { // memri, imm is a 34-bit value. 891 let PrintMethod = "printMemRegImm34"; 892 let MIOperandInfo = (ops dispRI34:$imm, ptr_rc_nor0:$reg); 893} 894// memri, imm is a 34-bit value for pc-relative instructions where 895// base register is set to zero. 896def memri34_pcrel : Operand<iPTR> { // memri, imm is a 34-bit value. 897 let PrintMethod = "printMemRegImm34PCRel"; 898 let MIOperandInfo = (ops dispRI34_pcrel:$imm, immZero:$reg); 899} 900 901// A version of ptr_rc usable with the asm parser. 902def PPCRegGxRCOperand : AsmOperandClass { 903 let Name = "RegGxRC"; let PredicateMethod = "isRegNumber"; 904} 905def ptr_rc_idx : Operand<iPTR>, PointerLikeRegClass<0> { 906 let ParserMatchClass = PPCRegGxRCOperand; 907} 908 909def PPCDispRIOperand : AsmOperandClass { 910 let Name = "DispRI"; let PredicateMethod = "isS16Imm"; 911 let RenderMethod = "addS16ImmOperands"; 912} 913def dispRI : Operand<iPTR> { 914 let ParserMatchClass = PPCDispRIOperand; 915 let EncoderMethod = "getDispRIEncoding"; 916} 917def PPCDispRIXOperand : AsmOperandClass { 918 let Name = "DispRIX"; let PredicateMethod = "isS16ImmX4"; 919 let RenderMethod = "addS16ImmOperands"; 920} 921def dispRIX : Operand<iPTR> { 922 let ParserMatchClass = PPCDispRIXOperand; 923 let EncoderMethod = "getDispRIXEncoding"; 924 let DecoderMethod = "decodeDispRIXOperand"; 925} 926def PPCDispRIHashOperand : AsmOperandClass { 927 let Name = "DispRIHash"; let PredicateMethod = "isHashImmX8"; 928 let RenderMethod = "addImmOperands"; 929} 930def dispRIHash : Operand<iPTR> { 931 let ParserMatchClass = PPCDispRIHashOperand; 932 let EncoderMethod = "getDispRIHashEncoding"; 933 let DecoderMethod = "decodeDispRIHashOperand"; 934} 935def PPCDispRIX16Operand : AsmOperandClass { 936 let Name = "DispRIX16"; let PredicateMethod = "isS16ImmX16"; 937 let RenderMethod = "addS16ImmOperands"; 938} 939def dispRIX16 : Operand<iPTR> { 940 let ParserMatchClass = PPCDispRIX16Operand; 941 let EncoderMethod = "getDispRIX16Encoding"; 942 let DecoderMethod = "decodeDispRIX16Operand"; 943 944} 945def PPCDispSPE8Operand : AsmOperandClass { 946 let Name = "DispSPE8"; let PredicateMethod = "isU8ImmX8"; 947 let RenderMethod = "addImmOperands"; 948} 949def dispSPE8 : Operand<iPTR> { 950 let ParserMatchClass = PPCDispSPE8Operand; 951 let DecoderMethod = "decodeDispSPE8Operand"; 952 let EncoderMethod = "getDispSPE8Encoding"; 953} 954def PPCDispSPE4Operand : AsmOperandClass { 955 let Name = "DispSPE4"; let PredicateMethod = "isU7ImmX4"; 956 let RenderMethod = "addImmOperands"; 957} 958def dispSPE4 : Operand<iPTR> { 959 let ParserMatchClass = PPCDispSPE4Operand; 960 let DecoderMethod = "decodeDispSPE4Operand"; 961 let EncoderMethod = "getDispSPE4Encoding"; 962} 963def PPCDispSPE2Operand : AsmOperandClass { 964 let Name = "DispSPE2"; let PredicateMethod = "isU6ImmX2"; 965 let RenderMethod = "addImmOperands"; 966} 967def dispSPE2 : Operand<iPTR> { 968 let ParserMatchClass = PPCDispSPE2Operand; 969 let DecoderMethod = "decodeDispSPE2Operand"; 970 let EncoderMethod = "getDispSPE2Encoding"; 971} 972 973def memri : Operand<iPTR> { 974 let PrintMethod = "printMemRegImm"; 975 let MIOperandInfo = (ops dispRI:$imm, ptr_rc_nor0:$reg); 976 let OperandType = "OPERAND_MEMORY"; 977} 978def memrr : Operand<iPTR> { 979 let PrintMethod = "printMemRegReg"; 980 let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg, ptr_rc_idx:$offreg); 981 let OperandType = "OPERAND_MEMORY"; 982} 983def memrix : Operand<iPTR> { // memri where the imm is 4-aligned. 984 let PrintMethod = "printMemRegImm"; 985 let MIOperandInfo = (ops dispRIX:$imm, ptr_rc_nor0:$reg); 986 let OperandType = "OPERAND_MEMORY"; 987} 988def memrihash : Operand<iPTR> { 989 // memrihash 8-aligned for ROP Protection Instructions. 990 let PrintMethod = "printMemRegImmHash"; 991 let MIOperandInfo = (ops dispRIHash:$imm, ptr_rc_nor0:$reg); 992 let OperandType = "OPERAND_MEMORY"; 993} 994def memrix16 : Operand<iPTR> { // memri, imm is 16-aligned, 12-bit, Inst{16:27} 995 let PrintMethod = "printMemRegImm"; 996 let MIOperandInfo = (ops dispRIX16:$imm, ptr_rc_nor0:$reg); 997 let OperandType = "OPERAND_MEMORY"; 998} 999def spe8dis : Operand<iPTR> { // SPE displacement where the imm is 8-aligned. 1000 let PrintMethod = "printMemRegImm"; 1001 let MIOperandInfo = (ops dispSPE8:$imm, ptr_rc_nor0:$reg); 1002 let OperandType = "OPERAND_MEMORY"; 1003} 1004def spe4dis : Operand<iPTR> { // SPE displacement where the imm is 4-aligned. 1005 let PrintMethod = "printMemRegImm"; 1006 let MIOperandInfo = (ops dispSPE4:$imm, ptr_rc_nor0:$reg); 1007 let OperandType = "OPERAND_MEMORY"; 1008} 1009def spe2dis : Operand<iPTR> { // SPE displacement where the imm is 2-aligned. 1010 let PrintMethod = "printMemRegImm"; 1011 let MIOperandInfo = (ops dispSPE2:$imm, ptr_rc_nor0:$reg); 1012 let OperandType = "OPERAND_MEMORY"; 1013} 1014 1015// A single-register address. This is used with the SjLj 1016// pseudo-instructions which translates to LD/LWZ. These instructions requires 1017// G8RC_NOX0 registers. 1018def memr : Operand<iPTR> { 1019 let MIOperandInfo = (ops ptr_rc_nor0:$ptrreg); 1020 let OperandType = "OPERAND_MEMORY"; 1021} 1022def PPCTLSRegOperand : AsmOperandClass { 1023 let Name = "TLSReg"; let PredicateMethod = "isTLSReg"; 1024 let RenderMethod = "addTLSRegOperands"; 1025} 1026def tlsreg32 : Operand<i32> { 1027 let EncoderMethod = "getTLSRegEncoding"; 1028 let ParserMatchClass = PPCTLSRegOperand; 1029} 1030def tlsgd32 : Operand<i32> {} 1031def tlscall32 : Operand<i32> { 1032 let PrintMethod = "printTLSCall"; 1033 let MIOperandInfo = (ops calltarget:$func, tlsgd32:$sym); 1034 let EncoderMethod = "getTLSCallEncoding"; 1035} 1036 1037// PowerPC Predicate operand. 1038def pred : Operand<OtherVT> { 1039 let PrintMethod = "printPredicateOperand"; 1040 let MIOperandInfo = (ops i32imm:$bibo, crrc:$reg); 1041} 1042 1043def PPCRegVSRCAsmOperand : AsmOperandClass { 1044 let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber"; 1045} 1046def vsrc : RegisterOperand<VSRC> { 1047 let ParserMatchClass = PPCRegVSRCAsmOperand; 1048} 1049 1050def PPCRegVSFRCAsmOperand : AsmOperandClass { 1051 let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber"; 1052} 1053def vsfrc : RegisterOperand<VSFRC> { 1054 let ParserMatchClass = PPCRegVSFRCAsmOperand; 1055} 1056 1057def PPCRegVSSRCAsmOperand : AsmOperandClass { 1058 let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber"; 1059} 1060def vssrc : RegisterOperand<VSSRC> { 1061 let ParserMatchClass = PPCRegVSSRCAsmOperand; 1062} 1063 1064def PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass { 1065 let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber"; 1066} 1067 1068def spilltovsrrc : RegisterOperand<SPILLTOVSRRC> { 1069 let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand; 1070} 1071 1072def PPCRegVSRpRCAsmOperand : AsmOperandClass { 1073 let Name = "RegVSRpRC"; let PredicateMethod = "isVSRpEvenRegNumber"; 1074} 1075 1076def vsrprc : RegisterOperand<VSRpRC> { 1077 let ParserMatchClass = PPCRegVSRpRCAsmOperand; 1078} 1079 1080def PPCRegVSRpEvenRCAsmOperand : AsmOperandClass { 1081 let Name = "RegVSRpEvenRC"; let PredicateMethod = "isVSRpEvenRegNumber"; 1082} 1083 1084def vsrpevenrc : RegisterOperand<VSRpRC> { 1085 let ParserMatchClass = PPCRegVSRpEvenRCAsmOperand; 1086 let EncoderMethod = "getVSRpEvenEncoding"; 1087 let DecoderMethod = "decodeVSRpEvenOperands"; 1088} 1089 1090def PPCRegACCRCAsmOperand : AsmOperandClass { 1091 let Name = "RegACCRC"; let PredicateMethod = "isACCRegNumber"; 1092} 1093 1094def acc : RegisterOperand<ACCRC> { 1095 let ParserMatchClass = PPCRegACCRCAsmOperand; 1096} 1097 1098def uacc : RegisterOperand<UACCRC> { 1099 let ParserMatchClass = PPCRegACCRCAsmOperand; 1100} 1101 1102// DMR Register Operands 1103def PPCRegDMRROWRCAsmOperand : AsmOperandClass { 1104 let Name = "RegDMRROWRC"; 1105 let PredicateMethod = "isDMRROWRegNumber"; 1106} 1107 1108def dmrrow : RegisterOperand<DMRROWRC> { 1109 let ParserMatchClass = PPCRegDMRROWRCAsmOperand; 1110} 1111 1112def PPCRegDMRROWpRCAsmOperand : AsmOperandClass { 1113 let Name = "RegDMRROWpRC"; 1114 let PredicateMethod = "isDMRROWpRegNumber"; 1115} 1116 1117def dmrrowp : RegisterOperand<DMRROWpRC> { 1118 let ParserMatchClass = PPCRegDMRROWpRCAsmOperand; 1119} 1120 1121def wacc : RegisterOperand<WACCRC> { 1122 let ParserMatchClass = PPCRegACCRCAsmOperand; 1123} 1124 1125def wacc_hi : RegisterOperand<WACC_HIRC> { 1126 let ParserMatchClass = PPCRegACCRCAsmOperand; 1127} 1128 1129def PPCRegDMRRCAsmOperand : AsmOperandClass { 1130 let Name = "RegDMRRC"; 1131 let PredicateMethod = "isDMRRegNumber"; 1132} 1133 1134def dmr : RegisterOperand<DMRRC> { 1135 let ParserMatchClass = PPCRegDMRRCAsmOperand; 1136} 1137 1138def PPCRegDMRpRCAsmOperand : AsmOperandClass { 1139 let Name = "RegDMRpRC"; 1140 let PredicateMethod = "isDMRpRegNumber"; 1141} 1142 1143def dmrp : RegisterOperand<DMRpRC> { 1144 let ParserMatchClass = PPCRegDMRpRCAsmOperand; 1145} 1146