| //== M68kRegisterInfo.td - M68k register definitions ----*- tablegen -*-==// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// This file describes the M68k Register file, defining the registers |
| /// aliases between the registers, and the register classes built out of the |
| /// registers. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| class MxReg<string N, bits<16> ENC, |
| list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX, |
| list<int> DWREGS = [], list<string> ALTNAMES = []> |
| : Register<N, ALTNAMES>, DwarfRegNum<DWREGS> { |
| let Namespace = "M68k"; |
| let HWEncoding = ENC; |
| let SubRegs = SUBREGS; |
| let SubRegIndices = SUBIDX; |
| } |
| |
| // Subregister indices. |
| let Namespace = "M68k" in { |
| def MxSubRegIndex8Lo : SubRegIndex<8, 0>; |
| def MxSubRegIndex16Lo : SubRegIndex<16, 0>; |
| } |
| |
| multiclass MxDataRegister<int INDEX, string REG_NAME, list<string> ALTNAMES = []> { |
| def "B"#NAME : MxReg<REG_NAME, INDEX, [], [], [INDEX], ALTNAMES>; |
| def "W"#NAME |
| : MxReg<REG_NAME, INDEX, |
| [!cast<Register>("B"#NAME)], [MxSubRegIndex8Lo], |
| [INDEX], ALTNAMES>; |
| def NAME |
| : MxReg<REG_NAME, INDEX, |
| [!cast<Register>("W"#NAME)], [MxSubRegIndex16Lo], |
| [INDEX], ALTNAMES>; |
| } |
| |
| multiclass MxAddressRegister<int INDEX, string REG_NAME, list<string> ALTNAMES = []> { |
| def "W"#NAME |
| : MxReg<REG_NAME, INDEX, [], [], [!add(8,INDEX)], ALTNAMES>; |
| def NAME |
| : MxReg<REG_NAME, INDEX, |
| [!cast<Register>("W"#NAME)], [MxSubRegIndex16Lo], |
| [!add(8,INDEX)], ALTNAMES>; |
| } |
| |
| defm D0 : MxDataRegister<0, "d0">; |
| defm D1 : MxDataRegister<1, "d1">; |
| defm D2 : MxDataRegister<2, "d2">; |
| defm D3 : MxDataRegister<3, "d3">; |
| defm D4 : MxDataRegister<4, "d4">; |
| defm D5 : MxDataRegister<5, "d5">; |
| defm D6 : MxDataRegister<6, "d6">; |
| defm D7 : MxDataRegister<7, "d7">; |
| |
| defm A0 : MxAddressRegister<0, "a0">; |
| defm A1 : MxAddressRegister<1, "a1">; |
| defm A2 : MxAddressRegister<2, "a2">; |
| defm A3 : MxAddressRegister<3, "a3">; |
| defm A4 : MxAddressRegister<4, "a4">; |
| defm A5 : MxAddressRegister<5, "a5", ["bp"]>; |
| defm A6 : MxAddressRegister<6, "a6", ["fp"]>; |
| defm SP : MxAddressRegister<7, "sp", ["usp", "ssp", "isp", "a7"]>; |
| |
| |
| // Pseudo Registers |
| class MxPseudoReg<string N, list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX = []> |
| : MxReg<N, 0, SUBREGS, SUBIDX>; |
| |
| def CCR : MxPseudoReg<"ccr">; |
| def SR : MxPseudoReg<"sr">; |
| |
| def PC : MxPseudoReg<"pc">; |
| |
| //===----------------------------------------------------------------------===// |
| // Register Classes |
| //===----------------------------------------------------------------------===// |
| |
| class MxRegClass<list<ValueType> regTypes, int alignment, dag regList> |
| : RegisterClass<"M68k", regTypes, alignment, regList>; |
| |
| // Data Registers |
| def DR8 : MxRegClass<[i8], 16, (sequence "BD%u", 0, 7)>; |
| def DR16 : MxRegClass<[i16], 16, (sequence "WD%u", 0, 7)>; |
| def DR32 : MxRegClass<[i32], 32, (sequence "D%u", 0, 7)>; |
| |
| // Address Registers |
| def AR16 : MxRegClass<[i16], 16, (add (sequence "WA%u", 0, 6), WSP)>; |
| def AR32 : MxRegClass<[i32], 32, (add (sequence "A%u", 0, 6), SP)>; |
| |
| def AR32_NOSP : MxRegClass<[i32], 32, (sequence "A%u", 0, 6)>; |
| |
| // Index Register Classes |
| // FIXME try alternative ordering like `D0, D1, A0, A1, ...` |
| def XR16 : MxRegClass<[i16], 16, (add DR16, AR16)>; |
| def XR32 : MxRegClass<[i32], 32, (add DR32, AR32)>; |
| |
| def SPC : MxRegClass<[i32], 32, (add SP)>; |
| |
| let CopyCost = -1 in { |
| def CCRC : MxRegClass<[i8], 16, (add CCR)>; |
| def SRC : MxRegClass<[i16], 16, (add SR)>; |
| } |
| |
| let isAllocatable = 0 in { |
| def PCC : MxRegClass<[i32], 32, (add PC)>; |
| } |
| |
| // Register used with tail call |
| def DR16_TC : MxRegClass<[i16], 16, (add D0, D1)>; |
| def DR32_TC : MxRegClass<[i32], 32, (add D0, D1)>; |
| |
| def AR16_TC : MxRegClass<[i16], 16, (add A0, A1)>; |
| def AR32_TC : MxRegClass<[i32], 32, (add A0, A1)>; |
| |
| def XR16_TC : MxRegClass<[i16], 16, (add DR16_TC, AR16_TC)>; |
| def XR32_TC : MxRegClass<[i32], 32, (add DR32_TC, AR32_TC)>; |
| |
| // These classes provide spill/restore order if used with MOVEM instruction |
| def SPILL : MxRegClass<[i32], 32, (add XR32)>; |
| def SPILL_R : MxRegClass<[i32], 32, (add SP, (sequence "A%u", 6, 0), (sequence "D%u", 7, 0))>; |