summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/Disassembler/MipsDisassembler.cpp9
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp12
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h4
-rw-r--r--lib/Target/Mips/Mips32r6InstrFormats.td32
-rw-r--r--lib/Target/Mips/Mips32r6InstrInfo.td28
-rw-r--r--lib/Target/Mips/MipsCodeEmitter.cpp7
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td5
-rw-r--r--test/MC/Mips/mips32r6/valid.s5
-rw-r--r--test/MC/Mips/mips64r6/valid.s5
9 files changed, 101 insertions, 6 deletions
diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index cbe96b9123..958712602b 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 <typename InsnType>
@@ -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 6deb3261b9..538a0cda9b 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<MCFixup> &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 8118e4fe45..735b0e43bb 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -116,6 +116,10 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
diff --git a/lib/Target/Mips/Mips32r6InstrFormats.td b/lib/Target/Mips/Mips32r6InstrFormats.td
index ac47f18bcc..e3aa920a98 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<bits<2> Val> {
+ bits<2> Value = Val;
+}
+def OPCODE2_ADDIUPC : OPCODE2<0b00>;
+
class OPCODE5<bits<5> 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<bits<6> funct, FIELD_FMT Format> : MipsR6Inst {
let Inst{5-0} = funct;
}
+class PCREL16_FM<OPCODE5 Operation> : 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<OPCODE2 Operation> : 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<bits<5> 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 769bb8add5..e4006c0849 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<OPCODE2_ADDIUPC>;
+class ALUIPC_ENC : PCREL16_FM<OPCODE5_ALUIPC>;
class AUI_ENC : AUI_FM;
+class AUIPC_ENC : PCREL16_FM<OPCODE5_AUIPC>;
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<string instr_asm, RegisterOperand GPROpnd> {
+ dag OutOperandList = (outs GPROpnd:$rs);
+ dag InOperandList = (ins simm19_lsl2:$imm);
+ string AsmString = !strconcat(instr_asm, "\t$rs, $imm");
+ list<dag> Pattern = [];
+}
+
+class ADDIUPC_DESC : ADDIUPC_DESC_BASE<"addiupc", GPR32Opnd>;
+
+class ALUIPC_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
+ dag OutOperandList = (outs GPROpnd:$rs);
+ dag InOperandList = (ins simm16:$imm);
+ string AsmString = !strconcat(instr_asm, "\t$rs, $imm");
+ list<dag> Pattern = [];
+}
+
+class ALUIPC_DESC : ALUIPC_DESC_BASE<"aluipc", GPR32Opnd>;
+class AUIPC_DESC : ALUIPC_DESC_BASE<"auipc", GPR32Opnd>;
+
class AUI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
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 58a6be5d45..d13a4661f3 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 8981979968..b63c5cf225 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -316,6 +316,11 @@ def simm16 : Operand<i32> {
let DecoderMethod= "DecodeSimm16";
}
+def simm19_lsl2 : Operand<i32> {
+ let EncoderMethod = "getSimm19Lsl2Encoding";
+ let DecoderMethod = "DecodeSimm19Lsl2";
+}
+
def simm20 : Operand<i32> {
}
diff --git a/test/MC/Mips/mips32r6/valid.s b/test/MC/Mips/mips32r6/valid.s
index a0633a5f92..f4ee49a6a0 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 e134981989..dbc1c502da 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]