Index: llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ llvm/trunk/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -144,9 +144,9 @@ rk_FloatReg, rk_DoubleReg, rk_QuadReg, - rk_CCReg, - rk_ASRReg + rk_Special, }; + private: enum KindTy { k_Token, @@ -679,7 +679,15 @@ default: Op = SparcOperand::CreateReg(RegNo, RegKind, S, E); break; - + case Sparc::PSR: + Op = SparcOperand::CreateToken("%psr", S); + break; + case Sparc::WIM: + Op = SparcOperand::CreateToken("%wim", S); + break; + case Sparc::TBR: + Op = SparcOperand::CreateToken("%tbr", S); + break; case Sparc::ICC: if (name == "xcc") Op = SparcOperand::CreateToken("%xcc", S); @@ -768,7 +776,7 @@ if (name.equals("y")) { RegNo = Sparc::Y; - RegKind = SparcOperand::rk_ASRReg; + RegKind = SparcOperand::rk_Special; return true; } @@ -776,20 +784,38 @@ && !name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) { RegNo = ASRRegs[intVal]; - RegKind = SparcOperand::rk_ASRReg; + RegKind = SparcOperand::rk_Special; return true; } if (name.equals("icc")) { RegNo = Sparc::ICC; - RegKind = SparcOperand::rk_CCReg; + RegKind = SparcOperand::rk_Special; + return true; + } + + if (name.equals("psr")) { + RegNo = Sparc::PSR; + RegKind = SparcOperand::rk_Special; + return true; + } + + if (name.equals("wim")) { + RegNo = Sparc::WIM; + RegKind = SparcOperand::rk_Special; + return true; + } + + if (name.equals("tbr")) { + RegNo = Sparc::TBR; + RegKind = SparcOperand::rk_Special; return true; } if (name.equals("xcc")) { // FIXME:: check 64bit. RegNo = Sparc::ICC; - RegKind = SparcOperand::rk_CCReg; + RegKind = SparcOperand::rk_Special; return true; } @@ -799,7 +825,7 @@ && intVal < 4) { // FIXME: check 64bit and handle %fcc1 - %fcc3 RegNo = Sparc::FCC0 + intVal; - RegKind = SparcOperand::rk_CCReg; + RegKind = SparcOperand::rk_Special; return true; } Index: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td +++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td @@ -731,6 +731,24 @@ (outs IntRegs:$rd), (ins ASRRegs:$rs1), "rd $rs1, $rd", []>; +// PSR, WIM, and TBR don't exist on the SparcV9, only the V8. +let Predicates = [HasNoV9] in { + let rs2 = 0, rs1 = 0, Uses=[PSR] in + def RDPSR : F3_1<2, 0b101001, + (outs IntRegs:$rd), (ins), + "rd %psr, $rd", []>; + + let rs2 = 0, rs1 = 0, Uses=[WIM] in + def RDWIM : F3_1<2, 0b101010, + (outs IntRegs:$rd), (ins), + "rd %wim, $rd", []>; + + let rs2 = 0, rs1 = 0, Uses=[TBR] in + def RDTBR : F3_1<2, 0b101011, + (outs IntRegs:$rd), (ins), + "rd %tbr, $rd", []>; +} + // Section B.29 - Write State Register Instructions def WRASRrr : F3_1<2, 0b110000, (outs ASRRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), @@ -739,6 +757,36 @@ (outs ASRRegs:$rd), (ins IntRegs:$rs1, simm13Op:$simm13), "wr $rs1, $simm13, $rd", []>; +// PSR, WIM, and TBR don't exist on the SparcV9, only the V8. +let Predicates = [HasNoV9] in { + let Defs = [PSR], rd=0 in { + def WRPSRrr : F3_1<2, 0b110001, + (outs), (ins IntRegs:$rs1, IntRegs:$rs2), + "wr $rs1, $rs2, %psr", []>; + def WRPSRri : F3_2<2, 0b110001, + (outs), (ins IntRegs:$rs1, simm13Op:$simm13), + "wr $rs1, $simm13, %psr", []>; + } + + let Defs = [WIM], rd=0 in { + def WRWIMrr : F3_1<2, 0b110010, + (outs), (ins IntRegs:$rs1, IntRegs:$rs2), + "wr $rs1, $rs2, %wim", []>; + def WRWIMri : F3_2<2, 0b110010, + (outs), (ins IntRegs:$rs1, simm13Op:$simm13), + "wr $rs1, $simm13, %wim", []>; + } + + let Defs = [TBR], rd=0 in { + def WRTBRrr : F3_1<2, 0b110011, + (outs), (ins IntRegs:$rs1, IntRegs:$rs2), + "wr $rs1, $rs2, %tbr", []>; + def WRTBRri : F3_2<2, 0b110011, + (outs), (ins IntRegs:$rs1, simm13Op:$simm13), + "wr $rs1, $simm13, %tbr", []>; + } +} + // Convert Integer to Floating-point Instructions, p. 141 def FITOS : F3_3u<2, 0b110100, 0b011000100, (outs FPRegs:$rd), (ins FPRegs:$rs2), Index: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td +++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td @@ -89,6 +89,11 @@ def ASR30 : SparcCtrlReg<30, "ASR30">; def ASR31 : SparcCtrlReg<31, "ASR31">; +// Note that PSR, WIM, and TBR don't exist on the SparcV9, only the V8. +def PSR : SparcCtrlReg<0, "PSR">; +def WIM : SparcCtrlReg<0, "WIM">; +def TBR : SparcCtrlReg<0, "TBR">; + // Integer registers def G0 : Ri< 0, "G0">, DwarfRegNum<[0]>; def G1 : Ri< 1, "G1">, DwarfRegNum<[1]>; Index: llvm/trunk/test/MC/Disassembler/Sparc/sparc-special-registers.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Sparc/sparc-special-registers.txt +++ llvm/trunk/test/MC/Disassembler/Sparc/sparc-special-registers.txt @@ -0,0 +1,34 @@ +# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s + +# CHECK: wr %g1, -2, %y +0x81 0x80 0x7f 0xfe + +# CHECK: rd %y, %i0 +0xb1 0x40 0x00 0x00 + +# CHECK: rd %asr1, %i0 +0xb1 0x40 0x40 0x00 + +# CHECK: wr %i0, 5, %y +0x81 0x86 0x20 0x05 + +# CHECK: wr %i0, %i1, %asr15 +0x9f 0x86 0x00 0x19 + +# CHECK: rd %psr, %i0 +0xb1 0x48 0x00 0x00 + +# CHECK: rd %wim, %i0 +0xb1 0x50 0x00 0x00 + +# CHECK: rd %tbr, %i0 +0xb1 0x58 0x00 0x00 + +# CHECK: wr %i0, 5, %psr +0x81 0x8e 0x20 0x05 + +# CHECK: wr %i0, 5, %wim +0x81 0x96 0x20 0x05 + +# CHECK: wr %i0, 5, %tbr +0x81 0x9e 0x20 0x05 Index: llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt +++ llvm/trunk/test/MC/Disassembler/Sparc/sparc.txt @@ -183,9 +183,6 @@ # CHECK: cmp %g1, -2 0x80 0xa0 0x7f 0xfe -# CHECK: wr %g1, -2, %y -0x81 0x80 0x7f 0xfe - # CHECK: unimp 12 0x00 0x00 0x00 0x0c @@ -201,17 +198,5 @@ # CHECK: rett %i7+8 0x81 0xcf 0xe0 0x08 -# CHECK: rd %y, %i0 -0xb1 0x40 0x00 0x00 - -# CHECK: rd %asr1, %i0 -0xb1 0x40 0x40 0x00 - -# CHECK: wr %i0, 5, %y -0x81 0x86 0x20 0x05 - -# CHECK: wr %i0, %i1, %asr15 -0x9f 0x86 0x00 0x19 - # CHECK: stbar 0x81 0x43 0xc0 0x00 Index: llvm/trunk/test/MC/Sparc/sparc-special-registers.s =================================================================== --- llvm/trunk/test/MC/Sparc/sparc-special-registers.s +++ llvm/trunk/test/MC/Sparc/sparc-special-registers.s @@ -15,3 +15,21 @@ ! CHECK: rd %asr15, %g0 ! encoding: [0x81,0x43,0xc0,0x00] rd %asr15, %g0 + + ! CHECK: rd %psr, %i0 ! encoding: [0xb1,0x48,0x00,0x00] + rd %psr, %i0 + + ! CHECK: rd %wim, %i0 ! encoding: [0xb1,0x50,0x00,0x00] + rd %wim, %i0 + + ! CHECK: rd %tbr, %i0 ! encoding: [0xb1,0x58,0x00,0x00] + rd %tbr, %i0 + + ! CHECK: wr %i0, 5, %psr ! encoding: [0x81,0x8e,0x20,0x05] + wr %i0, 5, %psr + + ! CHECK: wr %i0, 5, %wim ! encoding: [0x81,0x96,0x20,0x05] + wr %i0, 5, %wim + + ! CHECK: wr %i0, 5, %tbr ! encoding: [0x81,0x9e,0x20,0x05] + wr %i0, 5, %tbr