forked from OSchip/llvm-project
236 lines
8.4 KiB
TableGen
236 lines
8.4 KiB
TableGen
//===-- Nios2InstrFormats.td - Nios2 Instruction Formats ---*- tablegen -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Describe NIOS2 instructions format
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Format specifies the encoding used by the instruction. This is part of the
|
|
// ad-hoc solution used to emit machine instruction encodings by our machine
|
|
// code emitter.
|
|
class Format<bits<6> val> {
|
|
bits<6> Value = val;
|
|
}
|
|
|
|
def Pseudo : Format<0>;
|
|
// Nios2 R1 instr formats:
|
|
def FrmI : Format<1>;
|
|
def FrmR : Format<2>;
|
|
def FrmJ : Format<3>;
|
|
def FrmOther : Format<4>; // Instruction w/ a custom format
|
|
// Nios2 R2 instr 32-bit formats:
|
|
def FrmL26 : Format<5>; // corresponds to J format in R1
|
|
def FrmF2I16 : Format<6>; // corresponds to I format in R1
|
|
def FrmF2X4I12 : Format<7>;
|
|
def FrmF1X4I12 : Format<8>;
|
|
def FrmF1X4L17 : Format<9>;
|
|
def FrmF3X6L5 : Format<10>; // corresponds to R format in R1
|
|
def FrmF2X6L10 : Format<11>;
|
|
def FrmF3X6 : Format<12>; // corresponds to R format in R1
|
|
def FrmF3X8 : Format<13>; // corresponds to custom format in R1
|
|
// Nios2 R2 instr 16-bit formats:
|
|
def FrmI10 : Format<14>;
|
|
def FrmT1I7 : Format<15>;
|
|
def FrmT2I4 : Format<16>;
|
|
def FrmT1X1I6 : Format<17>;
|
|
def FrmX1I7 : Format<18>;
|
|
def FrmL5I4X1 : Format<19>;
|
|
def FrmT2X1L3 : Format<20>;
|
|
def FrmT2X1I3 : Format<21>;
|
|
def FrmT3X1 : Format<22>;
|
|
def FrmT2X3 : Format<23>;
|
|
def FrmF1X1 : Format<24>;
|
|
def FrmX2L5 : Format<25>;
|
|
def FrmF1I5 : Format<26>;
|
|
def FrmF2 : Format<27>;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Instruction Predicates:
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def isNios2r1 : Predicate<"Subtarget->isNios2r1()">;
|
|
def isNios2r2 : Predicate<"Subtarget->isNios2r2()">;
|
|
|
|
class PredicateControl {
|
|
// Predicates related to specific target CPU features
|
|
list<Predicate> FeaturePredicates = [];
|
|
// Predicates for the instruction group membership in given ISA
|
|
list<Predicate> InstrPredicates = [];
|
|
|
|
list<Predicate> Predicates = !listconcat(FeaturePredicates, InstrPredicates);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Base classes for 32-bit, 16-bit and pseudo instructions
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class Nios2Inst32<dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin, Format f>: Instruction,
|
|
PredicateControl {
|
|
field bits<32> Inst;
|
|
Format Form = f;
|
|
|
|
let Namespace = "Nios2";
|
|
let Size = 4;
|
|
|
|
bits<6> Opcode = 0;
|
|
|
|
// Bottom 6 bits are the 'opcode' field
|
|
let Inst{5-0} = Opcode;
|
|
|
|
let OutOperandList = outs;
|
|
let InOperandList = ins;
|
|
|
|
let AsmString = asmstr;
|
|
let Pattern = pattern;
|
|
let Itinerary = itin;
|
|
|
|
// Attributes specific to Nios2 instructions:
|
|
|
|
// TSFlags layout should be kept in sync with Nios2InstrInfo.h.
|
|
let TSFlags{5-0} = Form.Value;
|
|
let DecoderNamespace = "Nios2";
|
|
field bits<32> SoftFail = 0;
|
|
}
|
|
|
|
class Nios2Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass Itin = IIPseudo>:
|
|
Nios2Inst32<outs, ins, asmstr, pattern, Itin, Pseudo> {
|
|
|
|
let isCodeGenOnly = 1;
|
|
let isPseudo = 1;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Base classes for R1 and R2 instructions
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class Nios2R1Inst32<dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin, Format f>:
|
|
Nios2Inst32<outs, ins, asmstr, pattern, itin, f> {
|
|
let DecoderNamespace = "Nios2";
|
|
let InstrPredicates = [isNios2r1];
|
|
}
|
|
|
|
class Nios2R2Inst32<dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin, Format f>:
|
|
Nios2Inst32<outs, ins, asmstr, pattern, itin, f> {
|
|
let DecoderNamespace = "Nios2r2";
|
|
let InstrPredicates = [isNios2r2];
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Format I instruction class in Nios2 : <|A|B|immediate|opcode|>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin>: Nios2R1Inst32<outs, ins, asmstr,
|
|
pattern, itin, FrmI> {
|
|
|
|
bits<5> rA;
|
|
bits<5> rB;
|
|
bits<16> imm;
|
|
|
|
let Opcode = op;
|
|
|
|
let Inst{31-27} = rA;
|
|
let Inst{26-22} = rB;
|
|
let Inst{21-6} = imm;
|
|
}
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Format R instruction : <|A|B|C|opx|imm|opcode|>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class FR<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin>: Nios2R1Inst32<outs, ins, asmstr,
|
|
pattern, itin, FrmR> {
|
|
bits<5> rA;
|
|
bits<5> rB;
|
|
bits<5> rC;
|
|
bits<5> imm = 0;
|
|
|
|
let Opcode = 0x3a; /* opcode is always 0x3a for R instr. */
|
|
|
|
let Inst{31-27} = rA;
|
|
let Inst{26-22} = rB;
|
|
let Inst{21-17} = rC;
|
|
let Inst{16-11} = opx; /* opx stands for opcode extension */
|
|
let Inst{10-6} = imm; /* optional 5-bit immediate value */
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Format J instruction class in Nios2 : <|address|opcode|>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin>:
|
|
Nios2R1Inst32<outs, ins, asmstr, pattern, itin, FrmJ> {
|
|
bits<26> addr;
|
|
let Opcode = op;
|
|
let Inst{31-6} = addr;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Format F3X6 (R2) instruction : <|opx|RSV|C|B|A|opcode|>
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class F3X6<bits<6> opx, dag outs, dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin>:
|
|
Nios2R2Inst32<outs, ins, asmstr, pattern, itin, FrmF3X6> {
|
|
bits<5> rC;
|
|
bits<5> rB;
|
|
bits<5> rA;
|
|
bits<5> rsv = 0;
|
|
|
|
let Opcode = 0x20; /* opcode is always 0x20 (OPX group) for F3X6 instr. */
|
|
|
|
let Inst{31-26} = opx; /* opx stands for opcode extension */
|
|
let Inst{25-21} = rsv;
|
|
let Inst{20-16} = rC;
|
|
let Inst{15-11} = rB;
|
|
let Inst{10-6} = rA;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Multiclasses for common instructions of both R1 and R2:
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Multiclass for instructions that have R format in R1 and F3X6 format in R2
|
|
// and their opx values differ between R1 and R2
|
|
multiclass CommonInstr_R_F3X6_opx<bits<6> opxR1, bits<6> opxR2, dag outs,
|
|
dag ins, string asmstr, list<dag> pattern,
|
|
InstrItinClass itin> {
|
|
def NAME#_R1 : FR<opxR1, outs, ins, asmstr, pattern, itin>;
|
|
def NAME#_R2 : F3X6<opxR2, outs, ins, asmstr, pattern, itin>;
|
|
}
|
|
|
|
// Multiclass for instructions that have R format in R1 and F3X6 format in R2
|
|
// and their opx values are the same in R1 and R2
|
|
multiclass CommonInstr_R_F3X6<bits<6> opx, dag outs, dag ins, string asmstr,
|
|
list<dag> pattern, InstrItinClass itin> :
|
|
CommonInstr_R_F3X6_opx<opx, opx, outs, ins, asmstr, pattern, itin>;
|
|
|
|
// Multiclass for instructions that have I format in R1 and F2I16 format in R2
|
|
// and their op code values differ between R1 and R2
|
|
multiclass CommonInstr_I_F2I16_op<bits<6> opR1, bits<6> opR2, dag outs, dag ins,
|
|
string asmstr, list<dag> pattern,
|
|
InstrItinClass itin> {
|
|
def NAME#_R1 : FI<opR1, outs, ins, asmstr, pattern, itin>;
|
|
}
|
|
|
|
// Multiclass for instructions that have I format in R1 and F2I16 format in R2
|
|
// and their op code values are the same in R1 and R2
|
|
multiclass CommonInstr_I_F2I16<bits<6> op, dag outs, dag ins, string asmstr,
|
|
list<dag> pattern, InstrItinClass itin> :
|
|
CommonInstr_I_F2I16_op<op, op, outs, ins, asmstr, pattern, itin>;
|