[PATCH 1/3] s390: gas: Fix conversion of FP register names to DWARF register numbers
Jens Remus
jremus@linux.ibm.com
Mon Jan 12 15:30:37 GMT 2026
The assembler supports register names in CFI directives. For floating-
point (FP) registers f0..f15 the register numbers 0..15 are erroneously
converted to DWARF register numbers 16..31 by adding 16. This is wrong
as the s390 64-bit (s390x) ELF ABI [1] specifies the DWARF register
numbers for the FP registers as follows:
DWARF BINARY BINARY DWARF
REGISTER REGISTER REGISTER REGISTER
NUMBER NAME NUMBER NUMBER
16 f0 0b0000 -> 0b10000
17 f2 0b0010 -> 0b10001
18 f4 0b0100 -> 0b10010
19 f6 0b0110 -> 0b10011
20 f1 0b0001 -> 0b10100
21 f3 0b0011 -> 0b10101
22 f5 0b0101 -> 0b10110
23 f7 0b0111 -> 0b10111
24 f8 0b1000 -> 0b11000
25 f10 0b1010 -> 0b11001
26 f12 0b1100 -> 0b11010
27 f14 0b1110 -> 0b11011
28 f9 0b1001 -> 0b11100
29 f11 0b1011 -> 0b11101
30 f13 0b1101 -> 0b11110
31 f15 0b1111 -> 0b11111
Convert a FP register number (0..15) to its respective DWARF register
number (16..31) as follows:
Right rotate the least significant three bits and add 16.
Add a test case for the use of general register (GR; r0..r15) and
floating-point register (FPR; f0..f15) names in CFI directives.
[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases
gas/
* config/tc-s390.c (tc_s390_regname_to_dw2regnum): Fix
conversion of FP register names to DWARF register numbers.
gas/testsuite/
* gas/s390/s390.exp (cfi-regnames, cfi-regnames-err): Run new
tests.
* gas/s390/cfi-regnames.d: New test for GR and FPR names in CFI
directives.
* gas/s390/cfi-regnames.s: Likewise.
* gas/s390/cfi-regnames-err.l: Likewise.
* gas/s390/cfi-regnames-err.s: Likewise.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
gas/config/tc-s390.c | 12 +++++++-
gas/testsuite/gas/s390/cfi-regnames-err.l | 8 +++++
gas/testsuite/gas/s390/cfi-regnames-err.s | 9 ++++++
gas/testsuite/gas/s390/cfi-regnames.d | 36 +++++++++++++++++++++++
gas/testsuite/gas/s390/cfi-regnames.s | 33 +++++++++++++++++++++
gas/testsuite/gas/s390/s390.exp | 2 ++
6 files changed, 99 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/s390/cfi-regnames-err.l
create mode 100644 gas/testsuite/gas/s390/cfi-regnames-err.s
create mode 100644 gas/testsuite/gas/s390/cfi-regnames.d
create mode 100644 gas/testsuite/gas/s390/cfi-regnames.s
diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
index 8f6bcfc2e84e..55cd43db3a16 100644
--- a/gas/config/tc-s390.c
+++ b/gas/config/tc-s390.c
@@ -2879,7 +2879,17 @@ tc_s390_regname_to_dw2regnum (char *regname)
{
regnum = reg_name_search (regname);
if (regname[0] == 'f' && regnum != -1)
- regnum += 16;
+ {
+ /* Convert from floating-point register number (0..15)
+ * to DWARF floating point register number (15..31):
+ * Right rotate the least significant three bits and add 16. */
+ int dw2_regnum;
+ dw2_regnum = (regnum & 0b110) >> 1;
+ dw2_regnum |= (regnum & 0b1) << 2;
+ dw2_regnum |= (regnum & 0b1000);
+ dw2_regnum += 16;
+ regnum = dw2_regnum;
+ }
}
else if (strcmp (regname, "ap") == 0)
regnum = 32;
diff --git a/gas/testsuite/gas/s390/cfi-regnames-err.l b/gas/testsuite/gas/s390/cfi-regnames-err.l
new file mode 100644
index 000000000000..7944f9b78fcb
--- /dev/null
+++ b/gas/testsuite/gas/s390/cfi-regnames-err.l
@@ -0,0 +1,8 @@
+#name: s390/s390x register names in CFI directives errors
+.*: Assembler messages:
+# Invalid general register names
+.*:4: Error: bad register expression
+.*:5: Error: bad register expression
+# Invalid floating-point register names
+.*:7: Error: bad register expression
+.*:8: Error: bad register expression
diff --git a/gas/testsuite/gas/s390/cfi-regnames-err.s b/gas/testsuite/gas/s390/cfi-regnames-err.s
new file mode 100644
index 000000000000..55eae2cf1513
--- /dev/null
+++ b/gas/testsuite/gas/s390/cfi-regnames-err.s
@@ -0,0 +1,9 @@
+ .text
+ .cfi_startproc
+# Invalid general register names
+ .cfi_register r0, r16
+ .cfi_register %r0, %r16
+# Invalid floating-point register names
+ .cfi_register f0, f16
+ .cfi_register %f0, %f16
+ .cfi_endproc
diff --git a/gas/testsuite/gas/s390/cfi-regnames.d b/gas/testsuite/gas/s390/cfi-regnames.d
new file mode 100644
index 000000000000..8e4740587350
--- /dev/null
+++ b/gas/testsuite/gas/s390/cfi-regnames.d
@@ -0,0 +1,36 @@
+#name: s390/s390x register names in CFI directives
+#objdump: -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+#...
+
+# General register (GR) names r0..r15
+00000018 0000000000000028 0000001c FDE cie=00000000 pc=0000000000000000..0000000000000004
+ DW_CFA_advance_loc: 2 to 0000000000000002
+ DW_CFA_register: r0 in r1
+ DW_CFA_register: r2 in r3
+ DW_CFA_register: r4 in r5
+ DW_CFA_register: r6 in r7
+ DW_CFA_register: r8 in r9
+ DW_CFA_register: r10 in r11
+ DW_CFA_register: r12 in r13
+ DW_CFA_register: r14 in r15
+ DW_CFA_nop
+ DW_CFA_nop
+
+# Floating-point register (FPR) names f0..f15
+00000044 0000000000000028 00000048 FDE cie=00000000 pc=0000000000000004..0000000000000008
+ DW_CFA_advance_loc: 2 to 0000000000000006
+ DW_CFA_register: r16 \(f0\) in r20 \(f1\)
+ DW_CFA_register: r17 \(f2\) in r21 \(f3\)
+ DW_CFA_register: r18 \(f4\) in r22 \(f5\)
+ DW_CFA_register: r19 \(f6\) in r23 \(f7\)
+ DW_CFA_register: r24 \(f8\) in r28 \(f9\)
+ DW_CFA_register: r25 \(f10\) in r29 \(f11\)
+ DW_CFA_register: r26 \(f12\) in r30 \(f13\)
+ DW_CFA_register: r27 \(f14\) in r31 \(f15\)
+ DW_CFA_nop
+ DW_CFA_nop
diff --git a/gas/testsuite/gas/s390/cfi-regnames.s b/gas/testsuite/gas/s390/cfi-regnames.s
new file mode 100644
index 000000000000..cd11d4da450f
--- /dev/null
+++ b/gas/testsuite/gas/s390/cfi-regnames.s
@@ -0,0 +1,33 @@
+ .text
+# General register (GR) names r0..r15
+ .type gr, @function
+gr:
+ .cfi_startproc
+ .word 0
+ .cfi_register r0, r1
+ .cfi_register r2, r3
+ .cfi_register r4, r5
+ .cfi_register r6, r7
+ .cfi_register r8, r9
+ .cfi_register r10, r11
+ .cfi_register r12, r13
+ .cfi_register r14, r15
+ .word 0
+ .cfi_endproc
+ .size gr, .-gr
+# Floating-point register (FPR) names f0..f15
+ .type fpr, @function
+fpr:
+ .cfi_startproc
+ .word 0
+ .cfi_register f0, f1
+ .cfi_register f2, f3
+ .cfi_register f4, f5
+ .cfi_register f6, f7
+ .cfi_register f8, f9
+ .cfi_register f10, f11
+ .cfi_register f12, f13
+ .cfi_register f14, f15
+ .word 0
+ .cfi_endproc
+ .size fpr, .-fpr
diff --git a/gas/testsuite/gas/s390/s390.exp b/gas/testsuite/gas/s390/s390.exp
index 1d5d97f48631..49876aa00e33 100644
--- a/gas/testsuite/gas/s390/s390.exp
+++ b/gas/testsuite/gas/s390/s390.exp
@@ -64,4 +64,6 @@ if [expr [istarget "s390-*-*"] || [istarget "s390x-*-*"]] then {
run_list_test "zarch-warn-areg-zero" "-m64 -mwarn-areg-zero"
run_list_test "zarch-warn-regtype-mismatch-strict" "-m64 -mwarn-regtype-mismatch=strict"
run_list_test "zarch-warn-regtype-mismatch-relaxed" "-m64 -mwarn-regtype-mismatch=relaxed"
+ run_dump_test "cfi-regnames" ""
+ run_list_test "cfi-regnames-err" ""
}
--
2.51.0
More information about the Binutils
mailing list