--- /dev/null
+//===-- CSKYInstrFormats.td - CSKY Instruction Formats -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+class AddrMode<bits<5> val> {
+ bits<5> Value = val;
+}
+
+def AddrModeNone : AddrMode<0>;
+def AddrMode32B : AddrMode<1>; // ld32.b, ld32.bs, st32.b, st32.bs, +4kb
+def AddrMode32H : AddrMode<2>; // ld32.h, ld32.hs, st32.h, st32.hs, +8kb
+def AddrMode32WD : AddrMode<3>; // ld32.w, st32.w, ld32.d, st32.d, +16kb
+def AddrMode16B : AddrMode<4>; // ld16.b, +32b
+def AddrMode16H : AddrMode<5>; // ld16.h, +64b
+def AddrMode16W : AddrMode<6>; // ld16.w, +128b or +1kb
+def AddrMode32SDF : AddrMode<7>; // flds, fldd, +1kb
+
+class CSKYInst<AddrMode am, int sz, dag outs, dag ins, string asmstr,
+ list<dag> pattern> : Instruction {
+ let Namespace = "CSKY";
+ int Size = sz;
+ AddrMode AM = am;
+
+ let OutOperandList = outs;
+ let InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
+ let Itinerary = NoItinerary;
+ let TSFlags{4 - 0} = AM.Value;
+}
+
+class CSKYPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
+ : CSKYInst<AddrModeNone, 0, outs, ins, asmstr, pattern> {
+ let isCodeGenOnly = 1;
+ let isPseudo = 1;
+}
+
+class CSKY32Inst<AddrMode am, bits<6> opcode, dag outs, dag ins, string asmstr,
+ list<dag> pattern>
+ : CSKYInst<am, 4, outs, ins, asmstr, pattern> {
+ field bits<32> Inst;
+ let Inst{31 - 26} = opcode;
+}
+
+// CSKY 32-bit instruction
+// Format< OP[6] | Offset[26] >
+// Instruction(1): bsr32
+class J<bits<6> opcode, dag outs, dag ins, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, opcode, outs, ins, !strconcat(op, "\t$offset"),
+ pattern> {
+ bits<26> offset;
+ let Inst{25 - 0} = offset;
+}
+
+// Format< OP[6] | RZ[5] | SOP[3] | OFFSET[18] >
+// Instructions(7): grs, lrs32.b, lrs32.h, lrs32.w, srs32.b, srs32.h, srs32.w
+class I_18_Z_L<bits<3> sop, string op, Operand operand, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x33, (outs GPR:$rz), (ins operand:$offset),
+ !strconcat(op, "\t$rz, $offset"), pattern> {
+ bits<5> rz;
+ bits<18> offset;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 18} = sop;
+ let Inst{17 - 0} = offset;
+}
+
+// Format< OP[6] | RZ[5] | RX[5] | IMM[16] >
+// Instructions(1): ori32
+class I_16_ZX<string op, ImmLeaf ImmType, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3b,
+ (outs GPR:$rz), (ins GPR:$rx,ImmType:$imm16),
+ !strconcat(op, "\t$rz, $rx, $imm16"), pattern> {
+ bits<5> rz;
+ bits<5> rx;
+ bits<16> imm16;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 0} = imm16;
+}
+
+// Format< OP[6] | SOP[5] | RZ[5] | IMM[16] >
+// Instructions(3): movi32, movih32, (bgeni32)
+class I_16_MOV<bits<5> sop, string op, ImmLeaf ImmType>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs GPR:$rz), (ins ImmType:$imm16),
+ !strconcat(op, "\t$rz, $imm16"),
+ [(set GPR:$rz, ImmType:$imm16)]> {
+ bits<5> rz;
+ bits<16> imm16;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rz;
+ let Inst{15 - 0} = imm16;
+ let isReMaterializable = 1;
+ let isAsCheapAsAMove = 1;
+ let isMoveImm = 1;
+}
+
+// Format< OP[6] | SOP[5] | RZ[5] | OFFSET[16] >
+// Instructions(1): lrw32
+class I_16_Z_L<bits<5> sop, string op, Operand operand, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3a,
+ (outs GPR:$rz), (ins operand:$imm16),
+ !strconcat(op, "\t$rz, [$imm16]"), pattern> {
+ bits<5> rz;
+ bits<16> imm16;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rz;
+ let Inst{15 - 0} = imm16;
+}
+
+// Format< OP[6] | SOP[5] | 00000[5] | OFFSET[16] >
+// Instructions(5): bt32, bf32, br32, jmpi32, jsri32
+class I_16_L<bits<5> sop, dag outs, dag ins, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3a, outs, ins, !strconcat(op, "\t$imm16"),
+ pattern> {
+ bits<16> imm16;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = 0;
+ let Inst{15 - 0} = imm16;
+}
+
+// bt32, bf32, br32, jmpi32
+class I_16_L_B<bits<5> sop, string op, Operand operand, list<dag> pattern>
+ : I_16_L<sop, (outs), (ins operand:$imm16, CARRY:$ca), op, pattern> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+// Format< OP[6] | SOP[5] | RX[5] | 0000000000000000[16] >
+// Instructions(2): jmp32, jsr32
+class I_16_JX<bits<5> sop, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs), (ins GPR:$rx),
+ !strconcat(op, "\t$rx"), pattern> {
+ bits<5> rx;
+ bits<16> imm16;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 0} = 0;
+}
+
+// Format< OP[6] | SOP[5] | RX[5] | 00000000000000[14] | IMM[2] >
+// Instructions(1): jmpix32
+class I_16_J_XI<bits<5> sop, string op, Operand operand, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs),
+ (ins GPR:$rx, operand:$imm2),
+ !strconcat(op, "\t$rx, $imm2"), pattern> {
+ bits<5> rx;
+ bits<2> imm2;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 2} = 0;
+ let Inst{1 - 0} = imm2;
+}
+
+// Format< OP[6] | SOP[5] | PCODE[5] | 0000000000000000[16] >
+// Instructions(1): rts32
+class I_16_RET<bits<5> sop, bits<5> pcode, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs), (ins), op, pattern> {
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = pcode;
+ let Inst{15 - 0} = 0;
+ let isTerminator = 1;
+ let isReturn = 1;
+ let isBarrier = 1;
+}
+
+// Format< OP[6] | SOP[5] | RX[5] | IMM16[16] >
+// Instructions(3): cmpnei32, cmphsi32, cmplti32
+class I_16_X<bits<5> sop, string op>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs CARRY:$ca),
+ (ins GPR:$rx, i32imm:$imm16), !strconcat(op, "\t$rx, $imm16"), []> {
+ bits<16> imm16;
+ bits<5> rx;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 0} = imm16;
+ let isCompare = 1;
+}
+
+// Format< OP[6] | SOP[5] | RX[5] | OFFSET[16] >
+// Instructions(7): bez32, bnez32, bnezad32, bhz32, blsz32, blz32, bhsz32
+class I_16_X_L<bits<5> sop, string op, Operand operand>
+ : CSKY32Inst<AddrModeNone, 0x3a, (outs), (ins GPR:$rx, operand:$imm16),
+ !strconcat(op, "\t$rx, $imm16"), []> {
+ bits<5> rx;
+ bits<16> imm16;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 0} = imm16;
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | IMM[12] >
+// Instructions(5): addi32, subi32, andi32, andni32, xori32
+class I_12<bits<4> sop, string op, SDNode node, ImmLeaf ImmType>
+ : CSKY32Inst<AddrModeNone, 0x39, (outs GPR:$rz),
+ (ins GPR:$rx, ImmType:$imm12), !strconcat(op, "\t$rz, $rx, $imm12"),
+ [(set GPR:$rz, (node GPR:$rx, ImmType:$imm12))]> {
+ bits<5> rz;
+ bits<5> rx;
+ bits<12> imm12;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 12} = sop;
+ let Inst{11 - 0} = imm12;
+}
+
+class I_LDST<AddrMode am, bits<6> opcode, bits<4> sop, dag outs, dag ins,
+ string op, list<dag> pattern>
+ : CSKY32Inst<am, opcode, outs, ins, !strconcat(op, "\t$rz, ($rx, $imm12)"),
+ pattern> {
+ bits<5> rx;
+ bits<5> rz;
+ bits<12> imm12;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 12} = sop;
+ let Inst{11 - 0} = imm12;
+}
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] >
+// Instructions(6): ld32.b, ld32.bs, ld32.h, ld32.hs, ld32.w, ld32.d
+class I_LD<AddrMode am, bits<4> sop, string op, Operand operand>
+ : I_LDST<am, 0x36, sop,
+ (outs GPR:$rz), (ins GPR:$rx, operand:$imm12), op, []>;
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] >
+// Instructions(4): st32.b, st32.h, st32.w, st32.d
+class I_ST<AddrMode am, bits<4> sop, string op, Operand operand>
+ : I_LDST<am, 0x37, sop, (outs),
+ (ins GPR:$rz, GPR:$rx, operand:$imm12), op, []>;
+
+// Format< OP[6] | SOP[5] | PCODE[5] | 0000[4] | 000 | R28 | LIST2[3] | R15 |
+// LIST1[4] >
+// Instructions(2): push32, pop32
+class I_12_PP<bits<5> sop, bits<5> pcode, dag outs, dag ins, string op>
+ : CSKY32Inst<AddrModeNone, 0x3a, outs, ins, !strconcat(op, "\t$regs"), []> {
+ bits<12> regs;
+ let Inst{25 - 21} = sop;
+ let Inst{20 - 16} = pcode;
+ let Inst{15 - 12} = 0;
+ let Inst{11 - 0} = regs;
+}
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]>
+// Instructions(4): incf32, inct32, decf32, dect32
+class I_5_ZX<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType,
+ list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz),
+ (ins GPR:$false, GPR:$rx, ImmType:$imm5),
+ !strconcat(op, "\t$rz, $rx, $imm5"), pattern> {
+ bits<5> rz;
+ bits<5> rx;
+ bits<5> imm5;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = imm5;
+ let Constraints = "$rz = $false";
+}
+
+// Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5]>
+// Instructions(13): decgt32, declt32, decne32, lsli32, lslc32, lsri32
+// lsrc32, asri32, asrc32, rotli32, xsr32, bclri32, bseti32
+class I_5_XZ<bits<6> sop, bits<5> pcode, string op, dag ins, dag outs,
+ list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, ins, outs,
+ !strconcat(op, "\t$rz, $rx, $imm5"), pattern> {
+ bits<5> imm5;
+ bits<5> rx;
+ bits<5> rz;
+ let Inst{25 - 21} = imm5;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]>
+// Instructions(2): ldm32, (ldq32), stm32, (stq32)
+class I_5_YX<bits<6> opcode, dag outs, dag ins, string op, list<dag> pattern,
+ bits<5> imm5>
+ : CSKY32Inst<AddrModeNone, opcode, outs, ins,
+ op #"\t${ry}, (${rx}), " #!cast<int>(imm5), pattern> {
+ bits<5> rx;
+ bits<5> ry;
+ let Inst{25 - 21} = ry; // ry
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = 0b000111;
+ let Inst{9 - 5} = 0b00001;
+ let Inst{4 - 0} = imm5{4 - 0}; // imm5
+}
+
+// Format< OP[6] | LSB[5] | RX[5] | SOP[6] | MSB[5] | RZ[5]>
+// Instructions(6): zext32, zextb32, zexth32, sext32, sextb32, sexth32
+class I_5_XZ_U<bits<6> sop, bits<5> lsb, bits<5> msb, dag outs, dag ins,
+ string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, outs, ins,
+ op #"\t$rz, $rx, " #!cast<int>(msb) #", " #!cast<int>(lsb),
+ pattern> {
+ bits<5> rx;
+ bits<5> rz;
+ let Inst{25 - 21} = lsb; // lsb
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = msb; // msb
+ let Inst{4 - 0} = rz;
+}
+
+// sextb, sexth
+class I_5_XZ_US<bits<6> sop, bits<5> lsb, bits<5> msb, string op, SDNode opnode,
+ ValueType type> : I_5_XZ_U<sop, lsb, msb,
+ (outs GPR:$rz), (ins GPR:$rx),op, [(set GPR:$rz, (opnode GPR:$rx, type))]>;
+
+class I_5_XZ_UZ<bits<6> sop, bits<5> lsb, bits<5> msb, string op, int v>
+ : I_5_XZ_U<sop, lsb, msb, (outs GPR:$rz), (ins GPR:$rx), op,
+ [(set GPR:$rz, (and GPR:$rx, (i32 v)))]>;
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | SIZE[5] | LSB[5]>
+// Instructions(1): ins32
+class I_5_ZX_U<bits<6> sop, string op, Operand operand, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz), (ins operand:$size_lsb),
+ !strconcat(op, "\t$rz, operand:$size_lsb"), pattern> {
+ bits<10> size_lsb;
+ bits<5> rz;
+ bits<5> rx;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = size_lsb{9 - 5}; // size
+ let Inst{4 - 0} = size_lsb{4 - 0}; // lsb
+}
+
+// Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | 00000 >
+// Instructions(1): btsti32
+class I_5_X<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType,
+ list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31,
+ (outs CARRY:$ca), (ins GPR:$rx, ImmType:$imm5),
+ !strconcat(op, "\t$rx, $imm5"), pattern> {
+ bits<5> imm5;
+ bits<5> rx;
+ let Inst{25 - 21} = imm5;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = 0;
+ let isCompare = 1;
+}
+
+// Format< OP[6] | IMM[5] | 00000[5] | SOP[6] | PCODE[5] | RZ[5]>
+// Instructions(1): bmaski32
+class I_5_Z<bits<6> sop, bits<5> pcode, string op, ImmLeaf ImmType,
+ list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz), (ins ImmType:$imm5),
+ !strconcat(op, "\t$rz, $imm5"), pattern> {
+ bits<5> imm5;
+ bits<5> rz;
+ let Inst{25 - 21} = imm5;
+ let Inst{20 - 16} = 0;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] >
+// Instructions(24): addu32, addc32, subu32, subc32, (rsub32), ixh32, ixw32,
+// ixd32, and32, andn32, or32, xor32, nor32, lsl32, lsr32, asr32, rotl32
+// mult32, divu32, divs32, mul.(u/s)32, mula.32.l, mula.u32, mulall.s16.s
+class R_YXZ<bits<6> opcode, bits<6> sop, bits<5> pcode, dag outs, dag ins,
+ string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, opcode, outs, ins,
+ !strconcat(op, "\t$rz, $rx, $ry"), pattern> {
+ bits<5> ry;
+ bits<5> rx;
+ bits<5> rz;
+ let Inst{25 - 21} = ry;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// R_YXZ instructions with simple pattern
+// Output: GPR:rz
+// Input: GPR:rx, GPR:ry
+// Asm string: op rz, rx, ry
+// Instructions: addu32, subu32, ixh32, ixw32, ixd32, and32, andn32, or32,
+// xor32, nor32, lsl32, lsr32, asr32, mult32, divu32, divs32
+class R_YXZ_SP_F1<bits<6> sop, bits<5> pcode, PatFrag opnode, string op,
+ bit Commutable = 0> : R_YXZ<0x31, sop, pcode, (outs GPR:$rz),
+ (ins GPR:$rx, GPR:$ry), op, [(set GPR:$rz, (opnode GPR:$rx, GPR:$ry))]> {
+ let isCommutable = Commutable;
+}
+
+// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] >
+// Instructions:(8) ldr32.b, ldr32.h, ldr32.bs, ldr32.hs, ldr32.w,
+// str32.b, str32.h, str32.w
+class R_YXZ_LDST<bits<6> opcode, bits<6> sop, bits<5> pcode, int no, dag outs,
+ dag ins, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, opcode, outs, ins,
+ op #"\t$rz, ($rx, $ry << " #no #")", pattern> {
+ bits<5> rx;
+ bits<5> ry;
+ bits<5> rz;
+ let Inst{25 - 21} = ry; // ry;
+ let Inst{20 - 16} = rx; // rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode; // pcode;
+ let Inst{4 - 0} = rz;
+}
+
+class I_LDR<bits<6> sop, bits<5> pcode, string op, int no>
+ : R_YXZ_LDST<0x34, sop, pcode, no,
+ (outs GPR:$rz), (ins GPR:$rx, GPR:$ry), op, []>;
+
+class I_STR<bits<6> sop, bits<5> pcode, string op, int no>
+ : R_YXZ_LDST<0x35, sop, pcode, no, (outs),
+ (ins GPR:$rz, GPR:$rx, GPR:$ry), op, []>;
+
+// Format< OP[6] | RX[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] >
+// Instructions:(1) not32
+class R_XXZ<bits<6> sop, bits<5> pcode, dag outs, dag ins, string op,
+ list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, outs, ins, !strconcat(op, "\t$rz, $rx"),
+ pattern> {
+ bits<5> rx;
+ bits<5> rz;
+ let Inst{25 - 21} = rx;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] >
+// Instructions:(4) cmpne32, cmphs32, cmplt32, tst32
+class R_YX<bits<6> sop, bits<5> pcode, string op>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs CARRY:$ca),
+ (ins GPR:$rx, GPR:$ry),
+ !strconcat(op, "\t$rx, $ry"), []> {
+ bits<5> ry;
+ bits<5> rx;
+ let Inst{25 - 21} = ry;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = 0;
+ let isCompare = 1;
+}
+
+// Format< OP[6] | 00000[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] >
+// Instructions:(12)
+// mov32, xtrb0.32, xtrb1.32, xtrb2.32, xtrb3.32, brev32, revb32
+// revh32, abs32, ff0.32, ff1.32, bgenr32
+class R_XZ<bits<6> sop, bits<5> pcode, string op>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz), (ins GPR:$rx),
+ !strconcat(op, "\t$rz, $rx"), []> {
+ bits<5> rx;
+ bits<5> rz;
+ let Inst{25 - 21} = 0;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] >
+// Instructions:(2) movf32, movt32
+class R_ZX<bits<6> sop, bits<5> pcode, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz),
+ (ins CARRY:$ca, GPR:$rx, GPR:$false),
+ !strconcat(op, "\t$rz, $rx"), pattern> {
+ bits<5> rz;
+ bits<5> rx;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = 0;
+ let Constraints = "$rz = $false";
+ let isSelect = 1;
+}
+
+// Format< OP[6] | 00000[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] >
+// Instructions:(1) tstnbz32
+class R_X<bits<6> sop, bits<5> pcode, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs CARRY:$ca),(ins GPR:$rx),
+ !strconcat(op, "\t$rx"), pattern> {
+ bits<5> rx;
+ let Inst{25 - 21} = 0;
+ let Inst{20 - 16} = rx;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = 0;
+}
+
+// Format< OP[6] | 00000[5] | 00000[5] | SOP[6] | PCODE[5] | RZ[5] >
+// Instructions:(2) mvc32, mvcv32
+class R_Z_1<bits<6> sop, bits<5> pcode, string op>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz),
+ (ins CARRY:$ca), !strconcat(op, "\t$rz"), []> {
+ bits<5> rz;
+ let Inst{25 - 21} = 0;
+ let Inst{20 - 16} = 0;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = rz;
+}
+
+// Format< OP[6] | RZ[5] | 00000[5] | SOP[6] | PCODE[5] | 00000[5] >
+// Instructions:(2) clrf32, clrt32
+class R_Z_2<bits<6> sop, bits<5> pcode, string op, list<dag> pattern>
+ : CSKY32Inst<AddrModeNone, 0x31, (outs GPR:$rz),
+ (ins CARRY:$ca, GPR:$false), !strconcat(op, "\t$rz"), []> {
+ bits<5> rz;
+ let Inst{25 - 21} = rz;
+ let Inst{20 - 16} = 0;
+ let Inst{15 - 10} = sop;
+ let Inst{9 - 5} = pcode;
+ let Inst{4 - 0} = 0;
+ let Constraints = "$rz = $false";
+}
--- /dev/null
+//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the CSKY instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+include "CSKYInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
+// CSKY specific DAG Nodes.
+//===----------------------------------------------------------------------===//
+
+// TODO: Add CSKY specific DAG Nodes.
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+class oimm<int num> : Operand<i32>,
+ ImmLeaf<i32, "return isUInt<"#num#">(Imm - 1);"> {
+ let EncoderMethod = "getOImmOpValue<"#num#">";
+}
+
+class uimm<int num, int shift = 0> : Operand<i32>,
+ ImmLeaf<i32, "return isShiftedUInt<"#num#", "#shift#">(Imm);"> {
+ let EncoderMethod = "getImmOpValue<"#num#", "#shift#">";
+}
+
+class simm<int num, int shift = 0> : Operand<i32>,
+ ImmLeaf<i32, "return isShiftedInt<"#num#", "#shift#">(Imm);"> {
+ let EncoderMethod = "getImmOpValue<"#num#", "#shift#">";
+}
+
+def nimm_XFORM : SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32);
+}]>;
+class nimm<int num> : Operand<i32>,
+ ImmLeaf<i32, "return isUInt<"#num#">(~Imm);", nimm_XFORM> {
+}
+
+
+def oimm12 : oimm<12>;
+
+def nimm12 : nimm<12>;
+
+def uimm5 : uimm<5>;
+def uimm12 : uimm<12>;
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions.
+//===----------------------------------------------------------------------===//
+
+class TriOpFrag<dag res> : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>;
+class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
+class UnOpFrag<dag res> : PatFrag<(ops node:$Src), res>;
+
+def ADDI32 : I_12<0x0, "addi32", add, oimm12>;
+def SUBI32 : I_12<0x1, "subi32", sub, oimm12>;
+def ANDI32 : I_12<0x2, "andi32", and, uimm12>;
+def ANDNI32 : I_12<0x3, "andni32", and, nimm12>;
+def XORI32 : I_12<0x4, "xori32", xor, uimm12>;
+def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32",
+ (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
+ [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>;
+def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32",
+ (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
+ [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>;
+def ASRI32 : I_5_XZ<0x12, 0x4, "asri32",
+ (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5),
+ [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>;
+
+
+
+def ADDU32 : R_YXZ_SP_F1<0x0, 0x1,
+ BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>;
+def SUBU32 : R_YXZ_SP_F1<0x0, 0x4,
+ BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">;
+def AND32 : R_YXZ_SP_F1<0x8, 0x1,
+ BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>;
+def ANDN32 : R_YXZ_SP_F1<0x8, 0x2,
+ BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">;
+def OR32: R_YXZ_SP_F1<0x9, 0x1,
+ BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>;
+def XOR32 : R_YXZ_SP_F1<0x9, 0x2,
+ BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>;
+def NOR32 : R_YXZ_SP_F1<0x9, 0x4,
+ BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>;
+def LSL32 : R_YXZ_SP_F1<0x10, 0x1,
+ BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">;
+def LSR32 : R_YXZ_SP_F1<0x10, 0x2,
+ BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">;
+def ASR32 : R_YXZ_SP_F1<0x10, 0x4,
+ BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">;
+def MULT32 : R_YXZ_SP_F1<0x21, 0x1,
+ BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>;
+def DIVS32 : R_YXZ_SP_F1<0x20, 0x2,
+ BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">;
+def DIVU32 : R_YXZ_SP_F1<0x20, 0x1,
+ BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">;
+
+def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx),
+ "not", [(set GPR:$rz, (not GPR:$rx))]>;
--- /dev/null
+//===-- CSKYRegisterInfo.td - CSKY Register defs -----------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Declarations that describe the CSKY registers.
+//===----------------------------------------------------------------------===//
+
+let Namespace = "CSKY" in {
+ class CSKYReg<bits<6> Enc, string n, list<string> alt = []> : Register<n> {
+ let HWEncoding{5 - 0} = Enc;
+ let AltNames = alt;
+ }
+
+ class CSKYFReg32<bits<5> Enc, string n, list<string> alt = []> : Register<n> {
+ let HWEncoding{4 - 0} = Enc;
+ let AltNames = alt;
+ }
+
+ // Because CSKYFReg64 register have AsmName and AltNames that alias with their
+ // 32-bit sub-register, CSKYAsmParser will need to coerce a register number
+ // from a CSKYFReg32 to the equivalent CSKYFReg64 when appropriate.
+ def sub32_0 : SubRegIndex<32, 0>;
+ def sub32_32 : SubRegIndex<32, 32>;
+ def sub64_0 : SubRegIndex<64, 0>;
+ def sub64_64 : SubRegIndex<64,64>;
+
+ class CSKYFReg64<CSKYFReg32 subreg> : Register<""> {
+ let HWEncoding{4 - 0} = subreg.HWEncoding{4 - 0};
+ let SubRegs = [subreg];
+ let SubRegIndices = [sub32_0];
+ let AsmName = subreg.AsmName;
+ let AltNames = subreg.AltNames;
+ }
+
+ class CSKYFReg128<CSKYFReg64 subreg> : Register<""> {
+ let HWEncoding{4 - 0} = subreg.HWEncoding{4 - 0};
+ let SubRegs = [subreg];
+ let SubRegIndices = [sub64_0];
+ let AsmName = subreg.AsmName;
+ let AltNames = subreg.AltNames;
+ }
+
+ def ABIRegAltName : RegAltNameIndex;
+} // Namespace = "CSKY"
+
+let RegAltNameIndices = [ABIRegAltName] in {
+ def R0 : CSKYReg<0, "r0", ["a0"]>, DwarfRegNum<[0]>;
+ def R1 : CSKYReg<1, "r1", ["a1"]>, DwarfRegNum<[1]>;
+ def R2 : CSKYReg<2, "r2", ["a2"]>, DwarfRegNum<[2]>;
+ def R3 : CSKYReg<3, "r3", ["a3"]>, DwarfRegNum<[3]>;
+ def R4 : CSKYReg<4, "r4", ["l0"]>, DwarfRegNum<[4]>;
+ def R5 : CSKYReg<5, "r5", ["l1"]>, DwarfRegNum<[5]>;
+ def R6 : CSKYReg<6, "r6", ["l2"]>, DwarfRegNum<[6]>;
+ def R7 : CSKYReg<7, "r7", ["l3"]>, DwarfRegNum<[7]>;
+ def R8 : CSKYReg<8, "r8", ["l4"]>, DwarfRegNum<[8]>;
+ def R9 : CSKYReg<9, "r9", ["l5"]>, DwarfRegNum<[9]>;
+ def R10 : CSKYReg<10, "r10", ["l6"]>, DwarfRegNum<[10]>;
+ def R11 : CSKYReg<11, "r11", ["l7"]>, DwarfRegNum<[11]>;
+ def R12 : CSKYReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>;
+ def R13 : CSKYReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>;
+ def R14 : CSKYReg<14, "r14", ["sp"]>, DwarfRegNum<[14]>;
+ def R15 : CSKYReg<15, "r15", ["lr"]>, DwarfRegNum<[15]>;
+ def R16 : CSKYReg<16, "r16", ["l8"]>, DwarfRegNum<[16]>;
+ def R17 : CSKYReg<17, "r17", ["l9"]>, DwarfRegNum<[17]>;
+ def R18 : CSKYReg<18, "r18", ["t2"]>, DwarfRegNum<[18]>;
+ def R19 : CSKYReg<19, "r19", ["t3"]>, DwarfRegNum<[19]>;
+ def R20 : CSKYReg<20, "r20", ["t4"]>, DwarfRegNum<[20]>;
+ def R21 : CSKYReg<21, "r21", ["t5"]>, DwarfRegNum<[21]>;
+ def R22 : CSKYReg<22, "r22", ["t6"]>, DwarfRegNum<[22]>;
+ def R23 : CSKYReg<23, "r23", ["t7"]>, DwarfRegNum<[23]>;
+ def R24 : CSKYReg<24, "r24", ["t8"]>, DwarfRegNum<[24]>;
+ def R25 : CSKYReg<25, "r25", ["t9"]>, DwarfRegNum<[25]>;
+ def R26 : CSKYReg<26, "r26", ["r26"]>, DwarfRegNum<[26]>;
+ def R27 : CSKYReg<27, "r27", ["r27"]>, DwarfRegNum<[27]>;
+ def R28 : CSKYReg<28, "r28", ["rgb"]>, DwarfRegNum<[28]>;
+ def R29 : CSKYReg<29, "r29", ["rtb"]>, DwarfRegNum<[29]>;
+ def R30 : CSKYReg<30, "r30", ["svbr"]>, DwarfRegNum<[30]>;
+ def R31 : CSKYReg<31, "r31", ["tls"]>, DwarfRegNum<[31]>;
+ def C : CSKYReg<32, "cr0", ["psr"]>;
+
+}
+
+def GPRTuple : RegisterTuples<
+ [sub32_0, sub32_32],
+ [(add (sequence "R%u", 0, 30)), (add (sequence "R%u", 1, 31))],
+ [ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30"
+ ]>;
+
+// Floating point registers
+let RegAltNameIndices = [ABIRegAltName] in {
+ def F0_32 : CSKYFReg32<0, "fr0", ["vr0"]>, DwarfRegNum<[32]>;
+ def F1_32 : CSKYFReg32<1, "fr1", ["vr1"]>, DwarfRegNum<[33]>;
+ def F2_32 : CSKYFReg32<2, "fr2", ["vr2"]>, DwarfRegNum<[34]>;
+ def F3_32 : CSKYFReg32<3, "fr3", ["vr3"]>, DwarfRegNum<[35]>;
+ def F4_32 : CSKYFReg32<4, "fr4", ["vr4"]>, DwarfRegNum<[36]>;
+ def F5_32 : CSKYFReg32<5, "fr5", ["vr5"]>, DwarfRegNum<[37]>;
+ def F6_32 : CSKYFReg32<6, "fr6", ["vr6"]>, DwarfRegNum<[38]>;
+ def F7_32 : CSKYFReg32<7, "fr7", ["vr7"]>, DwarfRegNum<[39]>;
+ def F8_32 : CSKYFReg32<8, "fr8", ["vr8"]>, DwarfRegNum<[40]>;
+ def F9_32 : CSKYFReg32<9, "fr9", ["vr9"]>, DwarfRegNum<[41]>;
+ def F10_32 : CSKYFReg32<10, "fr10", ["vr10"]>, DwarfRegNum<[42]>;
+ def F11_32 : CSKYFReg32<11, "fr11", ["vr11"]>, DwarfRegNum<[43]>;
+ def F12_32 : CSKYFReg32<12, "fr12", ["vr12"]>, DwarfRegNum<[44]>;
+ def F13_32 : CSKYFReg32<13, "fr13", ["vr13"]>, DwarfRegNum<[45]>;
+ def F14_32 : CSKYFReg32<14, "fr14", ["vr14"]>, DwarfRegNum<[46]>;
+ def F15_32 : CSKYFReg32<15, "fr15", ["vr15"]>, DwarfRegNum<[47]>;
+ def F16_32 : CSKYFReg32<16, "fr16", ["vr16"]>, DwarfRegNum<[48]>;
+ def F17_32 : CSKYFReg32<17, "fr17", ["vr17"]>, DwarfRegNum<[49]>;
+ def F18_32 : CSKYFReg32<18, "fr18", ["vr18"]>, DwarfRegNum<[50]>;
+ def F19_32 : CSKYFReg32<19, "fr19", ["vr19"]>, DwarfRegNum<[51]>;
+ def F20_32 : CSKYFReg32<20, "fr20", ["vr20"]>, DwarfRegNum<[52]>;
+ def F21_32 : CSKYFReg32<21, "fr21", ["vr21"]>, DwarfRegNum<[53]>;
+ def F22_32 : CSKYFReg32<22, "fr22", ["vr22"]>, DwarfRegNum<[54]>;
+ def F23_32 : CSKYFReg32<23, "fr23", ["vr23"]>, DwarfRegNum<[55]>;
+ def F24_32 : CSKYFReg32<24, "fr24", ["vr24"]>, DwarfRegNum<[56]>;
+ def F25_32 : CSKYFReg32<25, "fr25", ["vr25"]>, DwarfRegNum<[57]>;
+ def F26_32 : CSKYFReg32<26, "fr26", ["vr26"]>, DwarfRegNum<[58]>;
+ def F27_32 : CSKYFReg32<27, "fr27", ["vr27"]>, DwarfRegNum<[59]>;
+ def F28_32 : CSKYFReg32<28, "fr28", ["vr28"]>, DwarfRegNum<[60]>;
+ def F29_32 : CSKYFReg32<29, "fr29", ["vr29"]>, DwarfRegNum<[61]>;
+ def F30_32 : CSKYFReg32<30, "fr30", ["vr30"]>, DwarfRegNum<[62]>;
+ def F31_32 : CSKYFReg32<31, "fr31", ["vr31"]>, DwarfRegNum<[63]>;
+
+ foreach Index = 0 - 31 in {
+ def F#Index#_64 : CSKYFReg64<!cast<CSKYFReg32>("F"#Index#"_32")>,
+ DwarfRegNum<[!add(Index, 32)]>;
+
+ def F#Index#_128 : CSKYFReg128<!cast<CSKYFReg64>("F"#Index#"_64")>,
+ DwarfRegNum<[!add(Index, 32)]>;
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Declarations that describe the CSKY register class.
+//===----------------------------------------------------------------------===//
+
+// The order of registers represents the preferred allocation sequence.
+// Registers are listed in the order caller-save, callee-save, specials.
+def GPR : RegisterClass<"CSKY", [i32], 32,
+ (add (sequence "R%u", 0, 3), (sequence "R%u", 12, 13),
+ (sequence "R%u", 18, 25), R15, (sequence "R%u", 4, 11),
+ (sequence "R%u", 16, 17), (sequence "R%u", 26, 27), R28,
+ (sequence "R%u", 29, 30), R14, R31)> {
+ let Size = 32;
+}
+
+def GPRPair : RegisterClass<"CSKY", [untyped], 32, (add GPRTuple)> {
+ let Size = 64;
+}
+
+def CARRY : RegisterClass<"CSKY", [i32], 32, (add C)> {
+ let Size = 32;
+ let CopyCost = -1;
+}
+
+// The order of registers represents the preferred allocation sequence.
+// Registers are listed in the order caller-save, callee-save, specials.
+def FPR32 : RegisterClass<"CSKY", [f32], 32,
+ (add (sequence "F%u_32", 0, 31))>;
+def sFPR32 : RegisterClass<"CSKY", [f32], 32,
+ (add (sequence "F%u_32", 0, 15))>;
+
+def FPR64 : RegisterClass<"CSKY", [f64], 64,
+ (add (sequence "F%u_64", 0, 31))>;
+def sFPR64 : RegisterClass<"CSKY", [f64], 64,
+ (add (sequence "F%u_64", 0, 15))>;
+
+def FPR128 : RegisterClass<"CSKY",
+ [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128,
+ (add (sequence "F%u_128", 0, 31))>;
+def sFPR128 : RegisterClass<"CSKY",
+ [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128,
+ (add (sequence "F%u_128", 0, 15))>;