xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIRegisterInfo.td (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
10b57cec5SDimitry Andric//===-- SIRegisterInfo.td - SI Register defs ---------------*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric//  Helpers
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andricclass getSubRegs<int size> {
140b57cec5SDimitry Andric  list<SubRegIndex> ret2 = [sub0, sub1];
150b57cec5SDimitry Andric  list<SubRegIndex> ret3 = [sub0, sub1, sub2];
160b57cec5SDimitry Andric  list<SubRegIndex> ret4 = [sub0, sub1, sub2, sub3];
170b57cec5SDimitry Andric  list<SubRegIndex> ret5 = [sub0, sub1, sub2, sub3, sub4];
180b57cec5SDimitry Andric  list<SubRegIndex> ret8 = [sub0, sub1, sub2, sub3, sub4, sub5, sub6, sub7];
190b57cec5SDimitry Andric  list<SubRegIndex> ret16 = [sub0, sub1, sub2, sub3,
200b57cec5SDimitry Andric                             sub4, sub5, sub6, sub7,
210b57cec5SDimitry Andric                             sub8, sub9, sub10, sub11,
220b57cec5SDimitry Andric                             sub12, sub13, sub14, sub15];
230b57cec5SDimitry Andric  list<SubRegIndex> ret32 = [sub0, sub1, sub2, sub3,
240b57cec5SDimitry Andric                             sub4, sub5, sub6, sub7,
250b57cec5SDimitry Andric                             sub8, sub9, sub10, sub11,
260b57cec5SDimitry Andric                             sub12, sub13, sub14, sub15,
270b57cec5SDimitry Andric                             sub16, sub17, sub18, sub19,
280b57cec5SDimitry Andric                             sub20, sub21, sub22, sub23,
290b57cec5SDimitry Andric                             sub24, sub25, sub26, sub27,
300b57cec5SDimitry Andric                             sub28, sub29, sub30, sub31];
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric  list<SubRegIndex> ret = !if(!eq(size, 2), ret2,
330b57cec5SDimitry Andric                              !if(!eq(size, 3), ret3,
340b57cec5SDimitry Andric                                  !if(!eq(size, 4), ret4,
350b57cec5SDimitry Andric                                      !if(!eq(size, 5), ret5,
360b57cec5SDimitry Andric                                          !if(!eq(size, 8), ret8,
370b57cec5SDimitry Andric                                              !if(!eq(size, 16), ret16, ret32))))));
380b57cec5SDimitry Andric}
390b57cec5SDimitry Andric
408bcb0991SDimitry Andric// Generates list of sequential register tuple names.
418bcb0991SDimitry Andric// E.g. RegSeq<3,2,2,"s">.ret -> [ "s[0:1]", "s[2:3]" ]
428bcb0991SDimitry Andricclass RegSeqNames<int last_reg, int stride, int size, string prefix,
438bcb0991SDimitry Andric                  int start = 0> {
448bcb0991SDimitry Andric  int next = !add(start, stride);
458bcb0991SDimitry Andric  int end_reg = !add(!add(start, size), -1);
468bcb0991SDimitry Andric  list<string> ret =
478bcb0991SDimitry Andric    !if(!le(end_reg, last_reg),
488bcb0991SDimitry Andric        !listconcat([prefix # "[" # start # ":" # end_reg # "]"],
498bcb0991SDimitry Andric                    RegSeqNames<last_reg, stride, size, prefix, next>.ret),
508bcb0991SDimitry Andric                    []);
510b57cec5SDimitry Andric}
528bcb0991SDimitry Andric
538bcb0991SDimitry Andric// Generates list of dags for register tupless.
548bcb0991SDimitry Andricclass RegSeqDags<RegisterClass RC, int last_reg, int stride, int size,
558bcb0991SDimitry Andric                int start = 0> {
568bcb0991SDimitry Andric  dag trunc_rc = (trunc RC,
578bcb0991SDimitry Andric                  !if(!and(!eq(stride, 1), !eq(start, 0)),
588bcb0991SDimitry Andric                      !add(!add(last_reg, 2), !mul(size, -1)),
598bcb0991SDimitry Andric                      !add(last_reg, 1)));
608bcb0991SDimitry Andric  list<dag> ret =
618bcb0991SDimitry Andric    !if(!lt(start, size),
628bcb0991SDimitry Andric        !listconcat([(add (decimate (shl trunc_rc, start), stride))],
638bcb0991SDimitry Andric                    RegSeqDags<RC, last_reg, stride, size, !add(start, 1)>.ret),
648bcb0991SDimitry Andric        []);
650b57cec5SDimitry Andric}
660b57cec5SDimitry Andric
678bcb0991SDimitry Andricclass SIRegisterTuples<list<SubRegIndex> Indices, RegisterClass RC,
688bcb0991SDimitry Andric                       int last_reg, int stride, int size, string prefix> :
698bcb0991SDimitry Andric  RegisterTuples<Indices,
708bcb0991SDimitry Andric                 RegSeqDags<RC, last_reg, stride, size>.ret,
718bcb0991SDimitry Andric                 RegSeqNames<last_reg, stride, size, prefix>.ret>;
728bcb0991SDimitry Andric
730b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
740b57cec5SDimitry Andric//  Declarations that describe the SI registers
750b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
768bcb0991SDimitry Andricclass SIReg <string n, bits<16> regIdx = 0> :
778bcb0991SDimitry Andric  Register<n>,
780b57cec5SDimitry Andric  DwarfRegNum<[!cast<int>(HWEncoding)]> {
790b57cec5SDimitry Andric  let Namespace = "AMDGPU";
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric  // This is the not yet the complete register encoding. An additional
820b57cec5SDimitry Andric  // bit is set for VGPRs.
830b57cec5SDimitry Andric  let HWEncoding = regIdx;
840b57cec5SDimitry Andric}
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric// Special Registers
870b57cec5SDimitry Andricdef VCC_LO : SIReg<"vcc_lo", 106>;
880b57cec5SDimitry Andricdef VCC_HI : SIReg<"vcc_hi", 107>;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric// Pseudo-registers: Used as placeholders during isel and immediately
910b57cec5SDimitry Andric// replaced, never seeing the verifier.
920b57cec5SDimitry Andricdef PRIVATE_RSRC_REG : SIReg<"private_rsrc", 0>;
930b57cec5SDimitry Andricdef FP_REG : SIReg<"fp", 0>;
940b57cec5SDimitry Andricdef SP_REG : SIReg<"sp", 0>;
950b57cec5SDimitry Andricdef SCRATCH_WAVE_OFFSET_REG : SIReg<"scratch_wave_offset", 0>;
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric// VCC for 64-bit instructions
988bcb0991SDimitry Andricdef VCC : RegisterWithSubRegs<"vcc", [VCC_LO, VCC_HI]>,
990b57cec5SDimitry Andric          DwarfRegAlias<VCC_LO> {
1000b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1010b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1020b57cec5SDimitry Andric  let HWEncoding = 106;
1030b57cec5SDimitry Andric}
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andricdef EXEC_LO : SIReg<"exec_lo", 126>;
1060b57cec5SDimitry Andricdef EXEC_HI : SIReg<"exec_hi", 127>;
1070b57cec5SDimitry Andric
1088bcb0991SDimitry Andricdef EXEC : RegisterWithSubRegs<"exec", [EXEC_LO, EXEC_HI]>,
1090b57cec5SDimitry Andric           DwarfRegAlias<EXEC_LO> {
1100b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1110b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1120b57cec5SDimitry Andric  let HWEncoding = 126;
1130b57cec5SDimitry Andric}
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric// 32-bit real registers, for MC only.
1160b57cec5SDimitry Andric// May be used with both 32-bit and 64-bit operands.
1170b57cec5SDimitry Andricdef SRC_VCCZ : SIReg<"src_vccz", 251>;
1180b57cec5SDimitry Andricdef SRC_EXECZ : SIReg<"src_execz", 252>;
1190b57cec5SDimitry Andricdef SRC_SCC : SIReg<"src_scc", 253>;
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric// 1-bit pseudo register, for codegen only.
1220b57cec5SDimitry Andric// Should never be emitted.
1230b57cec5SDimitry Andricdef SCC : SIReg<"scc">;
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andricdef M0 : SIReg <"m0", 124>;
1260b57cec5SDimitry Andricdef SGPR_NULL : SIReg<"null", 125>;
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andricdef SRC_SHARED_BASE : SIReg<"src_shared_base", 235>;
1290b57cec5SDimitry Andricdef SRC_SHARED_LIMIT : SIReg<"src_shared_limit", 236>;
1300b57cec5SDimitry Andricdef SRC_PRIVATE_BASE : SIReg<"src_private_base", 237>;
1310b57cec5SDimitry Andricdef SRC_PRIVATE_LIMIT : SIReg<"src_private_limit", 238>;
1320b57cec5SDimitry Andricdef SRC_POPS_EXITING_WAVE_ID : SIReg<"src_pops_exiting_wave_id", 239>;
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andricdef LDS_DIRECT : SIReg <"src_lds_direct", 254>;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andricdef XNACK_MASK_LO : SIReg<"xnack_mask_lo", 104>;
1370b57cec5SDimitry Andricdef XNACK_MASK_HI : SIReg<"xnack_mask_hi", 105>;
1380b57cec5SDimitry Andric
1398bcb0991SDimitry Andricdef XNACK_MASK : RegisterWithSubRegs<"xnack_mask", [XNACK_MASK_LO, XNACK_MASK_HI]>,
1400b57cec5SDimitry Andric                 DwarfRegAlias<XNACK_MASK_LO> {
1410b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1420b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1430b57cec5SDimitry Andric  let HWEncoding = 104;
1440b57cec5SDimitry Andric}
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric// Trap handler registers
1470b57cec5SDimitry Andricdef TBA_LO : SIReg<"tba_lo", 108>;
1480b57cec5SDimitry Andricdef TBA_HI : SIReg<"tba_hi", 109>;
1490b57cec5SDimitry Andric
1508bcb0991SDimitry Andricdef TBA : RegisterWithSubRegs<"tba", [TBA_LO, TBA_HI]>,
1510b57cec5SDimitry Andric          DwarfRegAlias<TBA_LO> {
1520b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1530b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1540b57cec5SDimitry Andric  let HWEncoding = 108;
1550b57cec5SDimitry Andric}
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andricdef TMA_LO : SIReg<"tma_lo", 110>;
1580b57cec5SDimitry Andricdef TMA_HI : SIReg<"tma_hi", 111>;
1590b57cec5SDimitry Andric
1608bcb0991SDimitry Andricdef TMA : RegisterWithSubRegs<"tma", [TMA_LO, TMA_HI]>,
1610b57cec5SDimitry Andric          DwarfRegAlias<TMA_LO> {
1620b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1630b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1640b57cec5SDimitry Andric  let HWEncoding = 110;
1650b57cec5SDimitry Andric}
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andricforeach Index = 0-15 in {
1680b57cec5SDimitry Andric  def TTMP#Index#_vi         : SIReg<"ttmp"#Index, !add(112, Index)>;
1690b57cec5SDimitry Andric  def TTMP#Index#_gfx9_gfx10 : SIReg<"ttmp"#Index, !add(108, Index)>;
1700b57cec5SDimitry Andric  def TTMP#Index             : SIReg<"ttmp"#Index, 0>;
1710b57cec5SDimitry Andric}
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andricmulticlass FLAT_SCR_LOHI_m <string n, bits<16> ci_e, bits<16> vi_e> {
1740b57cec5SDimitry Andric  def _ci : SIReg<n, ci_e>;
1750b57cec5SDimitry Andric  def _vi : SIReg<n, vi_e>;
1760b57cec5SDimitry Andric  def "" : SIReg<n, 0>;
1770b57cec5SDimitry Andric}
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andricclass FlatReg <Register lo, Register hi, bits<16> encoding> :
1808bcb0991SDimitry Andric    RegisterWithSubRegs<"flat_scratch", [lo, hi]>,
1810b57cec5SDimitry Andric    DwarfRegAlias<lo> {
1820b57cec5SDimitry Andric  let Namespace = "AMDGPU";
1830b57cec5SDimitry Andric  let SubRegIndices = [sub0, sub1];
1840b57cec5SDimitry Andric  let HWEncoding = encoding;
1850b57cec5SDimitry Andric}
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andricdefm FLAT_SCR_LO : FLAT_SCR_LOHI_m<"flat_scratch_lo", 104, 102>; // Offset in units of 256-bytes.
1880b57cec5SDimitry Andricdefm FLAT_SCR_HI : FLAT_SCR_LOHI_m<"flat_scratch_hi", 105, 103>; // Size is the per-thread scratch size, in bytes.
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andricdef FLAT_SCR_ci : FlatReg<FLAT_SCR_LO_ci, FLAT_SCR_HI_ci, 104>;
1910b57cec5SDimitry Andricdef FLAT_SCR_vi : FlatReg<FLAT_SCR_LO_vi, FLAT_SCR_HI_vi, 102>;
1920b57cec5SDimitry Andricdef FLAT_SCR : FlatReg<FLAT_SCR_LO, FLAT_SCR_HI, 0>;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric// SGPR registers
1950b57cec5SDimitry Andricforeach Index = 0-105 in {
1968bcb0991SDimitry Andric  def SGPR#Index : SIReg <"s"#Index, Index>;
1970b57cec5SDimitry Andric}
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andric// VGPR registers
2000b57cec5SDimitry Andricforeach Index = 0-255 in {
2018bcb0991SDimitry Andric  def VGPR#Index : SIReg <"v"#Index, Index> {
2020b57cec5SDimitry Andric    let HWEncoding{8} = 1;
2030b57cec5SDimitry Andric  }
2040b57cec5SDimitry Andric}
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric// AccVGPR registers
2070b57cec5SDimitry Andricforeach Index = 0-255 in {
2088bcb0991SDimitry Andric  def AGPR#Index : SIReg <"a"#Index, Index> {
2090b57cec5SDimitry Andric    let HWEncoding{8} = 1;
2100b57cec5SDimitry Andric  }
2110b57cec5SDimitry Andric}
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2140b57cec5SDimitry Andric//  Groupings using register classes and tuples
2150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andricdef SCC_CLASS : RegisterClass<"AMDGPU", [i1], 1, (add SCC)> {
2180b57cec5SDimitry Andric  let CopyCost = -1;
2190b57cec5SDimitry Andric  let isAllocatable = 0;
2200b57cec5SDimitry Andric}
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andricdef M0_CLASS : RegisterClass<"AMDGPU", [i32], 32, (add M0)> {
2230b57cec5SDimitry Andric  let CopyCost = 1;
2240b57cec5SDimitry Andric  let isAllocatable = 0;
2250b57cec5SDimitry Andric}
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric// TODO: Do we need to set DwarfRegAlias on register tuples?
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric// SGPR 32-bit registers
2300b57cec5SDimitry Andricdef SGPR_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
2318bcb0991SDimitry Andric                            (add (sequence "SGPR%u", 0, 105))> {
2320b57cec5SDimitry Andric  // Give all SGPR classes higher priority than VGPR classes, because
2330b57cec5SDimitry Andric  // we want to spill SGPRs to VGPRs.
2340b57cec5SDimitry Andric  let AllocationPriority = 9;
2350b57cec5SDimitry Andric}
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric// SGPR 64-bit registers
2388bcb0991SDimitry Andricdef SGPR_64Regs : SIRegisterTuples<getSubRegs<2>.ret, SGPR_32, 105, 2, 2, "s">;
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric// SGPR 96-bit registers. No operations use these, but for symmetry with 96-bit VGPRs.
2418bcb0991SDimitry Andricdef SGPR_96Regs : SIRegisterTuples<getSubRegs<3>.ret, SGPR_32, 105, 3, 3, "s">;
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric// SGPR 128-bit registers
2448bcb0991SDimitry Andricdef SGPR_128Regs : SIRegisterTuples<getSubRegs<4>.ret, SGPR_32, 105, 4, 4, "s">;
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric// SGPR 160-bit registers. No operations use these, but for symmetry with 160-bit VGPRs.
2478bcb0991SDimitry Andricdef SGPR_160Regs : SIRegisterTuples<getSubRegs<5>.ret, SGPR_32, 105, 4, 5, "s">;
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric// SGPR 256-bit registers
2508bcb0991SDimitry Andricdef SGPR_256Regs : SIRegisterTuples<getSubRegs<8>.ret, SGPR_32, 105, 4, 8, "s">;
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andric// SGPR 512-bit registers
2538bcb0991SDimitry Andricdef SGPR_512Regs : SIRegisterTuples<getSubRegs<16>.ret, SGPR_32, 105, 4, 16, "s">;
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric// SGPR 1024-bit registers
2568bcb0991SDimitry Andricdef SGPR_1024Regs : SIRegisterTuples<getSubRegs<32>.ret, SGPR_32, 105, 4, 32, "s">;
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric// Trap handler TMP 32-bit registers
2590b57cec5SDimitry Andricdef TTMP_32 : RegisterClass<"AMDGPU", [i32, f32, v2i16, v2f16], 32,
2600b57cec5SDimitry Andric                            (add (sequence "TTMP%u", 0, 15))> {
2610b57cec5SDimitry Andric  let isAllocatable = 0;
2620b57cec5SDimitry Andric}
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andric// Trap handler TMP 64-bit registers
2658bcb0991SDimitry Andricdef TTMP_64Regs : SIRegisterTuples<getSubRegs<2>.ret, TTMP_32, 15, 2, 2, "ttmp">;
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric// Trap handler TMP 128-bit registers
2688bcb0991SDimitry Andricdef TTMP_128Regs : SIRegisterTuples<getSubRegs<4>.ret, TTMP_32, 15, 4, 4, "ttmp">;
2690b57cec5SDimitry Andric
2708bcb0991SDimitry Andricdef TTMP_256Regs : SIRegisterTuples<getSubRegs<8>.ret, TTMP_32, 15, 4, 8, "ttmp">;
2710b57cec5SDimitry Andric
2728bcb0991SDimitry Andricdef TTMP_512Regs : SIRegisterTuples<getSubRegs<16>.ret, TTMP_32, 15, 4, 16, "ttmp">;
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andricclass TmpRegTuplesBase<int index, int size,
2750b57cec5SDimitry Andric                       list<Register> subRegs,
2760b57cec5SDimitry Andric                       list<SubRegIndex> indices = getSubRegs<size>.ret,
2770b57cec5SDimitry Andric                       int index1 = !add(index, !add(size, -1)),
2780b57cec5SDimitry Andric                       string name = "ttmp["#index#":"#index1#"]"> :
2798bcb0991SDimitry Andric  RegisterWithSubRegs<name, subRegs> {
2800b57cec5SDimitry Andric  let HWEncoding = subRegs[0].HWEncoding;
2810b57cec5SDimitry Andric  let SubRegIndices = indices;
2820b57cec5SDimitry Andric}
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andricclass TmpRegTuples<string tgt,
2850b57cec5SDimitry Andric                   int size,
2860b57cec5SDimitry Andric                   int index0,
2870b57cec5SDimitry Andric                   int index1 = !add(index0, 1),
2880b57cec5SDimitry Andric                   int index2 = !add(index0, !if(!eq(size, 2), 1, 2)),
2890b57cec5SDimitry Andric                   int index3 = !add(index0, !if(!eq(size, 2), 1, 3)),
2900b57cec5SDimitry Andric                   int index4 = !add(index0, !if(!eq(size, 8), 4, 1)),
2910b57cec5SDimitry Andric                   int index5 = !add(index0, !if(!eq(size, 8), 5, 1)),
2920b57cec5SDimitry Andric                   int index6 = !add(index0, !if(!eq(size, 8), 6, 1)),
2930b57cec5SDimitry Andric                   int index7 = !add(index0, !if(!eq(size, 8), 7, 1)),
2940b57cec5SDimitry Andric                   Register r0 = !cast<Register>("TTMP"#index0#tgt),
2950b57cec5SDimitry Andric                   Register r1 = !cast<Register>("TTMP"#index1#tgt),
2960b57cec5SDimitry Andric                   Register r2 = !cast<Register>("TTMP"#index2#tgt),
2970b57cec5SDimitry Andric                   Register r3 = !cast<Register>("TTMP"#index3#tgt),
2980b57cec5SDimitry Andric                   Register r4 = !cast<Register>("TTMP"#index4#tgt),
2990b57cec5SDimitry Andric                   Register r5 = !cast<Register>("TTMP"#index5#tgt),
3000b57cec5SDimitry Andric                   Register r6 = !cast<Register>("TTMP"#index6#tgt),
3010b57cec5SDimitry Andric                   Register r7 = !cast<Register>("TTMP"#index7#tgt)> :
3020b57cec5SDimitry Andric  TmpRegTuplesBase<index0, size,
3030b57cec5SDimitry Andric                   !if(!eq(size, 2), [r0, r1],
3040b57cec5SDimitry Andric                       !if(!eq(size, 4), [r0, r1, r2, r3],
3050b57cec5SDimitry Andric                                         [r0, r1, r2, r3, r4, r5, r6, r7])),
3060b57cec5SDimitry Andric                   getSubRegs<size>.ret>;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andricforeach Index = {0, 2, 4, 6, 8, 10, 12, 14} in {
3090b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#_vi         : TmpRegTuples<"_vi",   2, Index>;
3100b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#_gfx9_gfx10 : TmpRegTuples<"_gfx9_gfx10", 2, Index>;
3110b57cec5SDimitry Andric}
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andricforeach Index = {0, 4, 8, 12} in {
3140b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#
3150b57cec5SDimitry Andric                 _TTMP#!add(Index,2)#
3160b57cec5SDimitry Andric                 _TTMP#!add(Index,3)#_vi : TmpRegTuples<"_vi",   4, Index>;
3170b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#
3180b57cec5SDimitry Andric                 _TTMP#!add(Index,2)#
3190b57cec5SDimitry Andric                 _TTMP#!add(Index,3)#_gfx9_gfx10 : TmpRegTuples<"_gfx9_gfx10", 4, Index>;
3200b57cec5SDimitry Andric}
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andricforeach Index = {0, 4, 8} in {
3230b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#
3240b57cec5SDimitry Andric                 _TTMP#!add(Index,2)#
3250b57cec5SDimitry Andric                 _TTMP#!add(Index,3)#
3260b57cec5SDimitry Andric                 _TTMP#!add(Index,4)#
3270b57cec5SDimitry Andric                 _TTMP#!add(Index,5)#
3280b57cec5SDimitry Andric                 _TTMP#!add(Index,6)#
3290b57cec5SDimitry Andric                 _TTMP#!add(Index,7)#_vi : TmpRegTuples<"_vi",   8, Index>;
3300b57cec5SDimitry Andric  def TTMP#Index#_TTMP#!add(Index,1)#
3310b57cec5SDimitry Andric                 _TTMP#!add(Index,2)#
3320b57cec5SDimitry Andric                 _TTMP#!add(Index,3)#
3330b57cec5SDimitry Andric                 _TTMP#!add(Index,4)#
3340b57cec5SDimitry Andric                 _TTMP#!add(Index,5)#
3350b57cec5SDimitry Andric                 _TTMP#!add(Index,6)#
3360b57cec5SDimitry Andric                 _TTMP#!add(Index,7)#_gfx9_gfx10 : TmpRegTuples<"_gfx9_gfx10", 8, Index>;
3370b57cec5SDimitry Andric}
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andricdef TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15_vi :
3400b57cec5SDimitry Andric  TmpRegTuplesBase<0, 16,
3410b57cec5SDimitry Andric                   [TTMP0_vi, TTMP1_vi, TTMP2_vi, TTMP3_vi,
3420b57cec5SDimitry Andric                    TTMP4_vi, TTMP5_vi, TTMP6_vi, TTMP7_vi,
3430b57cec5SDimitry Andric                    TTMP8_vi, TTMP9_vi, TTMP10_vi, TTMP11_vi,
3440b57cec5SDimitry Andric                    TTMP12_vi, TTMP13_vi, TTMP14_vi, TTMP15_vi]>;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andricdef TTMP0_TTMP1_TTMP2_TTMP3_TTMP4_TTMP5_TTMP6_TTMP7_TTMP8_TTMP9_TTMP10_TTMP11_TTMP12_TTMP13_TTMP14_TTMP15_gfx9_gfx10 :
3470b57cec5SDimitry Andric  TmpRegTuplesBase<0, 16,
3480b57cec5SDimitry Andric                   [TTMP0_gfx9_gfx10, TTMP1_gfx9_gfx10, TTMP2_gfx9_gfx10, TTMP3_gfx9_gfx10,
3490b57cec5SDimitry Andric                    TTMP4_gfx9_gfx10, TTMP5_gfx9_gfx10, TTMP6_gfx9_gfx10, TTMP7_gfx9_gfx10,
3500b57cec5SDimitry Andric                    TTMP8_gfx9_gfx10, TTMP9_gfx9_gfx10, TTMP10_gfx9_gfx10, TTMP11_gfx9_gfx10,
3510b57cec5SDimitry Andric                    TTMP12_gfx9_gfx10, TTMP13_gfx9_gfx10, TTMP14_gfx9_gfx10, TTMP15_gfx9_gfx10]>;
3520b57cec5SDimitry Andric
3538bcb0991SDimitry Andricclass RegisterTypes<list<ValueType> reg_types> {
3548bcb0991SDimitry Andric  list<ValueType> types = reg_types;
3558bcb0991SDimitry Andric}
3568bcb0991SDimitry Andric
3578bcb0991SDimitry Andricdef Reg16Types : RegisterTypes<[i16, f16]>;
3588bcb0991SDimitry Andricdef Reg32Types : RegisterTypes<[i32, f32, v2i16, v2f16, p2, p3, p5, p6]>;
3598bcb0991SDimitry Andric
3608bcb0991SDimitry Andric
3610b57cec5SDimitry Andric// VGPR 32-bit registers
3620b57cec5SDimitry Andric// i16/f16 only on VI+
3638bcb0991SDimitry Andricdef VGPR_32 : RegisterClass<"AMDGPU", !listconcat(Reg32Types.types, Reg16Types.types), 32,
3648bcb0991SDimitry Andric                            (add (sequence "VGPR%u", 0, 255))> {
3650b57cec5SDimitry Andric  let AllocationPriority = 1;
3660b57cec5SDimitry Andric  let Size = 32;
3670b57cec5SDimitry Andric}
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric// VGPR 64-bit registers
3708bcb0991SDimitry Andricdef VGPR_64 : SIRegisterTuples<getSubRegs<2>.ret, VGPR_32, 255, 1, 2, "v">;
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric// VGPR 96-bit registers
3738bcb0991SDimitry Andricdef VGPR_96 : SIRegisterTuples<getSubRegs<3>.ret, VGPR_32, 255, 1, 3, "v">;
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric// VGPR 128-bit registers
3768bcb0991SDimitry Andricdef VGPR_128 : SIRegisterTuples<getSubRegs<4>.ret, VGPR_32, 255, 1, 4, "v">;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric// VGPR 160-bit registers
3798bcb0991SDimitry Andricdef VGPR_160 : SIRegisterTuples<getSubRegs<5>.ret, VGPR_32, 255, 1, 5, "v">;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric// VGPR 256-bit registers
3828bcb0991SDimitry Andricdef VGPR_256 : SIRegisterTuples<getSubRegs<8>.ret, VGPR_32, 255, 1, 8, "v">;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric// VGPR 512-bit registers
3858bcb0991SDimitry Andricdef VGPR_512 : SIRegisterTuples<getSubRegs<16>.ret, VGPR_32, 255, 1, 16, "v">;
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric// VGPR 1024-bit registers
3888bcb0991SDimitry Andricdef VGPR_1024 : SIRegisterTuples<getSubRegs<32>.ret, VGPR_32, 255, 1, 32, "v">;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric// AccVGPR 32-bit registers
3910b57cec5SDimitry Andricdef AGPR_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
3928bcb0991SDimitry Andric                            (add (sequence "AGPR%u", 0, 255))> {
3930b57cec5SDimitry Andric  let AllocationPriority = 1;
3940b57cec5SDimitry Andric  let Size = 32;
3950b57cec5SDimitry Andric}
3960b57cec5SDimitry Andric
3970b57cec5SDimitry Andric// AGPR 64-bit registers
3988bcb0991SDimitry Andricdef AGPR_64 : SIRegisterTuples<getSubRegs<2>.ret, AGPR_32, 255, 1, 2, "a">;
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric// AGPR 128-bit registers
4018bcb0991SDimitry Andricdef AGPR_128 : SIRegisterTuples<getSubRegs<4>.ret, AGPR_32, 255, 1, 4, "a">;
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric// AGPR 512-bit registers
4048bcb0991SDimitry Andricdef AGPR_512 : SIRegisterTuples<getSubRegs<16>.ret, AGPR_32, 255, 1, 16, "a">;
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric// AGPR 1024-bit registers
4078bcb0991SDimitry Andricdef AGPR_1024 : SIRegisterTuples<getSubRegs<32>.ret, AGPR_32, 255, 1, 32, "a">;
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4100b57cec5SDimitry Andric//  Register classes used as source and destination
4110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andricdef Pseudo_SReg_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
4148bcb0991SDimitry Andric  (add FP_REG, SP_REG, SCRATCH_WAVE_OFFSET_REG)> {
4150b57cec5SDimitry Andric  let isAllocatable = 0;
4160b57cec5SDimitry Andric  let CopyCost = -1;
4170b57cec5SDimitry Andric}
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andricdef Pseudo_SReg_128 : RegisterClass<"AMDGPU", [v4i32, v2i64, v2f64], 32,
4208bcb0991SDimitry Andric  (add PRIVATE_RSRC_REG)> {
4210b57cec5SDimitry Andric  let isAllocatable = 0;
4220b57cec5SDimitry Andric  let CopyCost = -1;
4230b57cec5SDimitry Andric}
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andricdef LDS_DIRECT_CLASS : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
4268bcb0991SDimitry Andric  (add LDS_DIRECT)> {
4270b57cec5SDimitry Andric  let isAllocatable = 0;
4280b57cec5SDimitry Andric  let CopyCost = -1;
4290b57cec5SDimitry Andric}
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andric// Subset of SReg_32 without M0 for SMRD instructions and alike.
4320b57cec5SDimitry Andric// See comments in SIInstructions.td for more info.
4330b57cec5SDimitry Andricdef SReg_32_XM0_XEXEC : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32,
4340b57cec5SDimitry Andric  (add SGPR_32, VCC_LO, VCC_HI, FLAT_SCR_LO, FLAT_SCR_HI, XNACK_MASK_LO, XNACK_MASK_HI,
4350b57cec5SDimitry Andric   SGPR_NULL, TTMP_32, TMA_LO, TMA_HI, TBA_LO, TBA_HI, SRC_SHARED_BASE, SRC_SHARED_LIMIT,
4360b57cec5SDimitry Andric   SRC_PRIVATE_BASE, SRC_PRIVATE_LIMIT, SRC_POPS_EXITING_WAVE_ID,
4378bcb0991SDimitry Andric   SRC_VCCZ, SRC_EXECZ, SRC_SCC)> {
4380b57cec5SDimitry Andric  let AllocationPriority = 10;
4390b57cec5SDimitry Andric}
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andricdef SReg_32_XEXEC_HI : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32,
4428bcb0991SDimitry Andric  (add SReg_32_XM0_XEXEC, EXEC_LO, M0_CLASS)> {
4430b57cec5SDimitry Andric  let AllocationPriority = 10;
4440b57cec5SDimitry Andric}
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andricdef SReg_32_XM0 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32,
4478bcb0991SDimitry Andric  (add SReg_32_XM0_XEXEC, EXEC_LO, EXEC_HI)> {
4480b57cec5SDimitry Andric  let AllocationPriority = 10;
4490b57cec5SDimitry Andric}
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andric// Register class for all scalar registers (SGPRs + Special Registers)
4520b57cec5SDimitry Andricdef SReg_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32,
4538bcb0991SDimitry Andric  (add SReg_32_XM0, M0_CLASS, EXEC_LO, EXEC_HI, SReg_32_XEXEC_HI)> {
4540b57cec5SDimitry Andric  let AllocationPriority = 10;
4550b57cec5SDimitry Andric}
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andricdef SRegOrLds_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16, i1], 32,
4588bcb0991SDimitry Andric  (add SReg_32_XM0, M0_CLASS, EXEC_LO, EXEC_HI, SReg_32_XEXEC_HI, LDS_DIRECT_CLASS)> {
4590b57cec5SDimitry Andric  let isAllocatable = 0;
4600b57cec5SDimitry Andric}
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andricdef SGPR_64 : RegisterClass<"AMDGPU", [v2i32, i64, v2f32, f64, v4i16, v4f16], 32,
4638bcb0991SDimitry Andric                            (add SGPR_64Regs)> {
4640b57cec5SDimitry Andric  let CopyCost = 1;
4650b57cec5SDimitry Andric  let AllocationPriority = 11;
4660b57cec5SDimitry Andric}
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andric// CCR (call clobbered registers) SGPR 64-bit registers
4690b57cec5SDimitry Andricdef CCR_SGPR_64 : RegisterClass<"AMDGPU", SGPR_64.RegTypes, 32,
4708bcb0991SDimitry Andric                                (add (trunc SGPR_64, 16))> {
4710b57cec5SDimitry Andric  let CopyCost = SGPR_64.CopyCost;
4720b57cec5SDimitry Andric  let AllocationPriority = SGPR_64.AllocationPriority;
4730b57cec5SDimitry Andric}
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andricdef TTMP_64 : RegisterClass<"AMDGPU", [v2i32, i64, f64, v4i16, v4f16], 32,
4760b57cec5SDimitry Andric                            (add TTMP_64Regs)> {
4770b57cec5SDimitry Andric  let isAllocatable = 0;
4780b57cec5SDimitry Andric}
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andricdef SReg_64_XEXEC : RegisterClass<"AMDGPU", [v2i32, i64, v2f32, f64, i1, v4i16, v4f16], 32,
4818bcb0991SDimitry Andric  (add SGPR_64, VCC, FLAT_SCR, XNACK_MASK, TTMP_64, TBA, TMA)> {
4820b57cec5SDimitry Andric  let CopyCost = 1;
4830b57cec5SDimitry Andric  let AllocationPriority = 13;
4840b57cec5SDimitry Andric}
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andricdef SReg_64 : RegisterClass<"AMDGPU", [v2i32, i64, v2f32, f64, i1, v4i16, v4f16], 32,
4878bcb0991SDimitry Andric  (add SReg_64_XEXEC, EXEC)> {
4880b57cec5SDimitry Andric  let CopyCost = 1;
4890b57cec5SDimitry Andric  let AllocationPriority = 13;
4900b57cec5SDimitry Andric}
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andricdef SReg_1_XEXEC : RegisterClass<"AMDGPU", [i1], 32,
4930b57cec5SDimitry Andric  (add SReg_64_XEXEC, SReg_32_XM0_XEXEC)> {
4940b57cec5SDimitry Andric  let CopyCost = 1;
4950b57cec5SDimitry Andric  let isAllocatable = 0;
4960b57cec5SDimitry Andric}
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andricdef SReg_1 : RegisterClass<"AMDGPU", [i1], 32,
4990b57cec5SDimitry Andric  (add SReg_1_XEXEC, EXEC, EXEC_LO)> {
5000b57cec5SDimitry Andric  let CopyCost = 1;
5010b57cec5SDimitry Andric  let isAllocatable = 0;
5020b57cec5SDimitry Andric}
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric// Requires 2 s_mov_b64 to copy
5050b57cec5SDimitry Andriclet CopyCost = 2 in {
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric// There are no 3-component scalar instructions, but this is needed
5080b57cec5SDimitry Andric// for symmetry with VGPRs.
5090b57cec5SDimitry Andricdef SGPR_96 : RegisterClass<"AMDGPU", [v3i32, v3f32], 32,
5108bcb0991SDimitry Andric  (add SGPR_96Regs)> {
5110b57cec5SDimitry Andric  let AllocationPriority = 14;
5120b57cec5SDimitry Andric}
5130b57cec5SDimitry Andric
5140b57cec5SDimitry Andricdef SReg_96 : RegisterClass<"AMDGPU", [v3i32, v3f32], 32,
5158bcb0991SDimitry Andric  (add SGPR_96)> {
5160b57cec5SDimitry Andric  let AllocationPriority = 14;
5170b57cec5SDimitry Andric}
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andricdef SGPR_128 : RegisterClass<"AMDGPU", [v4i32, v4f32, v2i64], 32,
5208bcb0991SDimitry Andric                             (add SGPR_128Regs)> {
5210b57cec5SDimitry Andric  let AllocationPriority = 15;
5220b57cec5SDimitry Andric}
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andricdef TTMP_128 : RegisterClass<"AMDGPU", [v4i32, v4f32, v2i64], 32,
5250b57cec5SDimitry Andric                             (add TTMP_128Regs)> {
5260b57cec5SDimitry Andric  let isAllocatable = 0;
5270b57cec5SDimitry Andric}
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andricdef SReg_128 : RegisterClass<"AMDGPU", [v4i32, v4f32, v2i64, v2f64], 32,
5308bcb0991SDimitry Andric                             (add SGPR_128, TTMP_128)> {
5310b57cec5SDimitry Andric  let AllocationPriority = 15;
5328bcb0991SDimitry Andric  let isAllocatable = 0;
5330b57cec5SDimitry Andric}
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric} // End CopyCost = 2
5360b57cec5SDimitry Andric
5370b57cec5SDimitry Andric// There are no 5-component scalar instructions, but this is needed
5380b57cec5SDimitry Andric// for symmetry with VGPRs.
5390b57cec5SDimitry Andricdef SGPR_160 : RegisterClass<"AMDGPU", [v5i32, v5f32], 32,
5408bcb0991SDimitry Andric                             (add SGPR_160Regs)> {
5410b57cec5SDimitry Andric  let AllocationPriority = 16;
5420b57cec5SDimitry Andric}
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andricdef SReg_160 : RegisterClass<"AMDGPU", [v5i32, v5f32], 32,
5458bcb0991SDimitry Andric                             (add SGPR_160)> {
5460b57cec5SDimitry Andric  let AllocationPriority = 16;
5470b57cec5SDimitry Andric}
5480b57cec5SDimitry Andric
5498bcb0991SDimitry Andricdef SGPR_256 : RegisterClass<"AMDGPU", [v8i32, v8f32], 32, (add SGPR_256Regs)> {
5500b57cec5SDimitry Andric  let AllocationPriority = 17;
5510b57cec5SDimitry Andric}
5520b57cec5SDimitry Andric
5530b57cec5SDimitry Andricdef TTMP_256 : RegisterClass<"AMDGPU", [v8i32, v8f32], 32, (add TTMP_256Regs)> {
5540b57cec5SDimitry Andric  let isAllocatable = 0;
5550b57cec5SDimitry Andric}
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andricdef SReg_256 : RegisterClass<"AMDGPU", [v8i32, v8f32], 32,
5588bcb0991SDimitry Andric                             (add SGPR_256, TTMP_256)> {
5590b57cec5SDimitry Andric  // Requires 4 s_mov_b64 to copy
5600b57cec5SDimitry Andric  let CopyCost = 4;
5610b57cec5SDimitry Andric  let AllocationPriority = 17;
5620b57cec5SDimitry Andric}
5630b57cec5SDimitry Andric
5640b57cec5SDimitry Andricdef SGPR_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 32,
5658bcb0991SDimitry Andric                             (add SGPR_512Regs)> {
5660b57cec5SDimitry Andric  let AllocationPriority = 18;
5670b57cec5SDimitry Andric}
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andricdef TTMP_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 32,
5700b57cec5SDimitry Andric                             (add TTMP_512Regs)> {
5710b57cec5SDimitry Andric  let isAllocatable = 0;
5720b57cec5SDimitry Andric}
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andricdef SReg_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 32,
5758bcb0991SDimitry Andric                             (add SGPR_512, TTMP_512)> {
5760b57cec5SDimitry Andric  // Requires 8 s_mov_b64 to copy
5770b57cec5SDimitry Andric  let CopyCost = 8;
5780b57cec5SDimitry Andric  let AllocationPriority = 18;
5790b57cec5SDimitry Andric}
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andricdef VRegOrLds_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
5828bcb0991SDimitry Andric                                 (add VGPR_32, LDS_DIRECT_CLASS)> {
5830b57cec5SDimitry Andric  let isAllocatable = 0;
5840b57cec5SDimitry Andric}
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andricdef SGPR_1024 : RegisterClass<"AMDGPU", [v32i32, v32f32], 32,
5878bcb0991SDimitry Andric                              (add SGPR_1024Regs)> {
5880b57cec5SDimitry Andric  let AllocationPriority = 19;
5890b57cec5SDimitry Andric}
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andricdef SReg_1024 : RegisterClass<"AMDGPU", [v32i32, v32f32], 32,
5928bcb0991SDimitry Andric                              (add SGPR_1024)> {
5930b57cec5SDimitry Andric  let CopyCost = 16;
5940b57cec5SDimitry Andric  let AllocationPriority = 19;
5950b57cec5SDimitry Andric}
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric// Register class for all vector registers (VGPRs + Interploation Registers)
5988bcb0991SDimitry Andricdef VReg_64 : RegisterClass<"AMDGPU", [i64, f64, v2i32, v2f32, v4f16, v4i16, p0, p1, p4], 32,
5998bcb0991SDimitry Andric                            (add VGPR_64)> {
6000b57cec5SDimitry Andric  let Size = 64;
6010b57cec5SDimitry Andric
6020b57cec5SDimitry Andric  // Requires 2 v_mov_b32 to copy
6030b57cec5SDimitry Andric  let CopyCost = 2;
6040b57cec5SDimitry Andric  let AllocationPriority = 2;
6050b57cec5SDimitry Andric}
6060b57cec5SDimitry Andric
6078bcb0991SDimitry Andricdef VReg_96 : RegisterClass<"AMDGPU", [v3i32, v3f32], 32, (add VGPR_96)> {
6080b57cec5SDimitry Andric  let Size = 96;
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andric  // Requires 3 v_mov_b32 to copy
6110b57cec5SDimitry Andric  let CopyCost = 3;
6120b57cec5SDimitry Andric  let AllocationPriority = 3;
6130b57cec5SDimitry Andric}
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andricdef VReg_128 : RegisterClass<"AMDGPU", [v4i32, v4f32, v2i64, v2f64], 32,
6168bcb0991SDimitry Andric                             (add VGPR_128)> {
6170b57cec5SDimitry Andric  let Size = 128;
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andric  // Requires 4 v_mov_b32 to copy
6200b57cec5SDimitry Andric  let CopyCost = 4;
6210b57cec5SDimitry Andric  let AllocationPriority = 4;
6220b57cec5SDimitry Andric}
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andricdef VReg_160 : RegisterClass<"AMDGPU", [v5i32, v5f32], 32,
6258bcb0991SDimitry Andric                             (add VGPR_160)> {
6260b57cec5SDimitry Andric  let Size = 160;
6270b57cec5SDimitry Andric
6280b57cec5SDimitry Andric  // Requires 5 v_mov_b32 to copy
6290b57cec5SDimitry Andric  let CopyCost = 5;
6300b57cec5SDimitry Andric  let AllocationPriority = 5;
6310b57cec5SDimitry Andric}
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andricdef VReg_256 : RegisterClass<"AMDGPU", [v8i32, v8f32], 32,
6348bcb0991SDimitry Andric                             (add VGPR_256)> {
6350b57cec5SDimitry Andric  let Size = 256;
6360b57cec5SDimitry Andric  let CopyCost = 8;
6370b57cec5SDimitry Andric  let AllocationPriority = 6;
6380b57cec5SDimitry Andric}
6390b57cec5SDimitry Andric
6400b57cec5SDimitry Andricdef VReg_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 32,
6418bcb0991SDimitry Andric                             (add VGPR_512)> {
6420b57cec5SDimitry Andric  let Size = 512;
6430b57cec5SDimitry Andric  let CopyCost = 16;
6440b57cec5SDimitry Andric  let AllocationPriority = 7;
6450b57cec5SDimitry Andric}
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andricdef VReg_1024 : RegisterClass<"AMDGPU", [v32i32, v32f32], 32,
6488bcb0991SDimitry Andric                              (add VGPR_1024)> {
6490b57cec5SDimitry Andric  let Size = 1024;
6500b57cec5SDimitry Andric  let CopyCost = 32;
6510b57cec5SDimitry Andric  let AllocationPriority = 8;
6520b57cec5SDimitry Andric}
6530b57cec5SDimitry Andric
6540b57cec5SDimitry Andricdef AReg_64 : RegisterClass<"AMDGPU", [i64, f64, v2i32, v2f32, v4f16, v4i16], 32,
6558bcb0991SDimitry Andric                            (add AGPR_64)> {
6560b57cec5SDimitry Andric  let Size = 64;
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andric  let CopyCost = 5;
6590b57cec5SDimitry Andric  let AllocationPriority = 2;
6600b57cec5SDimitry Andric}
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andricdef AReg_128 : RegisterClass<"AMDGPU", [v4i32, v4f32, v2i64, v2f64], 32,
6638bcb0991SDimitry Andric                             (add AGPR_128)> {
6640b57cec5SDimitry Andric  let Size = 128;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric  // Requires 4 v_accvgpr_write and 4 v_accvgpr_read to copy + burn 1 vgpr
6670b57cec5SDimitry Andric  let CopyCost = 9;
6680b57cec5SDimitry Andric  let AllocationPriority = 4;
6690b57cec5SDimitry Andric}
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andricdef AReg_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 32,
6728bcb0991SDimitry Andric                             (add AGPR_512)> {
6730b57cec5SDimitry Andric  let Size = 512;
6740b57cec5SDimitry Andric  let CopyCost = 33;
6750b57cec5SDimitry Andric  let AllocationPriority = 7;
6760b57cec5SDimitry Andric}
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andricdef AReg_1024 : RegisterClass<"AMDGPU", [v32i32, v32f32], 32,
6798bcb0991SDimitry Andric                              (add AGPR_1024)> {
6800b57cec5SDimitry Andric  let Size = 1024;
6810b57cec5SDimitry Andric  let CopyCost = 65;
6820b57cec5SDimitry Andric  let AllocationPriority = 8;
6830b57cec5SDimitry Andric}
6840b57cec5SDimitry Andric
685*480093f4SDimitry Andric
686*480093f4SDimitry Andric// This is not a real register. This is just to have a register to add
687*480093f4SDimitry Andric// to VReg_1 that does not alias any real register that would
688*480093f4SDimitry Andric// introduce inferred register classess.
689*480093f4SDimitry Andricdef ARTIFICIAL_VGPR : SIReg <"invalid vgpr", 0> {
690*480093f4SDimitry Andric  let isArtificial = 1;
691*480093f4SDimitry Andric}
692*480093f4SDimitry Andric
693*480093f4SDimitry Andric// FIXME: Should specify an empty set for this. No register should
694*480093f4SDimitry Andric// ever be allocated using VReg_1. This is a hack for SelectionDAG
695*480093f4SDimitry Andric// that should always be lowered by SILowerI1Copies. TableGen crashes
696*480093f4SDimitry Andric// on an empty register set, but also sorts register classes based on
697*480093f4SDimitry Andric// the number of registerss in them. Add only one register so this is
698*480093f4SDimitry Andric// sorted to the end and not preferred over VGPR_32.
699*480093f4SDimitry Andricdef VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add ARTIFICIAL_VGPR)> {
7008bcb0991SDimitry Andric  let Size = 1;
7010b57cec5SDimitry Andric}
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andricdef VS_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
7048bcb0991SDimitry Andric                          (add VGPR_32, SReg_32, LDS_DIRECT_CLASS)> {
7050b57cec5SDimitry Andric  let isAllocatable = 0;
7060b57cec5SDimitry Andric}
7070b57cec5SDimitry Andric
7088bcb0991SDimitry Andricdef VS_64 : RegisterClass<"AMDGPU", [i64, f64], 32, (add VReg_64, SReg_64)> {
7090b57cec5SDimitry Andric  let isAllocatable = 0;
7100b57cec5SDimitry Andric}
7110b57cec5SDimitry Andric
7120b57cec5SDimitry Andricdef AV_32 : RegisterClass<"AMDGPU", [i32, f32, i16, f16, v2i16, v2f16], 32,
7138bcb0991SDimitry Andric                          (add AGPR_32, VGPR_32)> {
7140b57cec5SDimitry Andric  let isAllocatable = 0;
7150b57cec5SDimitry Andric}
7160b57cec5SDimitry Andric
7170b57cec5SDimitry Andricdef AV_64 : RegisterClass<"AMDGPU", [i64, f64, v4f16], 32,
7188bcb0991SDimitry Andric                          (add AReg_64, VReg_64)> {
7190b57cec5SDimitry Andric  let isAllocatable = 0;
7200b57cec5SDimitry Andric}
7210b57cec5SDimitry Andric
7220b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7230b57cec5SDimitry Andric//  Register operands
7240b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7250b57cec5SDimitry Andric
7260b57cec5SDimitry Andricclass RegImmMatcher<string name> : AsmOperandClass {
7270b57cec5SDimitry Andric  let Name = name;
7280b57cec5SDimitry Andric  let RenderMethod = "addRegOrImmOperands";
7290b57cec5SDimitry Andric}
7300b57cec5SDimitry Andric
7310b57cec5SDimitry Andricmulticlass SIRegOperand32 <string rc, string MatchName, string opType,
7320b57cec5SDimitry Andric                           string rc_suffix = "_32"> {
7330b57cec5SDimitry Andric  let OperandNamespace = "AMDGPU" in {
7340b57cec5SDimitry Andric    def _b16 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7350b57cec5SDimitry Andric      let OperandType = opType#"_INT16";
7360b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"B16">;
7370b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_VSrc16";
7380b57cec5SDimitry Andric    }
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andric    def _f16 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7410b57cec5SDimitry Andric      let OperandType = opType#"_FP16";
7420b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"F16">;
7430b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_" # rc # "_16";
7440b57cec5SDimitry Andric    }
7450b57cec5SDimitry Andric
7460b57cec5SDimitry Andric    def _b32 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7470b57cec5SDimitry Andric      let OperandType = opType#"_INT32";
7480b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"B32">;
7490b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_" # rc # rc_suffix;
7500b57cec5SDimitry Andric    }
7510b57cec5SDimitry Andric
7520b57cec5SDimitry Andric    def _f32 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7530b57cec5SDimitry Andric      let OperandType = opType#"_FP32";
7540b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"F32">;
7550b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_" # rc # rc_suffix;
7560b57cec5SDimitry Andric    }
7570b57cec5SDimitry Andric
7580b57cec5SDimitry Andric    def _v2b16 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7590b57cec5SDimitry Andric      let OperandType = opType#"_V2INT16";
7600b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"V2B16">;
7610b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_VSrcV216";
7620b57cec5SDimitry Andric    }
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andric    def _v2f16 : RegisterOperand<!cast<RegisterClass>(rc#rc_suffix)> {
7650b57cec5SDimitry Andric      let OperandType = opType#"_V2FP16";
7660b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"V2F16">;
7670b57cec5SDimitry Andric      let DecoderMethod = "decodeOperand_VSrcV216";
7680b57cec5SDimitry Andric    }
7690b57cec5SDimitry Andric  }
7700b57cec5SDimitry Andric}
7710b57cec5SDimitry Andric
7720b57cec5SDimitry Andricmulticlass SIRegOperand <string rc, string MatchName, string opType> :
7730b57cec5SDimitry Andric  SIRegOperand32<rc, MatchName, opType> {
7740b57cec5SDimitry Andric  let OperandNamespace = "AMDGPU" in {
7750b57cec5SDimitry Andric    def _b64 : RegisterOperand<!cast<RegisterClass>(rc#"_64")> {
7760b57cec5SDimitry Andric      let OperandType = opType#"_INT64";
7770b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"B64">;
7780b57cec5SDimitry Andric    }
7790b57cec5SDimitry Andric
7800b57cec5SDimitry Andric    def _f64 : RegisterOperand<!cast<RegisterClass>(rc#"_64")> {
7810b57cec5SDimitry Andric      let OperandType = opType#"_FP64";
7820b57cec5SDimitry Andric      let ParserMatchClass = RegImmMatcher<MatchName#"F64">;
7830b57cec5SDimitry Andric    }
7840b57cec5SDimitry Andric  }
7850b57cec5SDimitry Andric}
7860b57cec5SDimitry Andric
7870b57cec5SDimitry Andric// FIXME: 64-bit sources can sometimes use 32-bit constants.
7880b57cec5SDimitry Andricmulticlass RegImmOperand <string rc, string MatchName>
7890b57cec5SDimitry Andric  : SIRegOperand<rc, MatchName, "OPERAND_REG_IMM">;
7900b57cec5SDimitry Andric
7910b57cec5SDimitry Andricmulticlass RegInlineOperand <string rc, string MatchName>
7920b57cec5SDimitry Andric  : SIRegOperand<rc, MatchName, "OPERAND_REG_INLINE_C">;
7930b57cec5SDimitry Andric
7940b57cec5SDimitry Andricmulticlass RegInlineOperand32 <string rc, string MatchName,
7950b57cec5SDimitry Andric                               string rc_suffix = "_32">
7960b57cec5SDimitry Andric  : SIRegOperand32<rc, MatchName, "OPERAND_REG_INLINE_C", rc_suffix>;
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andricmulticlass RegInlineOperandAC <string rc, string MatchName,
7990b57cec5SDimitry Andric                               string rc_suffix = "_32">
8000b57cec5SDimitry Andric  : SIRegOperand32<rc, MatchName, "OPERAND_REG_INLINE_AC", rc_suffix>;
8010b57cec5SDimitry Andric
8020b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8030b57cec5SDimitry Andric//  SSrc_* Operands with an SGPR or a 32-bit immediate
8040b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8050b57cec5SDimitry Andric
8060b57cec5SDimitry Andricdefm SSrc : RegImmOperand<"SReg", "SSrc">;
8070b57cec5SDimitry Andric
8080b57cec5SDimitry Andricdef SSrcOrLds_b32 : RegisterOperand<SRegOrLds_32> {
8090b57cec5SDimitry Andric  let OperandNamespace = "AMDGPU";
8100b57cec5SDimitry Andric  let OperandType = "OPERAND_REG_IMM_INT32";
8110b57cec5SDimitry Andric  let ParserMatchClass = RegImmMatcher<"SSrcOrLdsB32">;
8120b57cec5SDimitry Andric}
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8150b57cec5SDimitry Andric//  SCSrc_* Operands with an SGPR or a inline constant
8160b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andricdefm SCSrc : RegInlineOperand<"SReg", "SCSrc"> ;
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8210b57cec5SDimitry Andric//  VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate
8220b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andricdefm VSrc : RegImmOperand<"VS", "VSrc">;
8250b57cec5SDimitry Andric
8260b57cec5SDimitry Andricdef VSrc_128 : RegisterOperand<VReg_128> {
8270b57cec5SDimitry Andric  let DecoderMethod = "DecodeVS_128RegisterClass";
8280b57cec5SDimitry Andric}
8290b57cec5SDimitry Andric
8300b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8310b57cec5SDimitry Andric//  VSrc_* Operands with an VGPR
8320b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andric// This is for operands with the enum(9), VSrc encoding restriction,
8350b57cec5SDimitry Andric// but only allows VGPRs.
8360b57cec5SDimitry Andricdef VRegSrc_32 : RegisterOperand<VGPR_32> {
8370b57cec5SDimitry Andric  //let ParserMatchClass = RegImmMatcher<"VRegSrc32">;
8380b57cec5SDimitry Andric  let DecoderMethod = "DecodeVS_32RegisterClass";
8390b57cec5SDimitry Andric}
8400b57cec5SDimitry Andric
8410b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8420b57cec5SDimitry Andric//  ASrc_* Operands with an AccVGPR
8430b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andricdef ARegSrc_32 : RegisterOperand<AGPR_32> {
8460b57cec5SDimitry Andric  let DecoderMethod = "DecodeAGPR_32RegisterClass";
8470b57cec5SDimitry Andric  let EncoderMethod = "getAVOperandEncoding";
8480b57cec5SDimitry Andric}
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8510b57cec5SDimitry Andric//  VCSrc_* Operands with an SGPR, VGPR or an inline constant
8520b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andricdefm VCSrc : RegInlineOperand<"VS", "VCSrc">;
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8570b57cec5SDimitry Andric//  VISrc_* Operands with a VGPR or an inline constant
8580b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andricdefm VISrc : RegInlineOperand32<"VGPR", "VISrc">;
8610b57cec5SDimitry Andric
8620b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8630b57cec5SDimitry Andric//  AVSrc_* Operands with an AGPR or VGPR
8640b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andricdef AVSrc_32 : RegisterOperand<AV_32> {
8670b57cec5SDimitry Andric  let DecoderMethod = "DecodeAV_32RegisterClass";
8680b57cec5SDimitry Andric  let EncoderMethod = "getAVOperandEncoding";
8690b57cec5SDimitry Andric}
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andricdef AVSrc_64 : RegisterOperand<AV_64> {
8720b57cec5SDimitry Andric  let DecoderMethod = "DecodeAV_64RegisterClass";
8730b57cec5SDimitry Andric  let EncoderMethod = "getAVOperandEncoding";
8740b57cec5SDimitry Andric}
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8770b57cec5SDimitry Andric//  ACSrc_* Operands with an AGPR or an inline constant
8780b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8790b57cec5SDimitry Andric
8800b57cec5SDimitry Andricdefm AISrc      : RegInlineOperandAC<"AGPR", "AISrc">;
8810b57cec5SDimitry Andricdefm AISrc_128  : RegInlineOperandAC<"AReg", "AISrc_128",  "_128">;
8820b57cec5SDimitry Andricdefm AISrc_512  : RegInlineOperandAC<"AReg", "AISrc_512",  "_512">;
8830b57cec5SDimitry Andricdefm AISrc_1024 : RegInlineOperandAC<"AReg", "AISrc_1024", "_1024">;
884