1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00
llvm-mirror/lib/Target/Mips/MicroMips64r6InstrInfo.td
Zlatko Buljan b4097ad285 [mips][microMIPS] Add CodeGen support for DIV, MOD, DIVU, MODU, DDIV, DMOD, DDIVU and DMODU instructions
Differential Revision: http://reviews.llvm.org/D17137

This patch was reverted after the revertion of dependant patch http://reviews.llvm.org/D17068.
There was the problem with test-suite failure.
The problem is hopefully solved with dependant patch so this patch is commited again.

llvm-svn: 266179
2016-04-13 08:02:26 +00:00

251 lines
12 KiB
TableGen

//=- MicroMips64r6InstrInfo.td - Instruction Information -*- tablegen -*- -=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes MicroMips64r6 instructions.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//
// Instruction Encodings
//
//===----------------------------------------------------------------------===//
class DAUI_MMR6_ENC : DAUI_FM_MMR6;
class DAHI_MMR6_ENC : POOL32I_ADD_IMM_FM_MMR6<0b10001>;
class DATI_MMR6_ENC : POOL32I_ADD_IMM_FM_MMR6<0b10000>;
class DEXT_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b101100>;
class DEXTM_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b100100>;
class DEXTU_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b010100>;
class DALIGN_MMR6_ENC : POOL32S_DALIGN_FM_MMR6;
class DDIV_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddiv", 0b100011000>;
class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>;
class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>;
class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>;
class DINSU_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b110100>;
class DINSM_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b000100>;
class DINS_MM64R6_ENC : POOL32S_EXTBITS_FM_MMR6<0b001100>;
class DMTC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmtc0", 0b01011>;
class DMTC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmtc1", 0b10110000>;
class DMTC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmtc2", 0b0111110100>;
class DMFC0_MM64R6_ENC : POOL32S_DMFTC0_FM_MMR6<"dmfc0", 0b00011>;
class DMFC1_MM64R6_ENC : POOL32F_MFTC1_FM_MMR6<"dmfc1", 0b10010000>;
class DMFC2_MM64R6_ENC : POOL32A_MFTC2_FM_MMR6<"dmfc2", 0b0110110100>;
class DADD_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dadd", 0b100010000>;
class DADDIU_MM64R6_ENC : DADDIU_FM_MMR6<"daddiu">;
class DADDU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"daddu", 0b101010000>;
//===----------------------------------------------------------------------===//
//
// Instruction Descriptions
//
//===----------------------------------------------------------------------===//
class DAUI_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd>
: MMR6Arch<instr_asm>, MipsR6Inst {
dag OutOperandList = (outs GPROpnd:$rt);
dag InOperandList = (ins GPROpnd:$rs, simm16:$imm);
string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm");
list<dag> Pattern = [];
}
class DAUI_MMR6_DESC : DAUI_MMR6_DESC_BASE<"daui", GPR64Opnd>;
class DAHI_DATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd>
: MMR6Arch<instr_asm>, MipsR6Inst {
dag OutOperandList = (outs GPROpnd:$rs);
dag InOperandList = (ins GPROpnd:$rt, simm16:$imm);
string AsmString = !strconcat(instr_asm, "\t$rt, $imm");
string Constraints = "$rs = $rt";
}
class DAHI_MMR6_DESC : DAHI_DATI_DESC_BASE<"dahi", GPR64Opnd>;
class DATI_MMR6_DESC : DAHI_DATI_DESC_BASE<"dati", GPR64Opnd>;
class EXTBITS_DESC_BASE<string instr_asm, RegisterOperand RO, Operand PosOpnd,
Operand SizeOpnd, SDPatternOperator Op = null_frag>
: MMR6Arch<instr_asm>, MipsR6Inst {
dag OutOperandList = (outs RO:$rt);
dag InOperandList = (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size);
string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $pos, $size");
list<dag> Pattern = [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))];
InstrItinClass Itinerary = II_EXT;
Format Form = FrmR;
string BaseOpcode = instr_asm;
}
// TODO: Add 'pos + size' constraint check to dext* instructions
// DEXT: 0 < pos + size <= 63
// DEXTM, DEXTU: 32 < pos + size <= 64
class DEXT_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR64Opnd, uimm5_report_uimm6,
uimm5_plus1, MipsExt>;
class DEXTM_MMR6_DESC : EXTBITS_DESC_BASE<"dextm", GPR64Opnd, uimm5,
uimm5_plus33, MipsExt>;
class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm5_plus32,
uimm5_plus1, MipsExt>;
class DALIGN_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
Operand ImmOpnd> : MMR6Arch<instr_asm>, MipsR6Inst {
dag OutOperandList = (outs GPROpnd:$rd);
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, ImmOpnd:$bp);
string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt, $bp");
list<dag> Pattern = [];
}
class DALIGN_MMR6_DESC : DALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>;
class DDIV_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddiv", GPR64Opnd, sdiv>;
class DMOD_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmod", GPR64Opnd, srem>;
class DDIVU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"ddivu", GPR64Opnd, udiv>;
class DMODU_MM64R6_DESC : DIVMOD_MMR6_DESC_BASE<"dmodu", GPR64Opnd, urem>;
class DINSU_MM64R6_DESC : InsBase<"dinsu", GPR64Opnd, uimm5_plus32,
uimm5_inssize_plus1, MipsIns>;
class DINSM_MM64R6_DESC : InsBase<"dinsm", GPR64Opnd, uimm5, uimm_range_2_64>;
class DINS_MM64R6_DESC : InsBase<"dins", GPR64Opnd, uimm5, uimm5_inssize_plus1,
MipsIns>;
class DMTC0_MM64R6_DESC : MTC0_MMR6_DESC_BASE<"dmtc0", COP0Opnd, GPR64Opnd>;
class DMTC1_MM64R6_DESC : MTC1_MMR6_DESC_BASE<"dmtc1", FGR64Opnd, GPR64Opnd,
II_DMTC1, bitconvert>;
class DMTC2_MM64R6_DESC : MTC2_MMR6_DESC_BASE<"dmtc2", COP2Opnd, GPR64Opnd>;
class DMFC0_MM64R6_DESC : MFC0_MMR6_DESC_BASE<"dmfc0", GPR64Opnd, COP0Opnd>;
class DMFC1_MM64R6_DESC : MFC1_MMR6_DESC_BASE<"dmfc1", GPR64Opnd, FGR64Opnd,
II_DMFC1, bitconvert>;
class DMFC2_MM64R6_DESC : MFC2_MMR6_DESC_BASE<"dmfc2", GPR64Opnd, COP2Opnd>;
class DADD_MM64R6_DESC : ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>;
class DADDIU_MM64R6_DESC : ArithLogicI<"daddiu", simm16_64, GPR64Opnd,
II_DADDIU, immSExt16, add>,
IsAsCheapAsAMove;
class DADDU_MM64R6_DESC : ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>;
//===----------------------------------------------------------------------===//
//
// Instruction Definitions
//
//===----------------------------------------------------------------------===//
let DecoderNamespace = "MicroMipsR6" in {
def DAUI_MM64R6 : StdMMR6Rel, DAUI_MMR6_DESC, DAUI_MMR6_ENC, ISA_MICROMIPS64R6;
def DAHI_MM64R6 : StdMMR6Rel, DAHI_MMR6_DESC, DAHI_MMR6_ENC, ISA_MICROMIPS64R6;
def DATI_MM64R6 : StdMMR6Rel, DATI_MMR6_DESC, DATI_MMR6_ENC, ISA_MICROMIPS64R6;
def DEXT_MM64R6 : StdMMR6Rel, DEXT_MMR6_DESC, DEXT_MMR6_ENC,
ISA_MICROMIPS64R6;
def DEXTM_MM64R6 : StdMMR6Rel, DEXTM_MMR6_DESC, DEXTM_MMR6_ENC,
ISA_MICROMIPS64R6;
def DEXTU_MM64R6 : StdMMR6Rel, DEXTU_MMR6_DESC, DEXTU_MMR6_ENC,
ISA_MICROMIPS64R6;
def DALIGN_MM64R6 : StdMMR6Rel, DALIGN_MMR6_DESC, DALIGN_MMR6_ENC,
ISA_MICROMIPS64R6;
def DDIV_MM64R6 : R6MMR6Rel, DDIV_MM64R6_DESC, DDIV_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMOD_MM64R6 : R6MMR6Rel, DMOD_MM64R6_DESC, DMOD_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DDIVU_MM64R6 : R6MMR6Rel, DDIVU_MM64R6_DESC, DDIVU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DINSU_MM64R6: R6MMR6Rel, DINSU_MM64R6_DESC, DINSU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DINSM_MM64R6: R6MMR6Rel, DINSM_MM64R6_DESC, DINSM_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DINS_MM64R6: R6MMR6Rel, DINS_MM64R6_DESC, DINS_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMTC0_MM64R6 : StdMMR6Rel, DMTC0_MM64R6_ENC, DMTC0_MM64R6_DESC,
ISA_MICROMIPS64R6;
def DMTC1_MM64R6 : StdMMR6Rel, DMTC1_MM64R6_DESC, DMTC1_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMTC2_MM64R6 : StdMMR6Rel, DMTC2_MM64R6_ENC, DMTC2_MM64R6_DESC,
ISA_MICROMIPS64R6;
def DMFC0_MM64R6 : StdMMR6Rel, DMFC0_MM64R6_ENC, DMFC0_MM64R6_DESC,
ISA_MICROMIPS64R6;
def DMFC1_MM64R6 : StdMMR6Rel, DMFC1_MM64R6_DESC, DMFC1_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DMFC2_MM64R6 : StdMMR6Rel, DMFC2_MM64R6_ENC, DMFC2_MM64R6_DESC,
ISA_MICROMIPS64R6;
def DADD_MM64R6: StdMMR6Rel, DADD_MM64R6_DESC, DADD_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DADDIU_MM64R6: StdMMR6Rel, DADDIU_MM64R6_DESC, DADDIU_MM64R6_ENC,
ISA_MICROMIPS64R6;
def DADDU_MM64R6: StdMMR6Rel, DADDU_MM64R6_DESC, DADDU_MM64R6_ENC,
ISA_MICROMIPS64R6;
}
//===----------------------------------------------------------------------===//
//
// Arbitrary patterns that map to one or more instructions
//
//===----------------------------------------------------------------------===//
def : MipsPat<(MipsLo tglobaladdr:$in),
(DADDIU_MM64R6 ZERO_64, tglobaladdr:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(MipsLo tblockaddress:$in),
(DADDIU_MM64R6 ZERO_64, tblockaddress:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(MipsLo tjumptable:$in),
(DADDIU_MM64R6 ZERO_64, tjumptable:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(MipsLo tconstpool:$in),
(DADDIU_MM64R6 ZERO_64, tconstpool:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(MipsLo tglobaltlsaddr:$in),
(DADDIU_MM64R6 ZERO_64, tglobaltlsaddr:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(MipsLo texternalsym:$in),
(DADDIU_MM64R6 ZERO_64, texternalsym:$in)>, ISA_MICROMIPS64R6;
def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)),
(DADDIU_MM64R6 GPR64:$hi, tglobaladdr:$lo)>, ISA_MICROMIPS64R6;
def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)),
(DADDIU_MM64R6 GPR64:$hi, tblockaddress:$lo)>, ISA_MICROMIPS64R6;
def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)),
(DADDIU_MM64R6 GPR64:$hi, tjumptable:$lo)>, ISA_MICROMIPS64R6;
def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)),
(DADDIU_MM64R6 GPR64:$hi, tconstpool:$lo)>, ISA_MICROMIPS64R6;
def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)),
(DADDIU_MM64R6 GPR64:$hi, tglobaltlsaddr:$lo)>, ISA_MICROMIPS64R6;
def : MipsPat<(addc GPR64:$lhs, GPR64:$rhs),
(DADDU_MM64R6 GPR64:$lhs, GPR64:$rhs)>, ISA_MICROMIPS64R6;
def : MipsPat<(addc GPR64:$lhs, immSExt16:$imm),
(DADDIU_MM64R6 GPR64:$lhs, imm:$imm)>, ISA_MICROMIPS64R6;
def : WrapperPat<tglobaladdr, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
def : WrapperPat<tconstpool, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
def : WrapperPat<texternalsym, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
def : WrapperPat<tblockaddress, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
def : WrapperPat<tjumptable, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
def : WrapperPat<tglobaltlsaddr, DADDIU_MM64R6, GPR64>, ISA_MICROMIPS64R6;
//===----------------------------------------------------------------------===//
//
// Instruction aliases
//
//===----------------------------------------------------------------------===//
def : MipsInstAlias<"dmtc0 $rt, $rd",
(DMTC0_MM64R6 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>;
def : MipsInstAlias<"dmfc0 $rt, $rd",
(DMFC0_MM64R6 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>,
ISA_MICROMIPS64R6;
def : MipsInstAlias<"daddu $rs, $rt, $imm",
(DADDIU_MM64R6 GPR64Opnd:$rs,
GPR64Opnd:$rt,
simm16_64:$imm),
0>, ISA_MICROMIPS64R6;
def : MipsInstAlias<"daddu $rs, $imm",
(DADDIU_MM64R6 GPR64Opnd:$rs,
GPR64Opnd:$rs,
simm16_64:$imm),
0>, ISA_MICROMIPS64R6;
def : MipsInstAlias<"dsubu $rt, $rs, $imm",
(DADDIU_MM64R6 GPR64Opnd:$rt,
GPR64Opnd:$rs,
InvertedImOperand64:$imm),
0>, ISA_MICROMIPS64R6;
def : MipsInstAlias<"dsubu $rs, $imm",
(DADDIU_MM64R6 GPR64Opnd:$rs,
GPR64Opnd:$rs,
InvertedImOperand64:$imm),
0>, ISA_MICROMIPS64R6;