Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -221,6 +221,8 @@ int matchCPURegisterName(StringRef Symbol); + int matchHWRegsRegisterName(StringRef Symbol); + int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); int matchFPURegisterName(StringRef Name); @@ -845,6 +847,14 @@ return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); } + /// Create a register that is definitely a HWReg. + /// This is typically only used for named registers such as $hwr_cpunum. + static std::unique_ptr + createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo, + SMLoc S, SMLoc E, MipsAsmParser &Parser) { + return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser); + } + /// Create a register that is definitely an FCC. /// This is typically only used for named registers such as $fcc0. static std::unique_ptr @@ -1739,6 +1749,19 @@ return CC; } +int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { + int CC; + + CC = StringSwitch(Name) + .Case("hwr_cpunum", 0) + .Case("hwr_synci_step", 1) + .Case("hwr_cc", 2) + .Case("hwr_ccres", 3) + .Default(-1); + + return CC; +} + int MipsAsmParser::matchFPURegisterName(StringRef Name) { if (Name[0] == 'f') { @@ -2222,6 +2245,14 @@ return MatchOperand_Success; } + Index = matchHWRegsRegisterName(Identifier); + if (Index != -1) { + Operands.push_back(MipsOperand::createHWRegsReg( + Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); + return MatchOperand_Success; + } + + Index = matchFPURegisterName(Identifier); if (Index != -1) { Operands.push_back(MipsOperand::createFGRReg( Index: lib/Target/Mips/MipsRegisterInfo.td =================================================================== --- lib/Target/Mips/MipsRegisterInfo.td +++ lib/Target/Mips/MipsRegisterInfo.td @@ -212,8 +212,13 @@ // PC register def PC : Register<"pc">; - // Hardware register $29 - foreach I = 0-31 in + // Hardware registers + def HWR0 : MipsReg<0, "hwr_cpunum">; + def HWR1 : MipsReg<1, "hwr_synci_step">; + def HWR2 : MipsReg<2, "hwr_cc">; + def HWR3 : MipsReg<3, "hwr_ccres">; + + foreach I = 4-31 in def HWR#I : MipsReg<#I, ""#I>; // Accum registers Index: test/MC/Mips/mips-hwr-register-names.s =================================================================== --- /dev/null +++ test/MC/Mips/mips-hwr-register-names.s @@ -0,0 +1,189 @@ +# Check the hardware registers +# +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s + .set noat + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $hwr_cpunum + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x00,0x3b] + rdhwr $a0,$hwr_cpunum + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $hwr_cpunum + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x00,0x3b] + rdhwr $a0,$0 + + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $5, $hwr_synci_step + # CHECK-NEXT: .set pop # encoding: [0x7c,0x05,0x08,0x3b] + rdhwr $a1,$hwr_synci_step + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $5, $hwr_synci_step + # CHECK-NEXT: .set pop # encoding: [0x7c,0x05,0x08,0x3b] + rdhwr $a1,$1 + + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $6, $hwr_cc + # CHECK-NEXT: .set pop # encoding: [0x7c,0x06,0x10,0x3b] + rdhwr $a2,$hwr_cc + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $6, $hwr_cc + # CHECK-NEXT: .set pop # encoding: [0x7c,0x06,0x10,0x3b] + rdhwr $a2,$2 + + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $7, $hwr_ccres + # CHECK-NEXT: .set pop # encoding: [0x7c,0x07,0x18,0x3b] + rdhwr $a3,$hwr_ccres + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $7, $hwr_ccres + # CHECK-NEXT: .set pop # encoding: [0x7c,0x07,0x18,0x3b] + rdhwr $a3,$3 + + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $4 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x20,0x3b] + rdhwr $a0,$4 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $5 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x28,0x3b] + rdhwr $a0,$5 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $6 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x30,0x3b] + rdhwr $a0,$6 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $7 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x38,0x3b] + rdhwr $a0,$7 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $8 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x40,0x3b] + rdhwr $a0,$8 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $9 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x48,0x3b] + rdhwr $a0,$9 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $10 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x50,0x3b] + rdhwr $a0,$10 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $11 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x58,0x3b] + rdhwr $a0,$11 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $12 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x60,0x3b] + rdhwr $a0,$12 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $13 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x68,0x3b] + rdhwr $a0,$13 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $14 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x70,0x3b] + rdhwr $a0,$14 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $15 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x78,0x3b] + rdhwr $a0,$15 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $16 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x80,0x3b] + rdhwr $a0,$16 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $17 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x88,0x3b] + rdhwr $a0,$17 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $18 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x90,0x3b] + rdhwr $a0,$18 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $19 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0x98,0x3b] + rdhwr $a0,$19 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $20 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xa0,0x3b] + rdhwr $a0,$20 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $21 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xa8,0x3b] + rdhwr $a0,$21 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $22 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xb0,0x3b] + rdhwr $a0,$22 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $23 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xb8,0x3b] + rdhwr $a0,$23 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $24 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xc0,0x3b] + rdhwr $a0,$24 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $25 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xc8,0x3b] + rdhwr $a0,$25 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $26 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xd0,0x3b] + rdhwr $a0,$26 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $27 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xd8,0x3b] + rdhwr $a0,$27 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $28 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xe0,0x3b] + rdhwr $a0,$28 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $29 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xe8,0x3b] + rdhwr $a0,$29 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $30 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xf0,0x3b] + rdhwr $a0,$30 + # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $4, $31 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x04,0xf8,0x3b] + rdhwr $a0,$31 Index: test/MC/Mips/mips32r2/valid.s =================================================================== --- test/MC/Mips/mips32r2/valid.s +++ test/MC/Mips/mips32r2/valid.s @@ -137,7 +137,10 @@ or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] - rdhwr $sp,$11 + rdhwr $sp,$11 # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $sp, $11 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x1d,0x58,0x3b] rotr $1,15 # CHECK: rotr $1, $1, 15 # encoding: [0x00,0x21,0x0b,0xc2] rotr $1,$14,15 # CHECK: rotr $1, $14, 15 # encoding: [0x00,0x2e,0x0b,0xc2] rotrv $1,$14,$15 # CHECK: rotrv $1, $14, $15 # encoding: [0x01,0xee,0x08,0x46] Index: test/MC/Mips/mips32r6/valid.s =================================================================== --- test/MC/Mips/mips32r6/valid.s +++ test/MC/Mips/mips32r6/valid.s @@ -119,6 +119,10 @@ msubf.s $f2,$f3,$f4 # CHECK: msubf.s $f2, $f3, $f4 # encoding: [0x46,0x04,0x18,0x99] msubf.d $f2,$f3,$f4 # CHECK: msubf.d $f2, $f3, $f4 # encoding: [0x46,0x24,0x18,0x99] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0x7c,0xa1,0x04,0x35] + rdhwr $sp,$11 # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $sp, $11 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x1d,0x58,0x3b] sel.d $f0,$f1,$f2 # CHECK: sel.d $f0, $f1, $f2 # encoding: [0x46,0x22,0x08,0x10] sel.s $f0,$f1,$f2 # CHECK: sel.s $f0, $f1, $f2 # encoding: [0x46,0x02,0x08,0x10] seleqz $2,$3,$4 # CHECK: seleqz $2, $3, $4 # encoding: [0x00,0x64,0x10,0x35] Index: test/MC/Mips/mips64r2/valid.s =================================================================== --- test/MC/Mips/mips64r2/valid.s +++ test/MC/Mips/mips64r2/valid.s @@ -199,7 +199,10 @@ or $2, 4 # CHECK: ori $2, $2, 4 # encoding: [0x34,0x42,0x00,0x04] pause # CHECK: pause # encoding: [0x00,0x00,0x01,0x40] pref 1, 8($5) # CHECK: pref 1, 8($5) # encoding: [0xcc,0xa1,0x00,0x08] - rdhwr $sp,$11 + rdhwr $sp,$11 # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $sp, $11 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x1d,0x58,0x3b] rotr $1,15 # CHECK: rotr $1, $1, 15 # encoding: [0x00,0x21,0x0b,0xc2] rotr $1,$14,15 # CHECK: rotr $1, $14, 15 # encoding: [0x00,0x2e,0x0b,0xc2] rotrv $1,$14,$15 # CHECK: rotrv $1, $14, $15 # encoding: [0x01,0xee,0x08,0x46] Index: test/MC/Mips/mips64r6/valid.s =================================================================== --- test/MC/Mips/mips64r6/valid.s +++ test/MC/Mips/mips64r6/valid.s @@ -155,6 +155,10 @@ seleqz.d $f0, $f2, $f4 # CHECK: seleqz.d $f0, $f2, $f4 # encoding: [0x46,0x24,0x10,0x14] selnez.s $f0, $f2, $f4 # CHECK: selnez.s $f0, $f2, $f4 # encoding: [0x46,0x04,0x10,0x17] selnez.d $f0, $f2, $f4 # CHECK: selnez.d $f0, $f2, $f4 # encoding: [0x46,0x24,0x10,0x17] + rdhwr $sp,$11 # CHECK: .set push + # CHECK-NEXT: .set mips32r2 + # CHECK-NEXT: rdhwr $sp, $11 + # CHECK-NEXT: .set pop # encoding: [0x7c,0x1d,0x58,0x3b] rint.s $f2, $f4 # CHECK: rint.s $f2, $f4 # encoding: [0x46,0x00,0x20,0x9a] rint.d $f2, $f4 # CHECK: rint.d $f2, $f4 # encoding: [0x46,0x20,0x20,0x9a] class.s $f2, $f4 # CHECK: class.s $f2, $f4 # encoding: [0x46,0x00,0x20,0x9b]