1//===- LanaiInstrFormats.td - Lanai Instruction Formats ----*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10class InstLanai<dag outs, dag ins, string asmstr, list<dag> pattern>
11    : Instruction {
12  field bits<32> Inst;
13  field bits<32> SoftFail = 0;
14  let Size = 4;
15
16  let Namespace = "Lanai";
17  let DecoderNamespace = "Lanai";
18
19  bits<4> Opcode;
20  let Inst{31 - 28} = Opcode;
21
22  dag OutOperandList = outs;
23  dag InOperandList = ins;
24  let AsmString = asmstr;
25  let Pattern = pattern;
26}
27
28//------------------------------------------------------------------------------
29// Register Immediate (RI)
30//------------------------------------------------------------------------------
31// Encoding:
32//           -----------------------------------------------------------------
33//           |0.A.A.A| . . . . | . . . . |F.H| . . . . . . . . . . . . . . . |
34//           -----------------------------------------------------------------
35//            opcode     Rd        Rs1                constant (16)
36//
37// Action:
38//           Rd <- Rs1 op constant
39//
40// Except for shift instructions, `H' determines whether the constant
41// is in the high (1) or low (0) word.  The other halfword is 0x0000,
42// except for the `AND' instruction (`AAA' = 100), for which the other
43// halfword is 0xFFFF, and shifts (`AAA' = 111), for which the constant is
44// sign extended.
45//
46// `F' determines whether the instruction modifies (1) or does not
47// modify (0) the program flags.
48//
49// `AAA' specifies the operation: `add' (000), `addc' (001), `sub'
50// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or `shift'
51// (111).  For the shift, `H' specifies a logical (0) or arithmetic (1)
52// shift.  The amount and direction of the shift are determined by the
53// sign extended constant interpreted as a two's complement number.  The
54// shift operation is defined only for the range of:
55//      31 ... 0 -1 ... -31
56//      \      / \        /
57//        left     right
58//        shift    shift
59//
60// If and only if the `F' bit is 1, RI instructions modify the
61// condition bits, `Z' (Zero), `N' (Negative), `V' (oVerflow), and `C'
62// (Carry), according to the result.  If the flags are updated, they are
63// updated as follows:
64// `Z'
65//      is set if the result is zero and cleared otherwise.
66//
67// `N'
68//      is set to the most significant bit of the result.
69//
70// `V'
71//      For arithmetic instructions (`add', `addc', `sub', `subb') `V' is
72//      set if the sign (most significant) bits of the input operands are
73//      the same but different from the sign bit of the result and cleared
74//      otherwise.  For other RI instructions, `V' is cleared.
75//
76// `C'
77//      For arithmetic instructions, `C' is set/cleared if there is/is_not
78//      a carry generated out of the most significant when performing the
79//      twos-complement addition (`sub(a,b) == a + ~b + 1', `subb(a,b) ==
80//      a + ~b + `C'').  For left shifts, `C' is set to the least
81//      significant bit discarded by the shift operation.  For all other
82//      operations, `C' is cleared.
83//
84// A Jump is accomplished by `Rd' being `pc', and it has one shadow.
85//
86// The all-0s word is the instruction `R0 <- R0 + 0', which is a no-op.
87class InstRI<bits<3> op, dag outs, dag ins, string asmstr,
88             list<dag> pattern>
89    : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> {
90  let Itinerary = IIC_ALU;
91  bits<5> Rd;
92  bits<5> Rs1;
93  bit F;
94  bit H;
95  bits<16> imm16;
96
97  let Opcode{3} = 0;
98  let Opcode{2 - 0} = op;
99  let Inst{27 - 23} = Rd;
100  let Inst{22 - 18} = Rs1;
101  let Inst{17} = F;
102  let Inst{16} = H;
103  let Inst{15 - 0} = imm16;
104}
105
106//------------------------------------------------------------------------------
107// Register Register (RR)
108//------------------------------------------------------------------------------
109// Encoding:
110//           -----------------------------------------------------------------
111//           |1.1.0.0| . . . . | . . . . |F.I| . . . . |B.B.B|J.J.J.J.J|D.D.D|
112//           -----------------------------------------------------------------
113//            opcode     Rd        Rs1           Rs2   \       operation     /
114//
115// Action:
116//           `Rd <- Rs1 op Rs2' iff condition DDDI is true.
117//
118// `DDDI' is as described for the BR instruction.
119//
120// `F' determines whether the instruction modifies (1) or does not
121// modify (0) the program flags.
122//
123// `BBB' determines the operation: `add' (000), `addc' (001), `sub'
124// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or "special"
125// (111).  The `JJJJJ' field is irrelevant except for special.
126//
127// `JJJJJ' determines which special operation is performed.  `10---'
128// is a logical shift, and `11---' is an arithmetic shift, and ‘00000` is
129// the SELECT operation.  The amount and direction of the shift are
130// determined by the contents of `Rs2' interpreted as a two's complement
131// number (in the same way as shifts in the Register-Immediate
132// instructions in *Note RI::).  For the SELECT operation, Rd gets Rs1 if
133// condition DDDI is true, Rs2 otherwise. All other `JJJJJ' combinations
134// are reserved for instructions that may be defined in the future.
135//
136// If the `F' bit is 1, RR instructions modify the condition bits, `Z'
137// (Zero), `N' (Negative), `V' (oVerflow), and `C' (Carry), according to
138// the result.  All RR instructions modify the `Z', `N', and `V' flags.
139// Except for arithmetic instructions (`add', `addc', `sub', `subb'), `V'
140// is cleared.  Only arithmetic instructions and shifts modify `C'. Right
141// shifts clear C.
142//
143// DDDI is as described in the table for the BR instruction and only used for
144// the select instruction.
145//
146// A Jump is accomplished by `Rd' being `pc', and it has one shadow.
147class InstRR<bits<3> op, dag outs, dag ins, string asmstr,
148             list<dag> pattern>
149    : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> {
150  let Itinerary = IIC_ALU;
151  bits<5> Rd;
152  bits<5> Rs1;
153  bits<5> Rs2;
154  bit F;
155  bits<4> DDDI;
156  bits<5> JJJJJ;
157
158  let Opcode = 0b1100;
159  let Inst{27 - 23} = Rd;
160  let Inst{22 - 18} = Rs1;
161  let Inst{17} = F;
162  let Inst{16} = DDDI{0};
163  let Inst{15 - 11} = Rs2;
164  let Inst{10 - 8} = op;
165  let Inst{7 - 3} = JJJJJ;
166  let Inst{2 - 0} = DDDI{3 - 1};
167}
168
169//------------------------------------------------------------------------------
170// Register Memory (RM)
171//------------------------------------------------------------------------------
172// Encoding:
173//          -----------------------------------------------------------------
174//          |1.0.0.S| . . . . | . . . . |P.Q| . . . . . . . . . . . . . . . |
175//          -----------------------------------------------------------------
176//           opcode     Rd        Rs1                 constant (16)
177//
178// Action:
179//        Rd <- Memory(ea)      (Load)    see below for the
180//        Memory(ea) <- Rd      (Store)   definition of ea.
181//
182// `S' determines whether the instruction is a Load (0) or a Store (1).
183// Loads appear in Rd one cycle after this instruction executes.  If the
184// following instruction reads Rd, that instruction will be delayed by 1
185// clock cycle.
186//
187//   PQ      operation
188//   --      ------------------------------------------
189//   00      ea = Rs1
190//   01      ea = Rs1,             Rs1 <- Rs1 + constant
191//   10      ea = Rs1 + constant
192//   11      ea = Rs1 + constant,  Rs1 <- Rs1 + constant
193//
194// The constant is sign-extended for this instruction.
195//
196// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots.
197class InstRM<bit S, dag outs, dag ins, string asmstr, list<dag> pattern>
198    : InstLanai<outs, ins, asmstr, pattern> {
199  bits<5> Rd;
200  bits<5> Rs1;
201  bit P;
202  bit Q;
203  bits<16> imm16;
204  // Dummy variables to allow multiclass definition of RM and RRM
205  bits<2> YL;
206  bit E;
207
208  let Opcode{3 - 1} = 0b100;
209  let Opcode{0} = S;
210  let Inst{27 - 23} = Rd;
211  let Inst{22 - 18} = Rs1;
212  let Inst{17} = P;
213  let Inst{16} = Q;
214  let Inst{15 - 0} = imm16;
215
216  let PostEncoderMethod = "adjustPqBitsRmAndRrm";
217}
218
219//------------------------------------------------------------------------------
220// Register Register Memory (RRM)
221//------------------------------------------------------------------------------
222// Encoding:
223//           -----------------------------------------------------------------
224//           |1.0.1.S| . . . . | . . . . |P.Q| . . . . |B.B.B|J.J.J.J.J|Y.L.E|
225//           -----------------------------------------------------------------
226//            opcode     Rd        Rs1           Rs2   \       operation     /
227//
228// Action:
229//           Rd <- Memory(ea)      (Load)    see below for the
230//           Memory(ea) <- Rd      (Store)   definition of ea.
231//
232// The RRM instruction is identical to the RM (*note RM::.) instruction
233// except that:
234//
235// 1. `Rs1 + constant' is replaced with `Rs1 op Rs2', where `op' is
236//    determined in the same way as in the RR instruction (*note RR::.)
237//    and
238//
239// 2. part-word memory accesses are allowed as specified below.
240//
241//    If `BBB' != 111 (i.e.: For all but shift operations):
242//        If `YLE' = 01- => fuLl-word memory access
243//        If `YLE' = 00- => half-word memory access
244//        If `YLE' = 10- => bYte memory access
245//        If `YLE' = --1 => loads are zEro extended
246//        If `YLE' = --0 => loads are sign extended
247//
248//    If `BBB' = 111 (For shift operations):
249//        fullword memory access are performed.
250//
251// All part-word loads write the least significant part of the
252// destination register with the higher-order bits zero- or sign-extended.
253// All part-word stores store the least significant part-word of the
254// source register in the destination memory location.
255//
256// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots.
257class InstRRM<bit S, dag outs, dag ins, string asmstr,
258              list<dag> pattern>
259    : InstLanai<outs, ins, asmstr, pattern> {
260  bits<5> Rd;
261  bits<5> Rs1;
262  bits<5> Rs2;
263  bit P;
264  bit Q;
265  bits<3> BBB;
266  bits<5> JJJJJ;
267  bits<2> YL;
268  bit E;
269
270  let Opcode{3 - 1} = 0b101;
271  let Opcode{0} = S;
272  let Inst{27 - 23} = Rd;
273  let Inst{22 - 18} = Rs1;
274  let Inst{17} = P;
275  let Inst{16} = Q;
276  let Inst{15 - 11} = Rs2;
277  let Inst{10 - 8} = BBB;
278  let Inst{7 - 3} = JJJJJ;
279  let Inst{2 - 1} = YL;
280  let Inst{0} = E;
281
282  let PostEncoderMethod = "adjustPqBitsRmAndRrm";
283}
284
285//------------------------------------------------------------------------------
286// Conditional Branch (BR)
287//------------------------------------------------------------------------------
288// Encoding:
289//           -----------------------------------------------------------------
290//           |1.1.1.0|D.D.D| . . . . . . . . . . . . . . . . . . . . . . |0.I|
291//           -----------------------------------------------------------------
292//            opcode condition                   constant (23)
293//
294// Action:
295//            if (condition) { `pc' <- 4*(zero-extended constant) }
296//
297// The BR instruction is an absolute branch.
298// The constant is scaled as shown by its position in the instruction word such
299// that it specifies word-aligned addresses in the range [0,2^25-4]
300//
301// The `DDDI' field selects the condition that causes the branch to be taken.
302// (the `I' (Invert sense) bit inverts the sense of the condition):
303//
304//   DDDI  logical function                        [code, used for...]
305//   ----  --------------------------------------  ------------------------
306//   0000  1                                       [T, true]
307//   0001  0                                       [F, false]
308//   0010  C AND Z'                                [HI, high]
309//   0011  C' OR Z                                 [LS, low or same]
310//   0100  C'                                      [CC, carry cleared]
311//   0101  C                                       [CS, carry set]
312//   0110  Z'                                      [NE, not equal]
313//   0111  Z                                       [EQ, equal]
314//   1000  V'                                      [VC, oVerflow cleared]
315//   1001  V                                       [VS, oVerflow set]
316//   1010  N'                                      [PL, plus]
317//   1011  N                                       [MI, minus]
318//   1100  (N AND V) OR (N' AND V')                [GE, greater than or equal]
319//   1101  (N AND V') OR (N' AND V)                [LT, less than]
320//   1110  (N AND V AND Z') OR (N' AND V' AND Z')  [GT, greater than]
321//   1111  (Z) OR (N AND V') OR (N' AND V)         [LE, less than or equal]
322//
323// If the branch is not taken, the BR instruction is a no-op.  If the branch is
324// taken, the processor starts executing instructions at the branch target
325// address *after* the processor has executed one more instruction.  That is,
326// the branch has one “branch delay slot”.  Be very careful if you find yourself
327// wanting to put a branch in a branch delays slot!
328class InstBR<dag outs, dag ins, string asmstr, list<dag> pattern>
329    : InstLanai<outs, ins, asmstr, pattern> {
330  let Itinerary = IIC_ALU;
331  bits<25> addr;
332  bits<4> DDDI;
333
334  let Opcode = 0b1110;
335  let Inst{27 - 25} = DDDI{3 - 1};
336  let Inst{24 - 0} = addr;
337  // These instructions overwrite the last two address bits (which are assumed
338  // and ensured to be 0).
339  let Inst{1} = 0;
340  let Inst{0} = DDDI{0};
341}
342
343//------------------------------------------------------------------------------
344// Conditional Branch Relative (BRR)
345//------------------------------------------------------------------------------
346// Encoding:
347//           -----------------------------------------------------------------
348//           |1.1.1.0|D.D.D|1|-| . . . . |-.-| . . . . . . . . . . . . . |1.I|
349//           -----------------------------------------------------------------
350//            opcode condition     Rs1           constant (14)
351// Action:
352//           if (condition) { ‘pc’ <- Rs1 + 4*sign-extended constant) }
353//
354// BRR behaves like BR, except the branch target address is a 16-bit PC relative
355// offset.
356class InstBRR<dag outs, dag ins, string asmstr, list<dag> pattern>
357    : InstLanai<outs, ins, asmstr, pattern> {
358  bits<4> DDDI;
359  bits<5> Rs1;
360  bits<16> imm16;
361
362  let Opcode = 0b1110;
363  let Inst{27 - 25} = DDDI{3 - 1};
364  let Inst{24} = 1;
365  let Inst{22 - 18} = Rs1;
366  let Inst{17 - 16} = 0;
367  let Inst{15 - 0} = imm16;
368  // Overwrite last two bits which have to be zero
369  let Inst{1} = 1;
370  let Inst{0} = DDDI{0};
371
372  // Set don't cares to zero
373  let Inst{23} = 0;
374}
375
376//------------------------------------------------------------------------------
377// Conditional Set (SCC)
378//------------------------------------------------------------------------------
379// Encoding:
380//           -----------------------------------------------------------------
381//           |1.1.1.0|D.D.D|0.-| . . . . |-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-|1.I|
382//           -----------------------------------------------------------------
383//            opcode condition     Rs1
384//
385// Action:
386//       Rs1 <- logical function result
387//
388// SCC sets dst_reg to the boolean result of computing the logical function
389// specified by DDDI, as described in the table for the BR instruction.
390class InstSCC<dag outs, dag ins, string asmstr,
391              list<dag> pattern>
392    : InstLanai<outs, ins, asmstr, pattern> {
393  let Itinerary = IIC_ALU;
394  bits<5> Rs1; // dst_reg in documentation
395  bits<4> DDDI;
396
397  let Opcode = 0b1110;
398  let Inst{27 - 25} = DDDI{3 - 1};
399  let Inst{24} = 0;
400  let Inst{22 - 18} = Rs1;
401  let Inst{1} = 1;
402  let Inst{0} = DDDI{0};
403
404  // Set don't cares to zero
405  let Inst{23} = 0;
406  let Inst{17 - 2} = 0;
407}
408
409//------------------------------------------------------------------------------
410// Special Load/Store (SLS)
411//------------------------------------------------------------------------------
412//
413// Encoding:
414//           -----------------------------------------------------------------
415//           |1.1.1.1| . . . . | . . . . |0.S| . . . . . . . . . . . . . . . |
416//           -----------------------------------------------------------------
417//            opcode     Rd    addr 5msb's            address 16 lsb's
418//
419// Action:
420//           If S = 0 (LOAD):   Rd <- Memory(address);
421//           If S = 1 (STORE):  Memory(address) <- Rd
422//
423// The timing is the same as for RM (*note RM::.) and RRM (*note
424// RRM::.) instructions.  The two low-order bits of the 21-bit address are
425// ignored.  The address is zero extended.  Fullword memory accesses are
426// performed.
427class InstSLS<bit S, dag outs, dag ins, string asmstr, list<dag> pattern>
428    : InstLanai<outs, ins, asmstr, pattern> {
429  bits<5> Rd;
430  bits<5> msb;
431  bits<16> lsb;
432
433  let Opcode = 0b1111;
434  let Inst{27 - 23} = Rd;
435  let Inst{22 - 18} = msb;
436  let Inst{17} = 0;
437  let Inst{16} = S;
438  let Inst{15 - 0} = lsb;
439}
440
441//------------------------------------------------------------------------------
442// Special Load Immediate (SLI)
443//------------------------------------------------------------------------------
444// Encoding:
445//           -----------------------------------------------------------------
446//           |1.1.1.1| . . . . | . . . . |1.0| . . . . . . . . . . . . . . . |
447//           -----------------------------------------------------------------
448//            opcode     Rd    const 5msb's          constant 16 lsb's
449//
450// Action:
451//           Rd <- constant
452//
453// The 21-bit constant is zero-extended.  The timing is the same as the
454// RM instruction (*note RM::.).
455class InstSLI<dag outs, dag ins, string asmstr, list<dag> pattern>
456    : InstLanai<outs, ins, asmstr, pattern> {
457  bits<5> Rd;
458  bits<5> msb;
459  bits<16> lsb;
460
461  let Opcode = 0b1111;
462  let Inst{27 - 23} = Rd;
463  let Inst{22 - 18} = msb;
464  let Inst{17} = 1;
465  let Inst{16} = 0;
466  let Inst{15 - 0} = lsb;
467}
468
469//------------------------------------------------------------------------------
470// Special Part-Word Load/Store (SPLS)
471//------------------------------------------------------------------------------
472// Encoding:
473//        -----------------------------------------------------------------
474//        |1.1.1.1| . . . . | . . . . |1.1.0.Y.S.E.P.Q| . . . . . . . . . |
475//        -----------------------------------------------------------------
476//         opcode     Rd        Rs1                       constant (10)
477//
478// Action:
479//        If `YS' = 11  (bYte     Store):
480//             Memory(ea) <- (least significant byte of Rr)
481//        If `YS' = 01  (halfword Store):
482//             Memory(ea) <- (least significant half-word of Rr)
483//        If `YS' = 10  (bYte     load):  Rr <- Memory(ea)
484//        If `YS' = 00  (halfword load):  Rr <- Memory(ea)
485//             [Note: here ea is determined as in the the RM instruction. ]
486//        If `SE' = 01 then the value is zEro extended
487//             before being loaded into Rd.
488//        If `SE' = 00 then the value is sign extended
489//             before being loaded into Rd.
490//
491// `P' and `Q' are used to determine `ea' as in the RM instruction. The
492// constant is sign extended.  The timing is the same as the RM and RRM
493// instructions.  *Note RM:: and *Note RRM::.
494//
495// All part-word loads write the part-word into the least significant
496// part of the destination register, with the higher-order bits zero- or
497// sign-extended.  All part-word stores store the least significant
498// part-word of the source register into the destination memory location.
499class InstSPLS<dag outs, dag ins, string asmstr,
500               list<dag> pattern>
501    : InstLanai<outs, ins, asmstr, pattern> {
502  bits<5> Rd;
503  bits<5> Rs1;
504  bits<5> msb;
505  bit Y;
506  bit S;
507  bit E;
508  bit P;
509  bit Q;
510  bits<10> imm10;
511
512  let Opcode = 0b1111;
513  let Inst{27 - 23} = Rd;
514  let Inst{22 - 18} = Rs1;
515  let Inst{17 - 15} = 0b110;
516  let Inst{14} = Y;
517  let Inst{13} = S;
518  let Inst{12} = E;
519  let Inst{11} = P;
520  let Inst{10} = Q;
521  let Inst{9 - 0} = imm10;
522
523  let PostEncoderMethod = "adjustPqBitsSpls";
524}
525
526//------------------------------------------------------------------------------
527// Special instructions (popc, leadz, trailz)
528//------------------------------------------------------------------------------
529// Encoding:
530//         -----------------------------------------------------------------
531//         |1.1.0.1|    Rd   |   Rs1   |F.-| . . . . | . . | . . . . | OP  |
532//         -----------------------------------------------------------------
533//          opcode      Rd       Rs1
534// Action:
535//         Rd <- Perform action encoded in OP on Rs1
536//   OP is one of:
537//      0b001 POPC   Population count;
538//      0b010 LEADZ  Count number of leading zeros;
539//      0b011 TRAILZ Count number of trailing zeros;
540class InstSpecial<bits<3> op, dag outs, dag ins, string asmstr,
541                  list<dag> pattern> : InstLanai<outs, ins, asmstr,
542                  pattern>, Sched<[WriteALU]> {
543  let Itinerary = IIC_ALU;
544  bit F;
545  bits<5> Rd;
546  bits<5> Rs1;
547
548  let Opcode = 0b1101;
549  let Inst{27 - 23} = Rd;
550  let Inst{22 - 18} = Rs1;
551  let Inst{17} = F;
552  let Inst{16 - 3} = 0;
553  let Inst{2 - 0} = op;
554}
555
556// Pseudo instructions
557class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
558    : InstLanai<outs, ins, asmstr, pattern> {
559  let Inst{15 - 0} = 0;
560  let isPseudo = 1;
561}
562