diff options
author | Simon Dardis <simon.dardis@imgtec.com> | 2016-09-16 13:50:43 +0000 |
---|---|---|
committer | Simon Dardis <simon.dardis@imgtec.com> | 2016-09-16 13:50:43 +0000 |
commit | cf060794cd4da110c96530f437f2f2586347b1f3 (patch) | |
tree | f6143302de154a4a2a1d110c84d214ec7ef7e0b7 /llvm/lib/Target | |
parent | ceae630c9b6f2f3ef9534efc733109ea1007de06 (diff) | |
download | bcm5719-llvm-cf060794cd4da110c96530f437f2f2586347b1f3.tar.gz bcm5719-llvm-cf060794cd4da110c96530f437f2f2586347b1f3.zip |
[mips] Fix aui/daui/dahi/dati for MIPSR6
For compatiblity with binutils, define these instructions to take
two registers with a 16bit unsigned immediate. Both of the registers
have to be same for dahi and dati.
Reviewers: vkalintiris, dsanders, zoran.jovanovic
Differential Review: https://reviews.llvm.org/D21473
llvm-svn: 281724
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 36 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td | 12 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 14 |
7 files changed, 75 insertions, 11 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index cdbf4a62c8c..600316acaeb 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -3824,6 +3824,8 @@ MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, return Match_Success; case Mips::DATI: case Mips::DAHI: + case Mips::DATI_MM64R6: + case Mips::DAHI_MM64R6: if (static_cast<MipsOperand &>(*Operands[1]) .isValidForTie(static_cast<MipsOperand &>(*Operands[2]))) return Match_Success; @@ -3832,6 +3834,14 @@ MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, } unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { switch (Inst.getOpcode()) { + // As described by the MIPSR6 spec, daui must not use the zero operand for + // its source operand. + case Mips::DAUI: + case Mips::DAUI_MM64R6: + if (Inst.getOperand(1).getReg() == Mips::ZERO || + Inst.getOperand(1).getReg() == Mips::ZERO_64) + return Match_RequiresNoZeroRegister; + return Match_Success; // As described by the Mips32r2 spec, the registers Rd and Rs for // jalr.hb must be different. // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index f53998ea8e7..74a8f4f2152 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -439,6 +439,14 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); template <typename InsnType> +static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + +template <typename InsnType> +static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder); + +template <typename InsnType> static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder); @@ -596,6 +604,34 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, } template <typename InsnType> +static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder) { + InsnType Rt = fieldFromInstruction(insn, 16, 5); + InsnType Imm = fieldFromInstruction(insn, 0, 16); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, + Rt))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, + Rt))); + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} + +template <typename InsnType> +static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, + const void *Decoder) { + InsnType Rt = fieldFromInstruction(insn, 21, 5); + InsnType Imm = fieldFromInstruction(insn, 0, 16); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, + Rt))); + MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, + Rt))); + MI.addOperand(MCOperand::createImm(Imm)); + + return MCDisassembler::Success; +} + +template <typename InsnType> static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, const void *Decoder) { diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index b8d8aa0ce20..913074ba15a 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -567,7 +567,7 @@ class ALIGN_MMR6_DESC : ALIGN_MMR6_DESC_BASE<"align", GPR32Opnd, uimm2, class AUI_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass Itin> : MMR6Arch<instr_asm> { dag OutOperandList = (outs GPROpnd:$rt); - dag InOperandList = (ins GPROpnd:$rs, simm16:$imm); + dag InOperandList = (ins GPROpnd:$rs, uimm16:$imm); string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm"); list<dag> Pattern = []; InstrItinClass Itinerary = Itin; diff --git a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td index 508b34299bb..1f152d0e190 100644 --- a/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -81,7 +81,7 @@ class DAUI_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass Itin> : MMR6Arch<instr_asm>, MipsR6Inst { dag OutOperandList = (outs GPROpnd:$rt); - dag InOperandList = (ins GPROpnd:$rs, simm16:$imm); + dag InOperandList = (ins GPROpnd:$rs, uimm16:$imm); string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm"); list<dag> Pattern = []; InstrItinClass Itinerary = Itin; @@ -92,8 +92,8 @@ class DAHI_DATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass Itin> : MMR6Arch<instr_asm>, MipsR6Inst { dag OutOperandList = (outs GPROpnd:$rs); - dag InOperandList = (ins GPROpnd:$rt, simm16:$imm); - string AsmString = !strconcat(instr_asm, "\t$rt, $imm"); + dag InOperandList = (ins GPROpnd:$rt, uimm16:$imm); + string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $imm"); string Constraints = "$rs = $rt"; InstrItinClass Itinerary = Itin; } @@ -360,8 +360,10 @@ class LWUPC_MM64R6_DESC { 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; + let DecoderMethod = "DecodeDAHIDATIMMR6" in { + 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, diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index e81869513b6..34e3936b3cd 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -324,7 +324,7 @@ class AUI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass itin = NoItinerary> : MipsR6Arch<instr_asm> { dag OutOperandList = (outs GPROpnd:$rs); - dag InOperandList = (ins GPROpnd:$rt, simm16:$imm); + dag InOperandList = (ins GPROpnd:$rt, uimm16:$imm); string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $imm"); list<dag> Pattern = []; InstrItinClass Itinerary = itin; diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index c380dfdc480..dabf4e0a52e 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -48,8 +48,8 @@ class SCD_R6_ENC : SPECIAL3_LL_SC_FM<OPCODE6_SCD>; class AHI_ATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, InstrItinClass itin> { dag OutOperandList = (outs GPROpnd:$rs); - dag InOperandList = (ins GPROpnd:$rt, simm16_relaxed:$imm); - string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $imm"); + dag InOperandList = (ins GPROpnd:$rt, uimm16_altrelaxed:$imm); + string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $imm"); string Constraints = "$rs = $rt"; InstrItinClass Itinerary = itin; } @@ -111,8 +111,10 @@ class SC64_R6_DESC : SC_R6_DESC_BASE<"sc", GPR32Opnd, II_SC>; //===----------------------------------------------------------------------===// let AdditionalPredicates = [NotInMicroMips] in { - def DATI : DATI_ENC, DATI_DESC, ISA_MIPS64R6; - def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6; + let DecoderMethod = "DecodeDAHIDATI" 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 : R6MMR6Rel, DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 39b31074608..131a7519d3c 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -507,6 +507,14 @@ def UImm16RelaxedAsmOperandClass let PredicateMethod = "isAnyImm<16>"; let DiagnosticType = "UImm16_Relaxed"; } +// Similar to the relaxed classes which take an SImm and render it as +// an UImm, this takes a UImm and renders it as an SImm. +def UImm16AltRelaxedAsmOperandClass + : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> { + let Name = "UImm16_AltRelaxed"; + let PredicateMethod = "isUImm<16>"; + let DiagnosticType = "UImm16_AltRelaxed"; +} def UImm16AsmOperandClass : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>; def SImm16RelaxedAsmOperandClass @@ -515,6 +523,7 @@ def SImm16RelaxedAsmOperandClass let PredicateMethod = "isAnyImm<16>"; let DiagnosticType = "SImm16_Relaxed"; } + def SImm16AsmOperandClass : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>; def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass { @@ -785,6 +794,11 @@ def uimm16_64_relaxed : Operand<i64> { !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass"); } +def uimm16_altrelaxed : Operand<i32> { + let PrintMethod = "printUImm<16>"; + let ParserMatchClass = + !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass"); +} // Like uimm5 but reports a less confusing error for 32-63 when // an instruction alias permits that. def uimm5_report_uimm6 : Operand<i32> { |