xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.td (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1e8d8bef9SDimitry Andric//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===//
2e8d8bef9SDimitry Andric//
3e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric//
7e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric//
9e8d8bef9SDimitry Andric// This file describes the CSKY instructions in TableGen format.
10e8d8bef9SDimitry Andric//
11e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
12e8d8bef9SDimitry Andric
13e8d8bef9SDimitry Andric
14e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
15e8d8bef9SDimitry Andric// CSKY specific DAG Nodes.
16e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
17e8d8bef9SDimitry Andric
18*fe6060f1SDimitry Andric// Target-dependent nodes.
19*fe6060f1SDimitry Andricdef CSKY_RET : SDNode<"CSKYISD::RET", SDTNone,
20*fe6060f1SDimitry Andric    [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
21e8d8bef9SDimitry Andric
22e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
23e8d8bef9SDimitry Andric// Operand and SDNode transformation definitions.
24e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
25*fe6060f1SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
26*fe6060f1SDimitry Andric  let Name = prefix # "Imm" # width # suffix;
27*fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
28*fe6060f1SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
29*fe6060f1SDimitry Andric}
30*fe6060f1SDimitry Andric
31*fe6060f1SDimitry Andricclass SImmAsmOperand<int width, string suffix = "">
32*fe6060f1SDimitry Andric    : ImmAsmOperand<"S", width, suffix> {
33*fe6060f1SDimitry Andric}
34*fe6060f1SDimitry Andric
35*fe6060f1SDimitry Andricclass UImmAsmOperand<int width, string suffix = "">
36*fe6060f1SDimitry Andric    : ImmAsmOperand<"U", width, suffix> {
37*fe6060f1SDimitry Andric}
38*fe6060f1SDimitry Andric
39*fe6060f1SDimitry Andricclass OImmAsmOperand<int width, string suffix = "">
40*fe6060f1SDimitry Andric    : ImmAsmOperand<"O", width, suffix> {
41*fe6060f1SDimitry Andric}
42e8d8bef9SDimitry Andric
43e8d8bef9SDimitry Andricclass oimm<int num> : Operand<i32>,
44e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> {
45e8d8bef9SDimitry Andric  let EncoderMethod = "getOImmOpValue";
46*fe6060f1SDimitry Andric  let ParserMatchClass = OImmAsmOperand<num>;
47e8d8bef9SDimitry Andric}
48e8d8bef9SDimitry Andric
49e8d8bef9SDimitry Andricclass uimm<int num, int shift = 0> : Operand<i32>,
50e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
51e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
52*fe6060f1SDimitry Andric  let ParserMatchClass =
53*fe6060f1SDimitry Andric    !if(!ne(shift, 0),
54*fe6060f1SDimitry Andric        UImmAsmOperand<num, "Shift"#shift>,
55*fe6060f1SDimitry Andric        UImmAsmOperand<num>);
56e8d8bef9SDimitry Andric}
57e8d8bef9SDimitry Andric
58e8d8bef9SDimitry Andricclass simm<int num, int shift = 0> : Operand<i32>,
59e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
60e8d8bef9SDimitry Andric  let EncoderMethod = "getImmOpValue<"#shift#">";
61*fe6060f1SDimitry Andric  let ParserMatchClass = SImmAsmOperand<num>;
62e8d8bef9SDimitry Andric}
63e8d8bef9SDimitry Andric
64e8d8bef9SDimitry Andricdef nimm_XFORM : SDNodeXForm<imm, [{
65e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
66e8d8bef9SDimitry Andric}]>;
67e8d8bef9SDimitry Andricclass nimm<int num> : Operand<i32>,
68e8d8bef9SDimitry Andric  ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
69*fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<num>;
70e8d8bef9SDimitry Andric}
71e8d8bef9SDimitry Andric
72*fe6060f1SDimitry Andricdef uimm32_hi16 : SDNodeXForm<imm, [{
73*fe6060f1SDimitry Andric  return CurDAG->getTargetConstant((N->getZExtValue() >> 16) & 0xFFFF,
74*fe6060f1SDimitry Andric    SDLoc(N), MVT::i32);
75*fe6060f1SDimitry Andric}]>;
76*fe6060f1SDimitry Andricdef uimm16_16_xform : Operand<i32>,
77*fe6060f1SDimitry Andric  ImmLeaf<i32, "return isShiftedUInt<16, 16>(Imm);", uimm32_hi16> {
78*fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<16>;
79*fe6060f1SDimitry Andric}
80*fe6060f1SDimitry Andric
81*fe6060f1SDimitry Andricdef uimm_shift : Operand<i32>, ImmLeaf<i32, "return isUInt<2>(Imm);"> {
82*fe6060f1SDimitry Andric  let EncoderMethod = "getImmShiftOpValue";
83*fe6060f1SDimitry Andric  let ParserMatchClass = UImmAsmOperand<2>;
84*fe6060f1SDimitry Andric}
85*fe6060f1SDimitry Andric
86*fe6060f1SDimitry Andricdef CSKYSymbol : AsmOperandClass {
87*fe6060f1SDimitry Andric  let Name = "CSKYSymbol";
88*fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
89*fe6060f1SDimitry Andric  let DiagnosticType = "InvalidCSKYSymbol";
90*fe6060f1SDimitry Andric  let ParserMethod = "parseCSKYSymbol";
91*fe6060f1SDimitry Andric}
92*fe6060f1SDimitry Andric
93*fe6060f1SDimitry Andricdef br_symbol : Operand<iPTR> {
94*fe6060f1SDimitry Andric  let EncoderMethod =
95*fe6060f1SDimitry Andric    "getBranchSymbolOpValue<CSKY::fixup_csky_pcrel_imm16_scale2>";
96*fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
97*fe6060f1SDimitry Andric}
98*fe6060f1SDimitry Andric
99*fe6060f1SDimitry Andricdef call_symbol : Operand<iPTR> {
100*fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
101*fe6060f1SDimitry Andric  let EncoderMethod = "getCallSymbolOpValue";
102*fe6060f1SDimitry Andric}
103*fe6060f1SDimitry Andric
104*fe6060f1SDimitry Andricdef Constpool : AsmOperandClass {
105*fe6060f1SDimitry Andric  let Name = "ConstpoolSymbol";
106*fe6060f1SDimitry Andric  let RenderMethod = "addImmOperands";
107*fe6060f1SDimitry Andric  let DiagnosticType = "InvalidConstpool";
108*fe6060f1SDimitry Andric  let ParserMethod = "parseConstpoolSymbol";
109*fe6060f1SDimitry Andric}
110*fe6060f1SDimitry Andric
111*fe6060f1SDimitry Andricdef constpool_symbol : Operand<iPTR> {
112*fe6060f1SDimitry Andric  let ParserMatchClass = Constpool;
113*fe6060f1SDimitry Andric  let EncoderMethod =
114*fe6060f1SDimitry Andric    "getConstpoolSymbolOpValue<CSKY::fixup_csky_pcrel_uimm16_scale4>";
115*fe6060f1SDimitry Andric}
116*fe6060f1SDimitry Andric
117*fe6060f1SDimitry Andricdef bare_symbol : Operand<iPTR> {
118*fe6060f1SDimitry Andric  let ParserMatchClass = CSKYSymbol;
119*fe6060f1SDimitry Andric  let EncoderMethod = "getBareSymbolOpValue";
120*fe6060f1SDimitry Andric}
121e8d8bef9SDimitry Andric
122e8d8bef9SDimitry Andricdef oimm12 : oimm<12>;
123*fe6060f1SDimitry Andricdef oimm16 : oimm<16>;
124e8d8bef9SDimitry Andric
125e8d8bef9SDimitry Andricdef nimm12 : nimm<12>;
126e8d8bef9SDimitry Andric
127e8d8bef9SDimitry Andricdef uimm5 : uimm<5>;
128e8d8bef9SDimitry Andricdef uimm12 : uimm<12>;
129*fe6060f1SDimitry Andricdef uimm12_1 : uimm<12, 1>;
130*fe6060f1SDimitry Andricdef uimm12_2 : uimm<12, 2>;
131*fe6060f1SDimitry Andricdef uimm16 : uimm<16>;
132*fe6060f1SDimitry Andric
133*fe6060f1SDimitry Andric
134*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
135*fe6060f1SDimitry Andric// Instruction Formats
136*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
137*fe6060f1SDimitry Andric
138*fe6060f1SDimitry Andricinclude "CSKYInstrFormats.td"
139e8d8bef9SDimitry Andric
140e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
141e8d8bef9SDimitry Andric// Instruction definitions.
142e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
143e8d8bef9SDimitry Andric
144e8d8bef9SDimitry Andricclass TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
145e8d8bef9SDimitry Andricclass BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
146e8d8bef9SDimitry Andricclass UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
147e8d8bef9SDimitry Andric
148*fe6060f1SDimitry Andric
149*fe6060f1SDimitry Andric
150*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
151*fe6060f1SDimitry Andric// Basic ALU instructions.
152*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
153*fe6060f1SDimitry Andric
154e8d8bef9SDimitry Andric  def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
155e8d8bef9SDimitry Andric  def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
156*fe6060f1SDimitry Andric  def ORI32 : I_16_ZX<"ori32", uimm16,
157*fe6060f1SDimitry Andric  [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>;
158*fe6060f1SDimitry Andric  def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
159e8d8bef9SDimitry Andric  def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
160e8d8bef9SDimitry Andric  def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
161e8d8bef9SDimitry Andric  def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
162e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
163e8d8bef9SDimitry Andric    [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
164e8d8bef9SDimitry Andric  def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
165e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
166e8d8bef9SDimitry Andric    [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
167e8d8bef9SDimitry Andric  def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
168e8d8bef9SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
169e8d8bef9SDimitry Andric    [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
170*fe6060f1SDimitry Andric  def ROTLI32 : I_5_XZ<0x12, 0x8, "rotli32",
171*fe6060f1SDimitry Andric    (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
172*fe6060f1SDimitry Andric    [(set GPR:$rz, (rotl GPR:$rx, uimm5:$imm5))]>;
173e8d8bef9SDimitry Andric
174e8d8bef9SDimitry Andric
175e8d8bef9SDimitry Andric  def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
176e8d8bef9SDimitry Andric    BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
177e8d8bef9SDimitry Andric  def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
178e8d8bef9SDimitry Andric    BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
179*fe6060f1SDimitry Andric  def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
180*fe6060f1SDimitry Andric    BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
181e8d8bef9SDimitry Andric  def AND32 : R_YXZ_SP_F1<0x8, 0x1,
182e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
183e8d8bef9SDimitry Andric  def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
184e8d8bef9SDimitry Andric    BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
185e8d8bef9SDimitry Andric  def OR32: R_YXZ_SP_F1<0x9, 0x1,
186e8d8bef9SDimitry Andric    BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
187e8d8bef9SDimitry Andric  def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
188e8d8bef9SDimitry Andric    BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
189e8d8bef9SDimitry Andric  def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
190e8d8bef9SDimitry Andric    BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
191*fe6060f1SDimitry Andric  def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
192*fe6060f1SDimitry Andric    "not32", [(set GPR:$rz, (not GPR:$rx))]>;
193e8d8bef9SDimitry Andric  def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
194e8d8bef9SDimitry Andric    BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
195e8d8bef9SDimitry Andric  def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
196e8d8bef9SDimitry Andric    BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
197e8d8bef9SDimitry Andric  def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
198e8d8bef9SDimitry Andric    BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
199*fe6060f1SDimitry Andric  def ROTL32 : R_YXZ_SP_F1<0x10, 0x8,
200*fe6060f1SDimitry Andric    BinOpFrag<(rotl node:$LHS, (and node:$RHS, 0x1f))>, "rotl32">;
201*fe6060f1SDimitry Andric
202*fe6060f1SDimitry Andric  // TODO: Shift series instr. with carry.
203*fe6060f1SDimitry Andric
204*fe6060f1SDimitry Andric  def IXH32 : R_YXZ_SP_F1<0x2, 0x1,
205*fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">;
206*fe6060f1SDimitry Andric  def IXW32 : R_YXZ_SP_F1<0x2, 0x2,
207*fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">;
208*fe6060f1SDimitry Andric
209*fe6060f1SDimitry Andric  def IXD32 : R_YXZ_SP_F1<0x2, 0x4,
210*fe6060f1SDimitry Andric    BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">;
211*fe6060f1SDimitry Andric
212*fe6060f1SDimitry Andric  let isCommutable = 1 in
213*fe6060f1SDimitry Andric  def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout),
214*fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>;
215*fe6060f1SDimitry Andric  def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout),
216*fe6060f1SDimitry Andric    (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>;
217*fe6060f1SDimitry Andric
218*fe6060f1SDimitry Andric  // TODO: incf32.
219e8d8bef9SDimitry Andric  def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
220e8d8bef9SDimitry Andric    BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
221e8d8bef9SDimitry Andric  def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
222e8d8bef9SDimitry Andric    BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
223e8d8bef9SDimitry Andric
224*fe6060f1SDimitry Andric  def DECGT32 : I_5_XZ<0x4, 0x1, "decgt32",
225*fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
226*fe6060f1SDimitry Andric  def DECLT32 : I_5_XZ<0x4, 0x2, "declt32",
227*fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
228*fe6060f1SDimitry Andric  def DECNE32 : I_5_XZ<0x4, 0x4, "decne32",
229*fe6060f1SDimitry Andric    (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, uimm5:$imm5), []>;
230*fe6060f1SDimitry Andric
231*fe6060f1SDimitry Andric  // TODO: s/zext.
232*fe6060f1SDimitry Andric  def ZEXT32 : I_5_XZ_U<0x15, (outs GPR:$rz),
233*fe6060f1SDimitry Andric    (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "zext32",[]>;
234*fe6060f1SDimitry Andric  def SEXT32 : I_5_XZ_U<0x16, (outs GPR:$rz),
235*fe6060f1SDimitry Andric    (ins GPR:$rx, uimm5:$msb, uimm5:$lsb), "sext32", []>;
236*fe6060f1SDimitry Andric
237*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
238*fe6060f1SDimitry Andric// Load & Store instructions.
239*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
240*fe6060f1SDimitry Andric
241*fe6060f1SDimitry Andricdef LD32B : I_LD<AddrMode32B, 0x0, "ld32.b", uimm12>;
242*fe6060f1SDimitry Andricdef LD32H : I_LD<AddrMode32H, 0x1, "ld32.h", uimm12_1>;
243*fe6060f1SDimitry Andricdef LD32W : I_LD<AddrMode32WD, 0x2, "ld32.w", uimm12_2>;
244*fe6060f1SDimitry Andric
245*fe6060f1SDimitry Andric
246*fe6060f1SDimitry Andric  def LD32BS : I_LD<AddrMode32B, 0x4, "ld32.bs", uimm12>;
247*fe6060f1SDimitry Andric  def LD32HS : I_LD<AddrMode32H, 0x5, "ld32.hs", uimm12_1>;
248*fe6060f1SDimitry Andric
249*fe6060f1SDimitry Andric  // TODO: LDM and STM.
250*fe6060f1SDimitry Andric
251*fe6060f1SDimitry Andric
252*fe6060f1SDimitry Andricdef ST32B : I_ST<AddrMode32B, 0x0, "st32.b", uimm12>;
253*fe6060f1SDimitry Andricdef ST32H : I_ST<AddrMode32H, 0x1, "st32.h", uimm12_1>;
254*fe6060f1SDimitry Andricdef ST32W : I_ST<AddrMode32WD, 0x2, "st32.w", uimm12_2>;
255*fe6060f1SDimitry Andric
256*fe6060f1SDimitry Andric
257*fe6060f1SDimitry Andric  def LDR32B :  I_LDR<0x0, "ldr32.b">;
258*fe6060f1SDimitry Andric  def LDR32BS :  I_LDR<0x4, "ldr32.bs">;
259*fe6060f1SDimitry Andric  def LDR32H :  I_LDR<0x1, "ldr32.h">;
260*fe6060f1SDimitry Andric  def LDR32HS :  I_LDR<0x5, "ldr32.hs">;
261*fe6060f1SDimitry Andric  def LDR32W :  I_LDR<0x2, "ldr32.w">;
262*fe6060f1SDimitry Andric  def STR32B :  I_STR<0x0, "str32.b">;
263*fe6060f1SDimitry Andric  def STR32H :  I_STR<0x1, "str32.h">;
264*fe6060f1SDimitry Andric  def STR32W :  I_STR<0x2, "str32.w">;
265*fe6060f1SDimitry Andric
266*fe6060f1SDimitry Andric  //TODO: SPILL_CARRY and RESTORE_CARRY.
267*fe6060f1SDimitry Andric
268*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
269*fe6060f1SDimitry Andric// Compare instructions.
270*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
271*fe6060f1SDimitry Andric
272*fe6060f1SDimitry Andric  def CMPNEI32 : I_16_X<0x1A, "cmpnei32", uimm16>;
273*fe6060f1SDimitry Andric  def CMPHSI32 : I_16_X<0x18, "cmphsi32", oimm16>;
274*fe6060f1SDimitry Andric  def CMPLTI32 : I_16_X<0x19, "cmplti32", oimm16>;
275*fe6060f1SDimitry Andric
276*fe6060f1SDimitry Andric
277*fe6060f1SDimitry Andric  def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">;
278*fe6060f1SDimitry Andric  def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">;
279*fe6060f1SDimitry Andric  def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">;
280*fe6060f1SDimitry Andric
281*fe6060f1SDimitry Andric  // TODO: setc and clrc.
282*fe6060f1SDimitry Andric  // TODO: test32 and tstnbz.
283*fe6060f1SDimitry Andric
284*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
285*fe6060f1SDimitry Andric// Data move instructions.
286*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
287*fe6060f1SDimitry Andric
288*fe6060f1SDimitry Andric  def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>;
289*fe6060f1SDimitry Andric  def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>;
290*fe6060f1SDimitry Andric  def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>;
291*fe6060f1SDimitry Andric  def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16_xform>;
292*fe6060f1SDimitry Andric  def MVC32 : R_Z_1<0x1, 0x8, "mvc32">;
293*fe6060f1SDimitry Andric  def MOV32 : R_XZ<0x12, 0x1, "mov32">;
294*fe6060f1SDimitry Andric
295*fe6060f1SDimitry Andric  // TODO: ISEL Pseudo.
296*fe6060f1SDimitry Andric
297*fe6060f1SDimitry Andric  def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">;
298*fe6060f1SDimitry Andric  // TODO: clrf and clrt.
299*fe6060f1SDimitry Andric  def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", []>;
300*fe6060f1SDimitry Andric  def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", []>;
301*fe6060f1SDimitry Andric
302*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
303*fe6060f1SDimitry Andric// Branch and call instructions.
304*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
305*fe6060f1SDimitry Andric
306*fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1 in {
307*fe6060f1SDimitry Andric  let isBarrier = 1, isPredicable = 1 in
308*fe6060f1SDimitry Andric    def BR32 : I_16_L<0x0, (outs), (ins br_symbol:$imm16), "br32\t$imm16",
309*fe6060f1SDimitry Andric                     [(br bb:$imm16)]>;
310*fe6060f1SDimitry Andric
311*fe6060f1SDimitry Andric  def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_symbol:$imm16),
312*fe6060f1SDimitry Andric    "bt32\t$imm16", [(brcond CARRY:$ca, bb:$imm16)]>;
313*fe6060f1SDimitry Andric  def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_symbol:$imm16),
314*fe6060f1SDimitry Andric    "bf32\t$imm16", []>;
315*fe6060f1SDimitry Andric}
316*fe6060f1SDimitry Andric
317*fe6060f1SDimitry Andric
318*fe6060f1SDimitry Andric  def BEZ32 : I_16_X_L<0x8, "bez32", br_symbol>;
319*fe6060f1SDimitry Andric  def BNEZ32 : I_16_X_L<0x9, "bnez32", br_symbol>;
320*fe6060f1SDimitry Andric  def BHZ32 : I_16_X_L<0xA, "bhz32", br_symbol>;
321*fe6060f1SDimitry Andric  def BLSZ32 : I_16_X_L<0xB, "blsz32", br_symbol>;
322*fe6060f1SDimitry Andric  def BLZ32 : I_16_X_L<0xC, "blz32", br_symbol>;
323*fe6060f1SDimitry Andric  def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_symbol>;
324*fe6060f1SDimitry Andric
325*fe6060f1SDimitry Andric  let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
326*fe6060f1SDimitry Andric    def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register
327*fe6060f1SDimitry Andric    def JMPI32 : I_16_L<0x16, (outs), (ins constpool_symbol:$imm16),
328*fe6060f1SDimitry Andric                   "jmpi32\t$imm16", []>;
329*fe6060f1SDimitry Andric  }
330*fe6060f1SDimitry Andric
331*fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] in
332*fe6060f1SDimitry Andric    def JSR32 : I_16_JX<0x7, "jsr32", []>;
333*fe6060f1SDimitry Andric
334*fe6060f1SDimitry Andric  let isCall = 1, Defs = [ R15 ] , mayLoad = 1 in
335*fe6060f1SDimitry Andric    def JSRI32: I_16_L<0x17, (outs),
336*fe6060f1SDimitry Andric      (ins constpool_symbol:$imm16), "jsri32\t$imm16", []>;
337*fe6060f1SDimitry Andric
338*fe6060f1SDimitry Andric
339*fe6060f1SDimitry Andricdef BSR32 : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>;
340*fe6060f1SDimitry Andric
341*fe6060f1SDimitry Andricdef BSR32_BR : J<0x38, (outs), (ins call_symbol:$offset), "bsr32", []>{
342*fe6060f1SDimitry Andric  let isCodeGenOnly = 1;
343*fe6060f1SDimitry Andric  let isBranch = 1;
344*fe6060f1SDimitry Andric  let isTerminator = 1;
345*fe6060f1SDimitry Andric  let isBarrier = 1;
346*fe6060f1SDimitry Andric  let isPredicable = 1;
347*fe6060f1SDimitry Andric  let Defs = [ R15 ];
348*fe6060f1SDimitry Andric}
349*fe6060f1SDimitry Andric
350*fe6060f1SDimitry Andric
351*fe6060f1SDimitry Andric  def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>;
352*fe6060f1SDimitry Andric
353*fe6060f1SDimitry Andric
354*fe6060f1SDimitry Andricdef RTE32 : I_16_RET_I<0, 0, "rte32", []>;
355*fe6060f1SDimitry Andric
356*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
357*fe6060f1SDimitry Andric// Symbol address instructions.
358*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
359*fe6060f1SDimitry Andric
360*fe6060f1SDimitry Andricdef GRS32 : I_18_Z_L<0x3, "grs32\t$rz, $offset",
361*fe6060f1SDimitry Andric                    (outs GPR:$rz), (ins bare_symbol:$offset), []>;
362*fe6060f1SDimitry Andric
363*fe6060f1SDimitry Andriclet mayLoad = 1, mayStore = 0 in {
364*fe6060f1SDimitry Andricdef LRW32 : I_16_Z_L<0x14, "lrw32", (ins constpool_symbol:$imm16), []>;
365*fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in
366*fe6060f1SDimitry Andricdef LRW32_Gen : I_16_Z_L<0x14, "lrw32",
367*fe6060f1SDimitry Andric  (ins bare_symbol:$src1, constpool_symbol:$imm16), []>;
368*fe6060f1SDimitry Andric}
369*fe6060f1SDimitry Andric
370*fe6060f1SDimitry Andric// TODO: Atomic and fence instructions.
371*fe6060f1SDimitry Andric// TODO: Other operations.
372*fe6060f1SDimitry Andric// TODO: Special instructions.
373*fe6060f1SDimitry Andric// TODO: Pseudo for assembly.
374