s390: Emit relocation for 32-bit immediate operand

Message ID 20250915111004.785370-1-jremus@linux.ibm.com
State New
Headers
Series s390: Emit relocation for 32-bit immediate operand |

Commit Message

Jens Remus Sept. 15, 2025, 11:10 a.m. UTC
  IBM Z instruction format RIL-a has a 32-bit immediate operand in
instruction bits 16 to 47.  Enable the assembler to emit a 32-bit
direct or PC-relative relocation when processing a fixup, similar
as it is already done for 16-bit immediate operands in bits 16-31.

This enables to assemble the following:

	lgfi	%r1,symbol	# R_390_32
	lgfi	%r1,symbol-.	# R_390_PC32

Furthermore it brings GNU assembler on par with LLVM assembler in
that regard.

gas/
	* config/tc-s390.c (md_apply_fix): Emit 32-bit direct or
	PC-relative relocation for 32-bit immediate operand in
	instruction bits 16-47.

gas/testsuite/
	* gas/s390/zarch-reloc.d: Add tests for relocation of RIL-a
	32-bit immediate operand.
	* gas/s390/zarch-reloc.s: Likewise.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
 gas/config/tc-s390.c                 | 20 +++++++++++++++-----
 gas/testsuite/gas/s390/zarch-reloc.d | 12 ++++++++----
 gas/testsuite/gas/s390/zarch-reloc.s |  2 ++
 3 files changed, 25 insertions(+), 9 deletions(-)
  

Comments

Andreas Krebbel Nov. 4, 2025, 10:23 a.m. UTC | #1
On 9/15/25 1:10 PM, Jens Remus wrote:
> IBM Z instruction format RIL-a has a 32-bit immediate operand in
> instruction bits 16 to 47.  Enable the assembler to emit a 32-bit
> direct or PC-relative relocation when processing a fixup, similar
> as it is already done for 16-bit immediate operands in bits 16-31.
>
> This enables to assemble the following:
>
> 	lgfi	%r1,symbol	# R_390_32
> 	lgfi	%r1,symbol-.	# R_390_PC32
>
> Furthermore it brings GNU assembler on par with LLVM assembler in
> that regard.
>
> gas/
> 	* config/tc-s390.c (md_apply_fix): Emit 32-bit direct or
> 	PC-relative relocation for 32-bit immediate operand in
> 	instruction bits 16-47.
>
> gas/testsuite/
> 	* gas/s390/zarch-reloc.d: Add tests for relocation of RIL-a
> 	32-bit immediate operand.
> 	* gas/s390/zarch-reloc.s: Likewise.
>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>

Ok. Thanks!

Andreas
  
Jens Remus Nov. 4, 2025, 1:27 p.m. UTC | #2
On 11/4/2025 11:23 AM, Andreas Krebbel wrote:
> On 9/15/25 1:10 PM, Jens Remus wrote:
>> IBM Z instruction format RIL-a has a 32-bit immediate operand in
>> instruction bits 16 to 47.  Enable the assembler to emit a 32-bit
>> direct or PC-relative relocation when processing a fixup, similar
>> as it is already done for 16-bit immediate operands in bits 16-31.
>>
>> This enables to assemble the following:
>>
>>     lgfi    %r1,symbol    # R_390_32
>>     lgfi    %r1,symbol-.    # R_390_PC32
>>
>> Furthermore it brings GNU assembler on par with LLVM assembler in
>> that regard.
>>
>> gas/
>>     * config/tc-s390.c (md_apply_fix): Emit 32-bit direct or
>>     PC-relative relocation for 32-bit immediate operand in
>>     instruction bits 16-47.
>>
>> gas/testsuite/
>>     * gas/s390/zarch-reloc.d: Add tests for relocation of RIL-a
>>     32-bit immediate operand.
>>     * gas/s390/zarch-reloc.s: Likewise.
>>
>> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> 
> Ok. Thanks!

Thank you for the review!  Committed to mainline.

