Line 30... |
Line 30... |
#include <stdarg.h>
|
#include <stdarg.h>
|
#define NO_RELOC 0
|
#define NO_RELOC 0
|
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
#include "subsegs.h"
|
#include "subsegs.h"
|
#include "obstack.h"
|
#include "obstack.h"
|
|
#include "libiberty.h"
|
#include "opcode/arm.h"
|
#include "opcode/arm.h"
|
|
|
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
#include "elf/arm.h"
|
#include "elf/arm.h"
|
#include "dw2gencfi.h"
|
#include "dw2gencfi.h"
|
Line 2052... |
Line 2052... |
/* Parse an explicit relocation suffix on an expression. This is
|
/* Parse an explicit relocation suffix on an expression. This is
|
either nothing, or a word in parentheses. Note that if !OBJ_ELF,
|
either nothing, or a word in parentheses. Note that if !OBJ_ELF,
|
arm_reloc_hsh contains no entries, so this function can only
|
arm_reloc_hsh contains no entries, so this function can only
|
succeed if there is no () after the word. Returns -1 on error,
|
succeed if there is no () after the word. Returns -1 on error,
|
BFD_RELOC_UNUSED if there wasn't any suffix. */
|
BFD_RELOC_UNUSED if there wasn't any suffix. */
|
|
|
static int
|
static int
|
parse_reloc (char **str)
|
parse_reloc (char **str)
|
{
|
{
|
struct reloc_entry *r;
|
struct reloc_entry *r;
|
char *p, *q;
|
char *p, *q;
|
Line 4882... |
Line 4883... |
{
|
{
|
inst.error = _("invalid constant");
|
inst.error = _("invalid constant");
|
return FAIL;
|
return FAIL;
|
}
|
}
|
|
|
/* Convert to decoded value. md_apply_fix will put it back. */
|
/* Encode as specified. */
|
inst.reloc.exp.X_add_number
|
inst.operands[i].imm = inst.reloc.exp.X_add_number | value << 7;
|
= (((inst.reloc.exp.X_add_number << (32 - value))
|
return SUCCESS;
|
| (inst.reloc.exp.X_add_number >> value)) & 0xffffffff);
|
|
}
|
}
|
|
|
inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
|
inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
|
inst.reloc.pc_rel = 0;
|
inst.reloc.pc_rel = 0;
|
return SUCCESS;
|
return SUCCESS;
|
Line 7016... |
Line 7016... |
{
|
{
|
inst.instruction |= inst.operands[i].reg;
|
inst.instruction |= inst.operands[i].reg;
|
encode_arm_shift (i);
|
encode_arm_shift (i);
|
}
|
}
|
else
|
else
|
|
{
|
inst.instruction |= INST_IMMEDIATE;
|
inst.instruction |= INST_IMMEDIATE;
|
|
if (inst.reloc.type != BFD_RELOC_ARM_IMMEDIATE)
|
|
inst.instruction |= inst.operands[i].imm;
|
|
}
|
}
|
}
|
|
|
/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
|
/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
|
static void
|
static void
|
encode_arm_addr_mode_common (int i, bfd_boolean is_t)
|
encode_arm_addr_mode_common (int i, bfd_boolean is_t)
|
Line 7913... |
Line 7917... |
|
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[2].reg << 16;
|
inst.instruction |= inst.operands[2].reg << 16;
|
}
|
}
|
|
|
|
/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
|
|
which is not a multiple of four is UNPREDICTABLE. */
|
|
static void
|
|
check_ldr_r15_aligned (void)
|
|
{
|
|
constraint (!(inst.operands[1].immisreg)
|
|
&& (inst.operands[0].reg == REG_PC
|
|
&& inst.operands[1].reg == REG_PC
|
|
&& (inst.reloc.exp.X_add_number & 0x3)),
|
|
_("ldr to register 15 must be 4-byte alligned"));
|
|
}
|
|
|
static void
|
static void
|
do_ldst (void)
|
do_ldst (void)
|
{
|
{
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[0].reg << 12;
|
if (!inst.operands[1].isreg)
|
if (!inst.operands[1].isreg)
|
if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/FALSE))
|
if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/FALSE))
|
return;
|
return;
|
encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
|
encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
|
|
check_ldr_r15_aligned ();
|
}
|
}
|
|
|
static void
|
static void
|
do_ldstt (void)
|
do_ldstt (void)
|
{
|
{
|
Line 10531... |
Line 10548... |
"if executed on M-profile cores "
|
"if executed on M-profile cores "
|
"with interrupts enabled."));
|
"with interrupts enabled."));
|
}
|
}
|
|
|
/* Do some validations regarding addressing modes. */
|
/* Do some validations regarding addressing modes. */
|
if (inst.operands[1].immisreg && opcode != T_MNEM_ldr
|
if (inst.operands[1].immisreg)
|
&& opcode != T_MNEM_str)
|
|
reject_bad_reg (inst.operands[1].imm);
|
reject_bad_reg (inst.operands[1].imm);
|
|
|
|
constraint (inst.operands[1].writeback == 1
|
|
&& inst.operands[0].reg == inst.operands[1].reg,
|
|
BAD_OVERLAP);
|
|
|
inst.instruction = THUMB_OP32 (opcode);
|
inst.instruction = THUMB_OP32 (opcode);
|
inst.instruction |= inst.operands[0].reg << 12;
|
inst.instruction |= inst.operands[0].reg << 12;
|
encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
|
encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
|
|
check_ldr_r15_aligned ();
|
return;
|
return;
|
}
|
}
|
|
|
constraint (inst.operands[0].reg > 7, BAD_HIREG);
|
constraint (inst.operands[0].reg > 7, BAD_HIREG);
|
|
|
Line 22398... |
Line 22419... |
i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
|
i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
|
i++)
|
i++)
|
hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
|
hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
|
(void *) (barrier_opt_names + i));
|
(void *) (barrier_opt_names + i));
|
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
for (i = 0; i < sizeof (reloc_names) / sizeof (struct reloc_entry); i++)
|
for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
|
hash_insert (arm_reloc_hsh, reloc_names[i].name, (void *) (reloc_names + i));
|
{
|
|
struct reloc_entry * entry = reloc_names + i;
|
|
|
|
if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
|
|
/* This makes encode_branch() use the EABI versions of this relocation. */
|
|
entry->reloc = BFD_RELOC_UNUSED;
|
|
|
|
hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
|
|
}
|
#endif
|
#endif
|
|
|
set_constant_flonums ();
|
set_constant_flonums ();
|
|
|
/* Set the cpu variant based on the command-line options. We prefer
|
/* Set the cpu variant based on the command-line options. We prefer
|
Line 22931... |
Line 22960... |
{"arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL},
|
{"arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL},
|
{"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL},
|
{"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL},
|
{"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL},
|
{"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL},
|
{"cortex-a5", ARM_ARCH_V7A_MP_SEC,
|
{"cortex-a5", ARM_ARCH_V7A_MP_SEC,
|
FPU_NONE, "Cortex-A5"},
|
FPU_NONE, "Cortex-A5"},
|
|
{"cortex-a7", ARM_ARCH_V7A_IDIV_MP_SEC_VIRT,
|
|
FPU_ARCH_NEON_VFP_V4,
|
|
"Cortex-A7"},
|
{"cortex-a8", ARM_ARCH_V7A_SEC,
|
{"cortex-a8", ARM_ARCH_V7A_SEC,
|
ARM_FEATURE (0, FPU_VFP_V3
|
ARM_FEATURE (0, FPU_VFP_V3
|
| FPU_NEON_EXT_V1),
|
| FPU_NEON_EXT_V1),
|
"Cortex-A8"},
|
"Cortex-A8"},
|
{"cortex-a9", ARM_ARCH_V7A_MP_SEC,
|
{"cortex-a9", ARM_ARCH_V7A_MP_SEC,
|