1//==-- M68kRegisterInfo.td - M68k 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/// \file
10/// This file describes the M68k Register file, defining the registers
11/// aliases between the registers, and the register classes built out of the
12/// registers.
13///
14//===----------------------------------------------------------------------===//
15
16class MxReg<string N, bits<16> ENC,
17            list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX,
18            list<int> DWREGS = [], list<string> ALTNAMES = []>
19    : Register<N, ALTNAMES>, DwarfRegNum<DWREGS> {
20  let Namespace     = "M68k";
21  let HWEncoding    = ENC;
22  let SubRegs       = SUBREGS;
23  let SubRegIndices = SUBIDX;
24}
25
26// Subregister indices.
27let Namespace = "M68k" in {
28  def MxSubRegIndex8Lo  : SubRegIndex<8, 0>;
29  def MxSubRegIndex16Lo : SubRegIndex<16, 0>;
30}
31
32multiclass MxDataRegister<int INDEX, string REG_NAME, list<string> ALTNAMES = []> {
33  def "B"#NAME : MxReg<REG_NAME, INDEX, [], [], [INDEX], ALTNAMES>;
34  def "W"#NAME
35    : MxReg<REG_NAME, INDEX,
36            [!cast<Register>("B"#NAME)], [MxSubRegIndex8Lo],
37            [INDEX], ALTNAMES>;
38  def NAME
39    : MxReg<REG_NAME, INDEX,
40            [!cast<Register>("W"#NAME)], [MxSubRegIndex16Lo],
41            [INDEX], ALTNAMES>;
42}
43
44multiclass MxAddressRegister<int INDEX, string REG_NAME, list<string> ALTNAMES = []> {
45  def "W"#NAME
46    : MxReg<REG_NAME, INDEX, [], [], [!add(8,INDEX)], ALTNAMES>;
47  def NAME
48    : MxReg<REG_NAME, INDEX,
49            [!cast<Register>("W"#NAME)], [MxSubRegIndex16Lo],
50            [!add(8,INDEX)], ALTNAMES>;
51}
52
53defm D0 : MxDataRegister<0, "d0">;
54defm D1 : MxDataRegister<1, "d1">;
55defm D2 : MxDataRegister<2, "d2">;
56defm D3 : MxDataRegister<3, "d3">;
57defm D4 : MxDataRegister<4, "d4">;
58defm D5 : MxDataRegister<5, "d5">;
59defm D6 : MxDataRegister<6, "d6">;
60defm D7 : MxDataRegister<7, "d7">;
61
62defm A0 : MxAddressRegister<0, "a0">;
63defm A1 : MxAddressRegister<1, "a1">;
64defm A2 : MxAddressRegister<2, "a2">;
65defm A3 : MxAddressRegister<3, "a3">;
66defm A4 : MxAddressRegister<4, "a4">;
67defm A5 : MxAddressRegister<5, "a5", ["bp"]>;
68defm A6 : MxAddressRegister<6, "a6", ["fp"]>;
69defm SP : MxAddressRegister<7, "sp", ["usp", "ssp", "isp", "a7"]>;
70
71// Floating Point Registers
72class MxFPRegister<int INDEX, string REG_NAME, list<string> ALTNAMES = []>
73    : MxReg<REG_NAME, INDEX, /*SUBREGS=*/[], /*SUBIDX=*/[],
74            /*DWREGS=*/[!add(18,INDEX)], ALTNAMES>;
75
76foreach i = {0-7} in
77  def FP#i : MxFPRegister<i, "fp"#i>;
78
79// Unlike their counterparts in integer registers, these
80// control registers can be accessed and modified by instructions.
81def FPC   : MxFPRegister<8,  "fpcr",  ["fpc"]>;
82def FPS   : MxFPRegister<9,  "fpsr",  ["fps"]>;
83def FPIAR : MxFPRegister<10, "fpiar", ["fpi"]>;
84
85// Pseudo Registers
86class MxPseudoReg<string N, list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX = []>
87    : MxReg<N, 0, SUBREGS, SUBIDX>;
88
89def CCR : MxPseudoReg<"ccr">;
90def SR  : MxPseudoReg<"sr">;
91
92def PC  : MxPseudoReg<"pc">;
93
94//===----------------------------------------------------------------------===//
95// Register Classes
96//===----------------------------------------------------------------------===//
97
98class MxRegClass<list<ValueType> regTypes, int alignment, dag regList>
99    : RegisterClass<"M68k", regTypes, alignment, regList>;
100
101// Data Registers
102def DR8  : MxRegClass<[i8],  16, (sequence "BD%u", 0, 7)>;
103def DR16 : MxRegClass<[i16], 16, (sequence "WD%u", 0, 7)>;
104def DR32 : MxRegClass<[i32], 32, (sequence "D%u",  0, 7)>;
105
106// Address Registers
107def AR16 : MxRegClass<[i16], 16, (add (sequence "WA%u", 0, 6), WSP)>;
108def AR32 : MxRegClass<[i32], 32, (add (sequence "A%u", 0, 6), SP)>;
109
110def AR32_NOSP : MxRegClass<[i32], 32, (sequence "A%u", 0, 6)>;
111
112// Index Register Classes
113// FIXME try alternative ordering like `D0, D1, A0, A1, ...`
114def XR16 : MxRegClass<[i16], 16, (add DR16, AR16)>;
115def XR32 : MxRegClass<[i32], 32, (add DR32, AR32)>;
116
117def SPC  : MxRegClass<[i32], 32, (add SP)>;
118
119// Floating Point Data Registers
120def FPDR32 : MxRegClass<[f32], 32, (sequence "FP%u", 0, 7)>;
121def FPDR64 : MxRegClass<[f64], 32, (add FPDR32)>;
122def FPDR80 : MxRegClass<[f80], 32, (add FPDR32)>;
123
124let CopyCost = -1 in {
125  def CCRC : MxRegClass<[i8],  16, (add CCR)>;
126  def SRC  : MxRegClass<[i16], 16, (add SR)>;
127
128  // Float Point System Control Registers
129  def FPIC   : MxRegClass<[i32], 32, (add FPIAR)>;
130  def FPCSC  : MxRegClass<[i32], 32, (add FPC, FPS)>;
131  def FPSYSC : MxRegClass<[i32], 32, (add FPCSC, FPIC)>;
132}
133
134let isAllocatable = 0 in {
135  def PCC  : MxRegClass<[i32], 32, (add PC)>;
136}
137
138// Register used with tail call
139def DR16_TC : MxRegClass<[i16], 16, (add D0, D1)>;
140def DR32_TC : MxRegClass<[i32], 32, (add D0, D1)>;
141
142def AR16_TC : MxRegClass<[i16], 16, (add A0, A1)>;
143def AR32_TC : MxRegClass<[i32], 32, (add A0, A1)>;
144
145def XR16_TC : MxRegClass<[i16], 16, (add DR16_TC, AR16_TC)>;
146def XR32_TC : MxRegClass<[i32], 32, (add DR32_TC, AR32_TC)>;
147
148// These classes provide spill/restore order if used with MOVEM instruction
149def SPILL   : MxRegClass<[i32], 32, (add XR32)>;
150def SPILL_R : MxRegClass<[i32], 32, (add SP, (sequence "A%u", 6, 0), (sequence "D%u", 7, 0))>;
151