1251607Sdim//==- SystemZRegisterInfo.td - SystemZ register definitions -*- tablegen -*-==// 2251607Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6251607Sdim// 7251607Sdim//===----------------------------------------------------------------------===// 8251607Sdim 9251607Sdim//===----------------------------------------------------------------------===// 10251607Sdim// Class definitions. 11251607Sdim//===----------------------------------------------------------------------===// 12251607Sdim 13251607Sdimclass SystemZReg<string n> : Register<n> { 14251607Sdim let Namespace = "SystemZ"; 15251607Sdim} 16251607Sdim 17251607Sdimclass SystemZRegWithSubregs<string n, list<Register> subregs> 18251607Sdim : RegisterWithSubRegs<n, subregs> { 19251607Sdim let Namespace = "SystemZ"; 20251607Sdim} 21251607Sdim 22251607Sdimlet Namespace = "SystemZ" in { 23261991Sdimdef subreg_l32 : SubRegIndex<32, 0>; // Also acts as subreg_ll32. 24261991Sdimdef subreg_h32 : SubRegIndex<32, 32>; // Also acts as subreg_lh32. 25261991Sdimdef subreg_l64 : SubRegIndex<64, 0>; 26261991Sdimdef subreg_h64 : SubRegIndex<64, 64>; 27261991Sdimdef subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>; 28261991Sdimdef subreg_hl32 : ComposedSubRegIndex<subreg_h64, subreg_l32>; 29251607Sdim} 30251607Sdim 31288943Sdim// Define a register class that contains values of types TYPES and an 32251607Sdim// associated operand called NAME. SIZE is the size and alignment 33251607Sdim// of the registers and REGLIST is the list of individual registers. 34288943Sdimmulticlass SystemZRegClass<string name, list<ValueType> types, int size, 35314564Sdim dag regList, bit allocatable = 1> { 36251607Sdim def AsmOperand : AsmOperandClass { 37251607Sdim let Name = name; 38251607Sdim let ParserMethod = "parse"##name; 39251607Sdim let RenderMethod = "addRegOperands"; 40251607Sdim } 41314564Sdim let isAllocatable = allocatable in 42314564Sdim def Bit : RegisterClass<"SystemZ", types, size, regList> { 43314564Sdim let Size = size; 44314564Sdim } 45251607Sdim def "" : RegisterOperand<!cast<RegisterClass>(name##"Bit")> { 46251607Sdim let ParserMatchClass = !cast<AsmOperandClass>(name##"AsmOperand"); 47251607Sdim } 48251607Sdim} 49251607Sdim 50251607Sdim//===----------------------------------------------------------------------===// 51251607Sdim// General-purpose registers 52251607Sdim//===----------------------------------------------------------------------===// 53251607Sdim 54251607Sdim// Lower 32 bits of one of the 16 64-bit general-purpose registers 55251607Sdimclass GPR32<bits<16> num, string n> : SystemZReg<n> { 56251607Sdim let HWEncoding = num; 57251607Sdim} 58251607Sdim 59251607Sdim// One of the 16 64-bit general-purpose registers. 60261991Sdimclass GPR64<bits<16> num, string n, GPR32 low, GPR32 high> 61261991Sdim : SystemZRegWithSubregs<n, [low, high]> { 62251607Sdim let HWEncoding = num; 63261991Sdim let SubRegIndices = [subreg_l32, subreg_h32]; 64327952Sdim let CoveredBySubRegs = 1; 65251607Sdim} 66251607Sdim 67251607Sdim// 8 even-odd pairs of GPR64s. 68261991Sdimclass GPR128<bits<16> num, string n, GPR64 low, GPR64 high> 69261991Sdim : SystemZRegWithSubregs<n, [low, high]> { 70251607Sdim let HWEncoding = num; 71261991Sdim let SubRegIndices = [subreg_l64, subreg_h64]; 72327952Sdim let CoveredBySubRegs = 1; 73251607Sdim} 74251607Sdim 75251607Sdim// General-purpose registers 76251607Sdimforeach I = 0-15 in { 77261991Sdim def R#I#L : GPR32<I, "r"#I>; 78261991Sdim def R#I#H : GPR32<I, "r"#I>; 79261991Sdim def R#I#D : GPR64<I, "r"#I, !cast<GPR32>("R"#I#"L"), !cast<GPR32>("R"#I#"H")>, 80261991Sdim DwarfRegNum<[I]>; 81251607Sdim} 82251607Sdim 83251607Sdimforeach I = [0, 2, 4, 6, 8, 10, 12, 14] in { 84261991Sdim def R#I#Q : GPR128<I, "r"#I, !cast<GPR64>("R"#!add(I, 1)#"D"), 85261991Sdim !cast<GPR64>("R"#I#"D")>; 86251607Sdim} 87251607Sdim 88251607Sdim/// Allocate the callee-saved R6-R13 backwards. That way they can be saved 89251607Sdim/// together with R14 and R15 in one prolog instruction. 90288943Sdimdefm GR32 : SystemZRegClass<"GR32", [i32], 32, 91288943Sdim (add (sequence "R%uL", 0, 5), 92288943Sdim (sequence "R%uL", 15, 6))>; 93288943Sdimdefm GRH32 : SystemZRegClass<"GRH32", [i32], 32, 94288943Sdim (add (sequence "R%uH", 0, 5), 95288943Sdim (sequence "R%uH", 15, 6))>; 96288943Sdimdefm GR64 : SystemZRegClass<"GR64", [i64], 64, 97288943Sdim (add (sequence "R%uD", 0, 5), 98288943Sdim (sequence "R%uD", 15, 6))>; 99251607Sdim 100261991Sdim// Combine the low and high GR32s into a single class. This can only be 101261991Sdim// used for virtual registers if the high-word facility is available. 102288943Sdimdefm GRX32 : SystemZRegClass<"GRX32", [i32], 32, 103261991Sdim (add (sequence "R%uL", 0, 5), 104261991Sdim (sequence "R%uH", 0, 5), 105261991Sdim R15L, R15H, R14L, R14H, R13L, R13H, 106261991Sdim R12L, R12H, R11L, R11H, R10L, R10H, 107261991Sdim R9L, R9H, R8L, R8H, R7L, R7H, R6L, R6H)>; 108261991Sdim 109251607Sdim// The architecture doesn't really have any i128 support, so model the 110251607Sdim// register pairs as untyped instead. 111288943Sdimdefm GR128 : SystemZRegClass<"GR128", [untyped], 128, 112288943Sdim (add R0Q, R2Q, R4Q, R12Q, R10Q, R8Q, R6Q, R14Q)>; 113251607Sdim 114251607Sdim// Base and index registers. Everything except R0, which in an address 115251607Sdim// context evaluates as 0. 116288943Sdimdefm ADDR32 : SystemZRegClass<"ADDR32", [i32], 32, (sub GR32Bit, R0L)>; 117288943Sdimdefm ADDR64 : SystemZRegClass<"ADDR64", [i64], 64, (sub GR64Bit, R0D)>; 118251607Sdim 119251607Sdim// Not used directly, but needs to exist for ADDR32 and ADDR64 subregs 120251607Sdim// of a GR128. 121288943Sdimdefm ADDR128 : SystemZRegClass<"ADDR128", [untyped], 128, (sub GR128Bit, R0Q)>; 122251607Sdim 123314564Sdim// Any type register. Used for .insn directives when we don't know what the 124314564Sdim// register types could be. 125314564Sdimdefm AnyReg : SystemZRegClass<"AnyReg", 126314564Sdim [i64, f64, v8i8, v4i16, v2i32, v2f32], 64, 127314564Sdim (add (sequence "R%uD", 0, 15), 128314564Sdim (sequence "F%uD", 0, 15), 129341825Sdim (sequence "V%u", 0, 15)), 0/*allocatable*/>; 130314564Sdim 131251607Sdim//===----------------------------------------------------------------------===// 132251607Sdim// Floating-point registers 133251607Sdim//===----------------------------------------------------------------------===// 134251607Sdim 135276479Sdim// Maps FPR register numbers to their DWARF encoding. 136276479Sdimclass DwarfMapping<int id> { int Id = id; } 137276479Sdim 138276479Sdimdef F0Dwarf : DwarfMapping<16>; 139276479Sdimdef F2Dwarf : DwarfMapping<17>; 140276479Sdimdef F4Dwarf : DwarfMapping<18>; 141276479Sdimdef F6Dwarf : DwarfMapping<19>; 142276479Sdim 143276479Sdimdef F1Dwarf : DwarfMapping<20>; 144276479Sdimdef F3Dwarf : DwarfMapping<21>; 145276479Sdimdef F5Dwarf : DwarfMapping<22>; 146276479Sdimdef F7Dwarf : DwarfMapping<23>; 147276479Sdim 148276479Sdimdef F8Dwarf : DwarfMapping<24>; 149276479Sdimdef F10Dwarf : DwarfMapping<25>; 150276479Sdimdef F12Dwarf : DwarfMapping<26>; 151276479Sdimdef F14Dwarf : DwarfMapping<27>; 152276479Sdim 153276479Sdimdef F9Dwarf : DwarfMapping<28>; 154276479Sdimdef F11Dwarf : DwarfMapping<29>; 155276479Sdimdef F13Dwarf : DwarfMapping<30>; 156276479Sdimdef F15Dwarf : DwarfMapping<31>; 157276479Sdim 158288943Sdimdef F16Dwarf : DwarfMapping<68>; 159288943Sdimdef F18Dwarf : DwarfMapping<69>; 160288943Sdimdef F20Dwarf : DwarfMapping<70>; 161288943Sdimdef F22Dwarf : DwarfMapping<71>; 162288943Sdim 163288943Sdimdef F17Dwarf : DwarfMapping<72>; 164288943Sdimdef F19Dwarf : DwarfMapping<73>; 165288943Sdimdef F21Dwarf : DwarfMapping<74>; 166288943Sdimdef F23Dwarf : DwarfMapping<75>; 167288943Sdim 168288943Sdimdef F24Dwarf : DwarfMapping<76>; 169288943Sdimdef F26Dwarf : DwarfMapping<77>; 170288943Sdimdef F28Dwarf : DwarfMapping<78>; 171288943Sdimdef F30Dwarf : DwarfMapping<79>; 172288943Sdim 173288943Sdimdef F25Dwarf : DwarfMapping<80>; 174288943Sdimdef F27Dwarf : DwarfMapping<81>; 175288943Sdimdef F29Dwarf : DwarfMapping<82>; 176288943Sdimdef F31Dwarf : DwarfMapping<83>; 177288943Sdim 178288943Sdim// Upper 32 bits of one of the floating-point registers 179251607Sdimclass FPR32<bits<16> num, string n> : SystemZReg<n> { 180251607Sdim let HWEncoding = num; 181251607Sdim} 182251607Sdim 183288943Sdim// One of the floating-point registers. 184288943Sdimclass FPR64<bits<16> num, string n, FPR32 high> 185288943Sdim : SystemZRegWithSubregs<n, [high]> { 186251607Sdim let HWEncoding = num; 187344779Sdim let SubRegIndices = [subreg_h32]; 188251607Sdim} 189251607Sdim 190251607Sdim// 8 pairs of FPR64s, with a one-register gap inbetween. 191261991Sdimclass FPR128<bits<16> num, string n, FPR64 low, FPR64 high> 192261991Sdim : SystemZRegWithSubregs<n, [low, high]> { 193251607Sdim let HWEncoding = num; 194261991Sdim let SubRegIndices = [subreg_l64, subreg_h64]; 195327952Sdim let CoveredBySubRegs = 1; 196251607Sdim} 197251607Sdim 198288943Sdim// Floating-point registers. Registers 16-31 require the vector facility. 199251607Sdimforeach I = 0-15 in { 200251607Sdim def F#I#S : FPR32<I, "f"#I>; 201251607Sdim def F#I#D : FPR64<I, "f"#I, !cast<FPR32>("F"#I#"S")>, 202276479Sdim DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 203251607Sdim} 204288943Sdimforeach I = 16-31 in { 205288943Sdim def F#I#S : FPR32<I, "v"#I>; 206288943Sdim def F#I#D : FPR64<I, "v"#I, !cast<FPR32>("F"#I#"S")>, 207288943Sdim DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 208288943Sdim} 209251607Sdim 210251607Sdimforeach I = [0, 1, 4, 5, 8, 9, 12, 13] in { 211261991Sdim def F#I#Q : FPR128<I, "f"#I, !cast<FPR64>("F"#!add(I, 2)#"D"), 212261991Sdim !cast<FPR64>("F"#I#"D")>; 213251607Sdim} 214251607Sdim 215251607Sdim// There's no store-multiple instruction for FPRs, so we're not fussy 216251607Sdim// about the order in which call-saved registers are allocated. 217288943Sdimdefm FP32 : SystemZRegClass<"FP32", [f32], 32, (sequence "F%uS", 0, 15)>; 218288943Sdimdefm FP64 : SystemZRegClass<"FP64", [f64], 64, (sequence "F%uD", 0, 15)>; 219288943Sdimdefm FP128 : SystemZRegClass<"FP128", [f128], 128, 220288943Sdim (add F0Q, F1Q, F4Q, F5Q, F8Q, F9Q, F12Q, F13Q)>; 221251607Sdim 222251607Sdim//===----------------------------------------------------------------------===// 223288943Sdim// Vector registers 224288943Sdim//===----------------------------------------------------------------------===// 225288943Sdim 226288943Sdim// A full 128-bit vector register, with an FPR64 as its high part. 227288943Sdimclass VR128<bits<16> num, string n, FPR64 high> 228288943Sdim : SystemZRegWithSubregs<n, [high]> { 229288943Sdim let HWEncoding = num; 230344779Sdim let SubRegIndices = [subreg_h64]; 231288943Sdim} 232288943Sdim 233288943Sdim// Full vector registers. 234288943Sdimforeach I = 0-31 in { 235288943Sdim def V#I : VR128<I, "v"#I, !cast<FPR64>("F"#I#"D")>, 236288943Sdim DwarfRegNum<[!cast<DwarfMapping>("F"#I#"Dwarf").Id]>; 237288943Sdim} 238288943Sdim 239288943Sdim// Class used to store 32-bit values in the first element of a vector 240288943Sdim// register. f32 scalars are used for the WLEDB and WLDEB instructions. 241288943Sdimdefm VR32 : SystemZRegClass<"VR32", [f32, v4i8, v2i16], 32, 242288943Sdim (add (sequence "F%uS", 0, 7), 243288943Sdim (sequence "F%uS", 16, 31), 244288943Sdim (sequence "F%uS", 8, 15))>; 245288943Sdim 246288943Sdim// Class used to store 64-bit values in the upper half of a vector register. 247288943Sdim// The vector facility also includes scalar f64 instructions that operate 248288943Sdim// on the full vector register set. 249288943Sdimdefm VR64 : SystemZRegClass<"VR64", [f64, v8i8, v4i16, v2i32, v2f32], 64, 250288943Sdim (add (sequence "F%uD", 0, 7), 251288943Sdim (sequence "F%uD", 16, 31), 252288943Sdim (sequence "F%uD", 8, 15))>; 253288943Sdim 254288943Sdim// The subset of vector registers that can be used for floating-point 255288943Sdim// operations too. 256288943Sdimdefm VF128 : SystemZRegClass<"VF128", 257288943Sdim [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, 258288943Sdim (sequence "V%u", 0, 15)>; 259288943Sdim 260288943Sdim// All vector registers. 261288943Sdimdefm VR128 : SystemZRegClass<"VR128", 262341825Sdim [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, f128], 263321369Sdim 128, (add (sequence "V%u", 0, 7), 264321369Sdim (sequence "V%u", 16, 31), 265321369Sdim (sequence "V%u", 8, 15))>; 266288943Sdim 267288943Sdim// Attaches a ValueType to a register operand, to make the instruction 268288943Sdim// definitions easier. 269288943Sdimclass TypedReg<ValueType vtin, RegisterOperand opin> { 270288943Sdim ValueType vt = vtin; 271288943Sdim RegisterOperand op = opin; 272288943Sdim} 273288943Sdim 274321369Sdimdef v32f : TypedReg<i32, VR32>; 275321369Sdimdef v32sb : TypedReg<f32, VR32>; 276288943Sdimdef v64g : TypedReg<i64, VR64>; 277288943Sdimdef v64db : TypedReg<f64, VR64>; 278288943Sdimdef v128b : TypedReg<v16i8, VR128>; 279288943Sdimdef v128h : TypedReg<v8i16, VR128>; 280288943Sdimdef v128f : TypedReg<v4i32, VR128>; 281288943Sdimdef v128g : TypedReg<v2i64, VR128>; 282288943Sdimdef v128q : TypedReg<v16i8, VR128>; 283321369Sdimdef v128sb : TypedReg<v4f32, VR128>; 284288943Sdimdef v128db : TypedReg<v2f64, VR128>; 285321369Sdimdef v128xb : TypedReg<f128, VR128>; 286288943Sdimdef v128any : TypedReg<untyped, VR128>; 287288943Sdim 288288943Sdim//===----------------------------------------------------------------------===// 289251607Sdim// Other registers 290251607Sdim//===----------------------------------------------------------------------===// 291251607Sdim 292261991Sdim// The 2-bit condition code field of the PSW. Every register named in an 293261991Sdim// inline asm needs a class associated with it. 294261991Sdimdef CC : SystemZReg<"cc">; 295341825Sdimlet isAllocatable = 0, CopyCost = -1 in 296341825Sdim def CCR : RegisterClass<"SystemZ", [i32], 32, (add CC)>; 297314564Sdim 298353358Sdim// The floating-point control register. 299353358Sdim// Note: We only model the current rounding modes and the IEEE masks. 300353358Sdim// IEEE flags and DXC are not modeled here. 301353358Sdimdef FPC : SystemZReg<"fpc">; 302353358Sdimlet isAllocatable = 0 in 303353358Sdim def FPCRegs : RegisterClass<"SystemZ", [i32], 32, (add FPC)>; 304353358Sdim 305314564Sdim// Access registers. 306314564Sdimclass ACR32<bits<16> num, string n> : SystemZReg<n> { 307314564Sdim let HWEncoding = num; 308314564Sdim} 309314564Sdimforeach I = 0-15 in { 310314564Sdim def A#I : ACR32<I, "a"#I>, DwarfRegNum<[!add(I, 48)]>; 311314564Sdim} 312314564Sdimdefm AR32 : SystemZRegClass<"AR32", [i32], 32, 313314564Sdim (add (sequence "A%u", 0, 15)), 0>; 314314564Sdim 315321369Sdim// Control registers. 316321369Sdimclass CREG64<bits<16> num, string n> : SystemZReg<n> { 317321369Sdim let HWEncoding = num; 318321369Sdim} 319321369Sdimforeach I = 0-15 in { 320321369Sdim def C#I : CREG64<I, "c"#I>, DwarfRegNum<[!add(I, 32)]>; 321321369Sdim} 322321369Sdimdefm CR64 : SystemZRegClass<"CR64", [i64], 64, 323321369Sdim (add (sequence "C%u", 0, 15)), 0>; 324321369Sdim 325