From 06961bf147f7244158fc55564ac7e79721133b50 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Thu, 15 May 2014 10:45:58 +0000 Subject: [PATCH] [mips][mips64r6] Add addiupc, aluipc, and auipc Summary: No support for symbols in place of the immediate yet since it requires new relocations. Depends on D3671 Reviewers: jkolek, zoran.jovanovic, vmedic Reviewed By: vmedic Differential Revision: http://reviews.llvm.org/D3689 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208858 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 9 ++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 12 ++++++- .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 +++ lib/Target/Mips/Mips32r6InstrFormats.td | 32 +++++++++++++++++++ lib/Target/Mips/Mips32r6InstrInfo.td | 28 ++++++++++++++-- lib/Target/Mips/MipsCodeEmitter.cpp | 7 ++++ lib/Target/Mips/MipsInstrInfo.td | 5 +++ test/MC/Mips/mips32r6/valid.s | 5 ++- test/MC/Mips/mips64r6/valid.s | 5 ++- 9 files changed, 101 insertions(+), 6 deletions(-) diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index cbe96b91237..958712602b4 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -263,6 +263,9 @@ static DecodeStatus DecodeExtSize(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't /// handle. template @@ -908,3 +911,9 @@ static DecodeStatus DecodeExtSize(MCInst &Inst, Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); return MCDisassembler::Success; } + +static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) << 2)); + return MCDisassembler::Success; +} diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 6deb3261b9b..538a0cda9be 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -548,5 +548,15 @@ MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; } -#include "MipsGenMCCodeEmitter.inc" +unsigned +MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + assert(MI.getOperand(OpNo).isImm()); + // The immediate is encoded as 'immediate << 2'. + unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); + assert((Res & 3) == 0); + return Res >> 2; +} +#include "MipsGenMCCodeEmitter.inc" diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 8118e4fe45f..735b0e43bbd 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -116,6 +116,10 @@ public: SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/lib/Target/Mips/Mips32r6InstrFormats.td b/lib/Target/Mips/Mips32r6InstrFormats.td index ac47f18bcc8..e3aa920a98a 100644 --- a/lib/Target/Mips/Mips32r6InstrFormats.td +++ b/lib/Target/Mips/Mips32r6InstrFormats.td @@ -26,12 +26,20 @@ class MipsR6Inst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther>, def OPGROUP_COP1 { bits<6> Value = 0b010001; } def OPGROUP_AUI { bits<6> Value = 0b001111; } def OPGROUP_DAUI { bits<6> Value = 0b011101; } +def OPGROUP_PCREL { bits<6> Value = 0b111011; } def OPGROUP_REGIMM { bits<6> Value = 0b000001; } def OPGROUP_SPECIAL { bits<6> Value = 0b000000; } +class OPCODE2 Val> { + bits<2> Value = Val; +} +def OPCODE2_ADDIUPC : OPCODE2<0b00>; + class OPCODE5 Val> { bits<5> Value = Val; } +def OPCODE5_ALUIPC : OPCODE5<0b11111>; +def OPCODE5_AUIPC : OPCODE5<0b11110>; def OPCODE5_DAHI : OPCODE5<0b00110>; def OPCODE5_DATI : OPCODE5<0b11110>; @@ -79,6 +87,30 @@ class COP1_3R_FM funct, FIELD_FMT Format> : MipsR6Inst { let Inst{5-0} = funct; } +class PCREL16_FM : MipsR6Inst { + bits<5> rs; + bits<16> imm; + + bits<32> Inst; + + let Inst{31-26} = OPGROUP_PCREL.Value; + let Inst{25-21} = rs; + let Inst{20-16} = Operation.Value; + let Inst{15-0} = imm; +} + +class PCREL19_FM : MipsR6Inst { + bits<5> rs; + bits<19> imm; + + bits<32> Inst; + + let Inst{31-26} = OPGROUP_PCREL.Value; + let Inst{25-21} = rs; + let Inst{20-19} = Operation.Value; + let Inst{18-0} = imm; +} + class SPECIAL_3R_FM mulop, bits<6> funct> : MipsR6Inst { bits<5> rd; bits<5> rs; diff --git a/lib/Target/Mips/Mips32r6InstrInfo.td b/lib/Target/Mips/Mips32r6InstrInfo.td index 769bb8add5e..e4006c0849b 100644 --- a/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/lib/Target/Mips/Mips32r6InstrInfo.td @@ -58,7 +58,10 @@ include "Mips32r6InstrFormats.td" // //===----------------------------------------------------------------------===// +class ADDIUPC_ENC : PCREL19_FM; +class ALUIPC_ENC : PCREL16_FM; class AUI_ENC : AUI_FM; +class AUIPC_ENC : PCREL16_FM; class DIV_ENC : SPECIAL_3R_FM<0b00010, 0b011010>; class DIVU_ENC : SPECIAL_3R_FM<0b00010, 0b011011>; class MOD_ENC : SPECIAL_3R_FM<0b00011, 0b011010>; @@ -76,6 +79,25 @@ class SEL_S_ENC : COP1_3R_FM<0b010000, FIELD_FMT_S>; // //===----------------------------------------------------------------------===// +class ADDIUPC_DESC_BASE { + dag OutOperandList = (outs GPROpnd:$rs); + dag InOperandList = (ins simm19_lsl2:$imm); + string AsmString = !strconcat(instr_asm, "\t$rs, $imm"); + list Pattern = []; +} + +class ADDIUPC_DESC : ADDIUPC_DESC_BASE<"addiupc", GPR32Opnd>; + +class ALUIPC_DESC_BASE { + dag OutOperandList = (outs GPROpnd:$rs); + dag InOperandList = (ins simm16:$imm); + string AsmString = !strconcat(instr_asm, "\t$rs, $imm"); + list Pattern = []; +} + +class ALUIPC_DESC : ALUIPC_DESC_BASE<"aluipc", GPR32Opnd>; +class AUIPC_DESC : ALUIPC_DESC_BASE<"auipc", GPR32Opnd>; + class AUI_DESC_BASE { dag OutOperandList = (outs GPROpnd:$rs); dag InOperandList = (ins GPROpnd:$rt, simm16:$imm); @@ -126,11 +148,11 @@ class SEL_S_DESC : SEL_DESC_BASE<"sel.s", FGR32Opnd>; // //===----------------------------------------------------------------------===// -def ADDIUPC; +def ADDIUPC : ADDIUPC_ENC, ADDIUPC_DESC, ISA_MIPS32R6; def ALIGN; // Known as as BALIGN in DSP ASE -def ALUIPC; +def ALUIPC : ALUIPC_ENC, ALUIPC_DESC, ISA_MIPS32R6; def AUI : AUI_ENC, AUI_DESC, ISA_MIPS32R6; -def AUIPC; +def AUIPC : AUIPC_ENC, AUIPC_DESC, ISA_MIPS32R6; def BALC; def BC1EQZ; def BC1NEZ; diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index 58a6be5d45f..d13a4661f33 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -117,6 +117,7 @@ private: unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; unsigned getLSAImmEncoding(const MachineInstr &MI, unsigned OpNo) const; + unsigned getSimm19Lsl2Encoding(const MachineInstr &MI, unsigned OpNo) const; /// Expand pseudo instructions with accumulator register operands. void expandACCInstr(MachineBasicBlock::instr_iterator MI, @@ -248,6 +249,12 @@ unsigned MipsCodeEmitter::getLSAImmEncoding(const MachineInstr &MI, return 0; } +unsigned MipsCodeEmitter::getSimm19Lsl2Encoding(const MachineInstr &MI, + unsigned OpNo) const { + llvm_unreachable("Unimplemented function."); + return 0; +} + /// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 8981979968b..b63c5cf2250 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -316,6 +316,11 @@ def simm16 : Operand { let DecoderMethod= "DecodeSimm16"; } +def simm19_lsl2 : Operand { + let EncoderMethod = "getSimm19Lsl2Encoding"; + let DecoderMethod = "DecodeSimm19Lsl2"; +} + def simm20 : Operand { } diff --git a/test/MC/Mips/mips32r6/valid.s b/test/MC/Mips/mips32r6/valid.s index a0633a5f921..f4ee49a6a06 100644 --- a/test/MC/Mips/mips32r6/valid.s +++ b/test/MC/Mips/mips32r6/valid.s @@ -4,7 +4,10 @@ .set noat # FIXME: Add the instructions carried forward from older ISA's - aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9] + addiupc $4, 100 # CHECK: addiupc $4, 100 # encoding: [0xec,0x80,0x00,0x19] + aluipc $3, 56 # CHECK: aluipc $3, 56 # encoding: [0xec,0x7f,0x00,0x38] + aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9] + auipc $3, -1 # CHECK: auipc $3, -1 # encoding: [0xec,0x7e,0xff,0xff] div $2,$3,$4 # CHECK: div $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9a] divu $2,$3,$4 # CHECK: divu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9b] mod $2,$3,$4 # CHECK: mod $2, $3, $4 # encoding: [0x00,0x64,0x10,0xda] diff --git a/test/MC/Mips/mips64r6/valid.s b/test/MC/Mips/mips64r6/valid.s index e1349819891..dbc1c502da8 100644 --- a/test/MC/Mips/mips64r6/valid.s +++ b/test/MC/Mips/mips64r6/valid.s @@ -4,7 +4,10 @@ .set noat # FIXME: Add the instructions carried forward from older ISA's - aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9] + addiupc $4, 100 # CHECK: addiupc $4, 100 # encoding: [0xec,0x80,0x00,0x19] + aluipc $3, 56 # CHECK: aluipc $3, 56 # encoding: [0xec,0x7f,0x00,0x38] + aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9] + auipc $3, -1 # CHECK: auipc $3, -1 # encoding: [0xec,0x7e,0xff,0xff] daui $3,$2,0x1234 # CHECK: daui $3, $2, 4660 # encoding: [0x74,0x62,0x12,0x34] dahi $3,$3,0x5678 # CHECK: dahi $3, $3, 22136 # encoding: [0x04,0x66,0x56,0x78] dati $3,$3,0xabcd # CHECK: dati $3, $3, 43981 # encoding: [0x04,0x7e,0xab,0xcd]