[2/7] gas:pru: Fix LDI32 pseudo to conform to TI ABI

Message ID 20180428192827.18401-2-dimitar@dinux.eu
State Superseded
Headers show
Series
  • [1/7] bfd:pru: Fix LDI32 relocation to conform to TI ABI
Related show

Commit Message

Dimitar Dimitrov April 28, 2018, 7:28 p.m.
Per TI ABI, first LDI must load the MSB 16bits.

2018-04-26  Dimitar Dimitrov  <dimitar@dinux.eu>

        * config/tc-pru.c (md_apply_fix): Make LDI32 relocation conformant
          to TI ABI.
        (pru_assemble_arg_i): Ditto
        (output_insn_ldi32): Ditto
        * testsuite/gas/pru/ldi.d: Update test for the now fixed LDI32.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>

---
 gas/config/tc-pru.c         | 16 +++++++++++-----
 gas/testsuite/gas/pru/ldi.d |  8 ++++----
 2 files changed, 15 insertions(+), 9 deletions(-)

-- 
2.11.0

Patch

diff --git a/gas/config/tc-pru.c b/gas/config/tc-pru.c
index d0f630e2b4..91edf14557 100644
--- a/gas/config/tc-pru.c
+++ b/gas/config/tc-pru.c
@@ -814,8 +814,11 @@  md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	      /* As the only 64-bit "insn", LDI32 needs special handling. */
 	      uint32_t insn1 = insn & 0xffffffff;
 	      uint32_t insn2 = insn >> 32;
-	      SET_INSN_FIELD (IMM16, insn1, fixup & 0xffff);
-	      SET_INSN_FIELD (IMM16, insn2, fixup >> 16);
+	      SET_INSN_FIELD (IMM16, insn1, fixup >> 16);
+	      SET_INSN_FIELD (IMM16, insn2, fixup & 0xffff);
+
+	      SET_INSN_FIELD (RDSEL, insn1, RSEL_31_16);
+	      SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
 
 	      md_number_to_chars (buf, insn1, 4);
 	      md_number_to_chars (buf + 4, insn2, 4);
@@ -1141,7 +1144,8 @@  pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
 
   /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
   SET_INSN_FIELD (IO, insn_info->insn_code, 0);
-  SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 & 0xffff);
+  SET_INSN_FIELD (RDSEL, insn_info->insn_code, RSEL_31_16);
+  SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 >> 16);
   insn_info->ldi32_imm32 = imm32;
 }
 
@@ -1475,11 +1479,13 @@  output_insn_ldi32 (pru_insn_infoS *insn)
   unsigned long insn2;
 
   f = frag_more (8);
+  SET_INSN_FIELD (IMM16, insn->insn_code, insn->ldi32_imm32 >> 16);
+  SET_INSN_FIELD (RDSEL, insn->insn_code, RSEL_31_16);
   md_number_to_chars (f, insn->insn_code, 4);
 
   insn2 = insn->insn_code;
-  SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 >> 16);
-  SET_INSN_FIELD (RDSEL, insn2, RSEL_31_16);
+  SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 & 0xffff);
+  SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
   md_number_to_chars (f + 4, insn2, 4);
 
   /* Emit debug info.  */
diff --git a/gas/testsuite/gas/pru/ldi.d b/gas/testsuite/gas/pru/ldi.d
index 885150495e..4c2cf7a0c7 100644
--- a/gas/testsuite/gas/pru/ldi.d
+++ b/gas/testsuite/gas/pru/ldi.d
@@ -6,12 +6,12 @@ 
 .*: +file format elf32-pru
 
 Disassembly of section .text:
-0+0000 <[^>]*> 240000f0 	ldi	r16, 0
+0+0000 <[^>]*> 240000d0 	ldi	r16.w2, 0
 [\t ]*0: R_PRU_LDI32	\*ABS\*\+0x12345678
-0+0004 <[^>]*> 240000d0 	ldi	r16.w2, 0
+0+0004 <[^>]*> 24000090 	ldi	r16.w0, 0
 0+0008 <[^>]*> 241234f0 	ldi	r16, 4660
 0+000c <[^>]*> 240000f0 	ldi	r16, 0
 [\t ]*c: R_PRU_U16_PMEMIMM	.text
-0+0010 <[^>]*> 240000f0 	ldi	r16, 0
+0+0010 <[^>]*> 240000d0 	ldi	r16.w2, 0
 [\t ]*10: R_PRU_LDI32	var1
-0+0014 <[^>]*> 240000d0 	ldi	r16.w2, 0
+0+0014 <[^>]*> 24000090 	ldi	r16.w0, 0