Index: llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -1034,6 +1034,9 @@ case Sparc::TBR: Op = SparcOperand::CreateToken("%tbr", S); break; + case Sparc::PC: + Op = SparcOperand::CreateToken("%pc", S); + break; case Sparc::ICC: if (name == "xcc") Op = SparcOperand::CreateToken("%xcc", S); @@ -1341,6 +1344,11 @@ RegKind = SparcOperand::rk_Special; return true; } + if (name.equals("pc")) { + RegNo = Sparc::PC; + RegKind = SparcOperand::rk_Special; + return true; + } } return false; } Index: llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp =================================================================== --- llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -113,7 +113,7 @@ static const unsigned PRRegDecoderTable[] = { SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK, SP::TBA, SP::PSTATE, SP::TL, SP::PIL, SP::CWP, SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, - SP::OTHERWIN, SP::WSTATE + SP::OTHERWIN, SP::WSTATE, SP::PC }; static const uint16_t IntPairDecoderTable[] = { Index: llvm/lib/Target/Sparc/SparcInstrAliases.td =================================================================== --- llvm/lib/Target/Sparc/SparcInstrAliases.td +++ llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -444,6 +444,7 @@ def : InstAlias<"mov %psr, $rd", (RDPSR IntRegs:$rd), 0>; def : InstAlias<"mov %wim, $rd", (RDWIM IntRegs:$rd), 0>; def : InstAlias<"mov %tbr, $rd", (RDTBR IntRegs:$rd), 0>; +def : InstAlias<"mov %pc, $rd", (RDPC IntRegs:$rd), 0>; // mov reg_or_imm, specialreg -> wr %g0, reg_or_imm, specialreg def : InstAlias<"mov $rs2, $asr", (WRASRrr ASRRegs:$asr, G0, IntRegs:$rs2), 0>; Index: llvm/lib/Target/Sparc/SparcInstrInfo.td =================================================================== --- llvm/lib/Target/Sparc/SparcInstrInfo.td +++ llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -1056,6 +1056,14 @@ "rd %tbr, $rd", []>; } +// PC don't exist on the SparcV8, only the V9. +let Predicates = [HasV9] in { + let rs2 = 0, rs1 = 5 in + def RDPC : F3_1<2, 0b101000, + (outs IntRegs:$rd), (ins), + "rd %pc, $rd", []>; +} + // Section B.29 - Write State Register Instructions def WRASRrr : F3_1<2, 0b110000, (outs ASRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), Index: llvm/lib/Target/Sparc/SparcRegisterInfo.td =================================================================== --- llvm/lib/Target/Sparc/SparcRegisterInfo.td +++ llvm/lib/Target/Sparc/SparcRegisterInfo.td @@ -106,6 +106,8 @@ def PSR : SparcCtrlReg<0, "PSR">; def WIM : SparcCtrlReg<0, "WIM">; def TBR : SparcCtrlReg<0, "TBR">; +// PC on the other hand is only available for SparcV9. +def PC : SparcCtrlReg<5, "PC">; def TPC : SparcCtrlReg<0, "TPC">; def TNPC : SparcCtrlReg<1, "TNPC">; Index: llvm/test/MC/Sparc/sparcv9-instructions.s =================================================================== --- llvm/test/MC/Sparc/sparcv9-instructions.s +++ llvm/test/MC/Sparc/sparcv9-instructions.s @@ -293,3 +293,8 @@ ! V8-NEXT: rdpr %wstate,%i5 ! V9: rdpr %wstate, %i5 ! encoding: [0xbb,0x53,0x80,0x00] rdpr %wstate,%i5 + + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rd %pc, %o7 + ! V9: rd %pc, %o7 ! encoding: [0x9f,0x41,0x40,0x00] + rd %pc, %o7