Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -272,11 +272,12 @@ /// context). RegKind_CCR = 128, /// CCR RegKind_HWRegs = 256, /// HWRegs + RegKind_COP3 = 512, /// COP3 /// Potentially any (e.g. $1) RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | - RegKind_CCR | RegKind_HWRegs + RegKind_CCR | RegKind_HWRegs | RegKind_COP3 }; private: @@ -428,6 +429,14 @@ return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); } + /// Coerce the register to COP3 and return the real register for the + /// current target. + unsigned getCOP3Reg() const { + assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); + unsigned ClassID = Mips::COP3RegClassID; + return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); + } + /// Coerce the register to ACC64DSP and return the real register for the /// current target. unsigned getACC64DSPReg() const { @@ -539,6 +548,11 @@ Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); } + void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); + } + void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); @@ -750,6 +764,9 @@ bool isCOP2AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; } + bool isCOP3AsmReg() const { + return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; + } bool isMSA128AsmReg() const { return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; } Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -387,12 +387,22 @@ def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, ISA_MIPS2, FGR_32; -/// Cop2 Memory Instructions +// Cop2 Memory Instructions +// FIXME: These aren't really FPU instructions and as such don't belong in this +// file def LWC2 : LW_FT<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>; def SWC2 : SW_FT<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>; def LDC2 : LW_FT<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>, ISA_MIPS2; def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, ISA_MIPS2; +// Cop3 Memory Instructions +// FIXME: These aren't really FPU instructions and as such don't belong in this +// file +def LWC3 : LW_FT<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>; +def SWC3 : SW_FT<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>; +def LDC3 : LW_FT<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>, ISA_MIPS2; +def SDC3 : SW_FT<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>, ISA_MIPS2; + // Indexed loads and stores. // Base register + offset register addressing mode (indicated by "x" in the // instruction mnemonic) is disallowed under NaCl. Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -205,6 +205,10 @@ foreach I = 0-31 in def COP2#I : MipsReg<#I, ""#I>; + // COP3 registers. + foreach I = 0-31 in + def COP3#I : MipsReg<#I, ""#I>; + // PC register def PC : Register<"pc">; @@ -387,6 +391,10 @@ def COP2 : RegisterClass<"Mips", [i32], 32, (sequence "COP2%u", 0, 31)>, Unallocatable; +// Coprocessor 3 registers. +def COP3 : RegisterClass<"Mips", [i32], 32, (sequence "COP3%u", 0, 31)>, + Unallocatable; + // Octeon multiplier and product registers def OCTEON_MPL : RegisterClass<"Mips", [i64], 64, (add MPL0, MPL1, MPL2)>, Unallocatable; @@ -484,6 +492,10 @@ let Name = "COP2AsmReg"; } +def COP3AsmOperand : MipsAsmRegOperand { + let Name = "COP3AsmReg"; +} + def HWRegsOpnd : RegisterOperand { let ParserMatchClass = HWRegsAsmOperand; } @@ -524,6 +536,10 @@ let ParserMatchClass = COP2AsmOperand; } +def COP3Opnd : RegisterOperand { + let ParserMatchClass = COP3AsmOperand; +} + def MSA128BOpnd : RegisterOperand { let ParserMatchClass = MSA128AsmOperand; } Index: test/MC/Mips/mips1/invalid-mips2-wrong-error.s =================================================================== --- test/MC/Mips/mips1/invalid-mips2-wrong-error.s +++ test/MC/Mips/mips1/invalid-mips2-wrong-error.s @@ -8,7 +8,9 @@ .set noat ldc1 $f11,16391($s0) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ldc2 $8,-21181($at) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + ldc3 $29,-28645($s1) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction ll $v0,-7321($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sc $t7,18904($s3) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdc1 $f31,30574($t5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sdc2 $20,23157($s2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + sdc3 $12,5835($t2) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction Index: test/MC/Mips/mips1/invalid-mips2.s =================================================================== --- test/MC/Mips/mips1/invalid-mips2.s +++ test/MC/Mips/mips1/invalid-mips2.s @@ -4,7 +4,7 @@ # RUN: 2>%t1 # RUN: FileCheck %s < %t1 - .set noat + .set noat ceil.w.d $f11,$f25 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled ceil.w.s $f6,$f20 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled floor.w.d $f14,$f11 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled Index: test/MC/Mips/mips1/valid-xfail.s =================================================================== --- test/MC/Mips/mips1/valid-xfail.s +++ test/MC/Mips/mips1/valid-xfail.s @@ -8,5 +8,4 @@ .set noat lwc0 c0_entrylo,-7321($s2) - lwc3 $10,-32265($k0) swc0 c0_prid,18904($s3) Index: test/MC/Mips/mips1/valid.s =================================================================== --- test/MC/Mips/mips1/valid.s +++ test/MC/Mips/mips1/valid.s @@ -37,6 +37,7 @@ lw $t0,5674($a1) lwc1 $f16,10225($k0) lwc2 $18,-841($a2) + lwc3 $10,-32265($k0) lwl $s4,-4231($t7) lwr $zero,-19147($gp) mfc1 $a3,$f27 @@ -90,6 +91,7 @@ sw $ra,-10160($sp) swc1 $f6,-8465($t8) swc2 $25,24880($s0) + swc3 $10,-32265($k0) swl $t7,13694($s3) swr $s1,-26590($t6) tlbp # CHECK: tlbp # encoding: [0x42,0x00,0x00,0x08] Index: test/MC/Mips/mips2/valid-xfail.s =================================================================== --- test/MC/Mips/mips2/valid-xfail.s +++ /dev/null @@ -1,12 +0,0 @@ -# Instructions that should be valid but currently fail for known reasons (e.g. -# they aren't implemented yet). -# This test is set up to XPASS if any instruction generates an encoding. -# -# RUN: not llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips2 | not FileCheck %s -# CHECK-NOT: encoding -# XFAIL: * - - .set noat - ldc3 $29,-28645($s1) - lwc3 $10,-32265($k0) - sdc3 $12,5835($t2) Index: test/MC/Mips/mips2/valid.s =================================================================== --- test/MC/Mips/mips2/valid.s +++ test/MC/Mips/mips2/valid.s @@ -36,6 +36,7 @@ lbu $t0,30195($v1) ldc1 $f11,16391($s0) ldc2 $8,-21181($at) + ldc3 $29,-28645($s1) lh $t3,-8556($s5) lhu $s3,-22851($v0) li $at,-29773 @@ -44,6 +45,7 @@ lw $t0,5674($a1) lwc1 $f16,10225($k0) lwc2 $18,-841($a2) + lwc3 $10,-32265($k0) lwl $s4,-4231($t7) lwr $zero,-19147($gp) mfc1 $a3,$f27 @@ -77,6 +79,7 @@ sc $t7,18904($s3) sdc1 $f31,30574($t5) sdc2 $20,23157($s2) + sdc3 $12,5835($t2) sh $t6,-6704($t7) sll $a3,18 # CHECK: sll $7, $7, 18 # encoding: [0x00,0x07,0x3c,0x80] sll $a3,$zero,18 # CHECK: sll $7, $zero, 18 # encoding: [0x00,0x00,0x3c,0x80] @@ -104,6 +107,7 @@ sw $ra,-10160($sp) swc1 $f6,-8465($t8) swc2 $25,24880($s0) + swc3 $10,-32265($k0) swl $t7,13694($s3) swr $s1,-26590($t6) teqi $s5,-17504 Index: test/MC/Mips/mips3/valid-xfail.s =================================================================== --- test/MC/Mips/mips3/valid-xfail.s +++ /dev/null @@ -1,10 +0,0 @@ -# Instructions that should be valid but currently fail for known reasons (e.g. -# they aren't implemented yet). -# This test is set up to XPASS if any instruction generates an encoding. -# -# RUN: not llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips3 | not FileCheck %s -# CHECK-NOT: encoding -# XFAIL: * - - .set noat - lwc3 $10,-32265($k0) Index: test/MC/Mips/mips32/valid-xfail.s =================================================================== --- test/MC/Mips/mips32/valid-xfail.s +++ test/MC/Mips/mips32/valid-xfail.s @@ -35,6 +35,4 @@ c.ult.s $fcc7,$f24,$f10 c.un.d $fcc6,$f23,$f24 c.un.s $fcc1,$f30,$f4 - ldc3 $29,-28645($s1) rorv $t5,$a3,$s5 - sdc3 $12,5835($t2) Index: test/MC/Mips/mips32r2/valid-xfail.s =================================================================== --- test/MC/Mips/mips32r2/valid-xfail.s +++ test/MC/Mips/mips32r2/valid-xfail.s @@ -167,7 +167,6 @@ lbe $t6,122($t1) lbue $t3,-108($t2) lbux $t1,$t6($v0) - ldc3 $29,-28645($s1) lhe $s6,219($v1) lhue $gp,118($t3) lhx $sp,$k0($t7) @@ -263,7 +262,6 @@ rsqrt.s $f4,$f8 sbe $s7,33($s1) sce $sp,189($t2) - sdc3 $12,5835($t2) she $t8,105($v0) shilo $ac1,26 shilov $ac2,$t2