[PATCH v3 2/4] microblaze: use md_number_to_chars in md_apply_fix
Sam Price
thesamprice@gmail.com
Thu Sep 24 01:50:21 GMT 2026
From: Samuel Price <thesamprice@gmail.com>
The remaining cases open-code their writes as buf[n] |= ..., each with its
own target_big_endian branch. md_number_to_chars does the same job and is
what aarch64, mips, sparc and most other backends use.
For the data relocations the branch disappears entirely: BFD_RELOC_32 and
friends become a single call, since md_number_to_chars writes in target byte
order.
For the instruction relocations it does not. A 32-bit instruction word is
itself stored in target byte order, so its 16-bit immediate field moves as
well as its bytes: it is the low half of the word, which sits at offset 2
big-endian and offset 0 little-endian. md_number_to_chars handles the order
but not the offset, so that part stays, named INST_IMM_OFFSET next to the
INST_BYTE macros it belongs with. The 64-bit cases then address the second
instruction word as INST_WORD_SIZE + INST_IMM_OFFSET rather than by the
literal subscripts 4 through 7.
For instruction relocations only the data is swapped. A macro
'INST_IMM_OFFSET' was added to move past instruction. Mips does does not
use the macro, but does the calc inline. INST_BYTE macros were replaced
where with md_number_to_chars.
|= gave me a bit of pause, data is zeroed by emit_expr_fix gas/read.c
before the fixup is created.
No functional change intended. Whole testsuite, pristine master plus this
series, both byte orders, as expected passes / unexpected failures:
gas binutils ld
microblaze-elf 329/0 240/0 480/0
microblazeel-elf 328/2 241/0 480/0
No unexpected successes anywhere. The two microblazeel gas failures,
"difference of two undefined symbols" and "all end", are pre-existing and
unrelated to this series.
gas/
* config/tc-microblaze.c (INST_IMM_OFFSET): Define.
(md_apply_fix): Use md_number_to_chars throughout.
Signed-off-by: Sam Price <thesamprice@gmail.com>
Assisted-by: Claude (Anthropic)
---
gas/config/tc-microblaze.c | 63 +++++++-------------------------------
1 file changed, 11 insertions(+), 52 deletions(-)
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
index fcc41a7f1f2..b2edce8831b 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
@@ -49,6 +49,11 @@ static bool check_spl_reg (unsigned *);
#define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
#define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
#define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
+/* Offset of the 16-bit immediate field within an instruction word. The
+ word is stored in target byte order, so the field moves as well as its
+ bytes: it is the low half, which is at offset 2 big-endian and 0
+ little-endian. */
+#define INST_IMM_OFFSET (target_big_endian ? 2 : 0)
/* This array holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful. */
@@ -2113,16 +2118,7 @@ md_apply_fix (fixS * fixP,
{
case BFD_RELOC_MICROBLAZE_32_LO:
case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
- if (target_big_endian)
- {
- buf[2] |= ((val >> 8) & 0xff);
- buf[3] |= (val & 0xff);
- }
- else
- {
- buf[1] |= ((val >> 8) & 0xff);
- buf[0] |= (val & 0xff);
- }
+ md_number_to_chars (buf + INST_IMM_OFFSET, val, 2);
break;
case BFD_RELOC_MICROBLAZE_32_ROSDA:
case BFD_RELOC_MICROBLAZE_32_RWSDA:
@@ -2133,16 +2129,7 @@ md_apply_fix (fixS * fixP,
as_bad_where (file, fixP->fx_line,
_("pcrel for branch to %s too far (0x%x)"),
symname, (int) val);
- if (target_big_endian)
- {
- buf[2] |= ((val >> 8) & 0xff);
- buf[3] |= (val & 0xff);
- }
- else
- {
- buf[1] |= ((val >> 8) & 0xff);
- buf[0] |= (val & 0xff);
- }
+ md_number_to_chars (buf + INST_IMM_OFFSET, val, 2);
}
break;
case BFD_RELOC_8:
@@ -2159,20 +2146,7 @@ md_apply_fix (fixS * fixP,
/* Don't do anything if the symbol is not defined. */
if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
{
- if (target_big_endian)
- {
- buf[0] |= ((val >> 24) & 0xff);
- buf[1] |= ((val >> 16) & 0xff);
- buf[2] |= ((val >> 8) & 0xff);
- buf[3] |= (val & 0xff);
- }
- else
- {
- buf[3] |= ((val >> 24) & 0xff);
- buf[2] |= ((val >> 16) & 0xff);
- buf[1] |= ((val >> 8) & 0xff);
- buf[0] |= (val & 0xff);
- }
+ md_number_to_chars (buf, val, 4);
}
break;
case BFD_RELOC_64_PCREL:
@@ -2194,24 +2168,12 @@ md_apply_fix (fixS * fixP,
if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
- buf[0] = INST_BYTE0 (inst1);
- buf[1] = INST_BYTE1 (inst1);
- buf[2] = INST_BYTE2 (inst1);
- buf[3] = INST_BYTE3 (inst1);
+ md_number_to_chars (buf, inst1, INST_WORD_SIZE);
/* Add the value only if the symbol is defined. */
if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
{
- if (target_big_endian)
- {
- buf[6] |= ((val >> 8) & 0xff);
- buf[7] |= (val & 0xff);
- }
- else
- {
- buf[5] |= ((val >> 8) & 0xff);
- buf[4] |= (val & 0xff);
- }
+ md_number_to_chars (buf + INST_WORD_SIZE + INST_IMM_OFFSET, val, 2);
}
break;
@@ -2242,10 +2204,7 @@ md_apply_fix (fixS * fixP,
/* We can fixup call to a defined non-global address
within the same section only. */
- buf[0] = INST_BYTE0 (inst1);
- buf[1] = INST_BYTE1 (inst1);
- buf[2] = INST_BYTE2 (inst1);
- buf[3] = INST_BYTE3 (inst1);
+ md_number_to_chars (buf, inst1, INST_WORD_SIZE);
return;
default:
--
2.39.5 (Apple Git-154)
More information about the Binutils
mailing list