Regards,
Jens
  

Patch

diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c
index b073d8edbd25..ca6a20726efb 100644
--- a/gas/config/tc-s390.c
+++ b/gas/config/tc-s390.c
@@ -2592,14 +2592,24 @@  md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	  fixP->fx_pcrel_adjust = 3;
 	  fixP->fx_r_type = BFD_RELOC_390_PC24DBL;
 	}
-      else if (operand->bits == 32 && operand->shift == 16
-	       && (operand->flags & S390_OPERAND_PCREL))
+      else if (operand->bits == 32 && operand->shift == 16)
 	{
 	  fixP->fx_size = 4;
 	  fixP->fx_where += 2;
-	  fixP->fx_offset += 2;
-	  fixP->fx_pcrel_adjust = 2;
-	  fixP->fx_r_type = BFD_RELOC_390_PC32DBL;
+	  if (operand->flags & S390_OPERAND_PCREL)
+	    {
+	      fixP->fx_offset += 2;
+	      fixP->fx_pcrel_adjust = 2;
+	      fixP->fx_r_type = BFD_RELOC_390_PC32DBL;
+	    }
+	  else if (fixP->fx_pcrel)
+	    {
+	      fixP->fx_offset += 2;
+	      fixP->fx_pcrel_adjust = 2;
+	      fixP->fx_r_type = BFD_RELOC_32_PCREL;
+	    }
+	  else
+	    fixP->fx_r_type = BFD_RELOC_32;
 	}
       else
 	{
diff --git a/gas/testsuite/gas/s390/zarch-reloc.d b/gas/testsuite/gas/s390/zarch-reloc.d
index 136b3b1a62f7..29b10c68636d 100644
--- a/gas/testsuite/gas/s390/zarch-reloc.d
+++ b/gas/testsuite/gas/s390/zarch-reloc.d
@@ -23,10 +23,14 @@  Disassembly of section .text:
 [ 	]*42: R_390_GOTPLT64	test_R_390_GOTPLT64
   4a:	c0 10 00 00 00 00 [ 	]*larl	%r1,4a <foo\+0x4a>
 [ 	]*4c: R_390_GOTPLTENT	test_R_390_GOTPLTENT\+0x2
+  50:	c0 11 00 00 00 00 [ 	]*lgfi	%r1,0
+[ 	]*52: R_390_32	test_R_390_32
+  56:	c0 11 00 00 00 00 [ 	]*lgfi	%r1,0
+[ 	]*58: R_390_PC32	test_R_390_PC32\+0x58
 
 .* <bar>:
-  50:	c0 e5 00 00 00 00 [ 	]*brasl	%r14,50 <bar>
-[ 	]*52: R_390_PLT32DBL	foo\+0x2
+  5c:	c0 e5 00 00 00 00 [ 	]*brasl	%r14,5c <bar>
+[ 	]*5e: R_390_PLT32DBL	foo\+0x2
 [ 	]*...
-[ 	]*56: R_390_PLT64	foo\+0x6
-  5e:	07 07 [ 	]*nopr	%r7
+[ 	]*62: R_390_PLT64	foo\+0x6
+  6a:	07 07 [ 	]*nopr	%r7
diff --git a/gas/testsuite/gas/s390/zarch-reloc.s b/gas/testsuite/gas/s390/zarch-reloc.s
index d6ec22f26b66..8cb2ff0cb0f7 100644
--- a/gas/testsuite/gas/s390/zarch-reloc.s
+++ b/gas/testsuite/gas/s390/zarch-reloc.s
@@ -12,6 +12,8 @@  foo:
 	.quad	test_R_390_PLTOFF64@PLTOFF
 	.quad	test_R_390_GOTPLT64@GOTPLT
 	larl	%r1,test_R_390_GOTPLTENT@GOTPLT
+	lgfi	%r1,test_R_390_32
+	lgfi	%r1,test_R_390_PC32-foo
 
 bar:
 	brasl	%r14,foo@PLT