mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
[mips] First patch which adds support for micromips.
This patch adds support for recoded (meaning assembly-language compatible to standard mips32) arithmetic 32-bit instructions. Patch by Zoran Jovanovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179873 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8d99ec5748
commit
f530aff9de
@ -27,6 +27,9 @@
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#define GET_INSTRMAP_INFO
|
||||
#include "MipsGenInstrInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
@ -35,12 +38,13 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
|
||||
void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
|
||||
const MCInstrInfo &MCII;
|
||||
MCContext &Ctx;
|
||||
const MCSubtargetInfo &STI;
|
||||
bool IsLittleEndian;
|
||||
|
||||
public:
|
||||
MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_,
|
||||
const MCSubtargetInfo &sti, bool IsLittle) :
|
||||
MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) {}
|
||||
MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {}
|
||||
|
||||
~MipsMCCodeEmitter() {}
|
||||
|
||||
@ -144,6 +148,15 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
|
||||
llvm_unreachable("unimplemented opcode in EncodeInstruction()");
|
||||
|
||||
if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
|
||||
int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
|
||||
if (NewOpcode != -1) {
|
||||
Opcode = NewOpcode;
|
||||
TmpInst.setOpcode (NewOpcode);
|
||||
Binary = getBinaryCodeForInstr(TmpInst, Fixups);
|
||||
}
|
||||
}
|
||||
|
||||
const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
|
||||
|
||||
// Get byte count of instruction
|
||||
|
70
lib/Target/Mips/MicroMipsInstrFormats.td
Normal file
70
lib/Target/Mips/MicroMipsInstrFormats.td
Normal file
@ -0,0 +1,70 @@
|
||||
class MMArch {
|
||||
string Arch = "micromips";
|
||||
list<dag> Pattern = [];
|
||||
}
|
||||
|
||||
class ADD_FM_MM<bits<6> op, bits<10> funct> : MMArch {
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<5> rd;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = op;
|
||||
let Inst{25-21} = rt;
|
||||
let Inst{20-16} = rs;
|
||||
let Inst{15-11} = rd;
|
||||
let Inst{10} = 0;
|
||||
let Inst{9-0} = funct;
|
||||
}
|
||||
|
||||
class ADDI_FM_MM<bits<6> op> : MMArch {
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = op;
|
||||
let Inst{25-21} = rt;
|
||||
let Inst{20-16} = rs;
|
||||
let Inst{15-0} = imm16;
|
||||
}
|
||||
|
||||
class SLTI_FM_MM<bits<6> op> : MMArch {
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<16> imm16;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = op;
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-0} = imm16;
|
||||
}
|
||||
|
||||
class LUI_FM_MM : MMArch {
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = 0x10;
|
||||
let Inst{25-21} = 0xd;
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-0} = imm16;
|
||||
}
|
||||
|
||||
class MULT_FM_MM<bits<10> funct> : MMArch {
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = 0x00;
|
||||
let Inst{25-21} = rt;
|
||||
let Inst{20-16} = rs;
|
||||
let Inst{15-6} = funct;
|
||||
let Inst{5-0} = 0x3c;
|
||||
}
|
39
lib/Target/Mips/MicroMipsInstrInfo.td
Normal file
39
lib/Target/Mips/MicroMipsInstrInfo.td
Normal file
@ -0,0 +1,39 @@
|
||||
let isCodeGenOnly = 1 in {
|
||||
/// Arithmetic Instructions (ALU Immediate)
|
||||
def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd>,
|
||||
ADDI_FM_MM<0xc>;
|
||||
def ADDi_MM : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>,
|
||||
ADDI_FM_MM<0x4>;
|
||||
def SLTi_MM : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>,
|
||||
SLTI_FM_MM<0x24>;
|
||||
def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>,
|
||||
SLTI_FM_MM<0x2c>;
|
||||
def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>,
|
||||
ADDI_FM_MM<0x34>;
|
||||
def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>,
|
||||
ADDI_FM_MM<0x14>;
|
||||
def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>,
|
||||
ADDI_FM_MM<0x1c>;
|
||||
def LUi_MM : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM_MM;
|
||||
|
||||
/// Arithmetic Instructions (3-Operand, R-Type)
|
||||
def ADDu_MM : MMRel, ArithLogicR<"addu", CPURegsOpnd>, ADD_FM_MM<0, 0x150>;
|
||||
def SUBu_MM : MMRel, ArithLogicR<"subu", CPURegsOpnd>, ADD_FM_MM<0, 0x1d0>;
|
||||
def MUL_MM : MMRel, ArithLogicR<"mul", CPURegsOpnd>, ADD_FM_MM<0, 0x210>;
|
||||
def ADD_MM : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM_MM<0, 0x110>;
|
||||
def SUB_MM : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM_MM<0, 0x190>;
|
||||
def SLT_MM : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM_MM<0, 0x350>;
|
||||
def SLTu_MM : MMRel, SetCC_R<"sltu", setult, CPURegs>,
|
||||
ADD_FM_MM<0, 0x390>;
|
||||
def AND_MM : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>,
|
||||
ADD_FM_MM<0, 0x250>;
|
||||
def OR_MM : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>,
|
||||
ADD_FM_MM<0, 0x290>;
|
||||
def XOR_MM : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>,
|
||||
ADD_FM_MM<0, 0x310>;
|
||||
def NOR_MM : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM_MM<0, 0x2d0>;
|
||||
def MULT_MM : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>,
|
||||
MULT_FM_MM<0x22c>;
|
||||
def MULTu_MM : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>,
|
||||
MULT_FM_MM<0x26c>;
|
||||
}
|
@ -36,6 +36,24 @@ def FrmFR : Format<4>;
|
||||
def FrmFI : Format<5>;
|
||||
def FrmOther : Format<6>; // Instruction w/ a custom format
|
||||
|
||||
class MMRel;
|
||||
|
||||
def Std2MicroMips : InstrMapping {
|
||||
let FilterClass = "MMRel";
|
||||
// Instructions with the same BaseOpcode and isNVStore values form a row.
|
||||
let RowFields = ["BaseOpcode"];
|
||||
// Instructions with the same predicate sense form a column.
|
||||
let ColFields = ["Arch"];
|
||||
// The key column is the unpredicated instructions.
|
||||
let KeyCol = ["se"];
|
||||
// Value columns are PredSense=true and PredSense=false
|
||||
let ValueCols = [["se"], ["micromips"]];
|
||||
}
|
||||
|
||||
class StdArch {
|
||||
string Arch = "se";
|
||||
}
|
||||
|
||||
// Generic Mips Format
|
||||
class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin, Format f>: Instruction
|
||||
@ -74,9 +92,11 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
// Mips32/64 Instruction Format
|
||||
class InstSE<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin, Format f>:
|
||||
InstrItinClass itin, Format f, string opstr = ""> :
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, f> {
|
||||
let Predicates = [HasStdEnc];
|
||||
string BaseOpcode = opstr;
|
||||
string Arch;
|
||||
}
|
||||
|
||||
// Mips Pseudo Instructions Format
|
||||
@ -192,7 +212,7 @@ class MFC3OP_FM<bits<6> op, bits<5> mfmt>
|
||||
let Inst{2-0} = sel;
|
||||
}
|
||||
|
||||
class ADD_FM<bits<6> op, bits<6> funct> {
|
||||
class ADD_FM<bits<6> op, bits<6> funct> : StdArch {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -207,7 +227,7 @@ class ADD_FM<bits<6> op, bits<6> funct> {
|
||||
let Inst{5-0} = funct;
|
||||
}
|
||||
|
||||
class ADDI_FM<bits<6> op> {
|
||||
class ADDI_FM<bits<6> op> : StdArch {
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
@ -288,7 +308,7 @@ class B_FM {
|
||||
let Inst{15-0} = offset;
|
||||
}
|
||||
|
||||
class SLTI_FM<bits<6> op> {
|
||||
class SLTI_FM<bits<6> op> : StdArch {
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<16> imm16;
|
||||
@ -413,7 +433,7 @@ class SYNC_FM {
|
||||
let Inst{5-0} = 0xf;
|
||||
}
|
||||
|
||||
class MULT_FM<bits<6> op, bits<6> funct> {
|
||||
class MULT_FM<bits<6> op, bits<6> funct> : StdArch {
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
|
||||
|
@ -375,11 +375,9 @@ class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
|
||||
SDPatternOperator OpNode = null_frag>:
|
||||
InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
|
||||
!strconcat(opstr, "\t$rd, $rs, $rt"),
|
||||
[(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> {
|
||||
[(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
|
||||
let isCommutable = isComm;
|
||||
let isReMaterializable = 1;
|
||||
string BaseOpcode;
|
||||
string Arch;
|
||||
}
|
||||
|
||||
// Arithmetic and logical instructions with 2 register operands.
|
||||
@ -388,7 +386,8 @@ class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
|
||||
SDPatternOperator OpNode = null_frag> :
|
||||
InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
|
||||
!strconcat(opstr, "\t$rt, $rs, $imm16"),
|
||||
[(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], IIAlu, FrmI> {
|
||||
[(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
|
||||
IIAlu, FrmI, opstr> {
|
||||
let isReMaterializable = 1;
|
||||
}
|
||||
|
||||
@ -405,7 +404,7 @@ class MArithR<string opstr, bit isComm = 0> :
|
||||
class LogicNOR<string opstr, RegisterOperand RC>:
|
||||
InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt),
|
||||
!strconcat(opstr, "\t$rd, $rs, $rt"),
|
||||
[(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR> {
|
||||
[(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR, opstr> {
|
||||
let isCommutable = 1;
|
||||
}
|
||||
|
||||
@ -543,14 +542,15 @@ class CBranchZero<string opstr, PatFrag cond_op, RegisterClass RC> :
|
||||
class SetCC_R<string opstr, PatFrag cond_op, RegisterClass RC> :
|
||||
InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt),
|
||||
!strconcat(opstr, "\t$rd, $rs, $rt"),
|
||||
[(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], IIAlu, FrmR>;
|
||||
[(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))],
|
||||
IIAlu, FrmR, opstr>;
|
||||
|
||||
class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
|
||||
RegisterClass RC>:
|
||||
InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(opstr, "\t$rt, $rs, $imm16"),
|
||||
[(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))],
|
||||
IIAlu, FrmI>;
|
||||
IIAlu, FrmI, opstr>;
|
||||
|
||||
// Jump
|
||||
class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
|
||||
@ -637,7 +637,7 @@ class SYNC_FT :
|
||||
class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
|
||||
list<Register> DefRegs> :
|
||||
InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
|
||||
itin, FrmR> {
|
||||
itin, FrmR, opstr> {
|
||||
let isCommutable = 1;
|
||||
let Defs = DefRegs;
|
||||
let neverHasSideEffects = 1;
|
||||
@ -849,31 +849,39 @@ def COPY_AC64 : PseudoSE<(outs ACRegs:$dst), (ins ACRegs:$src), []>;
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Arithmetic Instructions (ALU Immediate)
|
||||
def ADDiu : ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>,
|
||||
def ADDiu : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>,
|
||||
ADDI_FM<0x9>, IsAsCheapAsAMove;
|
||||
def ADDi : ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>;
|
||||
def SLTi : SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, SLTI_FM<0xa>;
|
||||
def SLTiu : SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, SLTI_FM<0xb>;
|
||||
def ANDi : ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>,
|
||||
def ADDi : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>;
|
||||
def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>,
|
||||
SLTI_FM<0xa>;
|
||||
def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>,
|
||||
SLTI_FM<0xb>;
|
||||
def ANDi : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>,
|
||||
ADDI_FM<0xc>;
|
||||
def ORi : ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>,
|
||||
def ORi : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>,
|
||||
ADDI_FM<0xd>;
|
||||
def XORi : ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>,
|
||||
def XORi : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>,
|
||||
ADDI_FM<0xe>;
|
||||
def LUi : LoadUpper<"lui", CPURegs, uimm16>, LUI_FM;
|
||||
def LUi : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM;
|
||||
|
||||
/// Arithmetic Instructions (3-Operand, R-Type)
|
||||
def ADDu : ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, ADD_FM<0, 0x21>;
|
||||
def SUBu : ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, ADD_FM<0, 0x23>;
|
||||
def MUL : ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, ADD_FM<0x1c, 2>;
|
||||
def ADD : ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>;
|
||||
def SUB : ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>;
|
||||
def SLT : SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>;
|
||||
def SLTu : SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>;
|
||||
def AND : ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, ADD_FM<0, 0x24>;
|
||||
def OR : ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, ADD_FM<0, 0x25>;
|
||||
def XOR : ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, ADD_FM<0, 0x26>;
|
||||
def NOR : LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>;
|
||||
def ADDu : MMRel, ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>,
|
||||
ADD_FM<0, 0x21>;
|
||||
def SUBu : MMRel, ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>,
|
||||
ADD_FM<0, 0x23>;
|
||||
def MUL : MMRel, ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>,
|
||||
ADD_FM<0x1c, 2>;
|
||||
def ADD : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>;
|
||||
def SUB : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>;
|
||||
def SLT : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>;
|
||||
def SLTu : MMRel, SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>;
|
||||
def AND : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>,
|
||||
ADD_FM<0, 0x24>;
|
||||
def OR : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>,
|
||||
ADD_FM<0, 0x25>;
|
||||
def XOR : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>,
|
||||
ADD_FM<0, 0x26>;
|
||||
def NOR : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>;
|
||||
|
||||
/// Shift Instructions
|
||||
def SLL : shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>,
|
||||
@ -969,8 +977,10 @@ let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||
}
|
||||
|
||||
/// Multiply and Divide Instructions.
|
||||
def MULT : Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x18>;
|
||||
def MULTu : Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x19>;
|
||||
def MULT : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>,
|
||||
MULT_FM<0, 0x18>;
|
||||
def MULTu : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>,
|
||||
MULT_FM<0, 0x19>;
|
||||
def PseudoMULT : MultDivPseudo<MULT, ACRegs, CPURegsOpnd, MipsMult, IIImul>;
|
||||
def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, CPURegsOpnd, MipsMultu, IIImul>;
|
||||
def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>;
|
||||
@ -1329,3 +1339,6 @@ include "Mips16InstrInfo.td"
|
||||
include "MipsDSPInstrFormats.td"
|
||||
include "MipsDSPInstrInfo.td"
|
||||
|
||||
// Micromips
|
||||
include "MicroMipsInstrFormats.td"
|
||||
include "MicroMipsInstrInfo.td"
|
||||
|
Loading…
x
Reference in New Issue
Block a user