1//==- SystemZRegisterInfo.td - SystemZ register definitions -*- 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// Class definitions. 11//===----------------------------------------------------------------------===// 12 13class SystemZReg<string n> : Register<n> { 14 let Namespace = "SystemZ"; 15} 16 17class SystemZRegWithSubregs<string n, list<Register> subregs> 18 : RegisterWithSubRegs<n, subregs> { 19 let Namespace = "SystemZ"; 20} 21 22let Namespace = "SystemZ" in { 23def subreg_l32 : SubRegIndex<32, 0>; // Also acts as subreg_ll32. 24def subreg_h32 : SubRegIndex<32, 32>; // Also acts as subreg_lh32. 25def subreg_l64 : SubRegIndex<64, 0>; 26def subreg_h64 : SubRegIndex<64, 64>; 27def subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>; 28def subreg_hl32 : ComposedSubRegIndex<subreg_h64, subreg_l32>; 29} 30 31// Define a register class that contains values of types TYPES and an 32// associated operand called NAME. SIZE is the size and alignment 33// of the registers and REGLIST is the list of individual registers. 34// If the user provides an alternate order list of regs, it will be used for 35// XPLINK. Otherwise, by default, XPLINK will use the regList ordering as well 36multiclass SystemZRegClass<string name, list<ValueType> types, int size, 37 dag regList, list<dag> altRegList = [regList], bit allocatable = 1> { 38 def AsmOperand : AsmOperandClass { 39 let Name = name; 40 let ParserMethod = "parse"#name; 41 let RenderMethod = "addRegOperands"; 42 } 43 let isAllocatable = allocatable in 44 def Bit : RegisterClass<"SystemZ", types, size, regList> { 45 let Size = size; 46 let AltOrders = altRegList; 47 let AltOrderSelect = [{ 48 const SystemZSubtarget &S = MF.getSubtarget<SystemZSubtarget>(); 49 return S.isTargetXPLINK64(); 50 }]; 51 } 52 def "" : RegisterOperand<!cast<RegisterClass>(name#"Bit")> { 53 let ParserMatchClass = !cast<AsmOperandClass>(name#"AsmOperand"); 54 } 55} 56 57//===----------------------------------------------------------------------===// 58// General-purpose registers 59//===----------------------------------------------------------------------===// 60 61// Lower 32 bits of one of the 16 64-bit general-purpose registers 62class GPR32<bits<16> num, string n> : SystemZReg<n> { 63 let HWEncoding = num; 64} 65 66// One of the 16 64-bit general-purpose registers. 67class GPR64<bits<16> num, string n, GPR32 low, GPR32 high> 68 : SystemZRegWithSubregs<n, [low, high]> { 69 let HWEncoding = num; 70 let SubRegIndices = [subreg_l32, subreg_h32]; 71 let CoveredBySubRegs = 1; 72} 73 74// 8 even-odd pairs of GPR64s. 75class GPR128<bits<16> num, string n, GPR64 low, GPR64 high> 76 : SystemZRegWithSubregs<n, [low, high]> { 77 let HWEncoding = num; 78 let SubRegIndices = [subreg_l64, subreg_h64]; 79 let CoveredBySubRegs = 1; 80} 81 82// General-purpose registers 83foreach I = 0-15 in { 84 def R#I#L : GPR32<I, "r"#I>; 85 def R#I#H : GPR32<I, "r"#I>; 86 def R#I#D : GPR64<I, "r"#I, !cast<GPR32>("R"#I#"L"), !cast<GPR32>("R"#I#"H")>, 87 DwarfRegNum<[I]>; 88} 89 90foreach I = [0, 2, 4, 6, 8, 10, 12, 14] in { 91 def R#I#Q : GPR128<I, "r"#I, !cast<GPR64>("R"#!add(I, 1)#"D"), 92 !cast<GPR64>("R"#I#"D")>; 93} 94 95/// zLinux: Allocate the callee-saved R6-R13 backwards. That way they can be 96/// saved together with R14 and R15 in one prolog instruction. 97/// XPLINK64: Allocate all registers in natural order 98defm GR32 : SystemZRegClass<"GR32", [i32], 32, 99 (add (sequence "R%uL", 0, 5), 100 (sequence "R%uL", 15, 6)), 101 [(add (sequence "R%uL", 0, 15))]>; 102defm GRH32 : SystemZRegClass<"GRH32", [i32], 32, 103 (add (sequence "R%uH", 0, 5), 104 (sequence "R%uH", 15, 6)), 105 [(add (sequence "R%uH", 0, 15))]>; 106defm GR64 : SystemZRegClass<"GR64", [i64], 64, 107 (add (sequence "R%uD", 0, 5), 108 (sequence "R%uD", 15, 6)), 109 [(add (sequence "R%uD", 0, 15))]>; 110 111// Combine the low and high GR32s into a single class. This can only be 112// used for virtual registers if the high-word facility is available. 113/// XPLINK64: Allocate all registers in natural order 114defm GRX32 : SystemZRegClass<"GRX32", [i32], 32, 115 (add (sequence "R%uL", 0, 5), 116 (sequence "R%uH", 0, 5), 117 R15L, R15H, R14L, R14H, R13L, R13H, 118 R12L, R12H, R11L, R11H, R10L, R10H, 119 R9L, R9H, R8L, R8H, R7L, R7H, R6L, R6H), 120 [(add 121 R0L, R1L, R2L, R3L, R0H, R1H, R2H, R3H, 122 R4L, R4H, R5L, R5H, R6L, R6H, R7L, R7H, 123 R8L, R8H, R9L, R9H, R10L,R10H,R11L,R11H, 124 R12L,R12H,R13L,R13H,R14L,R14H,R15L,R15H) 125 ]>; 126 127// The architecture doesn't really have any i128 support, so model the 128// register pairs as untyped instead. 129// XPLINK64: Allocate all registers in natural order 130defm GR128 : SystemZRegClass<"GR128", [untyped], 128, 131 (add R0Q, R2Q, R4Q, R12Q, R10Q, R8Q, R6Q, R14Q), 132 [(add R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q)]>; 133 134// Base and index registers. Everything except R0, which in an address 135// context evaluates as 0. 136// XPLINK64: Allocate all registers in natural order 137defm ADDR32 : SystemZRegClass<"ADDR32", [i32], 32, (sub GR32Bit, R0L), 138 [(add (sequence "R%uL", 1, 15))]>; 139defm ADDR64 : SystemZRegClass<"ADDR64", [i64], 64, (sub GR64Bit, R0D), 140 [(add (sequence "R%uD", 1, 15))]>; 141 142// Not used directly, but needs to exist for ADDR32 and ADDR64 subregs 143// of a GR128. 144// XPLINK64: Allocate all registers in natural order 145defm ADDR128 : SystemZRegClass<"ADDR128", [untyped], 128, (sub GR128Bit, R0Q), 146 [(add R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q)]>; 147 148// Any type register. Used for .insn directives when we don't know what the 149// register types could be. 150defm AnyReg : SystemZRegClass<"AnyReg", 151 [i64, f64, v8i8, v4i16, v2i32, v2f32], 64, 152 (add (sequence "R%uD", 0, 15), 153 (sequence "F%uD", 0, 15), 154 (sequence "V%u", 0, 15)), 155 [], 0/*allocatable*/>; 156 157//===----------------------------------------------------------------------===// 158// Floating-point registers 159//===----------------------------------------------------------------------===// 160 161// Maps FPR register numbers to their DWARF encoding. 162class DwarfMapping<int id> { int Id = id; } 163 164def F0Dwarf : DwarfMapping<16>; 165def F2Dwarf : DwarfMapping<17>; 166def F4Dwarf : DwarfMapping<18>; 167def F6Dwarf : DwarfMapping<19>; 168 169def F1Dwarf : DwarfMapping<20>; 170def F3Dwarf : DwarfMapping<21>; 171def F5Dwarf : DwarfMapping<22>; 172def F7Dwarf : DwarfMapping<23>; 173 174def F8Dwarf : DwarfMapping<24>; 175def F10Dwarf : DwarfMapping<25>; 176def F12Dwarf : DwarfMapping<26>; 177def F14Dwarf : DwarfMapping<27>; 178 179def F9Dwarf : DwarfMapping<28>; 180def F11Dwarf : DwarfMapping<29>; 181def F13Dwarf : DwarfMapping<30>; 182def F15Dwarf : DwarfMapping<31>; 183 184def F16Dwarf : DwarfMapping<68>; 185def F18Dwarf : DwarfMapping<69>; 186def F20Dwarf : DwarfMapping<70>; 187def F22Dwarf : DwarfMapping<71>; 188 189def F17Dwarf : DwarfMapping<72>; 190def F19Dwarf : DwarfMapping<73>; 191def F21Dwarf : DwarfMapping<74>; 192def F23Dwarf : DwarfMapping<75>; 193 194def F24Dwarf : DwarfMapping<76>; 195def F26Dwarf : DwarfMapping<77>; 196def F28Dwarf : DwarfMapping<78>; 197def F30Dwarf : DwarfMapping<79>; 198 199def F25Dwarf : DwarfMapping<80>; 200def F27Dwarf : DwarfMapping<81>; 201def F29Dwarf : DwarfMapping<82>; 202def F31Dwarf : DwarfMapping<83>; 203 204// Upper 32 bits of one of the floating-point registers 205class FPR32<bits<16> num, string n> : SystemZReg<n> { 206 let HWEncoding = num; 207} 208 209// One of the floating-point registers. 210class FPR64<bits<16> num, string n, FPR32 high> 211 : SystemZRegWithSubregs<n, [high]> { 212 let HWEncoding = num; 213 let SubRegIndices = [subreg_h32]; 214} 215 216// 8 pairs of FPR64s, with a one-register gap inbetween. 217class FPR128<bits<16> num, string n, FPR64 low, FPR64 high> 218 : SystemZRegWithSubregs<n, [low, high]> { 219 let HWEncoding = num; 220 let SubRegIndices = [subreg_l64, subreg_h64]; 221 let CoveredBySubRegs = 1; 222} 223 224// Floating-point registers. Registers 16-31 require the vector facility. 225foreach I = 0-15 in { 226 def F#I#S : FPR32<I, "f"#I>; 227 def F#I#D : FPR64<I, "f"#I, !cast<FPR32>("F"#I#"S")>, 228 DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 229} 230foreach I = 16-31 in { 231 def F#I#S : FPR32<I, "v"#I>; 232 def F#I#D : FPR64<I, "v"#I, !cast<FPR32>("F"#I#"S")>, 233 DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 234} 235 236foreach I = [0, 1, 4, 5, 8, 9, 12, 13] in { 237 def F#I#Q : FPR128<I, "f"#I, !cast<FPR64>("F"#!add(I, 2)#"D"), 238 !cast<FPR64>("F"#I#"D")>; 239} 240 241// There's no store-multiple instruction for FPRs, so we're not fussy 242// about the order in which call-saved registers are allocated. 243defm FP32 : SystemZRegClass<"FP32", [f32], 32, (sequence "F%uS", 0, 15)>; 244defm FP64 : SystemZRegClass<"FP64", [f64], 64, (sequence "F%uD", 0, 15)>; 245defm FP128 : SystemZRegClass<"FP128", [f128], 128, 246 (add F0Q, F1Q, F4Q, F5Q, F8Q, F9Q, F12Q, F13Q)>; 247 248//===----------------------------------------------------------------------===// 249// Vector registers 250//===----------------------------------------------------------------------===// 251 252// A full 128-bit vector register, with an FPR64 as its high part. 253class VR128<bits<16> num, string n, FPR64 high> 254 : SystemZRegWithSubregs<n, [high]> { 255 let HWEncoding = num; 256 let SubRegIndices = [subreg_h64]; 257} 258 259// Full vector registers. 260foreach I = 0-31 in { 261 def V#I : VR128<I, "v"#I, !cast<FPR64>("F"#I#"D")>, 262 DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 263} 264 265// Class used to store 32-bit values in the first element of a vector 266// register. f32 scalars are used for the WLEDB and WLDEB instructions. 267defm VR32 : SystemZRegClass<"VR32", [f32, v4i8, v2i16], 32, 268 (add (sequence "F%uS", 0, 7), 269 (sequence "F%uS", 16, 31), 270 (sequence "F%uS", 8, 15))>; 271 272// Class used to store 64-bit values in the upper half of a vector register. 273// The vector facility also includes scalar f64 instructions that operate 274// on the full vector register set. 275defm VR64 : SystemZRegClass<"VR64", [f64, v8i8, v4i16, v2i32, v2f32], 64, 276 (add (sequence "F%uD", 0, 7), 277 (sequence "F%uD", 16, 31), 278 (sequence "F%uD", 8, 15))>; 279 280// The subset of vector registers that can be used for floating-point 281// operations too. 282defm VF128 : SystemZRegClass<"VF128", 283 [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, 284 (sequence "V%u", 0, 15)>; 285 286// All vector registers. 287defm VR128 : SystemZRegClass<"VR128", 288 [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, f128], 289 128, (add (sequence "V%u", 0, 7), 290 (sequence "V%u", 16, 31), 291 (sequence "V%u", 8, 15))>; 292 293// Attaches a ValueType to a register operand, to make the instruction 294// definitions easier. 295class TypedReg<ValueType vtin, RegisterOperand opin> { 296 ValueType vt = vtin; 297 RegisterOperand op = opin; 298} 299 300def v32f : TypedReg<i32, VR32>; 301def v32sb : TypedReg<f32, VR32>; 302def v64g : TypedReg<i64, VR64>; 303def v64db : TypedReg<f64, VR64>; 304def v128b : TypedReg<v16i8, VR128>; 305def v128h : TypedReg<v8i16, VR128>; 306def v128f : TypedReg<v4i32, VR128>; 307def v128g : TypedReg<v2i64, VR128>; 308def v128q : TypedReg<v16i8, VR128>; 309def v128sb : TypedReg<v4f32, VR128>; 310def v128db : TypedReg<v2f64, VR128>; 311def v128xb : TypedReg<f128, VR128>; 312def v128any : TypedReg<untyped, VR128>; 313 314//===----------------------------------------------------------------------===// 315// Other registers 316//===----------------------------------------------------------------------===// 317 318// The 2-bit condition code field of the PSW. Every register named in an 319// inline asm needs a class associated with it. 320def CC : SystemZReg<"cc">; 321let isAllocatable = 0, CopyCost = -1 in 322 def CCR : RegisterClass<"SystemZ", [i32], 32, (add CC)>; 323 324// The floating-point control register. 325// Note: We only model the current rounding modes and the IEEE masks. 326// IEEE flags and DXC are not modeled here. 327def FPC : SystemZReg<"fpc">; 328let isAllocatable = 0 in 329 def FPCRegs : RegisterClass<"SystemZ", [i32], 32, (add FPC)>; 330 331// Access registers. 332class ACR32<bits<16> num, string n> : SystemZReg<n> { 333 let HWEncoding = num; 334} 335foreach I = 0-15 in { 336 def A#I : ACR32<I, "a"#I>, DwarfRegNum<[!add(I, 48)]>; 337} 338defm AR32 : SystemZRegClass<"AR32", [i32], 32, 339 (add (sequence "A%u", 0, 15)), [], 0>; 340 341// Control registers. 342class CREG64<bits<16> num, string n> : SystemZReg<n> { 343 let HWEncoding = num; 344} 345foreach I = 0-15 in { 346 def C#I : CREG64<I, "c"#I>, DwarfRegNum<[!add(I, 32)]>; 347} 348defm CR64 : SystemZRegClass<"CR64", [i64], 64, 349 (add (sequence "C%u", 0, 15)), [], 0>; 350