Skip to content

[SPARC][IAS] Properly set implied feature sets for ISA levels/extensions #143232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

koachan
Copy link
Contributor

@koachan koachan commented Jun 7, 2025

Some SPARC ISA levels and/or extensions are defined in a way such that the availability of it implies the availability of other, more fundamental ISA features (for example, targeting 64-bit environment implies that V9 instructions are available).
Properly set those in the TableGen definitions.

Fixes #142388.

@koachan koachan requested review from brad0, rorth and s-barannikov June 7, 2025 03:57
@llvmbot llvmbot added backend:Sparc mc Machine (object) code labels Jun 7, 2025
@koachan
Copy link
Contributor Author

koachan commented Jun 7, 2025

Pinging @Rot127 too, does this help?

@llvmbot
Copy link
Member

llvmbot commented Jun 7, 2025

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-sparc

Author: Koakuma (koachan)

Changes

This prevents usage of V9 instructions in assembly code intended for 32-bit V8.

Fixes #142388.


Full diff: https://github.com/llvm/llvm-project/pull/143232.diff

6 Files Affected:

  • (modified) llvm/lib/Target/Sparc/SparcInstrInfo.td (+2-1)
  • (modified) llvm/test/CodeGen/SPARC/inlineasm-v9.ll (+9)
  • (modified) llvm/test/CodeGen/SPARC/inlineasm.ll (-9)
  • (added) llvm/test/MC/Sparc/Relocations/relocation-specifier-v9.s (+211)
  • (modified) llvm/test/MC/Sparc/Relocations/relocation-specifier.s (-51)
  • (modified) llvm/test/MC/Sparc/sparcv9-instructions.s (+42)
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 074a04a5dd747..1be017be1c64f 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -24,7 +24,8 @@ include "SparcInstrFormats.td"
 def Is32Bit : Predicate<"!Subtarget->is64Bit()">;
 
 // True when generating 64-bit code. This also implies HasV9.
-def Is64Bit : Predicate<"Subtarget->is64Bit()">;
+def Is64Bit : Predicate<"Subtarget->is64Bit()">,
+              AssemblerPredicate<(all_of FeatureV9)>;
 
 def UseSoftMulDiv : Predicate<"Subtarget->useSoftMulDiv()">,
               AssemblerPredicate<(all_of FeatureSoftMulDiv)>;
diff --git a/llvm/test/CodeGen/SPARC/inlineasm-v9.ll b/llvm/test/CodeGen/SPARC/inlineasm-v9.ll
index 47126d5d64daa..289bb33fb864b 100644
--- a/llvm/test/CodeGen/SPARC/inlineasm-v9.ll
+++ b/llvm/test/CodeGen/SPARC/inlineasm-v9.ll
@@ -58,3 +58,12 @@ Entry:
   tail call void asm sideeffect "", "{o0}"(i64 %val)
   ret void
 }
+
+; CHECK-LABEL: test_twinword:
+; CHECK: rd  %pc, %i1
+; CHECK: srlx %i1, 32, %i0
+
+define i64 @test_twinword(){
+  %1 = tail call i64 asm sideeffect "rd %asr5, ${0:L} \0A\09 srlx ${0:L}, 32, ${0:H}", "={i0}"()
+  ret i64 %1
+}
diff --git a/llvm/test/CodeGen/SPARC/inlineasm.ll b/llvm/test/CodeGen/SPARC/inlineasm.ll
index 3ca2168efb71b..07411385bdf37 100644
--- a/llvm/test/CodeGen/SPARC/inlineasm.ll
+++ b/llvm/test/CodeGen/SPARC/inlineasm.ll
@@ -144,15 +144,6 @@ entry:
   ret void
 }
 
