Fix PRU GAS for 32-bit hosts
authorDimitar Dimitrov <dimitar@dinux.eu>
Mon, 2 Jan 2017 16:20:21 +0000 (18:20 +0200)
committerAlan Modra <amodra@gmail.com>
Tue, 3 Jan 2017 07:10:44 +0000 (17:40 +1030)
The PRU GAS port I originally submitted does not build on 32bit hosts.
This patch fixes it by aligning md_number_to_chars's definition with
the global declaration in tc.h.

Here is the original bug report I got:
  https://github.com/rcn-ee/repos/pull/23#issuecomment-269915175

* config/tc-pru.c (md_number_to_chars): Fix parameter to be
valueT, as declared in tc.h.
(md_apply_fix): Fix to work on 32-bit hosts.

Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu>
gas/ChangeLog
gas/config/tc-pru.c

index 6a61d61fee1bf2809d6731be3394909dd7b3ee32..fccd817572f8c5656cd46351361fe16ab889a781 100644 (file)
@@ -1,3 +1,9 @@
+2017-01-03  Dimitar Dimitrov  <dimitar@dinux.eu>
+
+       * config/tc-pru.c (md_number_to_chars): Fix parameter to be
+       valueT, as declared in tc.h.
+       (md_apply_fix): Fix to work on 32-bit hosts.
+
 2017-01-02  Alan Modra  <amodra@gmail.com>
 
        Update year range in copyright notice of all files.
index dfc6f76801dceea5b42554ff20209812bae19d4d..5bfd67632a8609e57116ab7bc56efe16315b86d9 100644 (file)
@@ -175,7 +175,7 @@ md_chars_to_number (char *buf, int n)
    into the series of bytes that represent the number
    on the target machine.  */
 void
-md_number_to_chars (char *buf, uint64_t val, int n)
+md_number_to_chars (char *buf, valueT val, int n)
 {
   gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
   number_to_chars_littleendian (buf, val, n);
@@ -808,20 +808,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
          /* Fix up the instruction.  Non-contiguous bitfields need
             special handling.  */
-         if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
-           SET_BROFF_URAW (insn, fixup);
-         else if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
+         if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
            {
              /* 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);
-             insn = insn1 | ((uint64_t)insn2 << 32);
+
+             md_number_to_chars (buf, insn1, 4);
+             md_number_to_chars (buf + 4, insn2, 4);
            }
          else
-           insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
-         md_number_to_chars (buf, insn, fixP->fx_size);
+           {
+             if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
+               SET_BROFF_URAW (insn, fixup);
+             else
+               insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
+             md_number_to_chars (buf, insn, fixP->fx_size);
+           }
        }
 
       fixP->fx_done = 1;