diff --git a/llvm/lib/Target/CSKY/CMakeLists.txt b/llvm/lib/Target/CSKY/CMakeLists.txt --- a/llvm/lib/Target/CSKY/CMakeLists.txt +++ b/llvm/lib/Target/CSKY/CMakeLists.txt @@ -1,5 +1,12 @@ add_llvm_component_group(CSKY) +set(LLVM_TARGET_DEFINITIONS CSKY.td) + +tablegen(LLVM CSKYGenRegisterInfo.inc -gen-register-info) +tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info) + +add_public_tablegen_target(CSKYCommonTableGen) + add_llvm_target(CSKYCodeGen CSKYTargetMachine.cpp diff --git a/llvm/lib/Target/CSKY/CSKY.td b/llvm/lib/Target/CSKY/CSKY.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/CSKY/CSKY.td @@ -0,0 +1,32 @@ +//===-- CSKY.td - Describe the CSKY Target Machine ---------*- 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 +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +//===----------------------------------------------------------------------===// +// Registers, calling conventions, instruction descriptions. +//===----------------------------------------------------------------------===// + +include "CSKYRegisterInfo.td" +include "CSKYInstrInfo.td" + +//===----------------------------------------------------------------------===// +// CSKY processors supported. +//===----------------------------------------------------------------------===// + +def : ProcessorModel<"generic-csky", NoSchedModel, []>; + +//===----------------------------------------------------------------------===// +// Define the CSKY target. +//===----------------------------------------------------------------------===// + +def CSKYInstrInfo : InstrInfo; + +def CSKY : Target { + let InstructionSet = CSKYInstrInfo; +} diff --git a/llvm/lib/Target/CSKY/CSKYInstrFormats.td b/llvm/lib/Target/CSKY/CSKYInstrFormats.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/CSKY/CSKYInstrFormats.td @@ -0,0 +1,528 @@ +//===-- 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 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 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 pattern> + : CSKYInst { + let isCodeGenOnly = 1; + let isPseudo = 1; +} + +class CSKY32Inst opcode, dag outs, dag ins, string asmstr, + list pattern> + : CSKYInst { + field bits<32> Inst; + let Inst{31 - 26} = opcode; +} + +// CSKY 32-bit instruction +// Format< OP[6] | Offset[26] > +// Instruction(1): bsr32 +class J opcode, dag outs, dag ins, string op, list pattern> + : CSKY32Inst { + 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 sop, string op, Operand operand, list pattern> + : CSKY32Inst { + 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 pattern> + : CSKY32Inst { + 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 sop, string op, ImmLeaf ImmType> + : CSKY32Inst { + 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 sop, string op, Operand operand, list pattern> + : CSKY32Inst { + 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 sop, dag outs, dag ins, string op, list pattern> + : CSKY32Inst { + 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 sop, string op, Operand operand, list pattern> + : I_16_L { + let isBranch = 1; + let isTerminator = 1; +} + +// Format< OP[6] | SOP[5] | RX[5] | 0000000000000000[16] > +// Instructions(2): jmp32, jsr32 +class I_16_JX sop, string op, list pattern> + : CSKY32Inst { + 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 sop, string op, Operand operand, list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + 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 sop, string op> + : CSKY32Inst { + 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 sop, string op, Operand operand> + : CSKY32Inst { + 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 sop, string op, SDNode node, ImmLeaf ImmType> + : CSKY32Inst { + 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 opcode, bits<4> sop, dag outs, dag ins, + string op, list pattern> + : CSKY32Inst { + 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 sop, string op, Operand operand> + : I_LDST; + +// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] > +// Instructions(4): st32.b, st32.h, st32.w, st32.d +class I_ST sop, string op, Operand operand> + : I_LDST; + +// Format< OP[6] | SOP[5] | PCODE[5] | 0000[4] | 000 | R28 | LIST2[3] | R15 | +// LIST1[4] > +// Instructions(2): push32, pop32 +class I_12_PP sop, bits<5> pcode, dag outs, dag ins, string op> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, ImmLeaf ImmType, + list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, dag ins, dag outs, + list pattern> + : CSKY32Inst { + 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 opcode, dag outs, dag ins, string op, list pattern, + bits<5> imm5> + : CSKY32Inst(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 sop, bits<5> lsb, bits<5> msb, dag outs, dag ins, + string op, list pattern> + : CSKY32Inst(msb) #", " #!cast(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 sop, bits<5> lsb, bits<5> msb, string op, SDNode opnode, + ValueType type> : I_5_XZ_U; + +class I_5_XZ_UZ sop, bits<5> lsb, bits<5> msb, string op, int v> + : I_5_XZ_U; + +// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | SIZE[5] | LSB[5]> +// Instructions(1): ins32 +class I_5_ZX_U sop, string op, Operand operand, list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, ImmLeaf ImmType, + list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, ImmLeaf ImmType, + list pattern> + : CSKY32Inst { + 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 opcode, bits<6> sop, bits<5> pcode, dag outs, dag ins, + string op, list pattern> + : CSKY32Inst { + 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 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 opcode, bits<6> sop, bits<5> pcode, int no, dag outs, + dag ins, string op, list pattern> + : CSKY32Inst { + 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 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 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 sop, bits<5> pcode, dag outs, dag ins, string op, + list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op> + : CSKY32Inst { + 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 sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + 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"; +} diff --git a/llvm/lib/Target/CSKY/CSKYInstrInfo.td b/llvm/lib/Target/CSKY/CSKYInstrInfo.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/CSKY/CSKYInstrInfo.td @@ -0,0 +1,108 @@ +//===-- 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 : Operand, + ImmLeaf(Imm - 1);"> { + let EncoderMethod = "getOImmOpValue<"#num#">"; +} + +class uimm : Operand, + ImmLeaf(Imm);"> { + let EncoderMethod = "getImmOpValue<"#num#", "#shift#">"; +} + +class simm : Operand, + ImmLeaf(Imm);"> { + let EncoderMethod = "getImmOpValue<"#num#", "#shift#">"; +} + +def nimm_XFORM : SDNodeXFormgetTargetConstant(~N->getSExtValue(), SDLoc(N), MVT::i32); +}]>; +class nimm : Operand, + ImmLeaf(~Imm);", nimm_XFORM> { +} + + +def oimm12 : oimm<12>; + +def nimm12 : nimm<12>; + +def uimm5 : uimm<5>; +def uimm12 : uimm<12>; + +//===----------------------------------------------------------------------===// +// Instruction definitions. +//===----------------------------------------------------------------------===// + +class TriOpFrag : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>; +class BinOpFrag : PatFrag<(ops node:$LHS, node:$RHS), res>; +class UnOpFrag : 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))]>; diff --git a/llvm/lib/Target/CSKY/CSKYRegisterInfo.td b/llvm/lib/Target/CSKY/CSKYRegisterInfo.td new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/CSKY/CSKYRegisterInfo.td @@ -0,0 +1,182 @@ +//===-- 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 Enc, string n, list alt = []> : Register { + let HWEncoding{5 - 0} = Enc; + let AltNames = alt; + } + + class CSKYFReg32 Enc, string n, list alt = []> : Register { + 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 : 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 : 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("F"#Index#"_32")>, + DwarfRegNum<[!add(Index, 32)]>; + + def F#Index#_128 : CSKYFReg128("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))>;