From 58b865b86c3df0de0855a0a1106f8985060aed5c Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Sun, 4 Oct 2015 09:11:22 +0000 Subject: [PATCH] [SPARCv9] Add support for the rdpr/wrpr instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249262 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 76 ++++++++ .../Sparc/Disassembler/SparcDisassembler.cpp | 15 ++ lib/Target/Sparc/SparcInstrInfo.td | 19 ++ lib/Target/Sparc/SparcRegisterInfo.td | 21 ++ test/MC/Sparc/sparcv9-instructions.s | 183 ++++++++++++++++++ 5 files changed, 314 insertions(+) diff --git a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index d6bc3d0f888..d90911a423e 100644 --- a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -1024,6 +1024,82 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, RegKind = SparcOperand::rk_IntReg; return true; } + + if (name.equals("tpc")) { + RegNo = Sparc::TPC; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tnpc")) { + RegNo = Sparc::TNPC; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tstate")) { + RegNo = Sparc::TSTATE; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tt")) { + RegNo = Sparc::TT; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tick")) { + RegNo = Sparc::TICK; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tba")) { + RegNo = Sparc::TBA; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("pstate")) { + RegNo = Sparc::PSTATE; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("tl")) { + RegNo = Sparc::TL; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("pil")) { + RegNo = Sparc::PIL; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("cwp")) { + RegNo = Sparc::CWP; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("cansave")) { + RegNo = Sparc::CANSAVE; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("canrestore")) { + RegNo = Sparc::CANRESTORE; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("cleanwin")) { + RegNo = Sparc::CLEANWIN; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("otherwin")) { + RegNo = Sparc::OTHERWIN; + RegKind = SparcOperand::rk_Special; + return true; + } + if (name.equals("wstate")) { + RegNo = Sparc::WSTATE; + RegKind = SparcOperand::rk_Special; + return true; + } } return false; } diff --git a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp index e518fc75c14..51751ec511c 100644 --- a/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +++ b/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp @@ -117,6 +117,12 @@ static const unsigned ASRRegDecoderTable[] = { 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 +}; + static const uint16_t IntPairDecoderTable[] = { SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7, SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7, @@ -203,6 +209,15 @@ static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo >= array_lengthof(PRRegDecoderTable)) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo])); + return MCDisassembler::Success; +} + static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index d7649dafd4d..ffba2d790c3 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -1327,6 +1327,25 @@ let hasSideEffects = 1 in { } } + +// Section A.43 - Read Privileged Register Instructions +let Predicates = [HasV9] in { +let rs2 = 0 in + def RDPR : F3_1<2, 0b101010, + (outs IntRegs:$rd), (ins PRRegs:$rs1), + "rdpr $rs1, $rd", []>; +} + +// Section A.62 - Write Privileged Register Instructions +let Predicates = [HasV9] in { + def WRPRrr : F3_1<2, 0b110010, + (outs PRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), + "wrpr $rs1, $rs2, $rd", []>; + def WRPRri : F3_2<2, 0b110010, + (outs PRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), + "wrpr $rs1, $simm13, $rd", []>; +} + //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/Sparc/SparcRegisterInfo.td b/lib/Target/Sparc/SparcRegisterInfo.td index 982377d76ed..cca9463562a 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.td +++ b/lib/Target/Sparc/SparcRegisterInfo.td @@ -102,6 +102,22 @@ def PSR : SparcCtrlReg<0, "PSR">; def WIM : SparcCtrlReg<0, "WIM">; def TBR : SparcCtrlReg<0, "TBR">; +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">; +def CANRESTORE : SparcCtrlReg<11, "CANRESTORE">; +def CLEANWIN : SparcCtrlReg<12, "CLEANWIN">; +def OTHERWIN : SparcCtrlReg<13, "OTHERWIN">; +def WSTATE : SparcCtrlReg<14, "WSTATE">; + // Integer registers def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>; def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>; @@ -285,3 +301,8 @@ def ASRRegs : RegisterClass<"SP", [i32], 32, (add Y, (sequence "ASR%u", 1, 31))> { let isAllocatable = 0; } + +// Privileged Registers +def PRRegs : RegisterClass<"SP", [i64], 64, + (add TPC, TNPC, TSTATE, TT, TICK, TBA, PSTATE, TL, PIL, CWP, + CANSAVE, CANRESTORE, CLEANWIN, OTHERWIN, WSTATE)>; diff --git a/test/MC/Sparc/sparcv9-instructions.s b/test/MC/Sparc/sparcv9-instructions.s index 98e3096e18f..2f90d4360dd 100644 --- a/test/MC/Sparc/sparcv9-instructions.s +++ b/test/MC/Sparc/sparcv9-instructions.s @@ -110,3 +110,186 @@ ! V8-NEXT: stx %fsr,[%g2 + %i5] ! V9: stx %fsr, [%g2+%i5] ! encoding: [0xc3,0x28,0x80,0x1d] stx %fsr,[%g2 + %i5] + + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tpc + ! V9: wrpr %g6, %fp, %tpc ! encoding: [0x81,0x91,0x80,0x1e] + wrpr %g6,%i6,%tpc + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tnpc + ! V9: wrpr %g6, %fp, %tnpc ! encoding: [0x83,0x91,0x80,0x1e] + wrpr %g6,%i6,%tnpc + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tstate + ! V9: wrpr %g6, %fp, %tstate ! encoding: [0x85,0x91,0x80,0x1e] + wrpr %g6,%i6,%tstate + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tt + ! V9: wrpr %g6, %fp, %tt ! encoding: [0x87,0x91,0x80,0x1e] + wrpr %g6,%i6,%tt + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tick + ! V9: wrpr %g6, %fp, %tick ! encoding: [0x89,0x91,0x80,0x1e] + wrpr %g6,%i6,%tick + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tba + ! V9: wrpr %g6, %fp, %tba ! encoding: [0x8b,0x91,0x80,0x1e] + wrpr %g6,%i6,%tba + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%pstate + ! V9: wrpr %g6, %fp, %pstate ! encoding: [0x8d,0x91,0x80,0x1e] + wrpr %g6,%i6,%pstate + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%tl + ! V9: wrpr %g6, %fp, %tl ! encoding: [0x8f,0x91,0x80,0x1e] + wrpr %g6,%i6,%tl + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%pil + ! V9: wrpr %g6, %fp, %pil ! encoding: [0x91,0x91,0x80,0x1e] + wrpr %g6,%i6,%pil + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%cwp + ! V9: wrpr %g6, %fp, %cwp ! encoding: [0x93,0x91,0x80,0x1e] + wrpr %g6,%i6,%cwp + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%cansave + ! V9: wrpr %g6, %fp, %cansave ! encoding: [0x95,0x91,0x80,0x1e] + wrpr %g6,%i6,%cansave + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%canrestore + ! V9: wrpr %g6, %fp, %canrestore ! encoding: [0x97,0x91,0x80,0x1e] + wrpr %g6,%i6,%canrestore + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%cleanwin + ! V9: wrpr %g6, %fp, %cleanwin ! encoding: [0x99,0x91,0x80,0x1e] + wrpr %g6,%i6,%cleanwin + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%otherwin + ! V9: wrpr %g6, %fp, %otherwin ! encoding: [0x9b,0x91,0x80,0x1e] + wrpr %g6,%i6,%otherwin + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,%i6,%wstate + ! V9: wrpr %g6, %fp, %wstate ! encoding: [0x9d,0x91,0x80,0x1e] + wrpr %g6,%i6,%wstate + + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tpc + ! V9: wrpr %g6, 255, %tpc ! encoding: [0x81,0x91,0xa0,0xff] + wrpr %g6,255,%tpc + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tnpc + ! V9: wrpr %g6, 255, %tnpc ! encoding: [0x83,0x91,0xa0,0xff] + wrpr %g6,255,%tnpc + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tstate + ! V9: wrpr %g6, 255, %tstate ! encoding: [0x85,0x91,0xa0,0xff] + wrpr %g6,255,%tstate + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tt + ! V9: wrpr %g6, 255, %tt ! encoding: [0x87,0x91,0xa0,0xff] + wrpr %g6,255,%tt + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tick + ! V9: wrpr %g6, 255, %tick ! encoding: [0x89,0x91,0xa0,0xff] + wrpr %g6,255,%tick + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tba + ! V9: wrpr %g6, 255, %tba ! encoding: [0x8b,0x91,0xa0,0xff] + wrpr %g6,255,%tba + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%pstate + ! V9: wrpr %g6, 255, %pstate ! encoding: [0x8d,0x91,0xa0,0xff] + wrpr %g6,255,%pstate + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%tl + ! V9: wrpr %g6, 255, %tl ! encoding: [0x8f,0x91,0xa0,0xff] + wrpr %g6,255,%tl + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%pil + ! V9: wrpr %g6, 255, %pil ! encoding: [0x91,0x91,0xa0,0xff] + wrpr %g6,255,%pil + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%cwp + ! V9: wrpr %g6, 255, %cwp ! encoding: [0x93,0x91,0xa0,0xff] + wrpr %g6,255,%cwp + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%cansave + ! V9: wrpr %g6, 255, %cansave ! encoding: [0x95,0x91,0xa0,0xff] + wrpr %g6,255,%cansave + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%canrestore + ! V9: wrpr %g6, 255, %canrestore ! encoding: [0x97,0x91,0xa0,0xff] + wrpr %g6,255,%canrestore + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%cleanwin + ! V9: wrpr %g6, 255, %cleanwin ! encoding: [0x99,0x91,0xa0,0xff] + wrpr %g6,255,%cleanwin + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%otherwin + ! V9: wrpr %g6, 255, %otherwin ! encoding: [0x9b,0x91,0xa0,0xff] + wrpr %g6,255,%otherwin + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: wrpr %g6,255,%wstate + ! V9: wrpr %g6, 255, %wstate ! encoding: [0x9d,0x91,0xa0,0xff] + wrpr %g6,255,%wstate + + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tpc,%i5 + ! V9: rdpr %tpc, %i5 ! encoding: [0xbb,0x50,0x00,0x00] + rdpr %tpc,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tnpc,%i5 + ! V9: rdpr %tnpc, %i5 ! encoding: [0xbb,0x50,0x40,0x00] + rdpr %tnpc,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tstate,%i5 + ! V9: rdpr %tstate, %i5 ! encoding: [0xbb,0x50,0x80,0x00] + rdpr %tstate,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tt,%i5 + ! V9: rdpr %tt, %i5 ! encoding: [0xbb,0x50,0xc0,0x00] + rdpr %tt,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tick,%i5 + ! V9: rdpr %tick, %i5 ! encoding: [0xbb,0x51,0x00,0x00] + rdpr %tick,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tba,%i5 + ! V9: rdpr %tba, %i5 ! encoding: [0xbb,0x51,0x40,0x00] + rdpr %tba,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %pstate,%i5 + ! V9: rdpr %pstate, %i5 ! encoding: [0xbb,0x51,0x80,0x00] + rdpr %pstate,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %tl,%i5 + ! V9: rdpr %tl, %i5 ! encoding: [0xbb,0x51,0xc0,0x00] + rdpr %tl,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %pil,%i5 + ! V9: rdpr %pil, %i5 ! encoding: [0xbb,0x52,0x00,0x00] + rdpr %pil,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %cwp,%i5 + ! V9: rdpr %cwp, %i5 ! encoding: [0xbb,0x52,0x40,0x00] + rdpr %cwp,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %cansave,%i5 + ! V9: rdpr %cansave, %i5 ! encoding: [0xbb,0x52,0x80,0x00] + rdpr %cansave,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %canrestore,%i5 + ! V9: rdpr %canrestore, %i5 ! encoding: [0xbb,0x52,0xc0,0x00] + rdpr %canrestore,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %cleanwin,%i5 + ! V9: rdpr %cleanwin, %i5 ! encoding: [0xbb,0x53,0x00,0x00] + rdpr %cleanwin,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %otherwin,%i5 + ! V9: rdpr %otherwin, %i5 ! encoding: [0xbb,0x53,0x40,0x00] + rdpr %otherwin,%i5 + ! V8: error: instruction requires a CPU feature not currently enabled + ! V8-NEXT: rdpr %wstate,%i5 + ! V9: rdpr %wstate, %i5 ! encoding: [0xbb,0x53,0x80,0x00] + rdpr %wstate,%i5