[llvm] 3a7431e - [SPARC][IAS] Add definitions for v9 State Registers

Brad Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 20:44:17 PDT 2023


Author: Koakuma
Date: 2023-09-01T23:40:45-04:00
New Revision: 3a7431eb2dd1e4930143284daefd9e8661d1e2d4

URL: https://github.com/llvm/llvm-project/commit/3a7431eb2dd1e4930143284daefd9e8661d1e2d4
DIFF: https://github.com/llvm/llvm-project/commit/3a7431eb2dd1e4930143284daefd9e8661d1e2d4.diff

LOG: [SPARC][IAS] Add definitions for v9 State Registers

This adds definitions for SPARC v9 State Registers (privileged/nonprivileged,
see v9 manual ch. 5).

Reviewed By: barannikov88

Differential Revision: https://reviews.llvm.org/D157231

Added: 
    

Modified: 
    llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
    llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
    llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
    llvm/lib/Target/Sparc/SparcInstrAliases.td
    llvm/lib/Target/Sparc/SparcInstrInfo.td
    llvm/lib/Target/Sparc/SparcRegisterInfo.td
    llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
    llvm/test/MC/Sparc/sparc-special-registers.s
    llvm/test/MC/Sparc/sparcv9-instructions.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index bfb62cdae8d449..4d64c394f2c647 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -1220,9 +1220,6 @@ SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
       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);
@@ -1319,9 +1316,8 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, MCRegister &RegNo,
       return true;
     }
 
-    // %fprs is an alias of %asr6.
     if (name.equals("fprs")) {
-      RegNo = ASRRegs[6];
+      RegNo = Sparc::ASR6;
       RegKind = SparcOperand::rk_Special;
       return true;
     }
@@ -1525,7 +1521,27 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, MCRegister &RegNo,
       return true;
     }
     if (name.equals("pc")) {
-      RegNo = Sparc::PC;
+      RegNo = Sparc::ASR5;
+      RegKind = SparcOperand::rk_Special;
+      return true;
+    }
+    if (name.equals("asi")) {
+      RegNo = Sparc::ASR3;
+      RegKind = SparcOperand::rk_Special;
+      return true;
+    }
+    if (name.equals("ccr")) {
+      RegNo = Sparc::ASR2;
+      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;
     }

diff  --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index b7581c1979d829..ace59ee4d743c9 100644
--- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -101,20 +101,16 @@ static const unsigned FCCRegDecoderTable[] = {
   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::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};
 
 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,

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
index 51a6732d05c6d2..929c755e4821f6 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
@@ -42,6 +42,11 @@ void SparcInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
   OS << '%' << StringRef(getRegisterName(Reg)).lower();
 }
 
