From 366783e14c4c757102715bf8113ebf6696859f6c Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Wed, 12 Aug 2015 12:45:16 +0000 Subject: [PATCH] [mips][microMIPS] Create microMIPS64r6 subtarget and implement DALIGN, DAUI, DAHI, DATI, DEXT, DEXTM and DEXTU instructions Differential Revision: http://reviews.llvm.org/D10923 llvm-svn: 244744 --- .../Target/Mips/Disassembler/MipsDisassembler.cpp | 3 +- llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 2 +- llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td | 70 ++++++++++++++++ llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td | 98 ++++++++++++++++++++++ llvm/lib/Target/Mips/Mips64InstrInfo.td | 8 +- llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 10 ++- llvm/lib/Target/Mips/MipsInstrInfo.td | 9 ++ llvm/lib/Target/Mips/MipsSubtarget.h | 1 + llvm/test/MC/Disassembler/Mips/micromips64r6.txt | 15 ++++ 9 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td create mode 100644 llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td create mode 100644 llvm/test/MC/Disassembler/Mips/micromips64r6.txt diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index a34ba3b..38c6bb8 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -847,7 +847,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, if (hasMips32r6()) { DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); // Calling the auto-generated decoder function. - Result = decodeInstruction(DecoderTableMicroMips32r632, Instr, Insn, Address, + Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, this, STI); } else { DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); @@ -855,6 +855,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, this, STI); } + if (Result != MCDisassembler::Fail) { Size = 4; return Result; diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index 53bde13..3a989ee 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -283,7 +283,7 @@ class XORI_MMR6_DESC : ArithLogicI<"xori", simm16, GPR32Opnd>; // //===----------------------------------------------------------------------===// -let DecoderNamespace = "MicroMips32r6" in { +let DecoderNamespace = "MicroMipsR6" in { def ADD_MMR6 : StdMMR6Rel, ADD_MMR6_DESC, ADD_MMR6_ENC, ISA_MICROMIPS32R6; def ADDIU_MMR6 : StdMMR6Rel, ADDIU_MMR6_DESC, ADDIU_MMR6_ENC, ISA_MICROMIPS32R6; def ADDU_MMR6 : StdMMR6Rel, ADDU_MMR6_DESC, ADDU_MMR6_ENC, ISA_MICROMIPS32R6; diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td new file mode 100644 index 0000000..a530ec9 --- /dev/null +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -0,0 +1,70 @@ +//=- MicroMips64r6InstrFormats.td - Instruction Formats -*- 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 instruction formats. +// +//===----------------------------------------------------------------------===// + +class DAUI_FM_MMR6 { + bits<5> rt; + bits<5> rs; + bits<16> imm; + + bits<32> Inst; + + let Inst{31-26} = 0b111100; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-0} = imm; +} + +class POOL32I_ADD_IMM_FM_MMR6 funct> { + bits<5> rs; + bits<16> imm; + + bits<32> Inst; + + let Inst{31-26} = 0b010000; + let Inst{25-21} = funct; + let Inst{20-16} = rs; + let Inst{15-0} = imm; +} + +class POOL32S_EXTBITS_FM_MMR6 funct> { + bits<5> rt; + bits<5> rs; + bits<5> size; + bits<5> pos; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = size; + let Inst{10-6} = pos; + let Inst{5-0} = funct; +} + +class POOL32S_DALIGN_FM_MMR6 { + bits<5> rs; + bits<5> rt; + bits<5> rd; + bits<3> bp; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-11} = rd; + let Inst{10-8} = bp; + let Inst{7-6} = 0b00; + let Inst{5-0} = 0b011100; +} diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td new file mode 100644 index 0000000..f93843d --- /dev/null +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -0,0 +1,98 @@ +//=- 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; + +//===----------------------------------------------------------------------===// +// +// Instruction Descriptions +// +//===----------------------------------------------------------------------===// + +class DAUI_MMR6_DESC_BASE + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs GPROpnd:$rt); + dag InOperandList = (ins GPROpnd:$rs, simm16:$imm); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm"); + list Pattern = []; +} +class DAUI_MMR6_DESC : DAUI_MMR6_DESC_BASE<"daui", GPR64Opnd>; + +class DAHI_DATI_DESC_BASE + : MMR6Arch, 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 : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs RO:$rt); + dag InOperandList = (ins RO:$rs, PosOpnd:$pos, size_ext:$size); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $pos, $size"); + list Pattern = [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))]; + InstrItinClass Itinerary = II_EXT; + Format Form = FrmR; + string BaseOpcode = instr_asm; +} +class DEXT_MMR6_DESC : EXTBITS_DESC_BASE<"dext", GPR64Opnd, uimm6, + MipsExt>; +class DEXTM_MMR6_DESC : EXTBITS_DESC_BASE<"dextm", GPR64Opnd, uimm6, + MipsExt>; +class DEXTU_MMR6_DESC : EXTBITS_DESC_BASE<"dextu", GPR64Opnd, uimm6, + MipsExt>; + +class DALIGN_DESC_BASE : MMR6Arch, 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 Pattern = []; +} + +class DALIGN_MMR6_DESC : DALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>; + +//===----------------------------------------------------------------------===// +// +// 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; +} diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 1d18f4d..fdf0530 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -276,9 +276,11 @@ def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd>, LW_FM<0x19>; let isCodeGenOnly = 1 in def RDHWR64 : ReadHardware, RDHWR_FM; -def DEXT : ExtBase<"dext", GPR64Opnd, uimm6, MipsExt>, EXT_FM<3>; -def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm6>, EXT_FM<2>; -def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5>, EXT_FM<1>; +let AdditionalPredicates = [NotInMicroMips] in { + def DEXT : ExtBase<"dext", GPR64Opnd, uimm6, MipsExt>, EXT_FM<3>; + def DEXTM : ExtBase<"dextm", GPR64Opnd, uimm5>, EXT_FM<1>; + def DEXTU : ExtBase<"dextu", GPR64Opnd, uimm6>, EXT_FM<2>; +} def DINS : InsBase<"dins", GPR64Opnd, uimm6, MipsIns>, EXT_FM<7>; def DINSU : InsBase<"dinsu", GPR64Opnd, uimm6>, EXT_FM<6>; diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index 6b546e8..3102849 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -81,10 +81,12 @@ class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>; // //===----------------------------------------------------------------------===// -def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6; -def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6; -def DATI : DATI_ENC, DATI_DESC, ISA_MIPS64R6; -def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6; +let AdditionalPredicates = [NotInMicroMips] in { + def DATI : DATI_ENC, DATI_DESC, ISA_MIPS64R6; + def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6; + def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6; + def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6; +} def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; def DCLO_R6 : DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6; def DCLZ_R6 : DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 45eb356..aaac70c 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -186,6 +186,8 @@ def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, AssemblerPredicate<"!FeatureMips64r6">; def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">, AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">; +def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">, + AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">; def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; def HasCnMips : Predicate<"Subtarget->hasCnMips()">, @@ -255,6 +257,9 @@ class ISA_MIPS64R6 { list InsnPredicates = [HasMips64r6]; } class ISA_MICROMIPS32R6 { list InsnPredicates = [HasMicroMips32r6]; } +class ISA_MICROMIPS64R6 { + list InsnPredicates = [HasMicroMips64r6]; +} // The portions of MIPS-III that were also added to MIPS32 class INSN_MIPS3_32 { list InsnPredicates = [HasMips3_32]; } @@ -1981,3 +1986,7 @@ include "MicroMipsInstrFPU.td" // Micromips r6 include "MicroMips32r6InstrFormats.td" include "MicroMips32r6InstrInfo.td" + +// Micromips64 r6 +include "MicroMips64r6InstrFormats.td" +include "MicroMips64r6InstrInfo.td" diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 1e3a808..7a4a893 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -228,6 +228,7 @@ public: } bool inMicroMipsMode() const { return InMicroMipsMode; } bool inMicroMips32r6Mode() const { return InMicroMipsMode && hasMips32r6(); } + bool inMicroMips64r6Mode() const { return InMicroMipsMode && hasMips64r6(); } bool hasDSP() const { return HasDSP; } bool hasDSPR2() const { return HasDSPR2; } bool hasMSA() const { return HasMSA; } diff --git a/llvm/test/MC/Disassembler/Mips/micromips64r6.txt b/llvm/test/MC/Disassembler/Mips/micromips64r6.txt new file mode 100644 index 0000000..3abb7d2 --- /dev/null +++ b/llvm/test/MC/Disassembler/Mips/micromips64r6.txt @@ -0,0 +1,15 @@ +# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips64r6 -mattr=micromips | FileCheck %s + +0xf0 0x64 0x00 0x05 # CHECK: daui $3, $4, 5 + +0x42 0x23 0x00 0x04 # CHECK: dahi $3, 4 + +0x42 0x03 0x00 0x04 # CHECK: dati $3, 4 + +0x59 0x26 0x30 0xec # CHECK: dext $9, $6, 3, 7 + +0x59 0x26 0x30 0xe4 # CHECK: dextm $9, $6, 3, 7 + +0x59 0x26 0x30 0xd4 # CHECK: dextu $9, $6, 3, 7 + +0x58 0x43 0x25 0x1c # CHECK: dalign $4, $2, $3, 5 -- 2.7.4