diff options
Diffstat (limited to 'llvm/lib/Target/Mips')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 9 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 29 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsMSAInstrInfo.td | 17 |
9 files changed, 64 insertions, 46 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 09ae6a5d43c..aea022a336f 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -387,7 +387,6 @@ public: #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES - }; MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, @@ -894,10 +893,12 @@ public: Inst.addOperand(MCOperand::createReg(getHWRegsReg())); } - template <unsigned Bits> + template <unsigned Bits, int Offset = 0> void addConstantUImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); - uint64_t Imm = getConstantImm() & ((1 << Bits) - 1); + uint64_t Imm = getConstantImm() - Offset; + Imm &= (1 << Bits) - 1; + Imm += Offset; Inst.addOperand(MCOperand::createImm(Imm)); } @@ -963,6 +964,9 @@ public: bool isConstantImmz() const { return isConstantImm() && getConstantImm() == 0; } + template <unsigned Bits, int Offset = 0> bool isConstantUImm() const { + return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset); + } template <unsigned Bits> bool isUImm() const { return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm()); } @@ -3296,6 +3300,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(IDLoc, "source and destination must be different"); case Match_Immz: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); + case Match_UImm2_0: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 2-bit unsigned immediate"); + case Match_UImm2_1: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected immediate in range 1 .. 4"); } llvm_unreachable("Implement any new match types added!"); diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 121b49c8691..6332e1d52c4 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -380,12 +380,9 @@ static DecodeStatus DecodeSimm16(MCInst &Inst, uint64_t Address, const void *Decoder); -// Decode the immediate field of an LSA instruction which -// is off by one. -static DecodeStatus DecodeLSAImm(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder); +template <unsigned Bits, int Offset> +static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeInsSize(MCInst &Inst, unsigned Insn, @@ -1908,12 +1905,12 @@ static DecodeStatus DecodeSimm16(MCInst &Inst, return MCDisassembler::Success; } -static DecodeStatus DecodeLSAImm(MCInst &Inst, - unsigned Insn, - uint64_t Address, - const void *Decoder) { - // We add one to the immediate field as it was encoded as 'imm - 1'. - Inst.addOperand(MCOperand::createImm(Insn + 1)); +template <unsigned Bits, int Offset> +static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, + uint64_t Address, + const void *Decoder) { + Value &= ((1 << Bits) - 1); + Inst.addOperand(MCOperand::createImm(Value + Offset)); return MCDisassembler::Success; } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index bd6afcb1fe1..861049f000f 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -869,13 +869,15 @@ MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, return Position + Size - 1; } +template <unsigned Bits, int Offset> unsigned -MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const { +MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { assert(MI.getOperand(OpNo).isImm()); - // The immediate is encoded as 'immediate - 1'. - return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; + unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); + Value -= Offset; + return Value; } unsigned diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 56f286ab3d9..c2f4b6a72bb 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -191,10 +191,11 @@ public: SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; - // getLSAImmEncoding - Return binary encoding of LSA immediate. - unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo, - SmallVectorImpl<MCFixup> &Fixups, - const MCSubtargetInfo &STI) const; + /// Subtract Offset then encode as a N-bit unsigned integer. + template <unsigned Bits, int Offset> + unsigned getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td index f33ccf29543..572ba784c0d 100644 --- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -426,7 +426,7 @@ class LSA_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, list<dag> Pattern = []; } -class LSA_MMR6_DESC : LSA_MMR6_DESC_BASE<"lsa", GPR32Opnd, uimm2>; +class LSA_MMR6_DESC : LSA_MMR6_DESC_BASE<"lsa", GPR32Opnd, uimm2_plus1>; class PCREL_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, Operand ImmOpnd> : MMR6Arch<instr_asm> { diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index 8a6ae21e52e..9dd4d1e034e 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -597,7 +597,7 @@ class LSA_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, list<dag> Pattern = []; } -class LSA_R6_DESC : LSA_R6_DESC_BASE<"lsa", GPR32Opnd, uimm2>; +class LSA_R6_DESC : LSA_R6_DESC_BASE<"lsa", GPR32Opnd, uimm2_plus1>; class LL_R6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> { dag OutOperandList = (outs GPROpnd:$rt); diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index 3102849721d..6f34dbe28d3 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -62,7 +62,7 @@ class DCLO_R6_DESC : CLO_R6_DESC_BASE<"dclo", GPR64Opnd>; class DCLZ_R6_DESC : CLZ_R6_DESC_BASE<"dclz", GPR64Opnd>; class DDIV_DESC : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd, sdiv>; class DDIVU_DESC : DIVMOD_DESC_BASE<"ddivu", GPR64Opnd, udiv>; -class DLSA_R6_DESC : LSA_R6_DESC_BASE<"dlsa", GPR64Opnd, uimm2>; +class DLSA_R6_DESC : LSA_R6_DESC_BASE<"dlsa", GPR64Opnd, uimm2_plus1>; class DMOD_DESC : DIVMOD_DESC_BASE<"dmod", GPR64Opnd, srem>; class DMODU_DESC : DIVMOD_DESC_BASE<"dmodu", GPR64Opnd, urem>; class DMUH_DESC : MUL_R6_DESC_BASE<"dmuh", GPR64Opnd, mulhs>; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 0a32967b515..c0e62a56781 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -381,11 +381,24 @@ include "MipsInstrFormats.td" // Mips Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// +class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [], + int Offset = 0> : AsmOperandClass { + let Name = "ConstantUImm" # Bits # "_" # Offset; + let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">"; + let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">"; + let SuperClasses = Supers; + let DiagnosticType = "UImm" # Bits # "_" # Offset; +} + +def ConstantUImm2Plus1AsmOperandClass + : ConstantUImmAsmOperandClass<2, [], 1>; +def ConstantUImm2AsmOperandClass + : ConstantUImmAsmOperandClass<2>; def ConstantImmzAsmOperandClass : AsmOperandClass { let Name = "ConstantImmz"; let RenderMethod = "addConstantUImmOperands<1>"; let PredicateMethod = "isConstantImmz"; - let SuperClasses = []; + let SuperClasses = [ConstantUImm2AsmOperandClass]; let DiagnosticType = "Immz"; } @@ -461,9 +474,19 @@ def uimmz : Operand<i32> { let ParserMatchClass = ConstantImmzAsmOperandClass; } -// Unsigned Operand -def uimm2 : Operand<i32> { +// Unsigned Operands +foreach I = {2} in + def uimm # I : Operand<i32> { + let PrintMethod = "printUnsignedImm"; + let ParserMatchClass = + !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass"); + } + +def uimm2_plus1 : Operand<i32> { let PrintMethod = "printUnsignedImm"; + let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>"; + let DecoderMethod = "DecodeUImmWithOffset<2, 1>"; + let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass; } def uimm3 : Operand<i32> { diff --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td index 64bae3b5417..f3e08499bf9 100644 --- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td @@ -70,21 +70,6 @@ def immZExt6Ptr : ImmLeaf<iPTR, [{return isUInt<6>(Imm);}]>; // Operands -// The immediate of an LSA instruction needs special handling -// as the encoded value should be subtracted by one. -def uimm2LSAAsmOperand : AsmOperandClass { - let Name = "LSAImm"; - let ParserMethod = "parseLSAImm"; - let RenderMethod = "addImmOperands"; -} - -def LSAImm : Operand<i32> { - let PrintMethod = "printUnsignedImm"; - let EncoderMethod = "getLSAImmEncoding"; - let DecoderMethod = "DecodeLSAImm"; - let ParserMatchClass = uimm2LSAAsmOperand; -} - def uimm4 : Operand<i32> { let PrintMethod = "printUnsignedImm8"; } @@ -2380,7 +2365,7 @@ class LSA_DESC_BASE<string instr_asm, RegisterOperand RORD, RegisterOperand RORS = RORD, RegisterOperand RORT = RORD, InstrItinClass itin = NoItinerary > { dag OutOperandList = (outs RORD:$rd); - dag InOperandList = (ins RORS:$rs, RORT:$rt, LSAImm:$sa); + dag InOperandList = (ins RORS:$rs, RORT:$rt, uimm2_plus1:$sa); string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt, $sa"); list<dag> Pattern = [(set RORD:$rd, (add RORT:$rt, (shl RORS:$rs, |