aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-ppc.c28
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-ppc.c88
-rw-r--r--include/ChangeLog4
-rw-r--r--include/opcode/ppc.h5
6 files changed, 97 insertions, 41 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index de468a4..8a37271 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2018-12-06 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw <R_PPC_VLE_ADDR20>): Correct
+ mask and shift value.
+ (ppc_elf_vle_split16): Use E_OPCODE_MASK. Handle e_li
+ specially.
+
2018-12-05 Sam Tebbs <sam.tebbs@arm.com>
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Add check for 'B'.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index c31e26e..6b6043a 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -649,8 +649,8 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
ppc_elf_unhandled_reloc),
/* e_li split20 format. */
- HOW (R_PPC_VLE_ADDR20, 2, 20, 0x1f07ff, 16, FALSE, dont,
- bfd_elf_generic_reloc),
+ HOW (R_PPC_VLE_ADDR20, 2, 20, 0x1f7fff, 0, FALSE, dont,
+ ppc_elf_unhandled_reloc),
HOW (R_PPC_IRELATIVE, 2, 32, 0xffffffff, 0, FALSE, dont,
ppc_elf_unhandled_reloc),
@@ -3886,10 +3886,10 @@ ppc_elf_vle_split16 (bfd *input_bfd,
split16_format_type split16_format,
bfd_boolean fixup)
{
- unsigned int insn, opcode, top5;
+ unsigned int insn, opcode;
insn = bfd_get_32 (input_bfd, loc);
- opcode = insn & 0xfc00f800;
+ opcode = insn & E_OPCODE_MASK;
if (opcode == E_OR2I_INSN
|| opcode == E_AND2I_DOT_INSN
|| opcode == E_OR2IS_INSN
@@ -3926,10 +3926,22 @@ ppc_elf_vle_split16 (bfd *input_bfd,
input_bfd, input_section, offset, opcode);
}
}
- top5 = value & 0xf800;
- top5 = top5 << (split16_format == split16a_type ? 5 : 10);
- insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x3e007ff);
- insn |= top5;
+ if (split16_format == split16a_type)
+ {
+ insn &= ~((0xf800 << 5) | 0x7ff);
+ insn |= (value & 0xf800) << 5;
+ if ((insn & E_LI_MASK) == E_LI_INSN)
+ {
+ /* Hack for e_li. Extend sign. */
+ insn &= ~(0xf0000 >> 5);
+ insn |= (-(value & 0x8000) & 0xf0000) >> 5;
+ }
+ }
+ else
+ {
+ insn &= ~((0xf800 << 10) | 0x7ff);
+ insn |= (value & 0xf800) << 10;
+ }
insn |= value & 0x7ff;
bfd_put_32 (input_bfd, insn, loc);
}
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a4e0767..72ae3bc 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2018-12-06 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (md_assemble): Adjust relocs for VLE before
+ TLS tweaks. Handle e_li. Warn on unexpected operand field
+ for lo16/hi16/ha16 relocs.
+
2018-12-06 Andrew Burgess <andrew.burgess@embecosm.com>
* config/tc-riscv.h (FAKE_LABEL_NAME): Define as
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index a8eda5d..cebbd42 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -3433,39 +3433,6 @@ md_assemble (char *str)
if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
{
- /* Some TLS tweaks. */
- switch (reloc)
- {
- default:
- break;
-
- case BFD_RELOC_PPC_TLS:
- if (!_bfd_elf_ppc_at_tls_transform (opcode->opcode, 0))
- as_bad (_("@tls may not be used with \"%s\" operands"),
- opcode->name);
- else if (operand->shift != 11)
- as_bad (_("@tls may only be used in last operand"));
- else
- insn = ppc_insert_operand (insn, operand,
- ppc_obj64 ? 13 : 2,
- ppc_cpu, (char *) NULL, 0);
- break;
-
- /* We'll only use the 32 (or 64) bit form of these relocations
- in constants. Instructions get the 16 bit form. */
- case BFD_RELOC_PPC_DTPREL:
- reloc = BFD_RELOC_PPC_DTPREL16;
- break;
- case BFD_RELOC_PPC_TPREL:
- reloc = BFD_RELOC_PPC_TPREL16;
- break;
- }
-
- /* addpcis. */
- if (opcode->opcode == (19 << 26) + (2 << 1)
- && reloc == BFD_RELOC_HI16_S)
- reloc = BFD_RELOC_PPC_16DX_HA;
-
/* If VLE-mode convert LO/HI/HA relocations. */
if (opcode->flags & PPC_OPCODE_VLE)
{
@@ -3474,6 +3441,7 @@ md_assemble (char *str)
int use_a_reloc = (tmp_insn == E_OR2I_INSN
|| tmp_insn == E_AND2I_DOT_INSN
|| tmp_insn == E_OR2IS_INSN
+ || tmp_insn == E_LI_INSN
|| tmp_insn == E_LIS_INSN
|| tmp_insn == E_AND2IS_DOT_INSN);
@@ -3532,6 +3500,60 @@ md_assemble (char *str)
break;
}
}
+
+ /* TLS and other tweaks. */
+ switch (reloc)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_PPC_TLS:
+ if (!_bfd_elf_ppc_at_tls_transform (opcode->opcode, 0))
+ as_bad (_("@tls may not be used with \"%s\" operands"),
+ opcode->name);
+ else if (operand->shift != 11)
+ as_bad (_("@tls may only be used in last operand"));
+ else
+ insn = ppc_insert_operand (insn, operand,
+ ppc_obj64 ? 13 : 2,
+ ppc_cpu, (char *) NULL, 0);
+ break;
+
+ /* We'll only use the 32 (or 64) bit form of these relocations
+ in constants. Instructions get the 16 bit form. */
+ case BFD_RELOC_PPC_DTPREL:
+ reloc = BFD_RELOC_PPC_DTPREL16;
+ break;
+
+ case BFD_RELOC_PPC_TPREL:
+ reloc = BFD_RELOC_PPC_TPREL16;
+ break;
+
+ case BFD_RELOC_LO16:
+ if ((operand->bitm | 0xf) != 0xffff
+ || operand->shift != 0
+ || (operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ as_warn (_("%s unsupported on this instruction"), "@l");
+ break;
+
+ case BFD_RELOC_HI16:
+ if (operand->bitm != 0xffff
+ || operand->shift != 0
+ || (operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ as_warn (_("%s unsupported on this instruction"), "@h");
+ break;
+
+ case BFD_RELOC_HI16_S:
+ if (operand->bitm == 0xffff
+ && operand->shift == (int) PPC_OPSHIFT_INV
+ && opcode->opcode == (19 << 26) + (2 << 1))
+ /* addpcis. */
+ reloc = BFD_RELOC_PPC_16DX_HA;
+ else if (operand->bitm != 0xffff
+ || operand->shift != 0
+ || (operand->flags & PPC_OPERAND_NEGATIVE) != 0)
+ as_warn (_("%s unsupported on this instruction"), "@ha");
+ }
}
#endif /* OBJ_ELF */
diff --git a/include/ChangeLog b/include/ChangeLog
index b3fd56b..3b7c66d 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2018-12-06 Alan Modra <amodra@gmail.com>
+
+ * opcode/ppc.h (E_OPCODE_MASK, E_LI_MASK, E_LI_INSN): Define.
+
2018-12-06 Andrew Burgess <andrew.burgess@embecosm.com>
* dis-asm.h (riscv_symbol_is_valid): Declare.
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index 2b7f51e..c7262f1 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -476,6 +476,8 @@ ppc_optional_operand_value (const struct powerpc_operand *operand,
}
/* PowerPC VLE insns. */
+#define E_OPCODE_MASK 0xfc00f800
+
/* Form I16L, uses 16A relocs. */
#define E_OR2I_INSN 0x7000C000
#define E_AND2I_DOT_INSN 0x7000C800
@@ -492,6 +494,9 @@ ppc_optional_operand_value (const struct powerpc_operand *operand,
#define E_CMPH16I_INSN 0x7000B000
#define E_CMPHL16I_INSN 0x7000B800
+#define E_LI_INSN 0x70000000
+#define E_LI_MASK 0xfc008000
+
#ifdef __cplusplus
}
#endif