-; CHECK-LABEL: test_twinword:
-; CHECK: rd  %asr5, %i1
-; CHECK: srlx %i1, 32, %i0
-
-define i64 @test_twinword(){
-  %1 = tail call i64 asm sideeffect "rd %asr5, ${0:L} \0A\09 srlx ${0:L}, 32, ${0:H}", "={i0}"()
-  ret i64 %1
-}
-
 ; CHECK-LABEL: test_symbol:
 ; CHECK: ba,a brtarget
 define void @test_symbol() {
diff --git a/llvm/test/MC/Sparc/Relocations/relocation-specifier-v9.s b/llvm/test/MC/Sparc/Relocations/relocation-specifier-v9.s
new file mode 100644
index 0000000000000..566f57731565e
--- /dev/null
+++ b/llvm/test/MC/Sparc/Relocations/relocation-specifier-v9.s
@@ -0,0 +1,211 @@
+# RUN: llvm-mc %s -triple=sparcv9 | FileCheck %s --check-prefix=ASM
+
+# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj -o %t
+# RUN: llvm-objdump -dr %t | FileCheck %s --check-prefix=OBJDUMP
+# RUN: llvm-readelf -s - < %t | FileCheck %s --check-prefix=READELF --implicit-check-not=TLS
+
+# READELF: TLS     LOCAL  DEFAULT [[#]] s_tle_hix22
+# READELF: TLS     LOCAL  DEFAULT [[#]] s_tldo_hix22
+# READELF: TLS     GLOBAL DEFAULT   UND s_tle_lox10
+# READELF: TLS     GLOBAL DEFAULT   UND s_tie_hi22
+# READELF: TLS     GLOBAL DEFAULT   UND s_tie_lo10
+# READELF: TLS     GLOBAL DEFAULT   UND s_tie_ld
+# READELF: TLS     GLOBAL DEFAULT   UND s_tie_ldx
+# READELF: TLS     GLOBAL DEFAULT   UND s_tie_add
+# READELF: TLS     GLOBAL DEFAULT   UND s_tldm_hi22
+# READELF: TLS     GLOBAL DEFAULT   UND s_tldm_lo10
+# READELF: TLS     GLOBAL DEFAULT   UND s_tldm_add
+# READELF: TLS     GLOBAL DEFAULT   UND s_tldo_lox10
+# READELF: TLS     GLOBAL DEFAULT   UND s_tldo_add
+# READELF: TLS     GLOBAL DEFAULT   UND s_tgd_hi22
+# READELF: TLS     GLOBAL DEFAULT   UND s_tgd_lo10
+# READELF: TLS     GLOBAL DEFAULT   UND s_tgd_add
+
+main:
+
+# ASM:      or %g1, %lo(sym), %g3
+# ASM-NEXT: sethi %hi(sym), %l0
+# ASM-NEXT: sethi %h44(sym), %l0
+# ASM-NEXT: or %g1, %m44(sym), %g3
+# ASM-NEXT: or %g1, %l44(sym), %g3
+# OBJDUMP:     0000000:  R_SPARC_LO10	sym
+# OBJDUMP:     0000004:  R_SPARC_HI22	sym
+# OBJDUMP:     0000008:  R_SPARC_H44	sym
+# OBJDUMP:     000000c:  R_SPARC_M44	sym
+# OBJDUMP:     0000010:  R_SPARC_L44	sym
+or %g1, %lo(sym), %g3
+sethi %hi(sym), %l0
+sethi %h44(sym), %l0
+or %g1, %m44(sym), %g3
+or %g1, %l44(sym), %g3
+
+## FIXME: Emit %pc22/%pc10
+# ASM:      sethi %hi(sym), %o1
+# ASM-NEXT: or %o1, %lo(sym), %o1
+# OBJDUMP:      sethi 0x0, %o1
+# OBJDUMP-NEXT:   R_SPARC_PC22 sym
+# OBJDUMP-NEXT: or %o1, 0x0, %o1
+# OBJDUMP-NEXT:   R_SPARC_PC10 sym
+# OBJDUMP-NEXT: sethi 0x3fffff, %o1
+# OBJDUMP-NEXT: or %o1, 0x3e0, %o1
+sethi %pc22(sym), %o1
+or %o1, %pc10(sym), %o1
+sethi %pc22(main), %o1
+or %o1, %pc10(main), %o1
+
+# ASM:      sethi %hh(sym), %l0
+# ASM-NEXT: sethi %hh(sym), %l0
+# ASM-NEXT: or %g1, %hm(sym), %g3
+# ASM-NEXT: or %g1, %hm(sym), %g3
+# ASM-NEXT: sethi %lm(sym), %l0
+# OBJDUMP:      R_SPARC_HH22	sym
+# OBJDUMP:      R_SPARC_HH22	sym
+# OBJDUMP:      R_SPARC_HM10	sym
+# OBJDUMP:      R_SPARC_HM10	sym
+# OBJDUMP:      R_SPARC_LM22	sym
+sethi %hh(sym), %l0
+sethi %uhi(sym), %l0
+or %g1, %hm(sym), %g3
+or %g1, %ulo(sym), %g3
+sethi %lm(sym), %l0
+
+# ASM:      sethi %hix(sym), %g1
+# ASM-NEXT: xor %g1, %lox(sym), %g1
+# ASM-NEXT: sethi %gdop_hix22(sym), %l1
+# ASM-NEXT: or %l1, %gdop_lox10(sym), %l1
+# ASM-NEXT: ldx [%l7+%l1], %l2, %gdop(sym)
+# OBJDUMP:      sethi 0x3fffff, %g0
+# OBJDUMP-NEXT: xor %g0, -0x400, %g0
+# OBJDUMP-NEXT: sethi 0x0, %g1
+# OBJDUMP-NEXT:   R_SPARC_HIX22 sym
+# OBJDUMP-NEXT: xor %g1, 0x0, %g1
+# OBJDUMP-NEXT:   R_SPARC_LOX10 sym
+# OBJDUMP-NEXT: sethi 0x0, %l1
+# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP_HIX22 sym
+# OBJDUMP-NEXT: or %l1, 0x0, %l1
+# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP_LOX10 sym
+# OBJDUMP-NEXT: ldx [%l7+%l1], %l2
+# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP sym
+sethi %hix(zero), %g0
+xor %g0, %lox(zero), %g0
+sethi %hix(sym), %g1
+xor %g1, %lox(sym), %g1
+sethi %gdop_hix22(sym), %l1
+or %l1, %gdop_lox10(sym), %l1
+ldx [%l7 + %l1], %l2, %gdop(sym)
+
+.set abs, 0xfedcba98
+.set abs48, 0xfedcba987654
+zero = 0
+
+## FIXME: Don't emit GOT relocations when -position-independent is specified.
+# NOPIC:      sethi 0x3fb72e, %o0
+# NOPIC-NEXT: xor %o0, 0x298, %o0
+# NOPIC-NEXT: sethi 0x3b72ea, %o1
+# NOPIC-NEXT: xor %o0, 0x188, %o1
+sethi %hi(abs), %o0
+xor %o0, %lo(abs), %o0
+sethi %hi(-0x12345678), %o1
+xor %o0, %lo(-0x12345678), %o1
+
+# OBJDUMP:      ld [%o0+0x7], %o0
+ld [%o0 + seven], %o0
+seven = 7
+
+# OBJDUMP:      sethi 0x3b72ea, %o0
+# OBJDUMP-NEXT: or %o0, 0x187, %o0
+# OBJDUMP-NEXT: ld [%o0+0x654], %o0
+sethi %h44(abs48), %o0
+or %o0, %m44(abs48), %o0
+ld [%o0 + %l44(abs48)], %o0
+
+# OBJDUMP-NEXT: sethi 0x0, %o0
+# OBJDUMP-NEXT: sethi 0x3fb72e, %o0
+# OBJDUMP-NEXT: or %o0, 0x0, %o0
+sethi %hh(abs), %o0
+sethi %lm(abs), %o0
+or %o0, %hm(abs), %o0
+
+# OBJDUMP-NEXT: sethi 0x48d1, %o0
+# OBJDUMP-NEXT: xor %o0, -0x168, %o0
+sethi %hix(abs), %o0
+xor %o0, %lox(abs), %o0
+
+# OBJDUMP-LABEL: <.tls>:
+.section .tls,"ax"
+## Local Executable model:
+# ASM:      sethi %tle_hix22(s_tle_hix22), %i0
+# ASM-NEXT: xor %i0, %tle_lox10(s_tle_lox10), %i0
+
+# OBJDUMP:      31 00 00 00   sethi 0x0, %i0
+# OBJDUMP-NEXT:  00000000:  R_SPARC_TLS_LE_HIX22 s_tle_hix22
+# OBJDUMP-NEXT: b0 1e 20 00   xor %i0, 0x0, %i0
+# OBJDUMP-NEXT:  00000004:  R_SPARC_TLS_LE_LOX10 s_tle_lox10
+        sethi %tle_hix22(s_tle_hix22), %i0
+        xor %i0, %tle_lox10(s_tle_lox10), %i0
+
+## Initial Executable model
+# ASM:      sethi %tie_hi22(s_tie_hi22), %i1
+# ASM-NEXT: add %i1, %tie_lo10(s_tie_lo10), %i1
+# ASM-NEXT: ld [%i0+%i1], %i0, %tie_ld(s_tie_ld)
+# ASM-NEXT: ldx [%i0+%i1], %i0, %tie_ldx(s_tie_ldx)
+# ASM-NEXT: add %g7, %i0, %o0, %tie_add(s_tie_add)
+
+# OBJDUMP:      R_SPARC_TLS_IE_HI22	s_tie_hi22
+# OBJDUMP:      R_SPARC_TLS_IE_LO10	s_tie_lo10
+# OBJDUMP:      R_SPARC_TLS_IE_LD	s_tie_ld
+# OBJDUMP:      R_SPARC_TLS_IE_LDX	s_tie_ldx
+# OBJDUMP:      R_SPARC_TLS_IE_ADD	s_tie_add
+	sethi %tie_hi22(s_tie_hi22), %i1
+        add %i1, %tie_lo10(s_tie_lo10), %i1
+        ld [%i0+%i1], %i0, %tie_ld(s_tie_ld)
+        ldx [%i0+%i1], %i0, %tie_ldx(s_tie_ldx)
+        add %g7, %i0, %o0, %tie_add(s_tie_add)
+
+## Local Dynamic model
+# ASM:      sethi %tldo_hix22(s_tldo_hix22), %i1
+# ASM-NEXT: sethi %tldm_hi22(s_tldm_hi22), %i2
+# ASM-NEXT: add %i2, %tldm_lo10(s_tldm_lo10), %i2
+# ASM-NEXT: add %i0, %i2, %o0, %tldm_add(s_tldm_add)
+# ASM-NEXT: xor %i1, %tldo_lox10(s_tldo_lox10), %i0
+# ASM-NEXT: call __tls_get_addr, %tldm_call(s_tldm_call)
+# ASM-NEXT: nop
+# ASM-NEXT: add %o0, %i0, %o0, %tldo_add(s_tldo_add)
+
+# OBJDUMP:      R_SPARC_TLS_LDO_HIX22	s_tldo_hix22
+# OBJDUMP:      R_SPARC_TLS_LDM_HI22	s_tldm_hi22
+# OBJDUMP:      R_SPARC_TLS_LDM_LO10	s_tldm_lo10
+# OBJDUMP:      R_SPARC_TLS_LDM_ADD	s_tldm_add
+# OBJDUMP:      R_SPARC_TLS_LDO_LOX10	s_tldo_lox10
+# OBJDUMP:      R_SPARC_TLS_LDM_CALL	s_tldm_call
+# OBJDUMP:      R_SPARC_TLS_LDO_ADD	s_tldo_add
+        sethi %tldo_hix22(s_tldo_hix22), %i1
+        sethi %tldm_hi22(s_tldm_hi22), %i2
+        add %i2, %tldm_lo10(s_tldm_lo10), %i2
+	add %i0, %i2, %o0, %tldm_add(s_tldm_add)
+        xor %i1, %tldo_lox10(s_tldo_lox10), %i0
+        call __tls_get_addr, %tldm_call(s_tldm_call)
+        nop
+        add %o0, %i0, %o0, %tldo_add(s_tldo_add)
+
+## General Dynamic model
+# ASM:      sethi %tgd_hi22(s_tgd_hi22), %i1
+# ASM-NEXT: add %i1, %tgd_lo10(s_tgd_lo10), %i1
+# ASM-NEXT: add %i0, %i1, %o0, %tgd_add(s_tgd_add)
+# ASM-NEXT: call __tls_get_addr, %tgd_call(s_tgd_call)
+
+# OBJDUMP:      R_SPARC_TLS_GD_HI22	s_tgd_hi22
+# OBJDUMP:      R_SPARC_TLS_GD_LO10	s_tgd_lo10
+# OBJDUMP:      R_SPARC_TLS_GD_ADD	s_tgd_add
+# OBJDUMP:      R_SPARC_TLS_GD_CALL	s_tgd_call
+        sethi %tgd_hi22(s_tgd_hi22), %i1
+        add %i1, %tgd_lo10(s_tgd_lo10), %i1
+        add %i0, %i1, %o0, %tgd_add(s_tgd_add)
+        call __tls_get_addr, %tgd_call(s_tgd_call)
+
+        .type  Local,@object
+        .section      .tbss,#alloc,#write,#tls
+s_tle_hix22:
+s_tldo_hix22:
+        .word  0
+        .size  Local, 4
diff --git a/llvm/test/MC/Sparc/Relocations/relocation-specifier.s b/llvm/test/MC/Sparc/Relocations/relocation-specifier.s
index 1d89babb5e6cd..563f966b1e450 100644
--- a/llvm/test/MC/Sparc/Relocations/relocation-specifier.s
+++ b/llvm/test/MC/Sparc/Relocations/relocation-specifier.s
@@ -1,20 +1,12 @@
 # RUN: llvm-mc %s -triple=sparc | FileCheck %s --check-prefix=ASM
-# RUN: llvm-mc %s -triple=sparcv9 | FileCheck %s --check-prefix=ASM
 
 # RUN: llvm-mc %s -triple=sparc -filetype=obj -o %t
 # RUN: llvm-objdump -dr %t | FileCheck %s --check-prefix=OBJDUMP
-# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj -o %t
-# RUN: llvm-objdump -dr %t | FileCheck %s --check-prefix=OBJDUMP
 # RUN: llvm-readelf -s - < %t | FileCheck %s --check-prefix=READELF --implicit-check-not=TLS
 
 # READELF: TLS     LOCAL  DEFAULT [[#]] s_tle_hix22
 # READELF: TLS     LOCAL  DEFAULT [[#]] s_tldo_hix22
 # READELF: TLS     GLOBAL DEFAULT   UND s_tle_lox10
-# READELF: TLS     GLOBAL DEFAULT   UND s_tie_hi22
-# READELF: TLS     GLOBAL DEFAULT   UND s_tie_lo10
-# READELF: TLS     GLOBAL DEFAULT   UND s_tie_ld
-# READELF: TLS     GLOBAL DEFAULT   UND s_tie_ldx
-# READELF: TLS     GLOBAL DEFAULT   UND s_tie_add
 # READELF: TLS     GLOBAL DEFAULT   UND s_tldm_hi22
 # READELF: TLS     GLOBAL DEFAULT   UND s_tldm_lo10
 # READELF: TLS     GLOBAL DEFAULT   UND s_tldm_add
@@ -72,31 +64,6 @@ or %g1, %hm(sym), %g3
 or %g1, %ulo(sym), %g3
 sethi %lm(sym), %l0
 
-# ASM:      sethi %hix(sym), %g1
-# ASM-NEXT: xor %g1, %lox(sym), %g1
-# ASM-NEXT: sethi %gdop_hix22(sym), %l1
-# ASM-NEXT: or %l1, %gdop_lox10(sym), %l1
-# ASM-NEXT: ldx [%l7+%l1], %l2, %gdop(sym)
-# OBJDUMP:      sethi 0x3fffff, %g0
-# OBJDUMP-NEXT: xor %g0, -0x400, %g0
-# OBJDUMP-NEXT: sethi 0x0, %g1
-# OBJDUMP-NEXT:   R_SPARC_HIX22 sym
-# OBJDUMP-NEXT: xor %g1, 0x0, %g1
-# OBJDUMP-NEXT:   R_SPARC_LOX10 sym
-# OBJDUMP-NEXT: sethi 0x0, %l1
-# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP_HIX22 sym
-# OBJDUMP-NEXT: or %l1, 0x0, %l1
-# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP_LOX10 sym
-# OBJDUMP-NEXT: ldx [%l7+%l1], %l2
-# OBJDUMP-NEXT:   R_SPARC_GOTDATA_OP sym
-sethi %hix(zero), %g0
-xor %g0, %lox(zero), %g0
-sethi %hix(sym), %g1
-xor %g1, %lox(sym), %g1
-sethi %gdop_hix22(sym), %l1
-or %l1, %gdop_lox10(sym), %l1
-ldx [%l7 + %l1], %l2, %gdop(sym)
-
 .set abs, 0xfedcba98
 .set abs48, 0xfedcba987654
 zero = 0
@@ -147,24 +114,6 @@ xor %o0, %lox(abs), %o0
         sethi %tle_hix22(s_tle_hix22), %i0
         xor %i0, %tle_lox10(s_tle_lox10), %i0
 
-## Initial Executable model
-# ASM:      sethi %tie_hi22(s_tie_hi22), %i1
-# ASM-NEXT: add %i1, %tie_lo10(s_tie_lo10), %i1
-# ASM-NEXT: ld [%i0+%i1], %i0, %tie_ld(s_tie_ld)
-# ASM-NEXT: ldx [%i0+%i1], %i0, %tie_ldx(s_tie_ldx)
-# ASM-NEXT: add %g7, %i0, %o0, %tie_add(s_tie_add)
-
-# OBJDUMP:      R_SPARC_TLS_IE_HI22	s_tie_hi22
-# OBJDUMP:      R_SPARC_TLS_IE_LO10	s_tie_lo10
-# OBJDUMP:      R_SPARC_TLS_IE_LD	s_tie_ld
-# OBJDUMP:      R_SPARC_TLS_IE_LDX	s_tie_ldx
-# OBJDUMP:      R_SPARC_TLS_IE_ADD	s_tie_add
-	sethi %tie_hi22(s_tie_hi22), %i1
-        add %i1, %tie_lo10(s_tie_lo10), %i1
-        ld [%i0+%i1], %i0, %tie_ld(s_tie_ld)
-        ldx [%i0+%i1], %i0, %tie_ldx(s_tie_ldx)
-        add %g7, %i0, %o0, %tie_add(s_tie_add)
-
 ## Local Dynamic model
 # ASM:      sethi %tldo_hix22(s_tldo_hix22), %i1
 # ASM-NEXT: sethi %tldm_hi22(s_tldm_hi22), %i2
diff --git a/llvm/test/MC/Sparc/sparcv9-instructions.s b/llvm/test/MC/Sparc/sparcv9-instructions.s
index 1c174f399ed34..2547eb53b1e38 100644
--- a/llvm/test/MC/Sparc/sparcv9-instructions.s
+++ b/llvm/test/MC/Sparc/sparcv9-instructions.s
@@ -67,14 +67,24 @@
         ! V9: lda [%i0+%l6] #ASI_SNF, %o2 ! encoding: [0xd4,0x86,0x10,0x76]
         lduwa [%i0 + %l6] (130+1), %o2
 
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldsw [%i0 + %l6], %o2
         ! V9: ldsw [%i0+%l6], %o2    ! encoding: [0xd4,0x46,0x00,0x16]
         ldsw [%i0 + %l6], %o2
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldsw [%i0 + 32], %o2
         ! V9: ldsw [%i0+32], %o2     ! encoding: [0xd4,0x46,0x20,0x20]
         ldsw [%i0 + 32], %o2
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldsw [%g1], %o2
         ! V9: ldsw [%g1], %o2        ! encoding: [0xd4,0x40,0x40,0x00]
         ldsw [%g1], %o2
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldswa [%i0 + %l6] 131, %o2
         ! V9: ldswa [%i0+%l6] #ASI_SNF, %o2 ! encoding: [0xd4,0xc6,0x10,0x76]
         ldswa [%i0 + %l6] 131, %o2
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldswa [%i0 + %l6] (130+1), %o2
         ! V9: ldswa [%i0+%l6] #ASI_SNF, %o2 ! encoding: [0xd4,0xc6,0x10,0x76]
         ldswa [%i0 + %l6] (130+1), %o2
 
@@ -151,8 +161,12 @@
         ! V9: ldx [%g2+%i5], %fsr   ! encoding: [0xc3,0x08,0x80,0x1d]
         ldx [%g2 + %i5],%fsr
 
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldxa [%g2 + %i5] 131, %g0
         ! V9: ldxa [%g2+%i5] #ASI_SNF, %g0   ! encoding: [0xc0,0xd8,0x90,0x7d]
         ldxa [%g2 + %i5] 131, %g0
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldxa [%g2 + %i5] (130+1), %g0
         ! V9: ldxa [%g2+%i5] #ASI_SNF, %g0   ! encoding: [0xc0,0xd8,0x90,0x7d]
         ldxa [%g2 + %i5] (130+1), %g0
 
@@ -166,8 +180,12 @@
         ! 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: stxa %g0, [%g2 + %i5] 131
         ! V9: stxa %g0, [%g2+%i5] #ASI_SNF   ! encoding: [0xc0,0xf0,0x90,0x7d]
         stxa %g0, [%g2 + %i5] 131
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: stxa %g0, [%g2 + %i5] (130+1)
         ! V9: stxa %g0, [%g2+%i5] #ASI_SNF   ! encoding: [0xc0,0xf0,0x90,0x7d]
         stxa %g0, [%g2 + %i5] (130+1)
 
@@ -507,33 +525,57 @@
         ! V9: wr %i0, 1, %asr21         ! encoding: [0xab,0x86,0x20,0x01]
         wr %i0, 1, %clear_softint
 
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stw %o1, [%o0]
         ! V9: st %o1, [%o0]             ! encoding: [0xd2,0x22,0x00,0x00]
         stw %o1, [%o0]
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stuw %o1, [%o0]
         ! V9: st %o1, [%o0]             ! encoding: [0xd2,0x22,0x00,0x00]
         stuw %o1, [%o0]
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stsw %o1, [%o0]
         ! V9: st %o1, [%o0]             ! encoding: [0xd2,0x22,0x00,0x00]
         stsw %o1, [%o0]
 
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stwa %o2, [%i0 + %l6] 131
         ! V9: sta %o2, [%i0+%l6] #ASI_SNF ! encoding: [0xd4,0xa6,0x10,0x76]
         stwa %o2, [%i0 + %l6] 131
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stuwa %o2, [%i0 + %l6] 131
         ! V9: sta %o2, [%i0+%l6] #ASI_SNF ! encoding: [0xd4,0xa6,0x10,0x76]
         stuwa %o2, [%i0 + %l6] 131
+        ! V8:      error: invalid instruction mnemonic
+        ! V8-NEXT: stswa %o2, [%i0 + %l6] 131
         ! V9: sta %o2, [%i0+%l6] #ASI_SNF ! encoding: [0xd4,0xa6,0x10,0x76]
         stswa %o2, [%i0 + %l6] 131
 
         !! SPARCv9 provides a new variant of ASI-tagged memory accesses.
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldxa [%g2] %asi, %g0
         ! V9: ldxa [%g2] %asi, %g0    ! encoding: [0xc0,0xd8,0xa0,0x00]
         ldxa [%g2] %asi, %g0
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: stxa %g0, [%g2] %asi
         ! V9: stxa %g0, [%g2] %asi    ! encoding: [0xc0,0xf0,0xa0,0x00]
         stxa %g0, [%g2] %asi
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldxa [%g2 + 5] %asi, %g0
         ! V9: ldxa [%g2+5] %asi, %g0    ! encoding: [0xc0,0xd8,0xa0,0x05]
         ldxa [%g2 + 5] %asi, %g0
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: stxa %g0, [%g2 + 5] %asi
         ! V9: stxa %g0, [%g2+5] %asi    ! encoding: [0xc0,0xf0,0xa0,0x05]
         stxa %g0, [%g2 + 5] %asi
 
         !! Also make sure named ASI tags are parsed properly.
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: ldxa [%g2 + %i5] #ASI_SNF, %g0
         ! V9: ldxa [%g2+%i5] #ASI_SNF, %g0   ! encoding: [0xc0,0xd8,0x90,0x7d]
         ldxa [%g2 + %i5] #ASI_SNF, %g0
+        ! V8:      error: instruction requires a CPU feature not currently enabled
+        ! V8-NEXT: stxa %g0, [%g2 + %i5] #ASI_SNF
         ! V9: stxa %g0, [%g2+%i5] #ASI_SNF   ! encoding: [0xc0,0xf0,0x90,0x7d]
         stxa %g0, [%g2 + %i5] #ASI_SNF
 

@Rot127
Copy link

Rot127 commented Jun 7, 2025

Pinging @Rot127 too, does this help?

Yes, very. Although I would say HasV9 should imply Is64Bit.
But this is probably not how the definitions are written and I can add a workaround for our very specific use case.

In any case, thanks for the fix!

@Rot127
Copy link

Rot127 commented Jun 7, 2025

Ah btw. Doesn't the three VIS extensions also imply V9?

@koachan
Copy link
Contributor Author

koachan commented Jun 7, 2025

Yes, very. Although I would say HasV9 should imply Is64Bit. But this is probably not how the definitions are written and I can add a workaround for our very specific use case.

It's possible to target V9 while still using 32-bit addressing, that's why HasV9 is placed under Is64Bit and not otherwise.

Ah btw. Doesn't the three VIS extensions also imply V9?

Not sure if it's required by the spec, but looking at released processors I think this is true in practice.
Should I specify those too?

@Rot127
Copy link

Rot127 commented Jun 7, 2025

It's possible to target V9 while still using 32-bit addressing, that's why HasV9 is placed under Is64Bit and not otherwise.

I see. Thanks!

Not sure if it's required by the spec, but looking at released processors I think this is true in practice.
Should I specify those too?

If it is the right decision for LLVM sure. We use the LLVM architecture definitions to generate our disassembler modules in Capstone. The closer the definitions are to the ISA the better for us.
But I reckon this is not always the best option for LLVM use cases. And I am not deep enough in LLVM related problems to allow myself judgement on this, I think.

Oracle seems to list them under V9 though: https://docs.oracle.com/cd/E19683-01/816-1681/6m83631m2/index.html

! V9: stxa %g0, [%g2+5] %asi ! encoding: [0xc0,0xf0,0xa0,0x05]
stxa %g0, [%g2 + 5] %asi

!! Also make sure named ASI tags are parsed properly.
! V8: error: instruction requires a CPU feature not currently enabled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

V8 checks are exclusively for errors. In such a case, we should test [[#@LINE+2]]:column: error: .... llvm-mc copies the source line that triggers the error, but it is not useful and should be removed.

@koachan koachan changed the title [SPARC][IAS] Make Is64Bit imply FeatureV9 in the assembler [SPARC][IAS] Properly set implied feature sets for ISA levels/extensions Jun 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:Sparc mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Sparc] V9 only instructions are defined for Sparc V8
4 participants