1274955Ssvnmir//=- Mips64r6InstrInfo.td - Mips64r6 Instruction Information -*- tablegen -*-=//
2274955Ssvnmir//
3274955Ssvnmir//                     The LLVM Compiler Infrastructure
4274955Ssvnmir//
5274955Ssvnmir// This file is distributed under the University of Illinois Open Source
6274955Ssvnmir// License. See LICENSE.TXT for details.
7274955Ssvnmir//
8274955Ssvnmir//===----------------------------------------------------------------------===//
9274955Ssvnmir//
10274955Ssvnmir// This file describes Mips64r6 instructions.
11274955Ssvnmir//
12274955Ssvnmir//===----------------------------------------------------------------------===//
13274955Ssvnmir
14274955Ssvnmir// Notes about removals/changes from MIPS32r6:
15274955Ssvnmir// Reencoded: dclo, dclz
16274955Ssvnmir
17274955Ssvnmir//===----------------------------------------------------------------------===//
18274955Ssvnmir//
19274955Ssvnmir// Instruction Encodings
20274955Ssvnmir//
21274955Ssvnmir//===----------------------------------------------------------------------===//
22274955Ssvnmir
23274955Ssvnmirclass DALIGN_ENC  : SPECIAL3_DALIGN_FM<OPCODE6_DALIGN>;
24274955Ssvnmirclass DAUI_ENC    : DAUI_FM;
25274955Ssvnmirclass DAHI_ENC    : REGIMM_FM<OPCODE5_DAHI>;
26274955Ssvnmirclass DATI_ENC    : REGIMM_FM<OPCODE5_DATI>;
27274955Ssvnmirclass DBITSWAP_ENC : SPECIAL3_2R_FM<OPCODE6_DBITSWAP>;
28274955Ssvnmirclass DCLO_R6_ENC : SPECIAL_2R_FM<OPCODE6_DCLO>;
29274955Ssvnmirclass DCLZ_R6_ENC : SPECIAL_2R_FM<OPCODE6_DCLZ>;
30274955Ssvnmirclass DDIV_ENC    : SPECIAL_3R_FM<0b00010, 0b011110>;
31274955Ssvnmirclass DDIVU_ENC   : SPECIAL_3R_FM<0b00010, 0b011111>;
32274955Ssvnmirclass DLSA_R6_ENC : SPECIAL_LSA_FM<OPCODE6_DLSA>;
33274955Ssvnmirclass DMOD_ENC    : SPECIAL_3R_FM<0b00011, 0b011110>;
34274955Ssvnmirclass DMODU_ENC   : SPECIAL_3R_FM<0b00011, 0b011111>;
35274955Ssvnmirclass DMUH_ENC    : SPECIAL_3R_FM<0b00011, 0b011100>;
36274955Ssvnmirclass DMUHU_ENC   : SPECIAL_3R_FM<0b00011, 0b011101>;
37274955Ssvnmirclass DMUL_R6_ENC : SPECIAL_3R_FM<0b00010, 0b011100>;
38274955Ssvnmirclass DMULU_ENC   : SPECIAL_3R_FM<0b00010, 0b011101>;
39274955Ssvnmirclass LDPC_ENC    : PCREL18_FM<OPCODE3_LDPC>;
40274955Ssvnmirclass LLD_R6_ENC : SPECIAL3_LL_SC_FM<OPCODE6_LLD>;
41274955Ssvnmirclass SCD_R6_ENC : SPECIAL3_LL_SC_FM<OPCODE6_SCD>;
42274955Ssvnmir
43274955Ssvnmir//===----------------------------------------------------------------------===//
44274955Ssvnmir//
45274955Ssvnmir// Instruction Descriptions
46274955Ssvnmir//
47274955Ssvnmir//===----------------------------------------------------------------------===//
48274955Ssvnmir
49274955Ssvnmirclass AHI_ATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
50274955Ssvnmir  dag OutOperandList = (outs GPROpnd:$rs);
51274955Ssvnmir  dag InOperandList = (ins GPROpnd:$rt, simm16:$imm);
52274955Ssvnmir  string AsmString = !strconcat(instr_asm, "\t$rt, $imm");
53274955Ssvnmir  string Constraints = "$rs = $rt";
54274955Ssvnmir}
55274955Ssvnmir
56274955Ssvnmirclass DALIGN_DESC  : ALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>;
57274955Ssvnmirclass DAHI_DESC    : AHI_ATI_DESC_BASE<"dahi", GPR64Opnd>;
58274955Ssvnmirclass DATI_DESC    : AHI_ATI_DESC_BASE<"dati", GPR64Opnd>;
59274955Ssvnmirclass DAUI_DESC    : AUI_DESC_BASE<"daui", GPR64Opnd>;
60274955Ssvnmirclass DBITSWAP_DESC : BITSWAP_DESC_BASE<"dbitswap", GPR64Opnd>;
61274955Ssvnmirclass DCLO_R6_DESC : CLO_R6_DESC_BASE<"dclo", GPR64Opnd>;
62274955Ssvnmirclass DCLZ_R6_DESC : CLZ_R6_DESC_BASE<"dclz", GPR64Opnd>;
63274955Ssvnmirclass DDIV_DESC    : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd, sdiv>;
64274955Ssvnmirclass DDIVU_DESC   : DIVMOD_DESC_BASE<"ddivu", GPR64Opnd, udiv>;
65296417Sdimclass DLSA_R6_DESC : LSA_R6_DESC_BASE<"dlsa", GPR64Opnd, uimm2_plus1>;
66274955Ssvnmirclass DMOD_DESC    : DIVMOD_DESC_BASE<"dmod", GPR64Opnd, srem>;
67274955Ssvnmirclass DMODU_DESC   : DIVMOD_DESC_BASE<"dmodu", GPR64Opnd, urem>;
68274955Ssvnmirclass DMUH_DESC    : MUL_R6_DESC_BASE<"dmuh", GPR64Opnd, mulhs>;
69274955Ssvnmirclass DMUHU_DESC   : MUL_R6_DESC_BASE<"dmuhu", GPR64Opnd, mulhu>;
70274955Ssvnmirclass DMUL_R6_DESC : MUL_R6_DESC_BASE<"dmul", GPR64Opnd, mul>;
71274955Ssvnmirclass DMULU_DESC   : MUL_R6_DESC_BASE<"dmulu", GPR64Opnd>;
72274955Ssvnmirclass LDPC_DESC    : PCREL_DESC_BASE<"ldpc", GPR64Opnd, simm18_lsl3>;
73274955Ssvnmirclass LLD_R6_DESC   : LL_R6_DESC_BASE<"lld", GPR64Opnd>;
74274955Ssvnmirclass SCD_R6_DESC   : SC_R6_DESC_BASE<"scd", GPR64Opnd>;
75274955Ssvnmirclass SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>;
76274955Ssvnmirclass SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>;
77274955Ssvnmir
78274955Ssvnmir//===----------------------------------------------------------------------===//
79274955Ssvnmir//
80274955Ssvnmir// Instruction Definitions
81274955Ssvnmir//
82274955Ssvnmir//===----------------------------------------------------------------------===//
83274955Ssvnmir
84296417Sdimlet AdditionalPredicates = [NotInMicroMips] in {
85296417Sdim  def DATI : DATI_ENC, DATI_DESC, ISA_MIPS64R6;
86296417Sdim  def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6;
87296417Sdim  def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6;
88296417Sdim  def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6;
89296417Sdim}
90274955Ssvnmirdef DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6;
91274955Ssvnmirdef DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6;
92274955Ssvnmirdef DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6;
93274955Ssvnmirdef DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6;
94274955Ssvnmirdef DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6;
95274955Ssvnmirdef DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6;
96274955Ssvnmirdef DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6;
97274955Ssvnmirdef DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6;
98274955Ssvnmirdef DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6;
99274955Ssvnmirdef DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6;
100274955Ssvnmirdef DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6;
101274955Ssvnmirdef DMULU: DMULU_ENC, DMULU_DESC, ISA_MIPS64R6;
102274955Ssvnmirdef LDPC: LDPC_ENC, LDPC_DESC, ISA_MIPS64R6;
103274955Ssvnmirdef LLD_R6 : LLD_R6_ENC, LLD_R6_DESC, ISA_MIPS32R6;
104274955Ssvnmirdef SCD_R6 : SCD_R6_ENC, SCD_R6_DESC, ISA_MIPS32R6;
105274955Ssvnmirlet DecoderNamespace = "Mips32r6_64r6_GP64" in {
106274955Ssvnmir  def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64;
107274955Ssvnmir  def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64;
108274955Ssvnmir}
109274955Ssvnmir
110274955Ssvnmir//===----------------------------------------------------------------------===//
111274955Ssvnmir//
112274955Ssvnmir// Instruction Aliases
113274955Ssvnmir//
114274955Ssvnmir//===----------------------------------------------------------------------===//
115274955Ssvnmir
116274955Ssvnmirdef : MipsInstAlias<"jr $rs", (JALR64 ZERO_64, GPR64Opnd:$rs), 1>, ISA_MIPS64R6;
117274955Ssvnmir
118274955Ssvnmir//===----------------------------------------------------------------------===//
119274955Ssvnmir//
120274955Ssvnmir// Patterns and Pseudo Instructions
121274955Ssvnmir//
122274955Ssvnmir//===----------------------------------------------------------------------===//
123274955Ssvnmir
124274955Ssvnmir// i64 selects
125274955Ssvnmirdef : MipsPat<(select i64:$cond, i64:$t, i64:$f),
126274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, i64:$cond),
127274955Ssvnmir                    (SELEQZ64 i64:$f, i64:$cond))>,
128274955Ssvnmir              ISA_MIPS64R6;
129274955Ssvnmirdef : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, i64:$f),
130274955Ssvnmir              (OR64 (SELEQZ64 i64:$t, i64:$cond),
131274955Ssvnmir                    (SELNEZ64 i64:$f, i64:$cond))>,
132274955Ssvnmir              ISA_MIPS64R6;
133274955Ssvnmirdef : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, i64:$f),
134274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, i64:$cond),
135274955Ssvnmir                    (SELEQZ64 i64:$f, i64:$cond))>,
136274955Ssvnmir              ISA_MIPS64R6;
137274955Ssvnmirdef : MipsPat<(select (i32 (seteq i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f),
138274955Ssvnmir              (OR64 (SELEQZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)),
139274955Ssvnmir                    (SELNEZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>,
140274955Ssvnmir              ISA_MIPS64R6;
141274955Ssvnmirdef : MipsPat<(select (i32 (setne i64:$cond, immZExt16_64:$imm)), i64:$t, i64:$f),
142274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, (XORi64 i64:$cond, immZExt16_64:$imm)),
143274955Ssvnmir                    (SELEQZ64 i64:$f, (XORi64 i64:$cond, immZExt16_64:$imm)))>,
144274955Ssvnmir              ISA_MIPS64R6;
145274955Ssvnmirdef : MipsPat<
146274955Ssvnmir  (select (i32 (setgt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f),
147274955Ssvnmir  (OR64 (SELEQZ64 i64:$t,
148274955Ssvnmir                  (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)),
149274955Ssvnmir                                 sub_32)),
150274955Ssvnmir        (SELNEZ64 i64:$f,
151274955Ssvnmir                  (SUBREG_TO_REG (i64 0), (SLTi64 i64:$cond, (Plus1 imm:$imm)),
152274955Ssvnmir                                 sub_32)))>,
153274955Ssvnmir  ISA_MIPS64R6;
154274955Ssvnmirdef : MipsPat<
155274955Ssvnmir  (select (i32 (setugt i64:$cond, immSExt16Plus1:$imm)), i64:$t, i64:$f),
156274955Ssvnmir  (OR64 (SELEQZ64 i64:$t,
157274955Ssvnmir                  (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)),
158274955Ssvnmir                                 sub_32)),
159274955Ssvnmir        (SELNEZ64 i64:$f,
160274955Ssvnmir                  (SUBREG_TO_REG (i64 0), (SLTiu64 i64:$cond, (Plus1 imm:$imm)),
161274955Ssvnmir                                 sub_32)))>,
162274955Ssvnmir  ISA_MIPS64R6;
163274955Ssvnmir
164274955Ssvnmirdef : MipsPat<(select (i32 (setne i64:$cond, immz)), i64:$t, immz),
165274955Ssvnmir              (SELNEZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6;
166274955Ssvnmirdef : MipsPat<(select (i32 (seteq i64:$cond, immz)), i64:$t, immz),
167274955Ssvnmir              (SELEQZ64 i64:$t, i64:$cond)>, ISA_MIPS64R6;
168274955Ssvnmirdef : MipsPat<(select (i32 (setne i64:$cond, immz)), immz, i64:$f),
169274955Ssvnmir              (SELEQZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6;
170274955Ssvnmirdef : MipsPat<(select (i32 (seteq i64:$cond, immz)), immz, i64:$f),
171274955Ssvnmir              (SELNEZ64 i64:$f, i64:$cond)>, ISA_MIPS64R6;
172274955Ssvnmir
173274955Ssvnmir// i64 selects from an i32 comparison
174274955Ssvnmir// One complicating factor here is that bits 32-63 of an i32 are undefined.
175274955Ssvnmir// FIXME: Ideally, setcc would always produce an i64 on MIPS64 targets.
176274955Ssvnmir//        This would allow us to remove the sign-extensions here.
177274955Ssvnmirdef : MipsPat<(select i32:$cond, i64:$t, i64:$f),
178274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
179274955Ssvnmir                    (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
180274955Ssvnmir              ISA_MIPS64R6;
181274955Ssvnmirdef : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, i64:$f),
182274955Ssvnmir              (OR64 (SELEQZ64 i64:$t, (SLL64_32 i32:$cond)),
183274955Ssvnmir                    (SELNEZ64 i64:$f, (SLL64_32 i32:$cond)))>,
184274955Ssvnmir              ISA_MIPS64R6;
185274955Ssvnmirdef : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, i64:$f),
186274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, (SLL64_32 i32:$cond)),
187274955Ssvnmir                    (SELEQZ64 i64:$f, (SLL64_32 i32:$cond)))>,
188274955Ssvnmir              ISA_MIPS64R6;
189274955Ssvnmirdef : MipsPat<(select (i32 (seteq i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
190274955Ssvnmir              (OR64 (SELEQZ64 i64:$t, (SLL64_32 (XORi i32:$cond,
191274955Ssvnmir                                                      immZExt16:$imm))),
192274955Ssvnmir                    (SELNEZ64 i64:$f, (SLL64_32 (XORi i32:$cond,
193274955Ssvnmir                                                      immZExt16:$imm))))>,
194274955Ssvnmir              ISA_MIPS64R6;
195274955Ssvnmirdef : MipsPat<(select (i32 (setne i32:$cond, immZExt16:$imm)), i64:$t, i64:$f),
196274955Ssvnmir              (OR64 (SELNEZ64 i64:$t, (SLL64_32 (XORi i32:$cond,
197274955Ssvnmir                                                      immZExt16:$imm))),
198274955Ssvnmir                    (SELEQZ64 i64:$f, (SLL64_32 (XORi i32:$cond,
199274955Ssvnmir                                                      immZExt16:$imm))))>,
200274955Ssvnmir              ISA_MIPS64R6;
201274955Ssvnmir
202274955Ssvnmirdef : MipsPat<(select i32:$cond, i64:$t, immz),
203274955Ssvnmir              (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>,
204274955Ssvnmir              ISA_MIPS64R6;
205274955Ssvnmirdef : MipsPat<(select (i32 (setne i32:$cond, immz)), i64:$t, immz),
206274955Ssvnmir              (SELNEZ64 i64:$t, (SLL64_32 i32:$cond))>,
207274955Ssvnmir              ISA_MIPS64R6;
208274955Ssvnmirdef : MipsPat<(select (i32 (seteq i32:$cond, immz)), i64:$t, immz),
209274955Ssvnmir              (SELEQZ64 i64:$t, (SLL64_32 i32:$cond))>,
210274955Ssvnmir              ISA_MIPS64R6;
211274955Ssvnmirdef : MipsPat<(select i32:$cond, immz, i64:$f),
212274955Ssvnmir              (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>,
213274955Ssvnmir              ISA_MIPS64R6;
214274955Ssvnmirdef : MipsPat<(select (i32 (setne i32:$cond, immz)), immz, i64:$f),
215274955Ssvnmir              (SELEQZ64 i64:$f, (SLL64_32 i32:$cond))>,
216274955Ssvnmir              ISA_MIPS64R6;
217274955Ssvnmirdef : MipsPat<(select (i32 (seteq i32:$cond, immz)), immz, i64:$f),
218274955Ssvnmir              (SELNEZ64 i64:$f, (SLL64_32 i32:$cond))>,
219274955Ssvnmir              ISA_MIPS64R6;
220