diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Lanai/LanaiInstrFormats.td')
-rw-r--r-- | contrib/llvm/lib/Target/Lanai/LanaiInstrFormats.td | 561 |
1 files changed, 561 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Lanai/LanaiInstrFormats.td b/contrib/llvm/lib/Target/Lanai/LanaiInstrFormats.td new file mode 100644 index 000000000000..30289ea4ac0b --- /dev/null +++ b/contrib/llvm/lib/Target/Lanai/LanaiInstrFormats.td @@ -0,0 +1,561 @@ +//===- LanaiInstrFormats.td - Lanai Instruction Formats ----*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class InstLanai<dag outs, dag ins, string asmstr, list<dag> pattern> + : Instruction { + field bits<32> Inst; + field bits<32> SoftFail = 0; + let Size = 4; + + let Namespace = "Lanai"; + let DecoderNamespace = "Lanai"; + + bits<4> Opcode; + let Inst{31 - 28} = Opcode; + + dag OutOperandList = outs; + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; +} + +//------------------------------------------------------------------------------ +// Register Immediate (RI) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |0.A.A.A| . . . . | . . . . |F.H| . . . . . . . . . . . . . . . | +// ----------------------------------------------------------------- +// opcode Rd Rs1 constant (16) +// +// Action: +// Rd <- Rs1 op constant +// +// Except for shift instructions, `H' determines whether the constant +// is in the high (1) or low (0) word. The other halfword is 0x0000, +// except for the `AND' instruction (`AAA' = 100), for which the other +// halfword is 0xFFFF, and shifts (`AAA' = 111), for which the constant is +// sign extended. +// +// `F' determines whether the instruction modifies (1) or does not +// modify (0) the program flags. +// +// `AAA' specifies the operation: `add' (000), `addc' (001), `sub' +// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or `shift' +// (111). For the shift, `H' specifies a logical (0) or arithmetic (1) +// shift. The amount and direction of the shift are determined by the +// sign extended constant interpreted as a two's complement number. The +// shift operation is defined only for the range of: +// 31 ... 0 -1 ... -31 +// \ / \ / +// left right +// shift shift +// +// If and only if the `F' bit is 1, RI instructions modify the +// condition bits, `Z' (Zero), `N' (Negative), `V' (oVerflow), and `C' +// (Carry), according to the result. If the flags are updated, they are +// updated as follows: +// `Z' +// is set if the result is zero and cleared otherwise. +// +// `N' +// is set to the most significant bit of the result. +// +// `V' +// For arithmetic instructions (`add', `addc', `sub', `subb') `V' is +// set if the sign (most significant) bits of the input operands are +// the same but different from the sign bit of the result and cleared +// otherwise. For other RI instructions, `V' is cleared. +// +// `C' +// For arithmetic instructions, `C' is set/cleared if there is/is_not +// a carry generated out of the most significant when performing the +// twos-complement addition (`sub(a,b) == a + ~b + 1', `subb(a,b) == +// a + ~b + `C''). For left shifts, `C' is set to the least +// significant bit discarded by the shift operation. For all other +// operations, `C' is cleared. +// +// A Jump is accomplished by `Rd' being `pc', and it has one shadow. +// +// The all-0s word is the instruction `R0 <- R0 + 0', which is a no-op. +class InstRI<bits<3> op, dag outs, dag ins, string asmstr, + list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> { + let Itinerary = IIC_ALU; + bits<5> Rd; + bits<5> Rs1; + bit F; + bit H; + bits<16> imm16; + + let Opcode{3} = 0; + let Opcode{2 - 0} = op; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17} = F; + let Inst{16} = H; + let Inst{15 - 0} = imm16; +} + +//------------------------------------------------------------------------------ +// Register Register (RR) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.0.0| . . . . | . . . . |F.I| . . . . |B.B.B|J.J.J.J.J|D.D.D| +// ----------------------------------------------------------------- +// opcode Rd Rs1 Rs2 \ operation / +// +// Action: +// `Rd <- Rs1 op Rs2' iff condition DDDI is true. +// +// `DDDI' is as described for the BR instruction. +// +// `F' determines whether the instruction modifies (1) or does not +// modify (0) the program flags. +// +// `BBB' determines the operation: `add' (000), `addc' (001), `sub' +// (010), `subb' (011), `and' (100), `or' (101), `xor' (110), or "special" +// (111). The `JJJJJ' field is irrelevant except for special. +// +// `JJJJJ' determines which special operation is performed. `10---' +// is a logical shift, and `11---' is an arithmetic shift, and ‘00000` is +// the SELECT operation. The amount and direction of the shift are +// determined by the contents of `Rs2' interpreted as a two's complement +// number (in the same way as shifts in the Register-Immediate +// instructions in *Note RI::). For the SELECT operation, Rd gets Rs1 if +// condition DDDI is true, Rs2 otherwise. All other `JJJJJ' combinations +// are reserved for instructions that may be defined in the future. +// +// If the `F' bit is 1, RR instructions modify the condition bits, `Z' +// (Zero), `N' (Negative), `V' (oVerflow), and `C' (Carry), according to +// the result. All RR instructions modify the `Z', `N', and `V' flags. +// Except for arithmetic instructions (`add', `addc', `sub', `subb'), `V' +// is cleared. Only arithmetic instructions and shifts modify `C'. Right +// shifts clear C. +// +// DDDI is as described in the table for the BR instruction and only used for +// the select instruction. +// +// A Jump is accomplished by `Rd' being `pc', and it has one shadow. +class InstRR<bits<3> op, dag outs, dag ins, string asmstr, + list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern>, Sched<[WriteALU]> { + let Itinerary = IIC_ALU; + bits<5> Rd; + bits<5> Rs1; + bits<5> Rs2; + bit F; + bits<4> DDDI; + bits<5> JJJJJ; + + let Opcode = 0b1100; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17} = F; + let Inst{16} = DDDI{0}; + let Inst{15 - 11} = Rs2; + let Inst{10 - 8} = op; + let Inst{7 - 3} = JJJJJ; + let Inst{2 - 0} = DDDI{3 - 1}; +} + +//------------------------------------------------------------------------------ +// Register Memory (RM) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.0.0.S| . . . . | . . . . |P.Q| . . . . . . . . . . . . . . . | +// ----------------------------------------------------------------- +// opcode Rd Rs1 constant (16) +// +// Action: +// Rd <- Memory(ea) (Load) see below for the +// Memory(ea) <- Rd (Store) definition of ea. +// +// `S' determines whether the instruction is a Load (0) or a Store (1). +// Loads appear in Rd one cycle after this instruction executes. If the +// following instruction reads Rd, that instruction will be delayed by 1 +// clock cycle. +// +// PQ operation +// -- ------------------------------------------ +// 00 ea = Rs1 +// 01 ea = Rs1, Rs1 <- Rs1 + constant +// 10 ea = Rs1 + constant +// 11 ea = Rs1 + constant, Rs1 <- Rs1 + constant +// +// The constant is sign-extended for this instruction. +// +// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots. +class InstRM<bit S, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<5> Rd; + bits<5> Rs1; + bit P; + bit Q; + bits<16> imm16; + // Dummy variables to allow multiclass definition of RM and RRM + bits<2> YL; + bit E; + + let Opcode{3 - 1} = 0b100; + let Opcode{0} = S; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17} = P; + let Inst{16} = Q; + let Inst{15 - 0} = imm16; + + let PostEncoderMethod = "adjustPqBitsRmAndRrm"; +} + +//------------------------------------------------------------------------------ +// Register Register Memory (RRM) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.0.1.S| . . . . | . . . . |P.Q| . . . . |B.B.B|J.J.J.J.J|Y.L.E| +// ----------------------------------------------------------------- +// opcode Rd Rs1 Rs2 \ operation / +// +// Action: +// Rd <- Memory(ea) (Load) see below for the +// Memory(ea) <- Rd (Store) definition of ea. +// +// The RRM instruction is identical to the RM (*note RM::.) instruction +// except that: +// +// 1. `Rs1 + constant' is replaced with `Rs1 op Rs2', where `op' is +// determined in the same way as in the RR instruction (*note RR::.) +// and +// +// 2. part-word memory accesses are allowed as specified below. +// +// If `BBB' != 111 (i.e.: For all but shift operations): +// If `YLE' = 01- => fuLl-word memory access +// If `YLE' = 00- => half-word memory access +// If `YLE' = 10- => bYte memory access +// If `YLE' = --1 => loads are zEro extended +// If `YLE' = --0 => loads are sign extended +// +// If `BBB' = 111 (For shift operations): +// fullword memory access are performed. +// +// All part-word loads write the least significant part of the +// destination register with the higher-order bits zero- or sign-extended. +// All part-word stores store the least significant part-word of the +// source register in the destination memory location. +// +// A Jump is accomplished by `Rd' being `pc', and it has *two* delay slots. +class InstRRM<bit S, dag outs, dag ins, string asmstr, + list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<5> Rd; + bits<5> Rs1; + bits<5> Rs2; + bit P; + bit Q; + bits<3> BBB; + bits<5> JJJJJ; + bits<2> YL; + bit E; + + let Opcode{3 - 1} = 0b101; + let Opcode{0} = S; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17} = P; + let Inst{16} = Q; + let Inst{15 - 11} = Rs2; + let Inst{10 - 8} = BBB; + let Inst{7 - 3} = JJJJJ; + let Inst{2 - 1} = YL; + let Inst{0} = E; + + let PostEncoderMethod = "adjustPqBitsRmAndRrm"; +} + +//------------------------------------------------------------------------------ +// Conditional Branch (BR) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.0|D.D.D| . . . . . . . . . . . . . . . . . . . . . . |0.I| +// ----------------------------------------------------------------- +// opcode condition constant (23) +// +// Action: +// if (condition) { `pc' <- 4*(zero-extended constant) } +// +// The BR instruction is an absolute branch. +// The constant is scaled as shown by its position in the instruction word such +// that it specifies word-aligned addresses in the range [0,2^25-4] +// +// The `DDDI' field selects the condition that causes the branch to be taken. +// (the `I' (Invert sense) bit inverts the sense of the condition): +// +// DDDI logical function [code, used for...] +// ---- -------------------------------------- ------------------------ +// 0000 1 [T, true] +// 0001 0 [F, false] +// 0010 C AND Z' [HI, high] +// 0011 C' OR Z [LS, low or same] +// 0100 C' [CC, carry cleared] +// 0101 C [CS, carry set] +// 0110 Z' [NE, not equal] +// 0111 Z [EQ, equal] +// 1000 V' [VC, oVerflow cleared] +// 1001 V [VS, oVerflow set] +// 1010 N' [PL, plus] +// 1011 N [MI, minus] +// 1100 (N AND V) OR (N' AND V') [GE, greater than or equal] +// 1101 (N AND V') OR (N' AND V) [LT, less than] +// 1110 (N AND V AND Z') OR (N' AND V' AND Z') [GT, greater than] +// 1111 (Z) OR (N AND V') OR (N' AND V) [LE, less than or equal] +// +// If the branch is not taken, the BR instruction is a no-op. If the branch is +// taken, the processor starts executing instructions at the branch target +// address *after* the processor has executed one more instruction. That is, +// the branch has one “branch delay slot”. Be very careful if you find yourself +// wanting to put a branch in a branch delays slot! +class InstBR<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + let Itinerary = IIC_ALU; + bits<25> addr; + bits<4> DDDI; + + let Opcode = 0b1110; + let Inst{27 - 25} = DDDI{3 - 1}; + let Inst{24 - 0} = addr; + // These instructions overwrite the last two address bits (which are assumed + // and ensured to be 0). + let Inst{1} = 0; + let Inst{0} = DDDI{0}; +} + +//------------------------------------------------------------------------------ +// Conditional Branch Relative (BRR) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.0|D.D.D|1|-| . . . . |-.-| . . . . . . . . . . . . . |1.I| +// ----------------------------------------------------------------- +// opcode condition Rs1 constant (14) +// Action: +// if (condition) { ‘pc’ <- Rs1 + 4*sign-extended constant) } +// +// BRR behaves like BR, except the branch target address is a 16-bit PC relative +// offset. +class InstBRR<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<4> DDDI; + bits<5> Rs1; + bits<16> imm16; + + let Opcode = 0b1110; + let Inst{27 - 25} = DDDI{3 - 1}; + let Inst{24} = 1; + let Inst{22 - 18} = Rs1; + let Inst{17 - 16} = 0; + let Inst{15 - 0} = imm16; + // Overwrite last two bits which have to be zero + let Inst{1} = 1; + let Inst{0} = DDDI{0}; + + // Set don't cares to zero + let Inst{23} = 0; +} + +//------------------------------------------------------------------------------ +// Conditional Set (SCC) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.0|D.D.D|0.-| . . . . |-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-|1.I| +// ----------------------------------------------------------------- +// opcode condition Rs1 +// +// Action: +// Rs1 <- logical function result +// +// SCC sets dst_reg to the boolean result of computing the logical function +// specified by DDDI, as described in the table for the BR instruction. +class InstSCC<dag outs, dag ins, string asmstr, + list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + let Itinerary = IIC_ALU; + bits<5> Rs1; // dst_reg in documentation + bits<4> DDDI; + + let Opcode = 0b1110; + let Inst{27 - 25} = DDDI{3 - 1}; + let Inst{24} = 0; + let Inst{22 - 18} = Rs1; + let Inst{1} = 1; + let Inst{0} = DDDI{0}; + + // Set don't cares to zero + let Inst{23} = 0; + let Inst{17 - 2} = 0; +} + +//------------------------------------------------------------------------------ +// Special Load/Store (SLS) +//------------------------------------------------------------------------------ +// +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.1| . . . . | . . . . |0.S| . . . . . . . . . . . . . . . | +// ----------------------------------------------------------------- +// opcode Rd addr 5msb's address 16 lsb's +// +// Action: +// If S = 0 (LOAD): Rd <- Memory(address); +// If S = 1 (STORE): Memory(address) <- Rd +// +// The timing is the same as for RM (*note RM::.) and RRM (*note +// RRM::.) instructions. The two low-order bits of the 21-bit address are +// ignored. The address is zero extended. Fullword memory accesses are +// performed. +class InstSLS<bit S, dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<5> Rd; + bits<5> msb; + bits<16> lsb; + + let Opcode = 0b1111; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = msb; + let Inst{17} = 0; + let Inst{16} = S; + let Inst{15 - 0} = lsb; +} + +//------------------------------------------------------------------------------ +// Special Load Immediate (SLI) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.1| . . . . | . . . . |1.0| . . . . . . . . . . . . . . . | +// ----------------------------------------------------------------- +// opcode Rd const 5msb's constant 16 lsb's +// +// Action: +// Rd <- constant +// +// The 21-bit constant is zero-extended. The timing is the same as the +// RM instruction (*note RM::.). +class InstSLI<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<5> Rd; + bits<5> msb; + bits<16> lsb; + + let Opcode = 0b1111; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = msb; + let Inst{17} = 1; + let Inst{16} = 0; + let Inst{15 - 0} = lsb; +} + +//------------------------------------------------------------------------------ +// Special Part-Word Load/Store (SPLS) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.1.1| . . . . | . . . . |1.1.0.Y.S.E.P.Q| . . . . . . . . . | +// ----------------------------------------------------------------- +// opcode Rd Rs1 constant (10) +// +// Action: +// If `YS' = 11 (bYte Store): +// Memory(ea) <- (least significant byte of Rr) +// If `YS' = 01 (halfword Store): +// Memory(ea) <- (least significant half-word of Rr) +// If `YS' = 10 (bYte load): Rr <- Memory(ea) +// If `YS' = 00 (halfword load): Rr <- Memory(ea) +// [Note: here ea is determined as in the the RM instruction. ] +// If `SE' = 01 then the value is zEro extended +// before being loaded into Rd. +// If `SE' = 00 then the value is sign extended +// before being loaded into Rd. +// +// `P' and `Q' are used to determine `ea' as in the RM instruction. The +// constant is sign extended. The timing is the same as the RM and RRM +// instructions. *Note RM:: and *Note RRM::. +// +// All part-word loads write the part-word into the least significant +// part of the destination register, with the higher-order bits zero- or +// sign-extended. All part-word stores store the least significant +// part-word of the source register into the destination memory location. +class InstSPLS<dag outs, dag ins, string asmstr, + list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + bits<5> Rd; + bits<5> Rs1; + bits<5> msb; + bit Y; + bit S; + bit E; + bit P; + bit Q; + bits<10> imm10; + + let Opcode = 0b1111; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17 - 15} = 0b110; + let Inst{14} = Y; + let Inst{13} = S; + let Inst{12} = E; + let Inst{11} = P; + let Inst{10} = Q; + let Inst{9 - 0} = imm10; + + let PostEncoderMethod = "adjustPqBitsSpls"; +} + +//------------------------------------------------------------------------------ +// Special instructions (popc, leadz, trailz) +//------------------------------------------------------------------------------ +// Encoding: +// ----------------------------------------------------------------- +// |1.1.0.1| Rd | Rs1 |F.-| . . . . | . . | . . . . | OP | +// ----------------------------------------------------------------- +// opcode Rd Rs1 +// Action: +// Rd <- Perform action encoded in OP on Rs1 +// OP is one of: +// 0b001 POPC Population count; +// 0b010 LEADZ Count number of leading zeros; +// 0b011 TRAILZ Count number of trailing zeros; +class InstSpecial<bits<3> op, dag outs, dag ins, string asmstr, + list<dag> pattern> : InstLanai<outs, ins, asmstr, + pattern>, Sched<[WriteALU]> { + let Itinerary = IIC_ALU; + bit F; + bits<5> Rd; + bits<5> Rs1; + + let Opcode = 0b1101; + let Inst{27 - 23} = Rd; + let Inst{22 - 18} = Rs1; + let Inst{17} = F; + let Inst{16 - 3} = 0; + let Inst{2 - 0} = op; +} + +// Pseudo instructions +class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> + : InstLanai<outs, ins, asmstr, pattern> { + let Inst{15 - 0} = 0; + let isPseudo = 1; +} |