xref: /aosp_15_r20/external/llvm/lib/Target/Lanai/LanaiInstrInfo.td (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===-- LanaiInstrInfo.td - Target Description for Lanai Target -----------===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This file describes the Lanai instructions in TableGen format.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker// Instruction format superclass
16*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Workerinclude "LanaiInstrFormats.td"
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
21*9880d681SAndroid Build Coastguard Worker// Instruction Operands and Patterns
22*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker//  These are target-independent nodes, but have target-specific formats.
25*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
26*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
27*9880d681SAndroid Build Coastguard Worker                                          SDTCisVT<1, i32>]>;
28*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiCall         : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
29*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiSetFlag      : SDTypeProfile<0,  2, [SDTCisSameAs<0, 1>]>;
30*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiSelectCC     : SDTypeProfile<1,  3, [SDTCisSameAs<0, 1>,
31*9880d681SAndroid Build Coastguard Worker                                                  SDTCisSameAs<1, 2>]>;
32*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiSetCC        : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
33*9880d681SAndroid Build Coastguard Worker                                                  SDTCisVT<1, i32>]>;
34*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiBrCC         : SDTypeProfile<0,  2, [SDTCisVT<0, OtherVT>,
35*9880d681SAndroid Build Coastguard Worker                                                  SDTCisVT<1, i32>]>;
36*9880d681SAndroid Build Coastguard Workerdef SDT_LanaiAdjDynAlloc  : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
37*9880d681SAndroid Build Coastguard Worker                                                  SDTCisVT<1, i32>]>;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workerdef Call             : SDNode<"LanaiISD::CALL", SDT_LanaiCall,
40*9880d681SAndroid Build Coastguard Worker                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
41*9880d681SAndroid Build Coastguard Worker                               SDNPVariadic]>;
42*9880d681SAndroid Build Coastguard Workerdef RetFlag          : SDNode<"LanaiISD::RET_FLAG", SDTNone,
43*9880d681SAndroid Build Coastguard Worker                              [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
44*9880d681SAndroid Build Coastguard Workerdef CallSeqStart     : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
45*9880d681SAndroid Build Coastguard Worker                              [SDNPHasChain, SDNPOutGlue]>;
46*9880d681SAndroid Build Coastguard Workerdef CallSeqEnd       : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
47*9880d681SAndroid Build Coastguard Worker                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
48*9880d681SAndroid Build Coastguard Workerdef LanaiSetFlag     : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag,
49*9880d681SAndroid Build Coastguard Worker                              [SDNPOutGlue]>;
50*9880d681SAndroid Build Coastguard Workerdef LanaiSubbF       : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag,
51*9880d681SAndroid Build Coastguard Worker                              [SDNPOutGlue, SDNPInGlue]>;
52*9880d681SAndroid Build Coastguard Workerdef LanaiBrCC        : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC,
53*9880d681SAndroid Build Coastguard Worker                              [SDNPHasChain, SDNPInGlue]>;
54*9880d681SAndroid Build Coastguard Workerdef LanaiSelectCC    : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC,
55*9880d681SAndroid Build Coastguard Worker                              [SDNPInGlue]>;
56*9880d681SAndroid Build Coastguard Workerdef LanaiSetCC       : SDNode<"LanaiISD::SETCC", SDT_LanaiSetCC,
57*9880d681SAndroid Build Coastguard Worker                              [SDNPInGlue]>;
58*9880d681SAndroid Build Coastguard Workerdef LanaiHi          : SDNode<"LanaiISD::HI", SDTIntUnaryOp>;
59*9880d681SAndroid Build Coastguard Workerdef LanaiLo          : SDNode<"LanaiISD::LO", SDTIntUnaryOp>;
60*9880d681SAndroid Build Coastguard Workerdef LanaiSmall       : SDNode<"LanaiISD::SMALL", SDTIntUnaryOp>;
61*9880d681SAndroid Build Coastguard Workerdef LanaiAdjDynAlloc : SDNode<"LanaiISD::ADJDYNALLOC", SDT_LanaiAdjDynAlloc>;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker// Extract bits 0-15 (low-end) of an immediate value.
64*9880d681SAndroid Build Coastguard Workerdef LO16 : SDNodeXForm<imm, [{
65*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0xffff,
66*9880d681SAndroid Build Coastguard Worker                                   SDLoc(N), MVT::i32);
67*9880d681SAndroid Build Coastguard Worker}]>;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker// Extract bits 16-31 (high-end) of an immediate value.
70*9880d681SAndroid Build Coastguard Worker// Transformation function: shift the immediate value down into the low bits.
71*9880d681SAndroid Build Coastguard Workerdef HI16 : SDNodeXForm<imm, [{
72*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() >> 16, SDLoc(N),
73*9880d681SAndroid Build Coastguard Worker                                   MVT::i32);
74*9880d681SAndroid Build Coastguard Worker}]>;
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Workerdef NEG : SDNodeXForm<imm, [{
77*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
78*9880d681SAndroid Build Coastguard Worker}]>;
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Workerdef LO21 : SDNodeXForm<imm, [{
81*9880d681SAndroid Build Coastguard Worker  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0x1fffff,
82*9880d681SAndroid Build Coastguard Worker                                   SDLoc(N), MVT::i32);
83*9880d681SAndroid Build Coastguard Worker}]>;
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker// Branch targets
86*9880d681SAndroid Build Coastguard Workerdef BrTargetAsmOperand : AsmOperandClass {
87*9880d681SAndroid Build Coastguard Worker  let Name = "BrTarget";
88*9880d681SAndroid Build Coastguard Worker}
89*9880d681SAndroid Build Coastguard Workerdef BrTarget   : Operand<OtherVT> {
90*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = BrTargetAsmOperand;
91*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getBranchTargetOpValue";
92*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeBranch";
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerdef CallTargetAsmOperand : AsmOperandClass {
96*9880d681SAndroid Build Coastguard Worker  let Name = "CallTarget";
97*9880d681SAndroid Build Coastguard Worker}
98*9880d681SAndroid Build Coastguard Workerdef CallTarget : Operand<i32> {
99*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = CallTargetAsmOperand;
100*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getBranchTargetOpValue";
101*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeBranch";
102*9880d681SAndroid Build Coastguard Worker}
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Workerdef ImmShiftAsmOperand : AsmOperandClass { let Name = "ImmShift"; }
105*9880d681SAndroid Build Coastguard Workerdef immShift : Operand<i32>, PatLeaf<(imm), [{
106*9880d681SAndroid Build Coastguard Worker    int Imm = N->getSExtValue();
107*9880d681SAndroid Build Coastguard Worker    return Imm >= -31 && Imm <= 31;}]> {
108*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = ImmShiftAsmOperand;
109*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeShiftImm";
110*9880d681SAndroid Build Coastguard Worker}
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Workerdef Imm10AsmOperand : AsmOperandClass { let Name = "Imm10"; }
113*9880d681SAndroid Build Coastguard Workerdef imm10 : Operand<i32>, PatLeaf<(imm), [{
114*9880d681SAndroid Build Coastguard Worker    return isInt<10>(N->getSExtValue()); }]> {
115*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = Imm10AsmOperand;
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Workerdef immZExt21 : PatLeaf<(imm),
119*9880d681SAndroid Build Coastguard Worker                        [{return isUInt<21>(N->getZExtValue()); }], LO21>;
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Workerdef LoImm16AsmOperand : AsmOperandClass { let Name = "LoImm16"; }
122*9880d681SAndroid Build Coastguard Workerdef i32lo16z : Operand<i32>, PatLeaf<(i32 imm), [{
123*9880d681SAndroid Build Coastguard Worker    // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
124*9880d681SAndroid Build Coastguard Worker    // bits set.
125*9880d681SAndroid Build Coastguard Worker    return ((N->getZExtValue() & 0xFFFFUL) == N->getZExtValue());}], LO16> {
126*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = LoImm16AsmOperand;
127*9880d681SAndroid Build Coastguard Worker}
128*9880d681SAndroid Build Coastguard Workerdef i32neg16 : Operand<i32>, PatLeaf<(i32 imm), [{
129*9880d681SAndroid Build Coastguard Worker    // i32neg16 predicate - true if the 32-bit immediate is negative and can
130*9880d681SAndroid Build Coastguard Worker    // be represented by a 16 bit integer.
131*9880d681SAndroid Build Coastguard Worker    int Imm = N->getSExtValue();
132*9880d681SAndroid Build Coastguard Worker    return (Imm < 0) && (isInt<16>(Imm));}], LO16> {
133*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = LoImm16AsmOperand;
134*9880d681SAndroid Build Coastguard Worker}
135*9880d681SAndroid Build Coastguard Workerdef i32lo16s : Operand<i32>, PatLeaf<(i32 imm), [{
136*9880d681SAndroid Build Coastguard Worker    // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
137*9880d681SAndroid Build Coastguard Worker    // bits set.
138*9880d681SAndroid Build Coastguard Worker    return ((int64_t)(N->getSExtValue() & 0xFFFFUL) == N->getSExtValue());}], LO16> {
139*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = LoImm16AsmOperand;
140*9880d681SAndroid Build Coastguard Worker}
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Workerdef LoImm16AndAsmOperand : AsmOperandClass { let Name = "LoImm16And"; }
143*9880d681SAndroid Build Coastguard Workerdef i32lo16and : Operand<i32>, PatLeaf<(i32 imm), [{
144*9880d681SAndroid Build Coastguard Worker    // i32lo16 predicate - true if the 32-bit immediate has the rightmost 16
145*9880d681SAndroid Build Coastguard Worker    // bits set and the leftmost 16 bits 1's.
146*9880d681SAndroid Build Coastguard Worker    return (N->getZExtValue() >= 0xFFFF0000UL);}], LO16> {
147*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = LoImm16AndAsmOperand;
148*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printLo16AndImmOperand";
149*9880d681SAndroid Build Coastguard Worker}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Workerdef HiImm16AsmOperand : AsmOperandClass { let Name = "HiImm16"; }
152*9880d681SAndroid Build Coastguard Workerdef i32hi16 : Operand<i32>, PatLeaf<(i32 imm), [{
153*9880d681SAndroid Build Coastguard Worker    // i32hi16 predicate - true if the 32-bit immediate has only leftmost 16
154*9880d681SAndroid Build Coastguard Worker    // bits set.
155*9880d681SAndroid Build Coastguard Worker    return ((N->getZExtValue() & 0xFFFF0000UL) == N->getZExtValue());}], HI16> {
156*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = HiImm16AsmOperand;
157*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printHi16ImmOperand";
158*9880d681SAndroid Build Coastguard Worker}
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workerdef HiImm16AndAsmOperand : AsmOperandClass { let Name = "HiImm16And"; }
161*9880d681SAndroid Build Coastguard Workerdef i32hi16and : Operand<i32>, PatLeaf<(i32 imm), [{
162*9880d681SAndroid Build Coastguard Worker    // i32lo16 predicate - true if the 32-bit immediate has the leftmost 16
163*9880d681SAndroid Build Coastguard Worker    // bits set and the rightmost 16 bits 1's.
164*9880d681SAndroid Build Coastguard Worker    return ((N->getZExtValue() & 0xFFFFUL) == 0xFFFFUL);}], HI16> {
165*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = HiImm16AndAsmOperand;
166*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printHi16AndImmOperand";
167*9880d681SAndroid Build Coastguard Worker}
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerdef LoImm21AsmOperand : AsmOperandClass { let Name = "LoImm21"; }
170*9880d681SAndroid Build Coastguard Workerdef i32lo21 : Operand<i32>, PatLeaf<(i32 imm), [{
171*9880d681SAndroid Build Coastguard Worker    // i32lo21 predicate - true if the 32-bit immediate has only rightmost 21
172*9880d681SAndroid Build Coastguard Worker    // bits set.
173*9880d681SAndroid Build Coastguard Worker    return ((N->getZExtValue() & 0x1FFFFFUL) == N->getZExtValue());}], LO21> {
174*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = LoImm21AsmOperand;
175*9880d681SAndroid Build Coastguard Worker}
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Workerdef AluOp : Operand<i32> {
178*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printAluOperand";
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker// Addressing modes.
182*9880d681SAndroid Build Coastguard Workerdef ADDRrr : ComplexPattern<i32, 3, "selectAddrRr", [], []>;
183*9880d681SAndroid Build Coastguard Workerdef ADDRri : ComplexPattern<i32, 3, "selectAddrRi", [frameindex], []>;
184*9880d681SAndroid Build Coastguard Workerdef ADDRsls : ComplexPattern<i32, 1, "selectAddrSls", [frameindex], []>;
185*9880d681SAndroid Build Coastguard Workerdef ADDRspls : ComplexPattern<i32, 3, "selectAddrSpls", [frameindex], []>;
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker// Address operands
188*9880d681SAndroid Build Coastguard Workerdef MemRegImmAsmOperand : AsmOperandClass {
189*9880d681SAndroid Build Coastguard Worker  let Name = "MemRegImm";
190*9880d681SAndroid Build Coastguard Worker  let ParserMethod  = "parseMemoryOperand";
191*9880d681SAndroid Build Coastguard Worker}
192*9880d681SAndroid Build Coastguard Workerdef MEMri : Operand<i32> {
193*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeRiMemoryValue";
194*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getRiMemoryOpValue";
195*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, i32lo16s:$offset, AluOp:$Opcode);
196*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemRegImmAsmOperand;
197*9880d681SAndroid Build Coastguard Worker  let PrintMethod   = "printMemRiOperand";
198*9880d681SAndroid Build Coastguard Worker}
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Workerdef MemRegRegAsmOperand : AsmOperandClass {
201*9880d681SAndroid Build Coastguard Worker  let Name = "MemRegReg";
202*9880d681SAndroid Build Coastguard Worker  let ParserMethod  = "parseMemoryOperand";
203*9880d681SAndroid Build Coastguard Worker}
204*9880d681SAndroid Build Coastguard Workerdef MEMrr : Operand<i32> {
205*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeRrMemoryValue";
206*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getRrMemoryOpValue";
207*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$Op1, GPR:$Op2, AluOp:$Opcode);
208*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemRegRegAsmOperand;
209*9880d681SAndroid Build Coastguard Worker  let PrintMethod   = "printMemRrOperand";
210*9880d681SAndroid Build Coastguard Worker}
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerdef MemImmAsmOperand : AsmOperandClass {
213*9880d681SAndroid Build Coastguard Worker  let Name = "MemImm";
214*9880d681SAndroid Build Coastguard Worker  let ParserMethod  = "parseMemoryOperand";
215*9880d681SAndroid Build Coastguard Worker}
216*9880d681SAndroid Build Coastguard Workerdef MEMi : Operand<i32> {
217*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops i32lo21:$offset);
218*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemImmAsmOperand;
219*9880d681SAndroid Build Coastguard Worker  let PrintMethod   = "printMemImmOperand";
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Workerdef MemSplsAsmOperand : AsmOperandClass {
223*9880d681SAndroid Build Coastguard Worker  let Name = "MemSpls";
224*9880d681SAndroid Build Coastguard Worker  let ParserMethod  = "parseMemoryOperand";
225*9880d681SAndroid Build Coastguard Worker}
226*9880d681SAndroid Build Coastguard Workerdef MEMspls : Operand<i32> {
227*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodeSplsValue";
228*9880d681SAndroid Build Coastguard Worker  let EncoderMethod = "getSplsOpValue";
229*9880d681SAndroid Build Coastguard Worker  let MIOperandInfo = (ops GPR:$base, imm10:$offset, AluOp:$Opcode);
230*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = MemSplsAsmOperand;
231*9880d681SAndroid Build Coastguard Worker  let PrintMethod   = "printMemSplsOperand";
232*9880d681SAndroid Build Coastguard Worker}
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Workerdef CCOp : Operand<i32> {
235*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printCCOperand";
236*9880d681SAndroid Build Coastguard Worker}
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker// Predicate operand. Default to 0 = true.
239*9880d681SAndroid Build Coastguard Workerdef CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Workerdef pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> {
242*9880d681SAndroid Build Coastguard Worker  let PrintMethod = "printPredicateOperand";
243*9880d681SAndroid Build Coastguard Worker  let ParserMatchClass = CondCodeOperand;
244*9880d681SAndroid Build Coastguard Worker  let DecoderMethod = "decodePredicateOperand";
245*9880d681SAndroid Build Coastguard Worker}
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000001 in
248*9880d681SAndroid Build Coastguard Worker  def NOP : InstLanai<(outs), (ins), "nop", []>;
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker// Special NOPs to change logging level in vlanai.
251*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000002 in
252*9880d681SAndroid Build Coastguard Worker  def LOG0 : InstLanai<(outs), (ins), "log_0", []>;
253*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000003 in
254*9880d681SAndroid Build Coastguard Worker  def LOG1 : InstLanai<(outs), (ins), "log_1", []>;
255*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000004 in
256*9880d681SAndroid Build Coastguard Worker  def LOG2 : InstLanai<(outs), (ins), "log_2", []>;
257*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000005 in
258*9880d681SAndroid Build Coastguard Worker  def LOG3 : InstLanai<(outs), (ins), "log_3", []>;
259*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, Inst = 0x00000006 in
260*9880d681SAndroid Build Coastguard Worker  def LOG4 : InstLanai<(outs), (ins), "log_4", []>;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker// Map an SPLS instruction onto itself. All other instructions will be mapped
263*9880d681SAndroid Build Coastguard Worker// onto -1. Used to identify SPLS instructions.
264*9880d681SAndroid Build Coastguard Workerdef splsIdempotent : InstrMapping {
265*9880d681SAndroid Build Coastguard Worker  let FilterClass = "InstSPLS";
266*9880d681SAndroid Build Coastguard Worker  let RowFields = ["AsmString"];
267*9880d681SAndroid Build Coastguard Worker  let ColFields = ["PostEncoderMethod"];
268*9880d681SAndroid Build Coastguard Worker  let KeyCol = ["adjustPqBitsSpls"];
269*9880d681SAndroid Build Coastguard Worker  let ValueCols = [["adjustPqBitsSpls"]];
270*9880d681SAndroid Build Coastguard Worker}
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
273*9880d681SAndroid Build Coastguard Worker// ALU instructions
274*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
275*9880d681SAndroid Build Coastguard Workermulticlass ALUbase<bits<3> subOp, string AsmStr, SDNode OpNode,
276*9880d681SAndroid Build Coastguard Worker                   PatLeaf LoExt, PatLeaf HiExt,
277*9880d681SAndroid Build Coastguard Worker                   list<dag> loPattern, list<dag> hiPattern> {
278*9880d681SAndroid Build Coastguard Worker  // Register Immediate
279*9880d681SAndroid Build Coastguard Worker  let H = 0 in
280*9880d681SAndroid Build Coastguard Worker    def LO : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, LoExt:$imm16),
281*9880d681SAndroid Build Coastguard Worker                    !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
282*9880d681SAndroid Build Coastguard Worker                    loPattern>;
283*9880d681SAndroid Build Coastguard Worker  let H = 1 in
284*9880d681SAndroid Build Coastguard Worker    def HI : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, HiExt:$imm16),
285*9880d681SAndroid Build Coastguard Worker                    !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
286*9880d681SAndroid Build Coastguard Worker                    hiPattern>;
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker}
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Workermulticlass ALUarith<bits<3> subOp, string AsmStr, SDNode OpNode,
291*9880d681SAndroid Build Coastguard Worker                    PatLeaf LoExt, PatLeaf HiExt> {
292*9880d681SAndroid Build Coastguard Worker  defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, [], []>;
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker  // Register Register
295*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0 in
296*9880d681SAndroid Build Coastguard Worker    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
297*9880d681SAndroid Build Coastguard Worker                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
298*9880d681SAndroid Build Coastguard Worker                   [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
299*9880d681SAndroid Build Coastguard Worker}
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Workermulticlass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode,
302*9880d681SAndroid Build Coastguard Worker                    PatLeaf LoExt, PatLeaf HiExt> {
303*9880d681SAndroid Build Coastguard Worker  defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt,
304*9880d681SAndroid Build Coastguard Worker                    [(set GPR:$Rd, (OpNode GPR:$Rs1, LoExt:$imm16))],
305*9880d681SAndroid Build Coastguard Worker                    [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>;
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker  // Register Register
308*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0 in
309*9880d681SAndroid Build Coastguard Worker    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
310*9880d681SAndroid Build Coastguard Worker                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
311*9880d681SAndroid Build Coastguard Worker                   [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
312*9880d681SAndroid Build Coastguard Worker}
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker// Non flag setting ALU operations
315*9880d681SAndroid Build Coastguard Workerlet isAsCheapAsAMove = 1, F = 0 in {
316*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in {
317*9880d681SAndroid Build Coastguard Worker    defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>;
318*9880d681SAndroid Build Coastguard Worker  }
319*9880d681SAndroid Build Coastguard Worker  defm SUB_ : ALUarith<0b010,   "sub", sub, i32lo16z, i32hi16>;
320*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in {
321*9880d681SAndroid Build Coastguard Worker    defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>;
322*9880d681SAndroid Build Coastguard Worker    defm OR_  : ALUlogic<0b101,  "or",  or, i32lo16z, i32hi16>;
323*9880d681SAndroid Build Coastguard Worker    defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>;
324*9880d681SAndroid Build Coastguard Worker  }
325*9880d681SAndroid Build Coastguard Worker}
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GPR:$Rs1, i32lo16z:$imm),
328*9880d681SAndroid Build Coastguard Worker          (ADD_I_LO GPR:$Rs1, i32lo16z:$imm)>;
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GPR:$Rs1, i32lo16z:$imm),
331*9880d681SAndroid Build Coastguard Worker          (SUB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GPR:$Rs1, i32hi16:$imm),
334*9880d681SAndroid Build Coastguard Worker          (ADD_I_HI GPR:$Rs1, i32hi16:$imm)>;
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GPR:$Rs1, i32hi16:$imm),
337*9880d681SAndroid Build Coastguard Worker          (SUB_I_HI GPR:$Rs1, i32hi16:$imm)>;
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 i32lo16and:$imm), (AND_I_LO (i32 R1), i32lo16and:$imm)>;
340*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 i32hi16and:$imm), (AND_I_HI (i32 R1), i32hi16and:$imm)>;
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker// Change add/sub with negative number to sub/add
343*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GPR:$Rs1, i32neg16:$imm),
344*9880d681SAndroid Build Coastguard Worker          (SUB_I_LO GPR:$Rs1, (NEG $imm))>;
345*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GPR:$Rs1, i32neg16:$imm),
346*9880d681SAndroid Build Coastguard Worker          (ADD_I_LO GPR:$Rs1, (NEG $imm))>;
347*9880d681SAndroid Build Coastguard Worker
348*9880d681SAndroid Build Coastguard Worker// Flag (incl. carry) setting addition and subtraction
349*9880d681SAndroid Build Coastguard Workerlet F = 1, Defs = [SR] in {
350*9880d681SAndroid Build Coastguard Worker  defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>;
351*9880d681SAndroid Build Coastguard Worker  defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>;
352*9880d681SAndroid Build Coastguard Worker}
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc GPR:$Rs1, i32lo16z:$imm),
355*9880d681SAndroid Build Coastguard Worker          (ADD_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc GPR:$Rs1, i32lo16z:$imm),
358*9880d681SAndroid Build Coastguard Worker          (SUB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc GPR:$Rs1, i32hi16:$imm),
361*9880d681SAndroid Build Coastguard Worker          (ADD_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc GPR:$Rs1, i32hi16:$imm),
364*9880d681SAndroid Build Coastguard Worker          (SUB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker// Carry using addition and subtraction
367*9880d681SAndroid Build Coastguard Workerlet F = 0, Uses = [SR] in {
368*9880d681SAndroid Build Coastguard Worker  defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>;
369*9880d681SAndroid Build Coastguard Worker  defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>;
370*9880d681SAndroid Build Coastguard Worker}
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Workerdef : Pat<(adde GPR:$Rs1, i32lo16z:$imm),
373*9880d681SAndroid Build Coastguard Worker          (ADDC_I_LO GPR:$Rs1, i32lo16z:$imm)>;
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Workerdef : Pat<(sube GPR:$Rs1, i32lo16z:$imm),
376*9880d681SAndroid Build Coastguard Worker          (SUBB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Workerdef : Pat<(adde GPR:$Rs1, i32hi16:$imm),
379*9880d681SAndroid Build Coastguard Worker          (ADDC_I_HI GPR:$Rs1, i32hi16:$imm)>;
380*9880d681SAndroid Build Coastguard Worker
381*9880d681SAndroid Build Coastguard Workerdef : Pat<(sube GPR:$Rs1, i32hi16:$imm),
382*9880d681SAndroid Build Coastguard Worker          (SUBB_I_HI GPR:$Rs1, i32hi16:$imm)>;
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard Worker// Flag setting ALU operations
385*9880d681SAndroid Build Coastguard Workerlet isAsCheapAsAMove = 1, F = 1, Defs = [SR] in {
386*9880d681SAndroid Build Coastguard Worker  let isCommutable = 1 in {
387*9880d681SAndroid Build Coastguard Worker    defm AND_F_ : ALUlogic<0b100, "and.f",  and, i32lo16and, i32hi16and>;
388*9880d681SAndroid Build Coastguard Worker    defm OR_F_  : ALUlogic<0b101,  "or.f",   or, i32lo16z, i32hi16>;
389*9880d681SAndroid Build Coastguard Worker    defm XOR_F_ : ALUlogic<0b110, "xor.f",  xor, i32lo16z, i32hi16>;
390*9880d681SAndroid Build Coastguard Worker  }
391*9880d681SAndroid Build Coastguard Worker}
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Workerlet isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in {
394*9880d681SAndroid Build Coastguard Worker  defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>;
395*9880d681SAndroid Build Coastguard Worker  defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>;
396*9880d681SAndroid Build Coastguard Worker}
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2),
399*9880d681SAndroid Build Coastguard Worker          (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>;
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm),
402*9880d681SAndroid Build Coastguard Worker          (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
405*9880d681SAndroid Build Coastguard Worker          (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>;
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Workerlet isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
410*9880d681SAndroid Build Coastguard Worker  isReMaterializable = 1 in
411*9880d681SAndroid Build Coastguard Worker  def MOVHI : InstRI<0b000, (outs GPR:$Rd), (ins i32hi16:$imm16),
412*9880d681SAndroid Build Coastguard Worker                     "mov\t$imm16, $Rd",
413*9880d681SAndroid Build Coastguard Worker                     [(set GPR:$Rd, i32hi16:$imm16)]>;
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>;
416*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>;
417*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov $imm16, $dst",
418*9880d681SAndroid Build Coastguard Worker                (AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>;
419*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"mov $imm16, $dst",
420*9880d681SAndroid Build Coastguard Worker                (AND_I_HI GPR:$dst, R1, i32hi16and:$imm16)>;
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker// Shift instructions
423*9880d681SAndroid Build Coastguard Workerclass ShiftRI<string AsmStr, list<dag> Pattern>
424*9880d681SAndroid Build Coastguard Worker  : InstRI<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, immShift:$imm16),
425*9880d681SAndroid Build Coastguard Worker           !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), Pattern> {
426*9880d681SAndroid Build Coastguard Worker  let isReMaterializable = 1;
427*9880d681SAndroid Build Coastguard Worker}
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Workerlet F = 0 in {
430*9880d681SAndroid Build Coastguard Worker  let H = 0 in
431*9880d681SAndroid Build Coastguard Worker    def SL_I : ShiftRI<"sh", [(set GPR:$Rd, (shl GPR:$Rs1, immShift:$imm16))]>;
432*9880d681SAndroid Build Coastguard Worker  let H = 1 in
433*9880d681SAndroid Build Coastguard Worker    def SA_I : ShiftRI<"sha", []>;
434*9880d681SAndroid Build Coastguard Worker}
435*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl GPR:$Rs1, immShift:$imm), (SL_I GPR:$Rs1, (NEG $imm))>;
436*9880d681SAndroid Build Coastguard Workerdef : Pat<(sra GPR:$Rs1, immShift:$imm), (SA_I GPR:$Rs1, (NEG $imm))>;
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Workerlet F = 1, Defs = [SR] in {
439*9880d681SAndroid Build Coastguard Worker  let H = 0 in
440*9880d681SAndroid Build Coastguard Worker    def SL_F_I : ShiftRI<"sh.f", []>;
441*9880d681SAndroid Build Coastguard Worker  let H = 1 in
442*9880d681SAndroid Build Coastguard Worker    def SA_F_I : ShiftRI<"sha.f", []>;
443*9880d681SAndroid Build Coastguard Worker}
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Workerclass ShiftRR<string AsmStr, list<dag> Pattern>
446*9880d681SAndroid Build Coastguard Worker  : InstRR<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), AsmStr,
447*9880d681SAndroid Build Coastguard Worker           Pattern>;
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Workerlet F = 0 in {
450*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0b10000 in
451*9880d681SAndroid Build Coastguard Worker    def SHL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd",
452*9880d681SAndroid Build Coastguard Worker                        [(set GPR:$Rd, (shl GPR:$Rs1, GPR:$Rs2))]>;
453*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in {
454*9880d681SAndroid Build Coastguard Worker    let JJJJJ = 0b10000 in
455*9880d681SAndroid Build Coastguard Worker      def SRL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", []>;
456*9880d681SAndroid Build Coastguard Worker  }
457*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0b11000 in
458*9880d681SAndroid Build Coastguard Worker    def SRA_R : ShiftRR<"sha$DDDI\t$Rs1, $Rs2, $Rd", []>;
459*9880d681SAndroid Build Coastguard Worker}
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Workerlet F = 1, Defs = [SR] in {
462*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0b10000 in
463*9880d681SAndroid Build Coastguard Worker    def SHL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
464*9880d681SAndroid Build Coastguard Worker  let isCodeGenOnly = 1 in {
465*9880d681SAndroid Build Coastguard Worker    let JJJJJ = 0b10000 in
466*9880d681SAndroid Build Coastguard Worker      def SRL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
467*9880d681SAndroid Build Coastguard Worker  }
468*9880d681SAndroid Build Coastguard Worker  let JJJJJ = 0b11000 in
469*9880d681SAndroid Build Coastguard Worker    def SRA_F_R : ShiftRR<"sha.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
470*9880d681SAndroid Build Coastguard Worker}
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker// Expand shift-right operations
473*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl GPR:$Rs1, GPR:$Rs2),
474*9880d681SAndroid Build Coastguard Worker          (SRL_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
475*9880d681SAndroid Build Coastguard Workerdef : Pat<(sra GPR:$Rs1, GPR:$Rs2),
476*9880d681SAndroid Build Coastguard Worker          (SRA_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
479*9880d681SAndroid Build Coastguard Worker// LOAD instructions
480*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Workerclass LoadRR<string OpcString, PatFrag OpNode, ValueType Ty>
483*9880d681SAndroid Build Coastguard Worker  : InstRRM<0b0, (outs GPR:$Rd), (ins MEMrr:$src),
484*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcString, "\t$src, $Rd"),
485*9880d681SAndroid Build Coastguard Worker            [(set (Ty GPR:$Rd), (OpNode ADDRrr:$src))]>,
486*9880d681SAndroid Build Coastguard Worker    Sched<[WriteLD]> {
487*9880d681SAndroid Build Coastguard Worker  bits<20> src;
488*9880d681SAndroid Build Coastguard Worker
489*9880d681SAndroid Build Coastguard Worker  let Rs1 = src{19-15};
490*9880d681SAndroid Build Coastguard Worker  let Rs2 = src{14-10};
491*9880d681SAndroid Build Coastguard Worker  let P = src{9};
492*9880d681SAndroid Build Coastguard Worker  let Q = src{8};
493*9880d681SAndroid Build Coastguard Worker  let BBB = src{7-5};
494*9880d681SAndroid Build Coastguard Worker  let JJJJJ = src{4-0};
495*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1;
496*9880d681SAndroid Build Coastguard Worker}
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Workerclass LoadRI<string OpcString, PatFrag OpNode, ValueType Ty>
499*9880d681SAndroid Build Coastguard Worker  : InstRM<0b0, (outs GPR:$Rd), (ins MEMri:$src),
500*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcString, "\t$src, $Rd"),
501*9880d681SAndroid Build Coastguard Worker           [(set (Ty GPR:$Rd), (OpNode ADDRri:$src))]>,
502*9880d681SAndroid Build Coastguard Worker    Sched<[WriteLD]> {
503*9880d681SAndroid Build Coastguard Worker  bits<23> src;
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_LD;
506*9880d681SAndroid Build Coastguard Worker  let Rs1 = src{22-18};
507*9880d681SAndroid Build Coastguard Worker  let P = src{17};
508*9880d681SAndroid Build Coastguard Worker  let Q = src{16};
509*9880d681SAndroid Build Coastguard Worker  let imm16 = src{15-0};
510*9880d681SAndroid Build Coastguard Worker  let isReMaterializable = 1;
511*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1;
512*9880d681SAndroid Build Coastguard Worker}
513*9880d681SAndroid Build Coastguard Worker
514*9880d681SAndroid Build Coastguard Workerlet E = 0 in {
515*9880d681SAndroid Build Coastguard Worker  let YL = 0b01 in {
516*9880d681SAndroid Build Coastguard Worker    // uld is used here and ld in the alias as the alias is printed out first if
517*9880d681SAndroid Build Coastguard Worker    // an alias exist
518*9880d681SAndroid Build Coastguard Worker    def LDW_RI : LoadRI<"uld", load, i32>;
519*9880d681SAndroid Build Coastguard Worker    def LDW_RR : LoadRR<"ld", load, i32>;
520*9880d681SAndroid Build Coastguard Worker  }
521*9880d681SAndroid Build Coastguard Worker}
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"ld $src, $dst", (LDW_RI GPR:$dst, MEMri:$src)>;
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Workerlet E = 1 in {
526*9880d681SAndroid Build Coastguard Worker  let YL = 0b01 in {
527*9880d681SAndroid Build Coastguard Worker    def LDWz_RR : LoadRR<"uld", zextloadi32, i32>;
528*9880d681SAndroid Build Coastguard Worker  }
529*9880d681SAndroid Build Coastguard Worker}
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Workerlet E = 1 in {
532*9880d681SAndroid Build Coastguard Worker  let YL = 0b00 in
533*9880d681SAndroid Build Coastguard Worker    def LDHz_RR : LoadRR<"uld.h", zextloadi16, i32>;
534*9880d681SAndroid Build Coastguard Worker  let YL = 0b10 in
535*9880d681SAndroid Build Coastguard Worker    def LDBz_RR : LoadRR<"uld.b", zextloadi8, i32>;
536*9880d681SAndroid Build Coastguard Worker}
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Workerlet E = 0 in {
539*9880d681SAndroid Build Coastguard Worker  let YL = 0b00 in
540*9880d681SAndroid Build Coastguard Worker    def LDHs_RR : LoadRR<"ld.h", sextloadi16, i32>;
541*9880d681SAndroid Build Coastguard Worker  let YL = 0b10 in
542*9880d681SAndroid Build Coastguard Worker    def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>;
543*9880d681SAndroid Build Coastguard Worker}
544*9880d681SAndroid Build Coastguard Worker
545*9880d681SAndroid Build Coastguard Workerdef LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src),
546*9880d681SAndroid Build Coastguard Worker                     "ld\t$src, $Rd",
547*9880d681SAndroid Build Coastguard Worker                     [(set (i32 GPR:$Rd), (load ADDRsls:$src))]>,
548*9880d681SAndroid Build Coastguard Worker    Sched<[WriteLD]> {
549*9880d681SAndroid Build Coastguard Worker  bits<21> src;
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_LD;
552*9880d681SAndroid Build Coastguard Worker  let msb = src{20-16};
553*9880d681SAndroid Build Coastguard Worker  let lsb = src{15-0};
554*9880d681SAndroid Build Coastguard Worker  let isReMaterializable = 1;
555*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1;
556*9880d681SAndroid Build Coastguard Worker}
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Workerclass LoadSPLS<string asmstring, PatFrag opNode>
559*9880d681SAndroid Build Coastguard Worker  : InstSPLS<(outs GPR:$Rd), (ins MEMspls:$src),
560*9880d681SAndroid Build Coastguard Worker             !strconcat(asmstring, "\t$src, $Rd"),
561*9880d681SAndroid Build Coastguard Worker             [(set (i32 GPR:$Rd), (opNode ADDRspls:$src))]>,
562*9880d681SAndroid Build Coastguard Worker    Sched<[WriteLDSW]> {
563*9880d681SAndroid Build Coastguard Worker  bits<17> src;
564*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_LDSW;
565*9880d681SAndroid Build Coastguard Worker  let Rs1 = src{16-12};
566*9880d681SAndroid Build Coastguard Worker  let P = src{11};
567*9880d681SAndroid Build Coastguard Worker  let Q = src{10};
568*9880d681SAndroid Build Coastguard Worker  let imm10 = src{9-0};
569*9880d681SAndroid Build Coastguard Worker  let mayLoad = 1;
570*9880d681SAndroid Build Coastguard Worker  let isReMaterializable = 1;
571*9880d681SAndroid Build Coastguard Worker}
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Workerlet Y = 0, S = 0, E = 1 in
574*9880d681SAndroid Build Coastguard Worker  def LDHz_RI : LoadSPLS<"uld.h", zextloadi16>;
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Workerlet Y = 0, S = 0, E = 0 in
577*9880d681SAndroid Build Coastguard Worker  def LDHs_RI : LoadSPLS<"ld.h", sextloadi16>;
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Workerlet Y = 1, S = 0, E = 1 in
580*9880d681SAndroid Build Coastguard Worker  def LDBz_RI : LoadSPLS<"uld.b", zextloadi8>;
581*9880d681SAndroid Build Coastguard Worker
582*9880d681SAndroid Build Coastguard Workerlet Y = 1, S = 0, E = 0 in
583*9880d681SAndroid Build Coastguard Worker  def LDBs_RI : LoadSPLS<"ld.b", sextloadi8>;
584*9880d681SAndroid Build Coastguard Worker
585*9880d681SAndroid Build Coastguard Workerdef SLI : InstSLI<(outs GPR:$Rd), (ins i32lo21:$imm),
586*9880d681SAndroid Build Coastguard Worker                  "mov\t$imm, $Rd",
587*9880d681SAndroid Build Coastguard Worker                  [(set GPR:$Rd, i32lo21:$imm)]> {
588*9880d681SAndroid Build Coastguard Worker  bits<21> imm;
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker  let msb = imm{20-16};
591*9880d681SAndroid Build Coastguard Worker  let lsb = imm{15-0};
592*9880d681SAndroid Build Coastguard Worker  let isReMaterializable = 1;
593*9880d681SAndroid Build Coastguard Worker  let isAsCheapAsAMove = 1;
594*9880d681SAndroid Build Coastguard Worker}
595*9880d681SAndroid Build Coastguard Worker
596*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
597*9880d681SAndroid Build Coastguard Worker// STORE instructions
598*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Workerclass StoreRR<string OpcString, PatFrag OpNode, ValueType Ty>
601*9880d681SAndroid Build Coastguard Worker  : InstRRM<0b1, (outs), (ins GPR:$Rd, MEMrr:$dst),
602*9880d681SAndroid Build Coastguard Worker            !strconcat(OpcString, "\t$Rd, $dst"),
603*9880d681SAndroid Build Coastguard Worker            [(OpNode (Ty GPR:$Rd), ADDRrr:$dst)]>,
604*9880d681SAndroid Build Coastguard Worker    Sched<[WriteST]> {
605*9880d681SAndroid Build Coastguard Worker  bits<20> dst;
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_ST;
608*9880d681SAndroid Build Coastguard Worker  let Rs1 = dst{19-15};
609*9880d681SAndroid Build Coastguard Worker  let Rs2 = dst{14-10};
610*9880d681SAndroid Build Coastguard Worker  let P = dst{9};
611*9880d681SAndroid Build Coastguard Worker  let Q = dst{8};
612*9880d681SAndroid Build Coastguard Worker  let BBB = dst{7-5};
613*9880d681SAndroid Build Coastguard Worker  let JJJJJ = dst{4-0};
614*9880d681SAndroid Build Coastguard Worker  let mayStore = 1;
615*9880d681SAndroid Build Coastguard Worker}
616*9880d681SAndroid Build Coastguard Worker
617*9880d681SAndroid Build Coastguard Workerclass StoreRI<string OpcString, PatFrag OpNode, ValueType Ty>
618*9880d681SAndroid Build Coastguard Worker  : InstRM<0b1, (outs), (ins GPR:$Rd, MEMri:$dst),
619*9880d681SAndroid Build Coastguard Worker           !strconcat(OpcString, "\t$Rd, $dst"),
620*9880d681SAndroid Build Coastguard Worker           [(OpNode (Ty GPR:$Rd), ADDRri:$dst)]>,
621*9880d681SAndroid Build Coastguard Worker    Sched<[WriteST]> {
622*9880d681SAndroid Build Coastguard Worker  bits<23> dst;
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_ST;
625*9880d681SAndroid Build Coastguard Worker  let Rs1 = dst{22-18};
626*9880d681SAndroid Build Coastguard Worker  let P = dst{17};
627*9880d681SAndroid Build Coastguard Worker  let Q = dst{16};
628*9880d681SAndroid Build Coastguard Worker  let imm16 = dst{15-0};
629*9880d681SAndroid Build Coastguard Worker  let mayStore = 1;
630*9880d681SAndroid Build Coastguard Worker}
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Workerlet YL = 0b01, E = 0 in {
633*9880d681SAndroid Build Coastguard Worker  def SW_RR : StoreRR<"st", store, i32>;
634*9880d681SAndroid Build Coastguard Worker  def SW_RI : StoreRI<"st", store, i32>;
635*9880d681SAndroid Build Coastguard Worker}
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Workerlet E = 0 in {
638*9880d681SAndroid Build Coastguard Worker  let YL = 0b00 in
639*9880d681SAndroid Build Coastguard Worker    def STH_RR : StoreRR<"st.h", truncstorei16, i32>;
640*9880d681SAndroid Build Coastguard Worker  let YL = 0b10 in
641*9880d681SAndroid Build Coastguard Worker    def STB_RR : StoreRR<"st.b", truncstorei8, i32>;
642*9880d681SAndroid Build Coastguard Worker}
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Workerdef STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst),
645*9880d681SAndroid Build Coastguard Worker                     "st\t$Rd, $dst",
646*9880d681SAndroid Build Coastguard Worker                     [(store (i32 GPR:$Rd), ADDRsls:$dst)]>,
647*9880d681SAndroid Build Coastguard Worker    Sched<[WriteST]> {
648*9880d681SAndroid Build Coastguard Worker  bits<21> dst;
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_ST;
651*9880d681SAndroid Build Coastguard Worker  let msb = dst{20-16};
652*9880d681SAndroid Build Coastguard Worker  let lsb = dst{15-0};
653*9880d681SAndroid Build Coastguard Worker  let mayStore = 1;
654*9880d681SAndroid Build Coastguard Worker}
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Workerclass StoreSPLS<string asmstring, PatFrag opNode>
657*9880d681SAndroid Build Coastguard Worker  : InstSPLS<(outs), (ins GPR:$Rd, MEMspls:$dst),
658*9880d681SAndroid Build Coastguard Worker             !strconcat(asmstring, "\t$Rd, $dst"),
659*9880d681SAndroid Build Coastguard Worker             [(opNode (i32 GPR:$Rd), ADDRspls:$dst)]>,
660*9880d681SAndroid Build Coastguard Worker    Sched<[WriteSTSW]> {
661*9880d681SAndroid Build Coastguard Worker  bits<17> dst;
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker  let Itinerary = IIC_STSW;
664*9880d681SAndroid Build Coastguard Worker  let Rs1 = dst{16-12};
665*9880d681SAndroid Build Coastguard Worker  let P = dst{11};
666*9880d681SAndroid Build Coastguard Worker  let Q = dst{10};
667*9880d681SAndroid Build Coastguard Worker  let imm10 = dst{9-0};
668*9880d681SAndroid Build Coastguard Worker  let mayStore = 1;
669*9880d681SAndroid Build Coastguard Worker}
670*9880d681SAndroid Build Coastguard Worker
671*9880d681SAndroid Build Coastguard Workerlet Y = 0, S = 1, E = 0 in
672*9880d681SAndroid Build Coastguard Worker  def STH_RI : StoreSPLS<"st.h", truncstorei16>;
673*9880d681SAndroid Build Coastguard Worker
674*9880d681SAndroid Build Coastguard Workerlet Y = 1, S = 1, E = 0 in
675*9880d681SAndroid Build Coastguard Worker  def STB_RI : StoreSPLS<"st.b", truncstorei8>;
676*9880d681SAndroid Build Coastguard Worker
677*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
678*9880d681SAndroid Build Coastguard Worker// BRANCH instructions
679*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
680*9880d681SAndroid Build Coastguard Worker
681*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1 in {
682*9880d681SAndroid Build Coastguard Worker  def BT : InstBR<(outs), (ins BrTarget:$addr),
683*9880d681SAndroid Build Coastguard Worker                  "bt\t$addr",
684*9880d681SAndroid Build Coastguard Worker                  [(br bb:$addr)]> {
685*9880d681SAndroid Build Coastguard Worker    let DDDI = 0b0000;
686*9880d681SAndroid Build Coastguard Worker  }
687*9880d681SAndroid Build Coastguard Worker  let Uses = [SR] in
688*9880d681SAndroid Build Coastguard Worker    def BRCC : InstBR<(outs), (ins BrTarget:$addr, CCOp:$DDDI),
689*9880d681SAndroid Build Coastguard Worker                      "b$DDDI\t$addr",
690*9880d681SAndroid Build Coastguard Worker                      [(LanaiBrCC bb:$addr, imm:$DDDI)]>;
691*9880d681SAndroid Build Coastguard Worker
692*9880d681SAndroid Build Coastguard Worker  let isIndirectBranch = 1 in {
693*9880d681SAndroid Build Coastguard Worker    def JR : InstRR<0b101, (outs), (ins GPR:$Rs2), "bt\t$Rs2",
694*9880d681SAndroid Build Coastguard Worker                    [(brind GPR:$Rs2)]> {
695*9880d681SAndroid Build Coastguard Worker      let Rs1 = R0.Num;
696*9880d681SAndroid Build Coastguard Worker      let Rd = R2.Num;
697*9880d681SAndroid Build Coastguard Worker      let F = 0;
698*9880d681SAndroid Build Coastguard Worker      let JJJJJ = 0;
699*9880d681SAndroid Build Coastguard Worker      let DDDI = 0;
700*9880d681SAndroid Build Coastguard Worker    }
701*9880d681SAndroid Build Coastguard Worker  }
702*9880d681SAndroid Build Coastguard Worker}
703*9880d681SAndroid Build Coastguard Worker
704*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
705*9880d681SAndroid Build Coastguard Worker// Condition/SF instructions
706*9880d681SAndroid Build Coastguard Worker// -------------------------------------------------- //
707*9880d681SAndroid Build Coastguard Worker
708*9880d681SAndroid Build Coastguard Worker// Instructions to set flags used in lowering comparisons.
709*9880d681SAndroid Build Coastguard Workermulticlass SF<bits<3> op2Val, string AsmStr> {
710*9880d681SAndroid Build Coastguard Worker  let F = 1, Rd = R0.Num, JJJJJ = 0, Defs = [SR], DDDI = 0 in
711*9880d681SAndroid Build Coastguard Worker    def _RR : InstRR<op2Val, (outs), (ins GPR:$Rs1, GPR:$Rs2),
712*9880d681SAndroid Build Coastguard Worker                     !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
713*9880d681SAndroid Build Coastguard Worker                     [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
714*9880d681SAndroid Build Coastguard Worker  let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
715*9880d681SAndroid Build Coastguard Worker    def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
716*9880d681SAndroid Build Coastguard Worker                     !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
717*9880d681SAndroid Build Coastguard Worker                     [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
718*9880d681SAndroid Build Coastguard Worker  let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in
719*9880d681SAndroid Build Coastguard Worker    def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16),
720*9880d681SAndroid Build Coastguard Worker                     !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
721*9880d681SAndroid Build Coastguard Worker                     [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>;
722*9880d681SAndroid Build Coastguard Worker}
723*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, isCompare = 1 in {
724*9880d681SAndroid Build Coastguard Worker  defm SFSUB_F : SF<0b010, "sub.f">;
725*9880d681SAndroid Build Coastguard Worker}
726*9880d681SAndroid Build Coastguard Worker
727*9880d681SAndroid Build Coastguard Worker// Jump and link
728*9880d681SAndroid Build Coastguard Workerlet isCall = 1, hasDelaySlot = 1, isCodeGenOnly = 1, Uses = [SP],
729*9880d681SAndroid Build Coastguard Worker    Defs = [RCA] in {
730*9880d681SAndroid Build Coastguard Worker  def CALL : Pseudo<(outs), (ins CallTarget:$addr), "", []>;
731*9880d681SAndroid Build Coastguard Worker  def CALLR : Pseudo<(outs), (ins GPR:$Rs1), "", [(Call GPR:$Rs1)]>;
732*9880d681SAndroid Build Coastguard Worker}
733*9880d681SAndroid Build Coastguard Worker
734*9880d681SAndroid Build Coastguard Workerlet isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
735*9880d681SAndroid Build Coastguard Worker    Uses = [RCA] in {
736*9880d681SAndroid Build Coastguard Worker  def RET : InstRM<0b0, (outs), (ins),
737*9880d681SAndroid Build Coastguard Worker                   "ld\t-4[%fp], %pc ! return",
738*9880d681SAndroid Build Coastguard Worker                   [(RetFlag)]> {
739*9880d681SAndroid Build Coastguard Worker    let Rd = PC.Num;
740*9880d681SAndroid Build Coastguard Worker    let Rs1 = FP.Num;
741*9880d681SAndroid Build Coastguard Worker    let P = 1;
742*9880d681SAndroid Build Coastguard Worker    let Q = 0;
743*9880d681SAndroid Build Coastguard Worker    let imm16 = -4;
744*9880d681SAndroid Build Coastguard Worker
745*9880d681SAndroid Build Coastguard Worker    // Post encoding is not needed for RET.
746*9880d681SAndroid Build Coastguard Worker    let PostEncoderMethod = "";
747*9880d681SAndroid Build Coastguard Worker  }
748*9880d681SAndroid Build Coastguard Worker}
749*9880d681SAndroid Build Coastguard Worker
750*9880d681SAndroid Build Coastguard Worker// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
751*9880d681SAndroid Build Coastguard Worker// a stack adjustment and the codegen must know that they may modify the stack
752*9880d681SAndroid Build Coastguard Worker// pointer before prolog-epilog rewriting occurs.
753*9880d681SAndroid Build Coastguard Worker// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
754*9880d681SAndroid Build Coastguard Worker// sub / add which can clobber SP.
755*9880d681SAndroid Build Coastguard Workerlet Defs = [SP], Uses = [SP] in {
756*9880d681SAndroid Build Coastguard Worker  def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
757*9880d681SAndroid Build Coastguard Worker                                "#ADJCALLSTACKDOWN $amt",
758*9880d681SAndroid Build Coastguard Worker                                [(CallSeqStart timm:$amt)]>;
759*9880d681SAndroid Build Coastguard Worker  def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
760*9880d681SAndroid Build Coastguard Worker                                "#ADJCALLSTACKUP $amt1 $amt2",
761*9880d681SAndroid Build Coastguard Worker                                [(CallSeqEnd timm:$amt1, timm:$amt2)]>;
762*9880d681SAndroid Build Coastguard Worker}
763*9880d681SAndroid Build Coastguard Worker
764*9880d681SAndroid Build Coastguard Workerlet Defs = [SP], Uses = [SP] in {
765*9880d681SAndroid Build Coastguard Worker  def ADJDYNALLOC : Pseudo<(outs GPR:$dst), (ins GPR:$src),
766*9880d681SAndroid Build Coastguard Worker                           "#ADJDYNALLOC $dst $src",
767*9880d681SAndroid Build Coastguard Worker                           [(set GPR:$dst, (LanaiAdjDynAlloc GPR:$src))]>;
768*9880d681SAndroid Build Coastguard Worker}
769*9880d681SAndroid Build Coastguard Worker
770*9880d681SAndroid Build Coastguard Workerlet Uses = [SR] in {
771*9880d681SAndroid Build Coastguard Worker  def SCC : InstSCC<(outs GPR:$Rs1), (ins CCOp:$DDDI),
772*9880d681SAndroid Build Coastguard Worker                    "s$DDDI\t$Rs1",
773*9880d681SAndroid Build Coastguard Worker                    [(set (i32 GPR:$Rs1), (LanaiSetCC imm:$DDDI))]>;
774*9880d681SAndroid Build Coastguard Worker}
775*9880d681SAndroid Build Coastguard Worker
776*9880d681SAndroid Build Coastguard Worker// SCC's output is already 1-bit so and'ing with 1 is redundant.
777*9880d681SAndroid Build Coastguard Workerdef : Pat<(and (LanaiSetCC imm:$DDDI), 1), (SCC imm:$DDDI)>;
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker// Select with hardware support
780*9880d681SAndroid Build Coastguard Workerlet Uses = [SR], isSelect = 1 in {
781*9880d681SAndroid Build Coastguard Worker  def SELECT : InstRR<0b111, (outs GPR:$Rd),
782*9880d681SAndroid Build Coastguard Worker                      (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
783*9880d681SAndroid Build Coastguard Worker                      "sel.$DDDI $Rs1, $Rs2, $Rd",
784*9880d681SAndroid Build Coastguard Worker                      [(set (i32 GPR:$Rd),
785*9880d681SAndroid Build Coastguard Worker                       (LanaiSelectCC (i32 GPR:$Rs1), (i32 GPR:$Rs2),
786*9880d681SAndroid Build Coastguard Worker                                      (imm:$DDDI)))]> {
787*9880d681SAndroid Build Coastguard Worker    let JJJJJ = 0;
788*9880d681SAndroid Build Coastguard Worker    let F = 0;
789*9880d681SAndroid Build Coastguard Worker  }
790*9880d681SAndroid Build Coastguard Worker}
791*9880d681SAndroid Build Coastguard Worker
792*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1,
793*9880d681SAndroid Build Coastguard Worker    isIndirectBranch = 1, Uses = [SR] in {
794*9880d681SAndroid Build Coastguard Worker  def BRIND_CC : InstRR<0b101, (outs), (ins GPR:$Rs1, CCOp:$DDDI),
795*9880d681SAndroid Build Coastguard Worker                        "b$DDDI\t$Rs1", []> {
796*9880d681SAndroid Build Coastguard Worker    let F = 0;
797*9880d681SAndroid Build Coastguard Worker    let JJJJJ = 0;
798*9880d681SAndroid Build Coastguard Worker    let Rd = PC.Num;
799*9880d681SAndroid Build Coastguard Worker    let Rs2 = R0.Num;
800*9880d681SAndroid Build Coastguard Worker  }
801*9880d681SAndroid Build Coastguard Worker
802*9880d681SAndroid Build Coastguard Worker  def BRIND_CCA : InstRR<0b101, (outs), (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
803*9880d681SAndroid Build Coastguard Worker                         "b${DDDI}\t$Rs1 add $Rs2", []> {
804*9880d681SAndroid Build Coastguard Worker    let F = 0;
805*9880d681SAndroid Build Coastguard Worker    let Rd = PC.Num;
806*9880d681SAndroid Build Coastguard Worker    let JJJJJ = 0;
807*9880d681SAndroid Build Coastguard Worker  }
808*9880d681SAndroid Build Coastguard Worker}
809*9880d681SAndroid Build Coastguard Worker
810*9880d681SAndroid Build Coastguard Worker// TODO: This only considers the case where BROFF is an immediate and not where
811*9880d681SAndroid Build Coastguard Worker// it is a register. Add support for register relative branching.
812*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, Rs1 = 0,
813*9880d681SAndroid Build Coastguard Worker    Uses = [SR] in
814*9880d681SAndroid Build Coastguard Worker  def BRR : InstBRR<(outs), (ins i16imm:$imm16, CCOp:$DDDI),
815*9880d681SAndroid Build Coastguard Worker                    "b${DDDI}.r\t$imm16", []>;
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Workerlet F = 0 in {
818*9880d681SAndroid Build Coastguard Worker// Population Count (POPC)
819*9880d681SAndroid Build Coastguard Workerdef POPC: InstSpecial<0b001, (outs GPR:$Rd), (ins GPR:$Rs1),
820*9880d681SAndroid Build Coastguard Worker                      "popc\t$Rs1, $Rd",
821*9880d681SAndroid Build Coastguard Worker                      [(set GPR:$Rd, (ctpop GPR:$Rs1))]>;
822*9880d681SAndroid Build Coastguard Worker
823*9880d681SAndroid Build Coastguard Worker// Count Leading Zeros (LEADZ)
824*9880d681SAndroid Build Coastguard Workerdef LEADZ: InstSpecial<0b010, (outs GPR:$Rd), (ins GPR:$Rs1),
825*9880d681SAndroid Build Coastguard Worker                       "leadz\t$Rs1, $Rd", [(set GPR:$Rd, (ctlz GPR:$Rs1))]>;
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker// Count Trailing Zeros (TRAILZ)
828*9880d681SAndroid Build Coastguard Workerdef TRAILZ : InstSpecial<0b011, (outs GPR:$Rd), (ins GPR:$Rs1),
829*9880d681SAndroid Build Coastguard Worker                         "trailz\t$Rs1, $Rd",
830*9880d681SAndroid Build Coastguard Worker                         [(set GPR:$Rd, (cttz GPR:$Rs1))]>;
831*9880d681SAndroid Build Coastguard Worker}
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
834*9880d681SAndroid Build Coastguard Worker// Non-Instruction Patterns
835*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
836*9880d681SAndroid Build Coastguard Worker
837*9880d681SAndroid Build Coastguard Worker// i32 0 and R0 can be used interchangeably.
838*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 0), (i32 R0)>;
839*9880d681SAndroid Build Coastguard Worker// i32 -1 and R1 can be used interchangeably.
840*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 -1), (i32 R1)>;
841*9880d681SAndroid Build Coastguard Worker
842*9880d681SAndroid Build Coastguard Worker// unsigned 16-bit immediate
843*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 i32lo16z:$imm), (OR_I_LO (i32 R0), imm:$imm)>;
844*9880d681SAndroid Build Coastguard Worker
845*9880d681SAndroid Build Coastguard Worker// arbitrary immediate
846*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 imm:$imm), (OR_I_LO (MOVHI (HI16 imm:$imm)), (LO16 imm:$imm))>;
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker// Calls
849*9880d681SAndroid Build Coastguard Workerdef : Pat<(Call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
850*9880d681SAndroid Build Coastguard Workerdef : Pat<(Call texternalsym:$dst), (CALL texternalsym:$dst)>;
851*9880d681SAndroid Build Coastguard Worker
852*9880d681SAndroid Build Coastguard Worker// Loads
853*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
854*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi16 ADDRspls:$src), (i32 (LDHz_RI ADDRspls:$src))>;
855*9880d681SAndroid Build Coastguard Worker
856*9880d681SAndroid Build Coastguard Worker// GlobalAddress, ExternalSymbol, Jumptable, ConstantPool
857*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiHi tglobaladdr:$dst), (MOVHI tglobaladdr:$dst)>;
858*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiLo tglobaladdr:$dst), (OR_I_LO (i32 R0), tglobaladdr:$dst)>;
859*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSmall tglobaladdr:$dst), (SLI tglobaladdr:$dst)>;
860*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiHi texternalsym:$dst), (MOVHI texternalsym:$dst)>;
861*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiLo texternalsym:$dst), (OR_I_LO (i32 R0), texternalsym:$dst)>;
862*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSmall texternalsym:$dst), (SLI texternalsym:$dst)>;
863*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiHi tblockaddress:$dst), (MOVHI tblockaddress:$dst)>;
864*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiLo tblockaddress:$dst), (OR_I_LO (i32 R0), tblockaddress:$dst)>;
865*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSmall tblockaddress:$dst), (SLI tblockaddress:$dst)>;
866*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiHi tjumptable:$dst), (MOVHI tjumptable:$dst)>;
867*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiLo tjumptable:$dst), (OR_I_LO (i32 R0), tjumptable:$dst)>;
868*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSmall tjumptable:$dst), (SLI tjumptable:$dst)>;
869*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiHi tconstpool:$dst), (MOVHI tconstpool:$dst)>;
870*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiLo tconstpool:$dst), (OR_I_LO (i32 R0), tconstpool:$dst)>;
871*9880d681SAndroid Build Coastguard Workerdef : Pat<(LanaiSmall tconstpool:$dst), (SLI tconstpool:$dst)>;
872*9880d681SAndroid Build Coastguard Worker
873*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GPR:$hi, (LanaiLo tglobaladdr:$lo)),
874*9880d681SAndroid Build Coastguard Worker          (OR_I_LO GPR:$hi, tglobaladdr:$lo)>;
875*9880d681SAndroid Build Coastguard Workerdef : Pat<(or R0, (LanaiSmall tglobaladdr:$small)),
876*9880d681SAndroid Build Coastguard Worker          (SLI tglobaladdr:$small)>;
877*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GPR:$hi, (LanaiLo texternalsym:$lo)),
878*9880d681SAndroid Build Coastguard Worker          (OR_I_LO GPR:$hi, texternalsym:$lo)>;
879*9880d681SAndroid Build Coastguard Workerdef : Pat<(or R0, (LanaiSmall texternalsym:$small)),
880*9880d681SAndroid Build Coastguard Worker          (SLI texternalsym:$small)>;
881*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GPR:$hi, (LanaiLo tblockaddress:$lo)),
882*9880d681SAndroid Build Coastguard Worker          (OR_I_LO GPR:$hi, tblockaddress:$lo)>;
883*9880d681SAndroid Build Coastguard Workerdef : Pat<(or R0, (LanaiSmall tblockaddress:$small)),
884*9880d681SAndroid Build Coastguard Worker          (SLI tblockaddress:$small)>;
885*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GPR:$hi, (LanaiLo tjumptable:$lo)),
886*9880d681SAndroid Build Coastguard Worker          (OR_I_LO GPR:$hi, tjumptable:$lo)>;
887*9880d681SAndroid Build Coastguard Workerdef : Pat<(or R0, (LanaiSmall tjumptable:$small)),
888*9880d681SAndroid Build Coastguard Worker          (SLI tjumptable:$small)>;
889*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GPR:$hi, (LanaiLo tconstpool:$lo)),
890*9880d681SAndroid Build Coastguard Worker          (OR_I_LO GPR:$hi, tconstpool:$lo)>;
891*9880d681SAndroid Build Coastguard Workerdef : Pat<(or R0, (LanaiSmall tconstpool:$small)),
892*9880d681SAndroid Build Coastguard Worker          (SLI tconstpool:$small)>;
893