diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-10-18 17:50:36 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-10-18 17:50:36 +0000 |
commit | c3f16b316a7a15ee3bd32b4eb5753595cdce2757 (patch) | |
tree | 3009a165b69f1a2153bac52d79078f9afc831fcd /lib/Target/Mips | |
parent | de1ff7f5520989bf20ef391c9eb4aa320d865fbd (diff) | |
download | external_llvm-c3f16b316a7a15ee3bd32b4eb5753595cdce2757.zip external_llvm-c3f16b316a7a15ee3bd32b4eb5753595cdce2757.tar.gz external_llvm-c3f16b316a7a15ee3bd32b4eb5753595cdce2757.tar.bz2 |
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
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r-- | lib/Target/Mips/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/Mips/Makefile | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MipsCodeEmitter.cpp | 31 | ||||
-rw-r--r-- | lib/Target/Mips/MipsCondMov.td | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 52 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFormats.td | 75 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 97 |
7 files changed, 173 insertions, 91 deletions
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 1b4329b..71391f3 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -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) diff --git a/lib/Target/Mips/Makefile b/lib/Target/Mips/Makefile index cc4a8ae..d72693c 100644 --- a/lib/Target/Mips/Makefile +++ b/lib/Target/Mips/Makefile @@ -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 diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index 9220d9c..23fabe3 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -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" diff --git a/lib/Target/Mips/MipsCondMov.td b/lib/Target/Mips/MipsCondMov.td index 9c4798a..1a3f194 100644 --- a/lib/Target/Mips/MipsCondMov.td +++ b/lib/Target/Mips/MipsCondMov.td @@ -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">; diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 78846a2..62cee12 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -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]>; diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 6dd82c8..e1725fa 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -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; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index ed49dec..fd99b13 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -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))], |