Index: lib/Target/RISCV/CMakeLists.txt =================================================================== --- lib/Target/RISCV/CMakeLists.txt +++ lib/Target/RISCV/CMakeLists.txt @@ -1,3 +1,10 @@ +set(LLVM_TARGET_DEFINITIONS RISCV.td) + +tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) +tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info) + +add_public_tablegen_target(RISCVCommonTableGen) + add_llvm_target(RISCVCodeGen RISCVTargetMachine.cpp ) Index: lib/Target/RISCV/RISCV.td =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCV.td @@ -0,0 +1,27 @@ +//===-- RISCV.td - Describe the RISCV Target Machine -------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +include "RISCVRegisterInfo.td" +include "RISCVInstrInfo.td" + + +def RISCVInstrInfo : InstrInfo; + +def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", + "Implements RV64">; + +def : ProcessorModel<"generic-rv32", NoSchedModel, []>; + +def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>; + +def RISCV : Target { + let InstructionSet = RISCVInstrInfo; +} Index: lib/Target/RISCV/RISCVInstrFormats.td =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVInstrFormats.td @@ -0,0 +1,152 @@ +//===-- RISCVInstrFormats.td - RISCV Instruction Formats ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// +// These instruction format definitions are structured to match the +// description in the RISC-V User-Level ISA specification as closely as +// possible. For instance, the specification describes instructions with the +// MSB (31st bit) on the left and the LSB (0th bit) on the right. This is +// reflected in the order of parameters to each instruction class. +// +// One area of divergence is in the description of immediates. The +// specification describes immediate encoding in terms of bit-slicing +// operations on the logical value represented. The immediate argument to +// these instruction formats instead represents the bit sequence that will be +// inserted into the instruction. e.g. although JAL's immediate is logically +// a 21-bit value (where the LSB is always zero), we describe it as an imm20 +// to match how it is encoded. +// +//===----------------------------------------------------------------------===// + +class RISCVInst pattern> + : Instruction { + field bits<32> Inst; + let Size = 4; + + bits<7> Opcode = 0; + + let Inst{6-0} = Opcode; + + let Namespace = "RISCV"; + + dag OutOperandList = outs; + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; +} + +// Pseudo instructions +class Pseudo pattern> + : RISCVInst { + let isPseudo = 1; +} + +class FR funct7, bits<3> funct3, bits<7> opcode, dag outs, dag ins, + string asmstr, list pattern> : RISCVInst +{ + bits<5> rs2; + bits<5> rs1; + bits<5> rd; + + let Inst{31-25} = funct7; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = funct3; + let Inst{11-7} = rd; + let Opcode = opcode; +} + +class FI funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<12> imm12; + bits<5> rs1; + bits<5> rd; + + let Inst{31-20} = imm12; + let Inst{19-15} = rs1; + let Inst{14-12} = funct3; + let Inst{11-7} = rd; + let Opcode = opcode; +} + +class FI32Shift funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<5> shamt; + bits<5> rs1; + bits<5> rd; + + let Inst{31} = 0; + let Inst{30} = arithshift; + let Inst{29-25} = 0; + let Inst{24-20} = shamt; + let Inst{19-15} = rs1; + let Inst{14-12} = funct3; + let Inst{11-7} = rd; + let Opcode = opcode; +} + +class FS funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<12> imm12; + bits<5> rs2; + bits<5> rs1; + + let Inst{31-25} = imm12{11-5}; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = funct3; + let Inst{11-7} = imm12{4-0}; + let Opcode = opcode; +} + +class FSB funct3, bits<7> opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<12> imm12; + bits<5> rs2; + bits<5> rs1; + + let Inst{31} = imm12{11}; + let Inst{30-25} = imm12{9-4}; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = funct3; + let Inst{11-8} = imm12{3-0}; + let Inst{7} = imm12{10}; + let Opcode = opcode; +} + +class FU opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<20> imm20; + bits<5> rd; + + let Inst{31-12} = imm20; + let Inst{11-7} = rd; + let Opcode = opcode; +} + +class FUJ opcode, dag outs, dag ins, string asmstr, list pattern> + : RISCVInst +{ + bits<20> imm20; + bits<5> rd; + + let Inst{31} = imm20{19}; + let Inst{30-21} = imm20{9-0}; + let Inst{20} = imm20{10}; + let Inst{19-12} = imm20{18-11}; + let Inst{11-7} = rd; + let Opcode = opcode; +} Index: lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -0,0 +1,55 @@ +//===-- RISCVInstrInfo.td - Target Description for RISCV ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +include "RISCVInstrFormats.td" + +def simm12 : Operand; + +// As noted in RISCVRegisterInfo.td, the hope is that support for +// variable-sized register classes will mean that instruction definitions do +// not need to be duplicated for 32-bit and 64-bit register classes. For now +// we use 'GPR', which is 32-bit. When codegen for both RV32 and RV64 is +// added, we will need to duplicate instruction definitions unless a proposal +// like +// is adopted. + +class ALU_ri funct3, string OpcodeStr> : + FI +{ +} + +def ADDI : ALU_ri<0b000, "addi">; +def SLTI : ALU_ri<0b010, "slti">; +def SLTIU : ALU_ri<0b011, "sltiu">; +def XORI : ALU_ri<0b100, "xori">; +def ORI : ALU_ri<0b110, "ori">; +def ANDI : ALU_ri<0b111, "andi">; + +class ALU_rr funct7, bits<3> funct3, string OpcodeStr> : + FR +{ +} + +def ADD : ALU_rr<0b0000000, 0b000, "add">; +def SUB : ALU_rr<0b0100000, 0b000, "sub">; +def SLL : ALU_rr<0b0000000, 0b001, "sll">; +def SLT : ALU_rr<0b0000000, 0b010, "slt">; +def SLTU : ALU_rr<0b0000000, 0b011, "sltu">; +def XOR : ALU_rr<0b0000000, 0b100, "xor">; +def SRL : ALU_rr<0b0000000, 0b101, "srl">; +def SRA : ALU_rr<0b0100000, 0b101, "sra">; +def OR : ALU_rr<0b0000000, 0b110, "or">; +def AND : ALU_rr<0b0000000, 0b111, "and">; + Index: lib/Target/RISCV/RISCVRegisterInfo.td =================================================================== --- /dev/null +++ lib/Target/RISCV/RISCVRegisterInfo.td @@ -0,0 +1,87 @@ +//===-- RISCVRegisterInfo.td - RISC-V Register defs --------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Declarations that describe the RISC-V register file +//===----------------------------------------------------------------------===// + +let Namespace = "RISCV" in { + def sub_32 : SubRegIndex<32>; + + class RISCVReg32 Enc, string n, list alt = []> : Register { + let HWEncoding{4-0} = Enc; + let AltNames = alt; + } + + class RISCVReg64 : Register { + let HWEncoding{4-0} = subreg.HWEncoding{4-0}; + let AltNames = subreg.AltNames; + let RegAltNameIndices = subreg.RegAltNameIndices; + let SubRegs = [subreg]; + let SubRegIndices = [sub_32]; + } + + def ABIRegAltName : RegAltNameIndex; +} + +// Integer registers +let RegAltNameIndices = [ABIRegAltName] in { + def X0_32 : RISCVReg32<0, "x0", ["zero"]>, DwarfRegNum<[0]>; + def X1_32 : RISCVReg32<1, "x1", ["ra"]>, DwarfRegNum<[1]>; + def X2_32 : RISCVReg32<2, "x2", ["sp"]>, DwarfRegNum<[2]>; + def X3_32 : RISCVReg32<3, "x3", ["gp"]>, DwarfRegNum<[3]>; + def X4_32 : RISCVReg32<4, "x4", ["tp"]>, DwarfRegNum<[4]>; + def X5_32 : RISCVReg32<5, "x5", ["t0"]>, DwarfRegNum<[5]>; + def X6_32 : RISCVReg32<6, "x6", ["t1"]>, DwarfRegNum<[6]>; + def X7_32 : RISCVReg32<7, "x7", ["t2"]>, DwarfRegNum<[7]>; + def X8_32 : RISCVReg32<8, "x8", ["s0"]>, DwarfRegNum<[8]>; + def X9_32 : RISCVReg32<9, "x9", ["s1"]>, DwarfRegNum<[9]>; + def X10_32 : RISCVReg32<10,"x10", ["a0"]>, DwarfRegNum<[10]>; + def X11_32 : RISCVReg32<11,"x11", ["a1"]>, DwarfRegNum<[11]>; + def X12_32 : RISCVReg32<12,"x12", ["a2"]>, DwarfRegNum<[12]>; + def X13_32 : RISCVReg32<13,"x13", ["a3"]>, DwarfRegNum<[13]>; + def X14_32 : RISCVReg32<14,"x14", ["a4"]>, DwarfRegNum<[14]>; + def X15_32 : RISCVReg32<15,"x15", ["a5"]>, DwarfRegNum<[15]>; + def X16_32 : RISCVReg32<16,"x16", ["a6"]>, DwarfRegNum<[16]>; + def X17_32 : RISCVReg32<17,"x17", ["a7"]>, DwarfRegNum<[17]>; + def X18_32 : RISCVReg32<18,"x18", ["s2"]>, DwarfRegNum<[18]>; + def X19_32 : RISCVReg32<19,"x19", ["s3"]>, DwarfRegNum<[19]>; + def X20_32 : RISCVReg32<20,"x20", ["s4"]>, DwarfRegNum<[20]>; + def X21_32 : RISCVReg32<21,"x21", ["s5"]>, DwarfRegNum<[21]>; + def X22_32 : RISCVReg32<22,"x22", ["s6"]>, DwarfRegNum<[22]>; + def X23_32 : RISCVReg32<23,"x23", ["s7"]>, DwarfRegNum<[23]>; + def X24_32 : RISCVReg32<24,"x24", ["s8"]>, DwarfRegNum<[24]>; + def X25_32 : RISCVReg32<25,"x25", ["s9"]>, DwarfRegNum<[25]>; + def X26_32 : RISCVReg32<26,"x26", ["s10"]>, DwarfRegNum<[26]>; + def X27_32 : RISCVReg32<27,"x27", ["s11"]>, DwarfRegNum<[27]>; + def X28_32 : RISCVReg32<28,"x28", ["t3"]>, DwarfRegNum<[28]>; + def X29_32 : RISCVReg32<29,"x29", ["t4"]>, DwarfRegNum<[29]>; + def X30_32 : RISCVReg32<30,"x30", ["t5"]>, DwarfRegNum<[30]>; + def X31_32 : RISCVReg32<31,"x31", ["t6"]>, DwarfRegNum<[31]>; +} + +foreach Index = 0-31 in { + def X#Index#_64 : RISCVReg64("X"#Index#"_32")>, DwarfRegNum<[Index]>; +} + +// We currently define separate register classes for the 32-bit and 64-bit +// GPRs. Once variable-sized register classes +// or +// similar are implemented, we can just use one 'GPR' class for most +// instruction definitions. + +// TODO: once codegen is implemented, registers should be listed in an order +// reflecting the preferred register allocation sequence. +def GPR : RegisterClass<"RISCV", [i32], 32, (add + (sequence "X%u_32", 0, 31) +)>; + +def GPR64 : RegisterClass<"RISCV", [i64], 64, (add + (sequence "X%u_64", 0, 31) +)>;