Index: llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -1221,9 +1221,6 @@ 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); @@ -1322,7 +1319,7 @@ // %fprs is an alias of %asr6. if (name.equals("fprs")) { - RegNo = ASRRegs[6]; + RegNo = Sparc::FPRS; RegKind = SparcOperand::rk_Special; return true; } @@ -1530,6 +1527,26 @@ RegKind = SparcOperand::rk_Special; return true; } + if (name.equals("asi")) { + RegNo = Sparc::ASI; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("ccr")) { + RegNo = Sparc::CCR; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("gl")) { + RegNo = Sparc::GL; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("ver")) { + RegNo = Sparc::VER; + 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 @@ -101,20 +101,16 @@ SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; static const unsigned ASRRegDecoderTable[] = { - SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, - SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7, - SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, - SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15, - SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, - SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23, - SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, - SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; + SP::Y, SP::ASR1, SP::CCR, SP::ASI, SP::TICK, SP::PC, SP::FPRS, + SP::ASR7, SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, SP::ASR12, SP::ASR13, + SP::ASR14, SP::ASR15, SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, SP::ASR20, + SP::ASR21, SP::ASR22, SP::ASR23, SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, + SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; 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::PC -}; + 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}; static const uint16_t IntPairDecoderTable[] = { SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7, Index: llvm/lib/Target/Sparc/SparcInstrAliases.td =================================================================== --- llvm/lib/Target/Sparc/SparcInstrAliases.td +++ llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -524,7 +524,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>; +def : InstAlias<"mov %pc, $rd", (RDASR IntRegs:$rd, PC), 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 @@ -1123,14 +1123,6 @@ "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,24 +106,33 @@ 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">; -def TSTATE : SparcCtrlReg<2, "TSTATE">; -def TT : SparcCtrlReg<3, "TT">; -def TICK : SparcCtrlReg<4, "TICK">; -def TBA : SparcCtrlReg<5, "TBA">; -def PSTATE : SparcCtrlReg<6, "PSTATE">; -def TL : SparcCtrlReg<7, "TL">; -def PIL : SparcCtrlReg<8, "PIL">; -def CWP : SparcCtrlReg<9, "CWP">; -def CANSAVE : SparcCtrlReg<10, "CANSAVE">; + +// The rest of the state registers on the other hand is only available for SparcV9. +// Unprivileged V9 state registers +def CCR : SparcCtrlReg<2, "CCR">; +def ASI : SparcCtrlReg<3, "ASI">; +def PC : SparcCtrlReg<5, "PC">; +def FPRS : SparcCtrlReg<6, "FPRS">; +// %tick can be read by both privileged and unprivileged instructions, +// but can only be written by privileged instructions. +def TICK : SparcCtrlReg<4, "TICK">; +// Privileged V9 state registers +def TPC : SparcCtrlReg<0, "TPC">; +def TNPC : SparcCtrlReg<1, "TNPC">; +def TSTATE : SparcCtrlReg<2, "TSTATE">; +def TT : SparcCtrlReg<3, "TT">; +def TBA : SparcCtrlReg<5, "TBA">; +def PSTATE : SparcCtrlReg<6, "PSTATE">; +def TL : SparcCtrlReg<7, "TL">; +def PIL : SparcCtrlReg<8, "PIL">; +def CWP : SparcCtrlReg<9, "CWP">; +def CANSAVE : SparcCtrlReg<10, "CANSAVE">; def CANRESTORE : SparcCtrlReg<11, "CANRESTORE">; -def CLEANWIN : SparcCtrlReg<12, "CLEANWIN">; -def OTHERWIN : SparcCtrlReg<13, "OTHERWIN">; -def WSTATE : SparcCtrlReg<14, "WSTATE">; +def CLEANWIN : SparcCtrlReg<12, "CLEANWIN">; +def OTHERWIN : SparcCtrlReg<13, "OTHERWIN">; +def WSTATE : SparcCtrlReg<14, "WSTATE">; +def GL : SparcCtrlReg<16, "GL">; +def VER : SparcCtrlReg<31, "VER">; // Integer registers def G0 : Ri< 0, "G0">, DwarfRegNum<[0]> { @@ -362,7 +371,8 @@ let isAllocatable = 0 in { // Ancillary state registers def ASRRegs : RegisterClass<"SP", [i32], 32, - (add Y, (sequence "ASR%u", 1, 31))>; + (add Y, CCR, ASI, TICK, PC, FPRS, + (sequence "ASR%u", 1, 31))>; // This register class should not be used to hold i64 values. def CoprocRegs : RegisterClass<"SP", [i32], 32, @@ -379,5 +389,4 @@ // Privileged Registers def PRRegs : RegisterClass<"SP", [i64], 64, (add TPC, TNPC, TSTATE, TT, TICK, TBA, PSTATE, TL, PIL, CWP, - CANSAVE, CANRESTORE, CLEANWIN, OTHERWIN, WSTATE)>; - + CANSAVE, CANRESTORE, CLEANWIN, OTHERWIN, WSTATE, GL, VER)>; Index: llvm/test/MC/Sparc/sparc-special-registers.s =================================================================== --- llvm/test/MC/Sparc/sparc-special-registers.s +++ llvm/test/MC/Sparc/sparc-special-registers.s @@ -34,10 +34,10 @@ ! CHECK: wr %i0, 5, %tbr ! encoding: [0x81,0x9e,0x20,0x05] wr %i0, 5, %tbr - ! CHECK: rd %asr6, %i0 ! encoding: [0xb1,0x41,0x80,0x00] + ! CHECK: rd %fprs, %i0 ! encoding: [0xb1,0x41,0x80,0x00] rd %fprs, %i0 - ! CHECK: wr %i0, 7, %asr6 ! encoding: [0x8d,0x86,0x20,0x07] + ! CHECK: wr %i0, 7, %fprs ! encoding: [0x8d,0x86,0x20,0x07] wr %i0, 7, %fprs ! CHECK: ld [%g2+20], %fsr ! encoding: [0xc1,0x08,0xa0,0x14] Index: llvm/test/MC/Sparc/sparcv9-instructions.s =================================================================== --- llvm/test/MC/Sparc/sparcv9-instructions.s +++ llvm/test/MC/Sparc/sparcv9-instructions.s @@ -417,9 +417,27 @@ rdpr %wstate,%i5 ! V8: error: instruction requires a CPU feature not currently enabled - ! V8-NEXT: rd %pc, %o7 + ! V8-NEXT: rdpr %ver,%i5 + ! V9: rdpr %ver, %i5 ! encoding: [0xbb,0x57,0xc0,0x00] + rdpr %ver,%i5 + ! V9: rd %pc, %o7 ! encoding: [0x9f,0x41,0x40,0x00] rd %pc, %o7 + ! V9: rd %asi, %g1 ! encoding: [0x83,0x40,0xc0,0x00] + rd %asi, %g1 + ! V9: rd %ccr, %g1 ! encoding: [0x83,0x40,0x80,0x00] + rd %ccr, %g1 + ! V9: rd %tick, %i5 ! encoding: [0xbb,0x41,0x00,0x00] + rd %tick,%i5 + + ! V9: wr %i0, %i1, %asi ! encoding: [0x87,0x86,0x00,0x19] + wr %i0, %i1, %asi + ! V9: wr %i0, 1, %asi ! encoding: [0x87,0x86,0x20,0x01] + wr %i0, 1, %asi + ! V9: wr %i0, %i1, %ccr ! encoding: [0x85,0x86,0x00,0x19] + wr %i0, %i1, %ccr + ! V9: wr %i0, 1, %ccr ! encoding: [0x85,0x86,0x20,0x01] + wr %i0, 1, %ccr ! V9: st %o1, [%o0] ! encoding: [0xd2,0x22,0x00,0x00] stw %o1, [%o0]