mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Final patch that completes old JIT support for Mips:
-Fix binary codes and rename operands in .td files so that automatically generated function MipsCodeEmitter::getBinaryCodeForInstr gives correct encoding for instructions. -Define new class FMem for instructions that access memory. -Define new class FFRGPR for instructions that move data between GPR and FPU general and control registers. -Define custom encoder methods for memory operands, and also for size operands of ext and ins instructions. -Only static relocation model is currently implemented. Patch by Sasa Stankovic git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142378 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de1ff7f552
commit
c3f16b316a
@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Mips.td)
|
||||
|
||||
llvm_tablegen(MipsGenRegisterInfo.inc -gen-register-info)
|
||||
llvm_tablegen(MipsGenInstrInfo.inc -gen-instr-info)
|
||||
llvm_tablegen(MipsGenCodeEmitter.inc -gen-emitter)
|
||||
llvm_tablegen(MipsGenAsmWriter.inc -gen-asm-writer)
|
||||
llvm_tablegen(MipsGenDAGISel.inc -gen-dag-isel)
|
||||
llvm_tablegen(MipsGenCallingConv.inc -gen-callingconv)
|
||||
|
@ -13,7 +13,7 @@ TARGET = Mips
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
|
||||
MipsGenAsmWriter.inc \
|
||||
MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
|
||||
MipsGenDAGISel.inc MipsGenCallingConv.inc \
|
||||
MipsGenSubtargetInfo.inc
|
||||
|
||||
|
@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||
unsigned getRelocation(const MachineInstr &MI,
|
||||
const MachineOperand &MO) const;
|
||||
|
||||
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
};
|
||||
}
|
||||
|
||||
@ -153,6 +156,28 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
|
||||
return Mips::reloc_mips_lo;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
|
||||
assert(MI.getOperand(OpNo).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
|
||||
return
|
||||
(getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as pos+size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
|
||||
getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||
@ -238,8 +263,4 @@ FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||
return new MipsCodeEmitter(TM, JCE);
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
|
||||
// this function will be automatically generated by the CodeEmitterGenerator
|
||||
// using TableGen
|
||||
return 0;
|
||||
}
|
||||
#include "MipsGenCodeEmitter.inc"
|
||||
|
@ -16,6 +16,8 @@ class CondMovIntFP<RegisterClass CRC, RegisterClass DRC, bits<5> fmt,
|
||||
bits<6> func, string instr_asm> :
|
||||
FFR<0x11, func, fmt, (outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F),
|
||||
!strconcat(instr_asm, "\t$fd, $fs, $rt"), []> {
|
||||
bits<5> rt;
|
||||
let ft = rt;
|
||||
let Constraints = "$F = $fd";
|
||||
}
|
||||
|
||||
@ -116,8 +118,8 @@ def MOVT_I : CondMovFPInt<CPURegs, MipsCMovFP_T, 1, "movt">;
|
||||
def MOVT_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_T, 1, "movt">,
|
||||
Requires<[HasMips64]>;
|
||||
|
||||
def MOVF_I : CondMovFPInt<CPURegs, MipsCMovFP_F, 1, "movf">;
|
||||
def MOVF_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_F, 1, "movf">,
|
||||
def MOVF_I : CondMovFPInt<CPURegs, MipsCMovFP_F, 0, "movf">;
|
||||
def MOVF_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_F, 0, "movf">,
|
||||
Requires<[HasMips64]>;
|
||||
|
||||
def MOVT_S : CondMovFPFP<FGR32, MipsCMovFP_T, 16, 1, "movt.s">;
|
||||
|
@ -76,14 +76,16 @@ def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
|
||||
// FP load.
|
||||
class FPLoad<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs RC:$ft), (ins MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(set RC:$ft, (FOp addr:$base))]>;
|
||||
FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (FOp addr:$addr))],
|
||||
IILoad>;
|
||||
|
||||
// FP store.
|
||||
class FPStore<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs), (ins RC:$ft, MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(store RC:$ft, addr:$base)]>;
|
||||
FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
|
||||
IIStore>;
|
||||
|
||||
// Instructions that convert an FP value to 32-bit fixed point.
|
||||
multiclass FFR1_W_M<bits<6> funct, string opstr> {
|
||||
@ -158,22 +160,28 @@ defm FSQRT : FFR1P_M<0x4, "sqrt", fsqrt>;
|
||||
// stores, and moves between floating-point and integer registers.
|
||||
// When defining instructions, we reference all 32-bit registers,
|
||||
// regardless of register aliasing.
|
||||
let fd = 0 in {
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
|
||||
class FFRGPR<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> {
|
||||
bits<5> rt;
|
||||
let ft = rt;
|
||||
let fd = 0;
|
||||
}
|
||||
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
"cfc1\t$rt, $fs", []>;
|
||||
|
||||
def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
|
||||
"ctc1\t$fs, $rt", []>;
|
||||
def CTC1 : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt),
|
||||
"ctc1\t$rt, $fs", []>;
|
||||
|
||||
def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
def MFC1 : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
"mfc1\t$rt, $fs",
|
||||
[(set CPURegs:$rt, (bitconvert FGR32:$fs))]>;
|
||||
|
||||
def MTC1 : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
def MTC1 : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
"mtc1\t$rt, $fs",
|
||||
[(set FGR32:$fs, (bitconvert CPURegs:$rt))]>;
|
||||
}
|
||||
|
||||
def FMOV_S : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>;
|
||||
def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>,
|
||||
@ -203,7 +211,7 @@ let Predicates = [NotN64] in {
|
||||
}
|
||||
|
||||
/// Floating-point Aritmetic
|
||||
defm FADD : FFR2P_M<0x10, "add", fadd, 1>;
|
||||
defm FADD : FFR2P_M<0x00, "add", fadd, 1>;
|
||||
defm FDIV : FFR2P_M<0x03, "div", fdiv>;
|
||||
defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>;
|
||||
defm FSUB : FFR2P_M<0x01, "sub", fsub>;
|
||||
@ -218,12 +226,16 @@ def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
|
||||
|
||||
/// Floating Point Branch of False/True (Likely)
|
||||
let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in
|
||||
class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
|
||||
(ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]>;
|
||||
class FBRANCH<bits<1> nd, bits<1> tf, PatLeaf op, string asmstr> :
|
||||
FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]> {
|
||||
let Inst{20-18} = 0;
|
||||
let Inst{17} = nd;
|
||||
let Inst{16} = tf;
|
||||
}
|
||||
|
||||
def BC1F : FBRANCH<MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<MIPS_BRANCH_T, "bc1t">;
|
||||
def BC1F : FBRANCH<0, 0, MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<0, 1, MIPS_BRANCH_T, "bc1t">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Floating Point Flag Conditions
|
||||
@ -249,11 +261,11 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>;
|
||||
|
||||
/// Floating Point Compare
|
||||
let Defs=[FCR31] in {
|
||||
def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
def FCMP_S32 : FCC<0x10, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
"c.$cc.s\t$fs, $ft",
|
||||
[(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>;
|
||||
|
||||
def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
def FCMP_D32 : FCC<0x11, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
"c.$cc.d\t$fs, $ft",
|
||||
[(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>,
|
||||
Requires<[NotFP64bit]>;
|
||||
|
@ -21,30 +21,55 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// 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<4> val> {
|
||||
bits<4> Value = val;
|
||||
}
|
||||
|
||||
def Pseudo : Format<0>;
|
||||
def FrmR : Format<1>;
|
||||
def FrmI : Format<2>;
|
||||
def FrmJ : Format<3>;
|
||||
def FrmFR : Format<4>;
|
||||
def FrmFI : Format<5>;
|
||||
def FrmOther : Format<6>; // Instruction w/ a custom format
|
||||
|
||||
// Generic Mips Format
|
||||
class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: Instruction
|
||||
InstrItinClass itin, Format f>: Instruction
|
||||
{
|
||||
field bits<32> Inst;
|
||||
Format Form = f;
|
||||
|
||||
let Namespace = "Mips";
|
||||
|
||||
bits<6> opcode;
|
||||
bits<6> Opcode = 0;
|
||||
|
||||
// Top 5 bits are the 'opcode' field
|
||||
let Inst{31-26} = opcode;
|
||||
// Top 6 bits are the 'opcode' field
|
||||
let Inst{31-26} = Opcode;
|
||||
|
||||
dag OutOperandList = outs;
|
||||
dag InOperandList = ins;
|
||||
let OutOperandList = outs;
|
||||
let InOperandList = ins;
|
||||
|
||||
let AsmString = asmstr;
|
||||
let Pattern = pattern;
|
||||
let Itinerary = itin;
|
||||
|
||||
//
|
||||
// Attributes specific to Mips instructions...
|
||||
//
|
||||
bits<4> FormBits = Form.Value;
|
||||
|
||||
// TSFlags layout should be kept in sync with MipsInstrInfo.h.
|
||||
let TSFlags{3-0} = FormBits;
|
||||
}
|
||||
|
||||
// Mips Pseudo Instructions Format
|
||||
class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo> {
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo, Pseudo> {
|
||||
let isCodeGenOnly = 1;
|
||||
let isPseudo = 1;
|
||||
}
|
||||
|
||||
@ -54,7 +79,7 @@ class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
|
||||
class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmR>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
@ -62,7 +87,7 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
bits<5> shamt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
@ -77,13 +102,13 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -92,13 +117,13 @@ class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -110,11 +135,11 @@ class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmJ>
|
||||
{
|
||||
bits<26> addr;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-0} = addr;
|
||||
}
|
||||
@ -138,7 +163,7 @@ class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFR>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
@ -146,7 +171,7 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
bits<5> fmt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
let fmt = _fmt;
|
||||
|
||||
@ -162,13 +187,13 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFI>
|
||||
{
|
||||
bits<5> ft;
|
||||
bits<5> base;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = base;
|
||||
let Inst{20-16} = ft;
|
||||
@ -180,14 +205,14 @@ class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fs;
|
||||
bits<5> ft;
|
||||
bits<4> cc;
|
||||
bits<5> fmt;
|
||||
|
||||
let opcode = 0x11;
|
||||
let Opcode = 0x11;
|
||||
let fmt = _fmt;
|
||||
|
||||
let Inst{25-21} = fmt;
|
||||
@ -201,14 +226,14 @@ class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
|
||||
class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<3> cc;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 0;
|
||||
let Opcode = 0;
|
||||
let tf = _tf;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
@ -222,7 +247,7 @@ class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
|
||||
class FFCMOV<bits<5> _fmt, bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
@ -230,7 +255,7 @@ class FFCMOV<bits<5> _fmt, bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
bits<5> fmt;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 17;
|
||||
let Opcode = 17;
|
||||
let fmt = _fmt;
|
||||
let tf = _tf;
|
||||
|
||||
|
@ -153,6 +153,7 @@ def uimm16 : Operand<i32> {
|
||||
def mem : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
def mem64 : Operand<i64> {
|
||||
@ -163,6 +164,17 @@ def mem64 : Operand<i64> {
|
||||
def mem_ea : Operand<i32> {
|
||||
let PrintMethod = "printMemOperandEA";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
// size operand of ext instruction
|
||||
def size_ext : Operand<i32> {
|
||||
let EncoderMethod = "getSizeExtEncoding";
|
||||
}
|
||||
|
||||
// size operand of ins instruction
|
||||
def size_ins : Operand<i32> {
|
||||
let EncoderMethod = "getSizeInsEncoding";
|
||||
}
|
||||
|
||||
// Transformation Function - get the lower 16 bits.
|
||||
@ -269,14 +281,14 @@ class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm,
|
||||
// Arithmetic and logical instructions with 2 register operands.
|
||||
class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$i))], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu>;
|
||||
|
||||
class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"), [], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"), [], IIAlu>;
|
||||
|
||||
// Arithmetic Multiply ADD/SUB
|
||||
let rd = 0, shamt = 0, Defs = [HI, LO], Uses = [HI, LO] in
|
||||
@ -323,16 +335,23 @@ class shift_rotate_reg<bits<6> func, bits<5> isRotate, string instr_asm,
|
||||
|
||||
// Load Upper Imediate
|
||||
class LoadUpper<bits<6> op, string instr_asm>:
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm),
|
||||
!strconcat(instr_asm, "\t$rt, $imm"), [], IIAlu> {
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> {
|
||||
let rs = 0;
|
||||
}
|
||||
|
||||
class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> {
|
||||
bits<21> addr;
|
||||
let Inst{25-21} = addr{20-16};
|
||||
let Inst{15-0} = addr{15-0};
|
||||
}
|
||||
|
||||
// Memory Load/Store
|
||||
let canFoldAsLoad = 1 in
|
||||
class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
FMem<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(set RC:$rt, (OpNode addr:$addr))], IILoad> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -340,7 +359,7 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
|
||||
class StoreM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(OpNode RC:$rt, addr:$addr)], IIStore> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -384,9 +403,9 @@ multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode,
|
||||
|
||||
// Conditional Branch
|
||||
class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$imm16)], IIBranch> {
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let hasDelaySlot = 1;
|
||||
@ -394,9 +413,9 @@ class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
|
||||
class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op,
|
||||
RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$imm16)], IIBranch> {
|
||||
let rt = _rt;
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
@ -415,9 +434,9 @@ class SetCC_R<bits<6> op, bits<6> func, string instr_asm, PatFrag cond_op,
|
||||
|
||||
class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od,
|
||||
PatLeaf imm_type, RegisterClass RC>:
|
||||
FI<op, (outs CPURegs:$rd), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rd, $rs, $i"),
|
||||
[(set CPURegs:$rd, (cond_op RC:$rs, imm_type:$i))],
|
||||
FI<op, (outs CPURegs:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))],
|
||||
IIAlu>;
|
||||
|
||||
// Unconditional branch
|
||||
@ -454,10 +473,8 @@ let isCall=1, hasDelaySlot=1,
|
||||
}
|
||||
|
||||
class BranchLink<string instr_asm>:
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$target, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $target"), [], IIBranch> {
|
||||
let rt = 0;
|
||||
}
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$imm16, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"), [], IIBranch>;
|
||||
}
|
||||
|
||||
// Mul, Div
|
||||
@ -509,7 +526,7 @@ class MoveToLOHI<bits<6> func, string instr_asm, RegisterClass RC,
|
||||
}
|
||||
|
||||
class EffectiveAddress<string instr_asm> :
|
||||
FI<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
FMem<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
instr_asm, [(set CPURegs:$rt, addr:$addr)], IIAlu>;
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
@ -533,7 +550,7 @@ class CountLeading1<bits<6> func, string instr_asm, RegisterClass RC>:
|
||||
|
||||
// Sign Extend in Register.
|
||||
class SignExtInReg<bits<5> sa, string instr_asm, ValueType vt>:
|
||||
FR<0x3f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
FR<0x1f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt"),
|
||||
[(set CPURegs:$rd, (sext_inreg CPURegs:$rt, vt))], NoItinerary> {
|
||||
let rs = 0;
|
||||
@ -711,20 +728,22 @@ defm USW : StoreM32<0x2b, "usw", store_u, 1>;
|
||||
|
||||
let hasSideEffects = 1 in
|
||||
def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
|
||||
[(MipsSync imm:$stype)], NoItinerary>
|
||||
[(MipsSync imm:$stype)], NoItinerary, FrmOther>
|
||||
{
|
||||
let opcode = 0;
|
||||
bits<5> stype;
|
||||
let Opcode = 0;
|
||||
let Inst{25-11} = 0;
|
||||
let Inst{10-6} = stype;
|
||||
let Inst{5-0} = 15;
|
||||
}
|
||||
|
||||
/// Load-linked, Store-conditional
|
||||
let mayLoad = 1 in
|
||||
def LL : FI<0x30, (outs CPURegs:$dst), (ins mem:$addr),
|
||||
"ll\t$dst, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$src = $dst" in
|
||||
def SC : FI<0x38, (outs CPURegs:$dst), (ins CPURegs:$src, mem:$addr),
|
||||
"sc\t$src, $addr", [], IIStore>;
|
||||
def LL : FMem<0x30, (outs CPURegs:$rt), (ins mem:$addr),
|
||||
"ll\t$rt, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$rt = $dst" in
|
||||
def SC : FMem<0x38, (outs CPURegs:$dst), (ins CPURegs:$rt, mem:$addr),
|
||||
"sc\t$rt, $addr", [], IIStore>;
|
||||
|
||||
/// Jump and Branch Instructions
|
||||
def J : JumpFJ<0x02, "j">;
|
||||
@ -736,15 +755,17 @@ def BEQ : CBranch<0x04, "beq", seteq, CPURegs>;
|
||||
def BNE : CBranch<0x05, "bne", setne, CPURegs>;
|
||||
def BGEZ : CBranchZero<0x01, 1, "bgez", setge, CPURegs>;
|
||||
def BGTZ : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x07, 0, "blez", setle, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x06, 0, "blez", setle, CPURegs>;
|
||||
def BLTZ : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
|
||||
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
let rt=0x11 in
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
let rt=0x10 in
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1,
|
||||
isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
|
||||
isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target),
|
||||
"jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
|
||||
|
||||
/// Multiply and Divide Instructions.
|
||||
@ -799,14 +820,14 @@ def MUL : ArithLogicR<0x1c, 0x02, "mul", mul, IIImul, CPURegs, 1>,
|
||||
def RDHWR : ReadHardware;
|
||||
|
||||
def EXT : ExtIns<0, "ext", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ext:$sz),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsExt CPURegs:$rs, immZExt5:$pos, immZExt5:$sz))],
|
||||
NoItinerary>;
|
||||
|
||||
let Constraints = "$src = $rt" in
|
||||
def INS : ExtIns<4, "ins", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz, CPURegs:$src),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ins:$sz, CPURegs:$src),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsIns CPURegs:$rs, immZExt5:$pos, immZExt5:$sz,
|
||||
CPURegs:$src))],
|
||||
|
Loading…
Reference in New Issue
Block a user