[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:
Akira Hatanaka 2013-04-19 19:03:11 +00:00
parent 8d99ec5748
commit f530aff9de
5 changed files with 190 additions and 35 deletions

View File

@ -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

View 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;
}

View 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>;
}

View File

@ -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;

View File

@ -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"