diff options
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 33 | ||||
-rw-r--r-- | lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMips32r6InstrFormats.td | 15 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMips32r6InstrInfo.td | 30 | ||||
-rw-r--r-- | lib/Target/Mips/MicroMipsInstrInfo.td | 20 | ||||
-rw-r--r-- | test/MC/Disassembler/Mips/micromips32r6/valid.txt | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/Mips/micromips64r6/valid.txt | 2 | ||||
-rw-r--r-- | test/MC/Mips/micromips/invalid.s | 8 | ||||
-rw-r--r-- | test/MC/Mips/micromips32r6/invalid.s | 8 | ||||
-rw-r--r-- | test/MC/Mips/micromips32r6/valid.s | 2 | ||||
-rw-r--r-- | test/MC/Mips/micromips64r6/invalid.s | 8 | ||||
-rw-r--r-- | test/MC/Mips/micromips64r6/valid.s | 2 |
12 files changed, 123 insertions, 10 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 001a9be332d..1b61535c75a 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1007,9 +1007,19 @@ public: void addRegPairOperands(MCInst &Inst, unsigned N) const { assert(N == 2 && "Invalid number of operands!"); + assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!"); unsigned RegNo = getRegPair(); - Inst.addOperand(MCOperand::createReg(RegNo++)); - Inst.addOperand(MCOperand::createReg(RegNo)); + AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc); + Inst.addOperand(MCOperand::createReg( + RegIdx.RegInfo->getRegClass( + AsmParser.getABI().AreGprs64bit() + ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID).getRegister(RegNo++))); + Inst.addOperand(MCOperand::createReg( + RegIdx.RegInfo->getRegClass( + AsmParser.getABI().AreGprs64bit() + ? Mips::GPR64RegClassID + : Mips::GPR32RegClassID).getRegister(RegNo))); } void addMovePRegPairOperands(MCInst &Inst, unsigned N) const { @@ -1156,7 +1166,9 @@ public: assert(Kind == k_Token && "Invalid access!"); return StringRef(Tok.Data, Tok.Length); } - bool isRegPair() const { return Kind == k_RegPair; } + bool isRegPair() const { + return Kind == k_RegPair && RegIdx.Index <= 30; + } unsigned getReg() const override { // As a special case until we sort out the definition of div/divu, pretend @@ -1311,9 +1323,9 @@ public: } static std::unique_ptr<MipsOperand> - CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) { + CreateRegPair(MipsOperand MOP, SMLoc S, SMLoc E, MipsAsmParser &Parser) { auto Op = make_unique<MipsOperand>(k_RegPair, Parser); - Op->RegIdx.Index = RegNo; + Op->RegIdx.Index = MOP.RegIdx.Index; Op->StartLoc = S; Op->EndLoc = E; return Op; @@ -3618,11 +3630,15 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { // 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 + // and registers Rd and Base for microMIPS lwp instruction unsigned Opcode = Inst.getOpcode(); if ((Opcode == Mips::JALR_HB || Opcode == Mips::JALRC_HB_MMR6) && (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) return Match_RequiresDifferentSrcAndDst; + else if ((Opcode == Mips::LWP_MM || Opcode == Mips::LWP_MMR6) && + (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())) + return Match_RequiresDifferentSrcAndDst; return Match_Success; } @@ -3786,6 +3802,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_MemSImm11: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected memory with 11-bit signed offset"); + case Match_MemSImm12: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected memory with 12-bit signed offset"); case Match_MemSImm16: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected memory with 16-bit signed offset"); @@ -4673,9 +4692,9 @@ MipsAsmParser::parseRegisterPair(OperandVector &Operands) { SMLoc E = Parser.getTok().getLoc(); MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back()); - unsigned Reg = Op.getGPR32Reg(); + Operands.pop_back(); - Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this)); + Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this)); return MatchOperand_Success; } diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index eeaa5ade9c5..c77cc47e1af 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -1552,7 +1552,8 @@ static DecodeStatus DecodeMemMMImm12(MCInst &Inst, // fallthrough default: Inst.addOperand(MCOperand::createReg(Reg)); - if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) + if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM || + Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6) Inst.addOperand(MCOperand::createReg(Reg+1)); Inst.addOperand(MCOperand::createReg(Base)); diff --git a/lib/Target/Mips/MicroMips32r6InstrFormats.td b/lib/Target/Mips/MicroMips32r6InstrFormats.td index ae0c506119f..a7b16d3dbf9 100644 --- a/lib/Target/Mips/MicroMips32r6InstrFormats.td +++ b/lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -978,3 +978,18 @@ class POOL32A_DVPEVP_FM_MMR6<string instr_asm, bits<10> funct> let Inst{15-6} = funct; let Inst{5-0} = 0b111100; } + +class POOL32B_LWP_SWP_FM_MMR6<bits<4> funct> : MipsR6Inst { + bits<5> rd; + bits<21> addr; + bits<5> base = addr{20-16}; + bits<12> offset = addr{11-0}; + + bits<32> Inst; + + let Inst{31-26} = 0x8; + let Inst{25-21} = rd; + let Inst{20-16} = base; + let Inst{15-12} = funct; + let Inst{11-0} = offset; +} diff --git a/lib/Target/Mips/MicroMips32r6InstrInfo.td b/lib/Target/Mips/MicroMips32r6InstrInfo.td index 8df942fec4a..a180a570ba7 100644 --- a/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -75,6 +75,7 @@ class JIC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b101000>; class JRC16_MMR6_ENC: POOL16C_JALRC_FM_MM16R6<0x3>; class JRCADDIUSP_MMR6_ENC : POOL16C_JRCADDIUSP_FM_MM16R6<0x13>; class LSA_MMR6_ENC : POOL32A_LSA_FM<0b001111>; +class LWP_MMR6_ENC : POOL32B_LWP_SWP_FM_MMR6<0x1>; class LWPC_MMR6_ENC : PCREL19_FM_MMR6<0b01>; class LWM16_MMR6_ENC : POOL16C_LWM_SWM_FM_MM16R6<0x2>; class MFC0_MMR6_ENC : POOL32A_MFTC0_FM_MMR6<"mfc0", 0b00011, 0b111100>; @@ -113,6 +114,7 @@ class SWE_MMR6_ENC : POOL32C_SWE_FM_MMR6<"swe", 0x18, 0xa, 0x7>; class SW16_MMR6_ENC : LOAD_STORE_FM_MM16<0x3a>; class SWM16_MMR6_ENC : POOL16C_LWM_SWM_FM_MM16R6<0xa>; class SWSP_MMR6_ENC : LOAD_STORE_SP_FM_MM16<0x32>; +class SWP_MMR6_ENC : POOL32B_LWP_SWP_FM_MMR6<0x9>; class PREFE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b010>; class CACHEE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b011>; class WRPGPR_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x3c5>; @@ -526,6 +528,32 @@ class PCREL_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd, class ADDIUPC_MMR6_DESC : PCREL_MMR6_DESC_BASE<"addiupc", GPR32Opnd, simm19_lsl2>; class LWPC_MMR6_DESC: PCREL_MMR6_DESC_BASE<"lwpc", GPR32Opnd, simm19_lsl2>; +class LWP_MMR6_DESC : MMR6Arch<"lwp"> { + dag OutOperandList = (outs regpair:$rd); + dag InOperandList = (ins mem_simm12:$addr); + string AsmString = !strconcat("lwp", "\t$rd, $addr"); + list<dag> Pattern = []; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; + Format f = FrmI; + string BaseOpcode = "lwp"; + string DecoderMethod = "DecodeMemMMImm12"; + bit mayLoad = 1; +} + +class SWP_MMR6_DESC : MMR6Arch<"swp"> { + dag OutOperandList = (outs); + dag InOperandList = (ins regpair:$rd, mem_simm12:$addr); + string AsmString = !strconcat("swp", "\t$rd, $addr"); + list<dag> Pattern = []; + InstrItinClass Itin = NoItinerary; + ComplexPattern Addr = addr; + Format f = FrmI; + string BaseOpcode = "swp"; + string DecoderMethod = "DecodeMemMMImm12"; + bit mayStore = 1; +} + class SELEQNE_Z_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> : MMR6Arch<instr_asm> { dag OutOperandList = (outs GPROpnd:$rd); @@ -1174,6 +1202,7 @@ def JRC16_MMR6 : R6MMR6Rel, JRC16_MMR6_DESC, JRC16_MMR6_ENC, ISA_MICROMIPS32R6; def JRCADDIUSP_MMR6 : R6MMR6Rel, JRCADDIUSP_MMR6_DESC, JRCADDIUSP_MMR6_ENC, ISA_MICROMIPS32R6; def LSA_MMR6 : R6MMR6Rel, LSA_MMR6_ENC, LSA_MMR6_DESC, ISA_MICROMIPS32R6; +def LWP_MMR6 : StdMMR6Rel, LWP_MMR6_ENC, LWP_MMR6_DESC, ISA_MICROMIPS32R6; def LWPC_MMR6 : R6MMR6Rel, LWPC_MMR6_ENC, LWPC_MMR6_DESC, ISA_MICROMIPS32R6; def LWM16_MMR6 : StdMMR6Rel, LWM16_MMR6_DESC, LWM16_MMR6_ENC, ISA_MICROMIPS32R6; def MTC0_MMR6 : StdMMR6Rel, MTC0_MMR6_ENC, MTC0_MMR6_DESC, ISA_MICROMIPS32R6; @@ -1221,6 +1250,7 @@ def SUBU_MMR6 : StdMMR6Rel, SUBU_MMR6_DESC, SUBU_MMR6_ENC, ISA_MICROMIPS32R6; def SW16_MMR6 : StdMMR6Rel, SW16_MMR6_DESC, SW16_MMR6_ENC, ISA_MICROMIPS32R6; def SWM16_MMR6 : StdMMR6Rel, SWM16_MMR6_DESC, SWM16_MMR6_ENC, ISA_MICROMIPS32R6; def SWSP_MMR6 : StdMMR6Rel, SWSP_MMR6_DESC, SWSP_MMR6_ENC, ISA_MICROMIPS32R6; +def SWP_MMR6 : StdMMR6Rel, SWP_MMR6_ENC, SWP_MMR6_DESC, ISA_MICROMIPS32R6; def PREFE_MMR6 : StdMMR6Rel, PREFE_MMR6_ENC, PREFE_MMR6_DESC, ISA_MICROMIPS32R6; def CACHEE_MMR6 : StdMMR6Rel, CACHEE_MMR6_ENC, CACHEE_MMR6_DESC, ISA_MICROMIPS32R6; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index ea5b9c17bf0..d552109b75a 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -128,6 +128,21 @@ def mem_mm_4sp : Operand<i32> { let OperandType = "OPERAND_MEMORY"; } +def MipsMemSimm12AsmOperand : AsmOperandClass { + let Name = "MemOffsetSimm12"; + let SuperClasses = [MipsMemAsmOperand]; + let RenderMethod = "addMemOperands"; + let ParserMethod = "parseMemOperand"; + let PredicateMethod = "isMemWithSimmOffset<12>"; + let DiagnosticType = "MemSImm12"; +} + +def mem_simm12 : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm12); + let EncoderMethod = "getMemEncoding"; + let ParserMatchClass = MipsMemSimm12AsmOperand; +} + def jmptarget_mm : Operand<OtherVT> { let EncoderMethod = "getJumpTargetOpValueMM"; } @@ -217,6 +232,7 @@ MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt), def RegPairAsmOperand : AsmOperandClass { let Name = "RegPair"; let ParserMethod = "parseRegisterPair"; + let PredicateMethod = "isRegPair"; } def regpair : Operand<i32> { @@ -229,7 +245,7 @@ def regpair : Operand<i32> { class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : - InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr), + InstSE<(outs), (ins regpair:$rt, mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayStore = 1; @@ -237,7 +253,7 @@ class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary, class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> : - InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr), + InstSE<(outs regpair:$rt), (ins mem_simm12:$addr), !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMemMMImm12"; let mayLoad = 1; diff --git a/test/MC/Disassembler/Mips/micromips32r6/valid.txt b/test/MC/Disassembler/Mips/micromips32r6/valid.txt index 38475325617..13a9abfee14 100644 --- a/test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ b/test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -307,3 +307,5 @@ 0x00 0x65 0x10 0x90 # CHECK: srav $2, $3, $5 0x00 0x83 0x38 0x40 # CHECK: srl $4, $3, 7 0x00 0x65 0x10 0x50 # CHECK: srlv $2, $3, $5 +0x22 0x04 0x10 0x08 # CHECK: lwp $16, 8($4) +0x22 0x04 0x90 0x08 # CHECK: swp $16, 8($4) diff --git a/test/MC/Disassembler/Mips/micromips64r6/valid.txt b/test/MC/Disassembler/Mips/micromips64r6/valid.txt index 757e6e3d103..58e27a490e1 100644 --- a/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ b/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -256,3 +256,5 @@ 0x58 0xa4 0x18 0x58 # CHECK: dmuh $3, $4, $5 0x58 0xa4 0x18 0x98 # CHECK: dmulu $3, $4, $5 0x58 0xa4 0x18 0xd8 # CHECK: dmuhu $3, $4, $5 +0x22 0x04 0x10 0x08 # CHECK: lwp $16, 8($4) +0x22 0x04 0x90 0x08 # CHECK: swp $16, 8($4) diff --git a/test/MC/Mips/micromips/invalid.s b/test/MC/Mips/micromips/invalid.s index f034f312d72..9ef6d865a77 100644 --- a/test/MC/Mips/micromips/invalid.s +++ b/test/MC/Mips/micromips/invalid.s @@ -83,3 +83,11 @@ she $4, 8($33) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset she $4, 512($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset she $4, -513($5) # CHECK: :[[@LINE]]:11: error: expected memory with 9-bit signed offset + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + # FIXME: This ought to point at the $34 but memory is treated as one operand. + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 8($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset diff --git a/test/MC/Mips/micromips32r6/invalid.s b/test/MC/Mips/micromips32r6/invalid.s index 7ebbc6fa320..ad1eb6ff251 100644 --- a/test/MC/Mips/micromips32r6/invalid.s +++ b/test/MC/Mips/micromips32r6/invalid.s @@ -188,3 +188,11 @@ swm32 $5, $6, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected swm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected swm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + # FIXME: This ought to point at the $34 but memory is treated as one operand. + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 8($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset diff --git a/test/MC/Mips/micromips32r6/valid.s b/test/MC/Mips/micromips32r6/valid.s index 23cd4275377..041915711a4 100644 --- a/test/MC/Mips/micromips32r6/valid.s +++ b/test/MC/Mips/micromips32r6/valid.s @@ -327,3 +327,5 @@ sll $3, 7 # CHECK: sll $3, $3, 7 # encoding: [0x00,0x63,0x38,0x00] sra $3, 7 # CHECK: sra $3, $3, 7 # encoding: [0x00,0x63,0x38,0x80] srl $3, 7 # CHECK: srl $3, $3, 7 # encoding: [0x00,0x63,0x38,0x40] + lwp $16, 8($4) # CHECK: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] + swp $16, 8($4) # CHECK: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] diff --git a/test/MC/Mips/micromips64r6/invalid.s b/test/MC/Mips/micromips64r6/invalid.s index 34995dda42e..c1c00dc5edf 100644 --- a/test/MC/Mips/micromips64r6/invalid.s +++ b/test/MC/Mips/micromips64r6/invalid.s @@ -220,3 +220,11 @@ swm32 $5, $6, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: $16 or $31 expected swm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected swm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand + lwp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + # FIXME: This ought to point at the $34 but memory is treated as one operand. + lwp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + lwp $16, 8($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: source and destination must be different + swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset diff --git a/test/MC/Mips/micromips64r6/valid.s b/test/MC/Mips/micromips64r6/valid.s index 45172a796e9..b08bb7b5f62 100644 --- a/test/MC/Mips/micromips64r6/valid.s +++ b/test/MC/Mips/micromips64r6/valid.s @@ -259,5 +259,7 @@ a: dmuh $3, $4, $5 # CHECK dmuh $3, $4, $5 # encoding: [0x58,0xa4,0x18,0x58] dmulu $3, $4, $5 # CHECK dmulu $3, $4, $5 # encoding: [0x58,0xa4,0x18,0x98] dmuhu $3, $4, $5 # CHECK dmuhu $3, $4, $5 # encoding: [0x58,0xa4,0x18,0xd8] + lwp $16, 8($4) # CHECK: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] + swp $16, 8($4) # CHECK: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] 1: |