+void SparcInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg,
+                                    unsigned AltIdx) const {
+  OS << '%' << StringRef(getRegisterName(Reg, AltIdx)).lower();
+}
+
 void SparcInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                                  StringRef Annot, const MCSubtargetInfo &STI,
                                  raw_ostream &O) {
@@ -111,7 +116,11 @@ void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
   const MCOperand &MO = MI->getOperand (opNum);
 
   if (MO.isReg()) {
-    printRegName(O, MO.getReg());
+    unsigned Reg = MO.getReg();
+    if (isV9(STI))
+      printRegName(O, Reg, SP::RegNamesStateReg);
+    else
+      printRegName(O, Reg);
     return ;
   }
 

diff  --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
index a9f4a652e0c0da..cccdeadd816c7b 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_LIB_TARGET_SPARC_MCTARGETDESC_SPARCINSTPRINTER_H
 #define LLVM_LIB_TARGET_SPARC_MCTARGETDESC_SPARCINSTPRINTER_H
 
+#include "SparcMCTargetDesc.h"
 #include "llvm/MC/MCInstPrinter.h"
 
 namespace llvm {
@@ -24,6 +25,7 @@ class SparcInstPrinter : public MCInstPrinter {
       : MCInstPrinter(MAI, MII, MRI) {}
 
   void printRegName(raw_ostream &OS, MCRegister Reg) const override;
+  void printRegName(raw_ostream &OS, MCRegister Reg, unsigned AltIdx) const;
   void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
                  const MCSubtargetInfo &STI, raw_ostream &O) override;
   bool printSparcAliasInstr(const MCInst *MI, const MCSubtargetInfo &STI,
@@ -39,7 +41,8 @@ class SparcInstPrinter : public MCInstPrinter {
   void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
                                unsigned OpIdx, unsigned PrintMethodIdx,
                                const MCSubtargetInfo &STI, raw_ostream &O);
-  static const char *getRegisterName(MCRegister Reg);
+  static const char *getRegisterName(MCRegister Reg,
+                                     unsigned AltIdx = SP::NoRegAltName);
 
   void printOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
                     raw_ostream &OS);

diff  --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index b2a22eb0bd45b9..26ea043149d626 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -524,7 +524,6 @@ def : InstAlias<"mov $asr, $rd", (RDASR IntRegs:$rd, ASRRegs:$asr), 0>;
 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>;

diff  --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 8a02c92129295b..61723550969138 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -1123,14 +1123,6 @@ let Predicates = [HasNoV9] in {
 		     "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),

diff  --git a/llvm/lib/Target/Sparc/SparcRegisterInfo.td b/llvm/lib/Target/Sparc/SparcRegisterInfo.td
index 947bbaed8c70cd..3c4e96c1d1b85a 100644
--- a/llvm/lib/Target/Sparc/SparcRegisterInfo.td
+++ b/llvm/lib/Target/Sparc/SparcRegisterInfo.td
@@ -15,7 +15,8 @@ class SparcReg<bits<16> Enc, string n> : Register<n> {
   let Namespace = "SP";
 }
 
-class SparcCtrlReg<bits<16> Enc, string n>: Register<n> {
+class SparcCtrlReg<bits<16> Enc, string n,
+                   list<string> altNames = []>: Register<n, altNames> {
   let HWEncoding = Enc;
   let Namespace = "SP";
 }
@@ -27,6 +28,11 @@ def sub_even64 : SubRegIndex<64>;
 def sub_odd64  : SubRegIndex<64, 64>;
 }
 
+let Namespace = "SP",
+    FallbackRegAltNameIndex = NoRegAltName in {
+  def RegNamesStateReg : RegAltNameIndex;
+}
+
 // Registers are identified with 5-bit ID numbers.
 // Ri - 32-bit integer registers
 class Ri<bits<16> Enc, string n> : SparcReg<Enc, n>;
@@ -71,11 +77,18 @@ def CPQ : SparcCtrlReg<0, "CPQ">; // Co-processor queue.
 def Y : SparcCtrlReg<0, "Y">, DwarfRegNum<[64]>;
 // Ancillary state registers (implementation defined)
 def ASR1 : SparcCtrlReg<1, "ASR1">;
-def ASR2 : SparcCtrlReg<2, "ASR2">;
-def ASR3 : SparcCtrlReg<3, "ASR3">;
-def ASR4 : SparcCtrlReg<4, "ASR4">;
-def ASR5 : SparcCtrlReg<5, "ASR5">;
-def ASR6 : SparcCtrlReg<6, "ASR6">;
+let RegAltNameIndices = [RegNamesStateReg] in {
+// FIXME: Currently this results in the assembler accepting
+// the alternate names (%ccr, %asi, etc.) when targeting V8.
+// Make sure that the alternate names are available for V9 only:
+// %asr2-asr6      : valid on both V8 and V9.
+// %ccr, %asi, etc.: valid on V9, returns "no such register" error on V8.
+def ASR2 : SparcCtrlReg<2, "ASR2", ["CCR"]>;
+def ASR3 : SparcCtrlReg<3, "ASR3", ["ASI"]>;
+def ASR4 : SparcCtrlReg<4, "ASR4", ["TICK"]>;
+def ASR5 : SparcCtrlReg<5, "ASR5", ["PC"]>;
+def ASR6 : SparcCtrlReg<6, "ASR6", ["FPRS"]>;
+}
 def ASR7 : SparcCtrlReg<7, "ASR7">;
 def ASR8 : SparcCtrlReg<8, "ASR8">;
 def ASR9 : SparcCtrlReg<9, "ASR9">;
@@ -106,24 +119,25 @@ def ASR31 : SparcCtrlReg<31, "ASR31">;
 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">;
+
+// 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 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">;
+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]> {
@@ -361,8 +375,11 @@ def FCCRegs : RegisterClass<"SP", [i1], 1, (sequence "FCC%u", 0, 3)>;
 
 let isAllocatable = 0 in {
   // Ancillary state registers
+  // FIXME: TICK is special-cased here as it can be accessed
+  // from the ASR (as ASR4) or the privileged register set.
+  // For now this is required for the parser to work.
   def ASRRegs : RegisterClass<"SP", [i32], 32,
-                              (add Y, (sequence "ASR%u", 1, 31))>;
+                              (add Y, TICK, (sequence "ASR%u", 1, 31))>;
 
   // This register class should not be used to hold i64 values.
   def CoprocRegs : RegisterClass<"SP", [i32], 32,
@@ -379,5 +396,4 @@ let isAllocatable = 0 in {
 // 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)>;

diff  --git a/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
index 1d5ababfb25f6e..a5d146b03e6486 100644
--- a/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
+++ b/llvm/test/MC/Disassembler/Sparc/sparc-special-registers.txt
@@ -1,4 +1,5 @@
-# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux   | FileCheck %s --check-prefixes=CHECK,V8
+# RUN: llvm-mc --disassemble %s -triple=sparcv9-unknown-linux | FileCheck %s --check-prefixes=CHECK,V9
 
 # CHECK: wr %g1, -2, %y
 0x81 0x80 0x7f 0xfe
@@ -38,3 +39,41 @@
 
 # CHECK: std %fq, [%i5+%l1]
 0xc1 0x37 0x40 0x11
+
+
+## Those instructions are processed 
diff erently on V8 and V9.
+
+# V8: rd %asr2, %i0
+# V9: rd %ccr, %i0
+0xb1 0x40 0x80 0x00
+# V8: wr %i0, 7, %asr2
+# V9: wr %i0, 7, %ccr
+0x85 0x86 0x20 0x07
+
+# V8: rd %asr3, %i0
+# V9: rd %asi, %i0
+0xb1 0x40 0xc0 0x00
+# V8: wr %i0, 7, %asr3
+# V9: wr %i0, 7, %asi
+0x87 0x86 0x20 0x07
+
+# V8: rd %asr4, %i0
+# V9: rd %tick, %i0
+0xb1 0x41 0x00 0x00
+# V8: wr %i0, 7, %asr4
+# V9: wr %i0, 7, %tick
+0x89 0x86 0x20 0x07
+
+# V8: rd %asr5, %i0
+# V9: rd %pc, %i0
+0xb1 0x41 0x40 0x00
+# V8: wr %i0, 7, %asr5
+# V9: wr %i0, 7, %pc
+0x8b 0x86 0x20 0x07
+
+# V8: rd %asr6, %i0
+# V9: rd %fprs, %i0
+0xb1 0x41 0x80 0x00
+# V8: wr %i0, 7, %asr6
+# V9: wr %i0, 7, %fprs
+0x8d 0x86 0x20 0x07

diff  --git a/llvm/test/MC/Sparc/sparc-special-registers.s b/llvm/test/MC/Sparc/sparc-special-registers.s
index 7667abea0144f3..287a4e4069b347 100644
--- a/llvm/test/MC/Sparc/sparc-special-registers.s
+++ b/llvm/test/MC/Sparc/sparc-special-registers.s
@@ -1,5 +1,5 @@
-! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
-! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
+! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s --check-prefixes=CHECK,V8
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s --check-prefixes=CHECK,V9
 
         ! CHECK: rd %y, %i0            ! encoding: [0xb1,0x40,0x00,0x00]
         rd %y, %i0
@@ -34,12 +34,6 @@
         ! CHECK: wr %i0, 5, %tbr          ! encoding: [0x81,0x9e,0x20,0x05]
         wr %i0, 5, %tbr
 
-        ! CHECK: rd %asr6, %i0         ! encoding: [0xb1,0x41,0x80,0x00]
-        rd %fprs, %i0
-
-        ! CHECK: wr %i0, 7, %asr6      ! encoding: [0x8d,0x86,0x20,0x07]
-        wr %i0, 7, %fprs
-
         ! CHECK: ld [%g2+20], %fsr     ! encoding: [0xc1,0x08,0xa0,0x14]
         ld [%g2 + 20],%fsr
 
@@ -54,3 +48,69 @@
 
         ! CHECK: std %fq, [%g6+%i2]    ! encoding: [0xc1,0x31,0x80,0x1a]
         std %fq, [%g6 + %i2]
+
+!! Those instructions are processed 
diff erently on V8 and V9.
+
+! V8: rd %asr2, %i0         ! encoding: [0xb1,0x40,0x80,0x00]
+! V9: rd %ccr, %i0          ! encoding: [0xb1,0x40,0x80,0x00]
+rd %asr2, %i0
+! V8: wr %i0, 7, %asr2      ! encoding: [0x85,0x86,0x20,0x07]
+! V9: wr %i0, 7, %ccr       ! encoding: [0x85,0x86,0x20,0x07]
+wr %i0, 7, %asr2
+
+! V8: rd %asr3, %i0         ! encoding: [0xb1,0x40,0xc0,0x00]
+! V9: rd %asi, %i0          ! encoding: [0xb1,0x40,0xc0,0x00]
+rd %asr3, %i0
+! V8: wr %i0, 7, %asr3      ! encoding: [0x87,0x86,0x20,0x07]
+! V9: wr %i0, 7, %asi       ! encoding: [0x87,0x86,0x20,0x07]
+wr %i0, 7, %asr3
+
+! V8: rd %asr4, %i0         ! encoding: [0xb1,0x41,0x00,0x00]
+! V9: rd %tick, %i0         ! encoding: [0xb1,0x41,0x00,0x00]
+rd %asr4, %i0
+! V8: wr %i0, 7, %asr4      ! encoding: [0x89,0x86,0x20,0x07]
+! V9: wr %i0, 7, %tick      ! encoding: [0x89,0x86,0x20,0x07]
+wr %i0, 7, %asr4
+
+! V8: rd %asr5, %i0         ! encoding: [0xb1,0x41,0x40,0x00]
+! V9: rd %pc, %i0           ! encoding: [0xb1,0x41,0x40,0x00]
+rd %asr5, %i0
+! V8: wr %i0, 7, %asr5      ! encoding: [0x8b,0x86,0x20,0x07]
+! V9: wr %i0, 7, %pc        ! encoding: [0x8b,0x86,0x20,0x07]
+wr %i0, 7, %asr5
+
+! V8: rd %asr6, %i0         ! encoding: [0xb1,0x41,0x80,0x00]
+! V9: rd %fprs, %i0         ! encoding: [0xb1,0x41,0x80,0x00]
+rd %asr6, %i0
+! V8: wr %i0, 7, %asr6      ! encoding: [0x8d,0x86,0x20,0x07]
+! V9: wr %i0, 7, %fprs      ! encoding: [0x8d,0x86,0x20,0x07]
+wr %i0, 7, %asr6
+
+!! Alternate names for %asr2-%asr6 are only for V9.
+!! TODO: make sure that using alternate names returns
+!! an error on V8 (currently it doesn't, see SparcRegisterInfo.td).
+
+! V9: rd %ccr, %i0          ! encoding: [0xb1,0x40,0x80,0x00]
+rd %ccr, %i0
+! V9: wr %i0, 7, %ccr       ! encoding: [0x85,0x86,0x20,0x07]
+wr %i0, 7, %ccr
+
+! V9: rd %asi, %i0          ! encoding: [0xb1,0x40,0xc0,0x00]
+rd %asi, %i0
+! V9: wr %i0, 7, %asi       ! encoding: [0x87,0x86,0x20,0x07]
+wr %i0, 7, %asi
+
+! V9: rd %tick, %i0         ! encoding: [0xb1,0x41,0x00,0x00]
+rd %tick, %i0
+! V9: wr %i0, 7, %tick      ! encoding: [0x89,0x86,0x20,0x07]
+wr %i0, 7, %tick
+
+! V9: rd %pc, %i0           ! encoding: [0xb1,0x41,0x40,0x00]
+rd %pc, %i0
+! V9: wr %i0, 7, %pc        ! encoding: [0x8b,0x86,0x20,0x07]
+wr %i0, 7, %pc
+
+! V9: rd %fprs, %i0         ! encoding: [0xb1,0x41,0x80,0x00]
+rd %fprs, %i0
+! V9: wr %i0, 7, %fprs      ! encoding: [0x8d,0x86,0x20,0x07]
+wr %i0, 7, %fprs

diff  --git a/llvm/test/MC/Sparc/sparcv9-instructions.s b/llvm/test/MC/Sparc/sparcv9-instructions.s
index a029219b0781ac..23e9f0798576f4 100644
--- a/llvm/test/MC/Sparc/sparcv9-instructions.s
+++ b/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]


        


More information about the llvm-commits mailing list