/* The maximum number of operands we need. */
#define ARM_IT_MAX_OPERANDS 6
+#define ARM_IT_MAX_RELOCS 3
struct arm_it
{
bfd_reloc_code_real_type type;
expressionS exp;
int pc_rel;
- } reloc;
+ } relocs[ARM_IT_MAX_RELOCS];
enum it_instruction_type it_insn_type;
}
else
{
- if (inst.reloc.type != 0)
+ if (inst.relocs[0].type != 0)
{
inst.error = _("expression too complex");
return FAIL;
}
- memcpy (&inst.reloc.exp, &exp, sizeof (expressionS));
- inst.reloc.type = BFD_RELOC_ARM_MULTI;
- inst.reloc.pc_rel = 0;
+ memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
+ inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
+ inst.relocs[0].pc_rel = 0;
}
}
{
imm1 = inst.operands[1].imm;
imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
- : inst.reloc.exp.X_unsigned ? 0
+ : inst.relocs[0].exp.X_unsigned ? 0
: ((bfd_int64_t) inst.operands[1].imm) >> 32);
if (target_big_endian)
{
{
if (nbytes == 4)
{
- if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
- && (inst.reloc.exp.X_op == O_constant)
+ if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
+ && (inst.relocs[0].exp.X_op == O_constant)
&& (pool->literals[entry].X_add_number
- == inst.reloc.exp.X_add_number)
+ == inst.relocs[0].exp.X_add_number)
&& (pool->literals[entry].X_md == nbytes)
&& (pool->literals[entry].X_unsigned
- == inst.reloc.exp.X_unsigned))
+ == inst.relocs[0].exp.X_unsigned))
break;
- if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
- && (inst.reloc.exp.X_op == O_symbol)
+ if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
+ && (inst.relocs[0].exp.X_op == O_symbol)
&& (pool->literals[entry].X_add_number
- == inst.reloc.exp.X_add_number)
+ == inst.relocs[0].exp.X_add_number)
&& (pool->literals[entry].X_add_symbol
- == inst.reloc.exp.X_add_symbol)
+ == inst.relocs[0].exp.X_add_symbol)
&& (pool->literals[entry].X_op_symbol
- == inst.reloc.exp.X_op_symbol)
+ == inst.relocs[0].exp.X_op_symbol)
&& (pool->literals[entry].X_md == nbytes))
break;
}
&& (pool->literals[entry].X_op == O_constant)
&& (pool->literals[entry].X_add_number == (offsetT) imm1)
&& (pool->literals[entry].X_unsigned
- == inst.reloc.exp.X_unsigned)
+ == inst.relocs[0].exp.X_unsigned)
&& (pool->literals[entry + 1].X_op == O_constant)
&& (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
&& (pool->literals[entry + 1].X_unsigned
- == inst.reloc.exp.X_unsigned))
+ == inst.relocs[0].exp.X_unsigned))
break;
padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
We also check to make sure the literal operand is a
constant number. */
- if (!(inst.reloc.exp.X_op == O_constant
- || inst.reloc.exp.X_op == O_big))
+ if (!(inst.relocs[0].exp.X_op == O_constant
+ || inst.relocs[0].exp.X_op == O_big))
{
inst.error = _("invalid type for literal pool");
return FAIL;
return FAIL;
}
- pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry] = inst.relocs[0].exp;
pool->literals[entry].X_op = O_constant;
pool->literals[entry].X_add_number = 0;
pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
return FAIL;
}
- pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry] = inst.relocs[0].exp;
pool->literals[entry].X_op = O_constant;
pool->literals[entry].X_add_number = imm1;
- pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+ pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
pool->literals[entry++].X_md = 4;
- pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry] = inst.relocs[0].exp;
pool->literals[entry].X_op = O_constant;
pool->literals[entry].X_add_number = imm2;
- pool->literals[entry].X_unsigned = inst.reloc.exp.X_unsigned;
+ pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
pool->literals[entry].X_md = 4;
pool->alignment = 3;
pool->next_free_entry += 1;
}
else
{
- pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry] = inst.relocs[0].exp;
pool->literals[entry].X_md = 4;
}
}
else if (padding_slot_p)
{
- pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry] = inst.relocs[0].exp;
pool->literals[entry].X_md = nbytes;
}
- inst.reloc.exp.X_op = O_symbol;
- inst.reloc.exp.X_add_number = pool_size;
- inst.reloc.exp.X_add_symbol = pool->symbol;
+ inst.relocs[0].exp.X_op = O_symbol;
+ inst.relocs[0].exp.X_add_number = pool_size;
+ inst.relocs[0].exp.X_add_symbol = pool->symbol;
return SUCCESS;
}
inst.operands[i].imm = reg;
inst.operands[i].immisreg = 1;
}
- else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+ else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
return FAIL;
}
inst.operands[i].shift_kind = shift;
inst.operands[i].isreg = 1;
/* parse_shift will override this if appropriate */
- inst.reloc.exp.X_op = O_constant;
- inst.reloc.exp.X_add_number = 0;
+ inst.relocs[0].exp.X_op = O_constant;
+ inst.relocs[0].exp.X_add_number = 0;
if (skip_past_comma (str) == FAIL)
return SUCCESS;
return parse_shift (str, i, NO_SHIFT_RESTRICT);
}
- if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
return FAIL;
if (skip_past_comma (str) == SUCCESS)
if (my_get_expression (&exp, str, GE_NO_PREFIX))
return FAIL;
- if (exp.X_op != O_constant || inst.reloc.exp.X_op != O_constant)
+ if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
{
inst.error = _("constant expression expected");
return FAIL;
inst.error = _("invalid rotation");
return FAIL;
}
- if (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 255)
+ if (inst.relocs[0].exp.X_add_number < 0
+ || inst.relocs[0].exp.X_add_number > 255)
{
inst.error = _("invalid constant");
return FAIL;
}
/* Encode as specified. */
- inst.operands[i].imm = inst.reloc.exp.X_add_number | value << 7;
+ inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
return SUCCESS;
}
- inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
- inst.reloc.pc_rel = 0;
+ inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.relocs[0].pc_rel = 0;
return SUCCESS;
}
/* We now have the group relocation table entry corresponding to
the name in the assembler source. Next, we parse the expression. */
- if (my_get_expression (&inst.reloc.exp, str, GE_NO_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
return PARSE_OPERAND_FAIL_NO_BACKTRACK;
/* Record the relocation type (always the ALU variant here). */
- inst.reloc.type = (bfd_reloc_code_real_type) entry->alu_code;
- gas_assert (inst.reloc.type != 0);
+ inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
+ gas_assert (inst.relocs[0].type != 0);
return PARSE_OPERAND_SUCCESS;
}
}
/* Parse all forms of an ARM address expression. Information is written
- to inst.operands[i] and/or inst.reloc.
+ to inst.operands[i] and/or inst.relocs[0].
Preindexed addressing (.preind=1):
- [Rn, #offset] .reg=Rn .reloc.exp=offset
+ [Rn, #offset] .reg=Rn .relocs[0].exp=offset
[Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
[Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
- .shift_kind=shift .reloc.exp=shift_imm
+ .shift_kind=shift .relocs[0].exp=shift_imm
These three may have a trailing ! which causes .writeback to be set also.
Postindexed addressing (.postind=1, .writeback=1):
- [Rn], #offset .reg=Rn .reloc.exp=offset
+ [Rn], #offset .reg=Rn .relocs[0].exp=offset
[Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
[Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
- .shift_kind=shift .reloc.exp=shift_imm
+ .shift_kind=shift .relocs[0].exp=shift_imm
Unindexed addressing (.preind=0, .postind=0):
Other:
[Rn]{!} shorthand for [Rn,#0]{!}
- =immediate .isreg=0 .reloc.exp=immediate
- label .reg=PC .reloc.pc_rel=1 .reloc.exp=label
+ =immediate .isreg=0 .relocs[0].exp=immediate
+ label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
It is the caller's responsibility to check for addressing modes not
- supported by the instruction, and to set inst.reloc.type. */
+ supported by the instruction, and to set inst.relocs[0].type. */
static parse_operand_result
parse_address_main (char **str, int i, int group_relocations,
if (skip_past_char (&p, '=') == FAIL)
{
/* Bare address - translate to PC-relative offset. */
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].pc_rel = 1;
inst.operands[i].reg = REG_PC;
inst.operands[i].isreg = 1;
inst.operands[i].preind = 1;
- if (my_get_expression (&inst.reloc.exp, &p, GE_OPT_PREFIX_BIG))
+ if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
return PARSE_OPERAND_FAIL;
}
- else if (parse_big_immediate (&p, i, &inst.reloc.exp,
+ else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
/*allow_symbol_p=*/TRUE))
return PARSE_OPERAND_FAIL;
/* We now have the group relocation table entry corresponding to
the name in the assembler source. Next, we parse the
expression. */
- if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
return PARSE_OPERAND_FAIL_NO_BACKTRACK;
/* Record the relocation type. */
switch (group_type)
{
case GROUP_LDR:
- inst.reloc.type = (bfd_reloc_code_real_type) entry->ldr_code;
+ inst.relocs[0].type
+ = (bfd_reloc_code_real_type) entry->ldr_code;
break;
case GROUP_LDRS:
- inst.reloc.type = (bfd_reloc_code_real_type) entry->ldrs_code;
+ inst.relocs[0].type
+ = (bfd_reloc_code_real_type) entry->ldrs_code;
break;
case GROUP_LDC:
- inst.reloc.type = (bfd_reloc_code_real_type) entry->ldc_code;
+ inst.relocs[0].type
+ = (bfd_reloc_code_real_type) entry->ldc_code;
break;
default:
gas_assert (0);
}
- if (inst.reloc.type == 0)
+ if (inst.relocs[0].type == 0)
{
inst.error = _("this group relocation is not allowed on this instruction");
return PARSE_OPERAND_FAIL_NO_BACKTRACK;
{
char *q = p;
- if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
return PARSE_OPERAND_FAIL;
/* If the offset is 0, find out if it's a +0 or -0. */
- if (inst.reloc.exp.X_op == O_constant
- && inst.reloc.exp.X_add_number == 0)
+ if (inst.relocs[0].exp.X_op == O_constant
+ && inst.relocs[0].exp.X_add_number == 0)
{
skip_whitespace (q);
if (*q == '#')
inst.operands[i].negative = 0;
p--;
}
- if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
return PARSE_OPERAND_FAIL;
/* If the offset is 0, find out if it's a +0 or -0. */
- if (inst.reloc.exp.X_op == O_constant
- && inst.reloc.exp.X_add_number == 0)
+ if (inst.relocs[0].exp.X_op == O_constant
+ && inst.relocs[0].exp.X_add_number == 0)
{
skip_whitespace (q);
if (*q == '#')
if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
{
inst.operands[i].preind = 1;
- inst.reloc.exp.X_op = O_constant;
- inst.reloc.exp.X_add_number = 0;
+ inst.relocs[0].exp.X_op = O_constant;
+ inst.relocs[0].exp.X_add_number = 0;
}
*str = p;
return PARSE_OPERAND_SUCCESS;
p = *str;
skip_past_char (&p, '#');
if (strncasecmp (p, ":lower16:", 9) == 0)
- inst.reloc.type = BFD_RELOC_ARM_MOVW;
+ inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
else if (strncasecmp (p, ":upper16:", 9) == 0)
- inst.reloc.type = BFD_RELOC_ARM_MOVT;
+ inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
- if (inst.reloc.type != BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type != BFD_RELOC_UNUSED)
{
p += 9;
skip_whitespace (p);
}
- if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+ if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
return FAIL;
- if (inst.reloc.type == BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type == BFD_RELOC_UNUSED)
{
- if (inst.reloc.exp.X_op != O_constant)
+ if (inst.relocs[0].exp.X_op != O_constant)
{
inst.error = _("constant expression expected");
return FAIL;
}
- if (inst.reloc.exp.X_add_number < 0
- || inst.reloc.exp.X_add_number > 0xffff)
+ if (inst.relocs[0].exp.X_add_number < 0
+ || inst.relocs[0].exp.X_add_number > 0xffff)
{
inst.error = _("immediate value out of range");
return FAIL;
{
if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
return FAIL;
- if (inst.reloc.exp.X_add_number != 1)
+ if (inst.relocs[0].exp.X_add_number != 1)
{
inst.error = _("invalid shift");
return FAIL;
OP_EXP, /* arbitrary expression */
OP_EXPi, /* same, with optional immediate prefix */
OP_EXPr, /* same, with optional relocation suffix */
+ OP_EXPs, /* same, with optional non-first operand relocation suffix */
OP_HALF, /* 0 .. 65535 or low/high reloc. */
OP_IROT1, /* VCADD rotate immediate: 90, 270. */
OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
/* Expressions */
case OP_EXPi: EXPi:
- po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+ po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
GE_OPT_PREFIX));
break;
case OP_EXP:
- po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+ po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
GE_NO_PREFIX));
break;
case OP_EXPr: EXPr:
- po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
+ po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
GE_NO_PREFIX));
- if (inst.reloc.exp.X_op == O_symbol)
+ if (inst.relocs[0].exp.X_op == O_symbol)
{
val = parse_reloc (&str);
if (val == -1)
}
break;
+ case OP_EXPs:
+ po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
+ GE_NO_PREFIX));
+ if (inst.relocs[i].exp.X_op == O_symbol)
+ {
+ inst.operands[i].hasreloc = 1;
+ }
+ else if (inst.relocs[i].exp.X_op == O_constant)
+ {
+ inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
+ inst.operands[i].hasreloc = 0;
+ }
+ break;
+
/* Operand for MOVW or MOVT. */
case OP_HALF:
po_misc_or_fail (parse_half (&str));
inst.instruction |= inst.operands[i].imm << 8;
}
else
- inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
}
}
else
{
inst.instruction |= INST_IMMEDIATE;
- if (inst.reloc.type != BFD_RELOC_ARM_IMMEDIATE)
+ if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
inst.instruction |= inst.operands[i].imm;
}
}
else
{
inst.instruction |= inst.operands[i].shift_kind << 5;
- inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
}
}
}
- else /* immediate offset in inst.reloc */
+ else /* immediate offset in inst.relocs[0] */
{
- if (is_pc && !inst.reloc.pc_rel)
+ if (is_pc && !inst.relocs[0].pc_rel)
{
const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
as_tsktsk (_("use of PC in this instruction is deprecated"));
}
- if (inst.reloc.type == BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type == BFD_RELOC_UNUSED)
{
/* Prefer + for zero encoded value. */
if (!inst.operands[i].negative)
inst.instruction |= INDEX_UP;
- inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
}
}
}
if (!inst.operands[i].negative)
inst.instruction |= INDEX_UP;
}
- else /* immediate offset in inst.reloc */
+ else /* immediate offset in inst.relocs[0] */
{
- constraint ((inst.operands[i].reg == REG_PC && !inst.reloc.pc_rel
+ constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
&& inst.operands[i].writeback),
BAD_PC_WRITEBACK);
inst.instruction |= HWOFFSET_IMM;
- if (inst.reloc.type == BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type == BFD_RELOC_UNUSED)
{
/* Prefer + for zero encoded value. */
if (!inst.operands[i].negative)
inst.instruction |= INDEX_UP;
- inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+ inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
}
}
}
static void do_vfp_nsyn_opcode (const char *);
-/* inst.reloc.exp describes an "=expr" load pseudo-operation.
+/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
Determine whether it can be performed with a move instruction; if
it can, convert inst.instruction to that move instruction and
return TRUE; if it can't, convert inst.instruction to a literal-pool
return TRUE;
}
- if (inst.reloc.exp.X_op != O_constant
- && inst.reloc.exp.X_op != O_symbol
- && inst.reloc.exp.X_op != O_big)
+ if (inst.relocs[0].exp.X_op != O_constant
+ && inst.relocs[0].exp.X_op != O_symbol
+ && inst.relocs[0].exp.X_op != O_big)
{
inst.error = _("constant expression expected");
return TRUE;
}
- if (inst.reloc.exp.X_op == O_constant
- || inst.reloc.exp.X_op == O_big)
+ if (inst.relocs[0].exp.X_op == O_constant
+ || inst.relocs[0].exp.X_op == O_big)
{
#if defined BFD_HOST_64_BIT
bfd_int64_t v;
#else
offsetT v;
#endif
- if (inst.reloc.exp.X_op == O_big)
+ if (inst.relocs[0].exp.X_op == O_big)
{
LITTLENUM_TYPE w[X_PRECISION];
LITTLENUM_TYPE * l;
- if (inst.reloc.exp.X_add_number == -1)
+ if (inst.relocs[0].exp.X_add_number == -1)
{
gen_to_words (w, X_PRECISION, E_PRECISION);
l = w;
#endif
}
else
- v = inst.reloc.exp.X_add_number;
+ v = inst.relocs[0].exp.X_add_number;
if (!inst.operands[i].issingle)
{
unsigned immlo = inst.operands[1].imm;
unsigned immhi = inst.operands[1].regisimm
? inst.operands[1].reg
- : inst.reloc.exp.X_unsigned
+ : inst.relocs[0].exp.X_unsigned
? 0
: ((bfd_int64_t)((int) immlo)) >> 32;
int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
inst.operands[1].reg = REG_PC;
inst.operands[1].isreg = 1;
inst.operands[1].preind = 1;
- inst.reloc.pc_rel = 1;
- inst.reloc.type = (thumb_p
+ inst.relocs[0].pc_rel = 1;
+ inst.relocs[0].type = (thumb_p
? BFD_RELOC_ARM_THUMB_OFFSET
: (mode_3
? BFD_RELOC_ARM_HWLITERAL
}
if (reloc_override)
- inst.reloc.type = (bfd_reloc_code_real_type) reloc_override;
- else if ((inst.reloc.type < BFD_RELOC_ARM_ALU_PC_G0_NC
- || inst.reloc.type > BFD_RELOC_ARM_LDC_SB_G2)
- && inst.reloc.type != BFD_RELOC_ARM_LDR_PC_G0)
+ inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
+ else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
+ || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
+ && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
{
if (thumb_mode)
- inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
else
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
}
/* Prefer + for zero encoded value. */
do_rm_rd_rn (void)
{
constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
- constraint (((inst.reloc.exp.X_op != O_constant
- && inst.reloc.exp.X_op != O_illegal)
- || inst.reloc.exp.X_add_number != 0),
+ constraint (((inst.relocs[0].exp.X_op != O_constant
+ && inst.relocs[0].exp.X_op != O_illegal)
+ || inst.relocs[0].exp.X_add_number != 0),
BAD_ADDR_MODE);
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 12;
/* Frag hacking will turn this into a sub instruction if the offset turns
out to be negative. */
- inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
- inst.reloc.pc_rel = 1;
- inst.reloc.exp.X_add_number -= 8;
+ inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.relocs[0].pc_rel = 1;
+ inst.relocs[0].exp.X_add_number -= 8;
if (support_interwork
- && inst.reloc.exp.X_op == O_symbol
- && inst.reloc.exp.X_add_symbol != NULL
- && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
- && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
- inst.reloc.exp.X_add_number |= 1;
+ && inst.relocs[0].exp.X_op == O_symbol
+ && inst.relocs[0].exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+ inst.relocs[0].exp.X_add_number |= 1;
}
/* This is a pseudo-op of the form "adrl rd, label" to be converted
/* Frag hacking will turn this into a sub instruction if the offset turns
out to be negative. */
- inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
+ inst.relocs[0].pc_rel = 1;
inst.size = INSN_SIZE * 2;
- inst.reloc.exp.X_add_number -= 8;
+ inst.relocs[0].exp.X_add_number -= 8;
if (support_interwork
- && inst.reloc.exp.X_op == O_symbol
- && inst.reloc.exp.X_add_symbol != NULL
- && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
- && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
- inst.reloc.exp.X_add_number |= 1;
+ && inst.relocs[0].exp.X_op == O_symbol
+ && inst.relocs[0].exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+ inst.relocs[0].exp.X_add_number |= 1;
}
static void
do_arit (void)
{
- constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+ constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+ && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
THUMB1_RELOC_ONLY);
if (!inst.operands[1].present)
inst.operands[1].reg = inst.operands[0].reg;
constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
&& inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
_("the only valid suffixes here are '(plt)' and '(tlscall)'"));
- inst.reloc.type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
+ inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
? BFD_RELOC_ARM_PLT32
: thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
}
else
- inst.reloc.type = (bfd_reloc_code_real_type) default_reloc;
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
+ inst.relocs[0].pc_rel = 1;
}
static void
want_reloc = FALSE;
if (want_reloc)
- inst.reloc.type = BFD_RELOC_ARM_V4BX;
+ inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
}
|| (inst.operands[1].reg == REG_PC),
BAD_ADDR_MODE);
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
_("offset must be zero in ARM encoding"));
constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg << 16;
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
}
static 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)),
+ && (inst.relocs[0].exp.X_add_number & 0x3)),
_("ldr to register 15 must be 4-byte aligned"));
}
reject [Rn,...]. */
if (inst.operands[1].preind)
{
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
_("this instruction requires a post-indexed address"));
inst.operands[1].preind = 0;
reject [Rn,...]. */
if (inst.operands[1].preind)
{
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
_("this instruction requires a post-indexed address"));
inst.operands[1].preind = 0;
static void
do_mov (void)
{
- constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+ constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+ && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
THUMB1_RELOC_ONLY);
inst.instruction |= inst.operands[0].reg << 12;
encode_arm_shifter_operand (1);
bfd_boolean top;
top = (inst.instruction & 0x00400000) != 0;
- constraint (top && inst.reloc.type == BFD_RELOC_ARM_MOVW,
+ constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
_(":lower16: not allowed in this instruction"));
- constraint (!top && inst.reloc.type == BFD_RELOC_ARM_MOVT,
+ constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
_(":upper16: not allowed in this instruction"));
inst.instruction |= inst.operands[0].reg << 12;
- if (inst.reloc.type == BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type == BFD_RELOC_UNUSED)
{
- imm = inst.reloc.exp.X_add_number;
+ imm = inst.relocs[0].exp.X_add_number;
/* The value is in two pieces: 0:11, 16:19. */
inst.instruction |= (imm & 0x00000fff);
inst.instruction |= (imm & 0x0000f000) << 4;
else
{
inst.instruction |= INST_IMMEDIATE;
- inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
- inst.reloc.pc_rel = 0;
+ inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
+ inst.relocs[0].pc_rel = 0;
}
}
_("extraneous shift as part of operand to shift insn"));
}
else
- inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
}
static void
do_smc (void)
{
- inst.reloc.type = BFD_RELOC_ARM_SMC;
- inst.reloc.pc_rel = 0;
+ inst.relocs[0].type = BFD_RELOC_ARM_SMC;
+ inst.relocs[0].pc_rel = 0;
}
static void
do_hvc (void)
{
- inst.reloc.type = BFD_RELOC_ARM_HVC;
- inst.reloc.pc_rel = 0;
+ inst.relocs[0].type = BFD_RELOC_ARM_HVC;
+ inst.relocs[0].pc_rel = 0;
}
static void
do_swi (void)
{
- inst.reloc.type = BFD_RELOC_ARM_SWI;
- inst.reloc.pc_rel = 0;
+ inst.relocs[0].type = BFD_RELOC_ARM_SWI;
+ inst.relocs[0].pc_rel = 0;
}
static void
constraint (inst.operands[0].reg == inst.operands[1].reg
|| inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
_("offset must be zero in ARM encoding"));
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg;
inst.instruction |= inst.operands[2].reg << 16;
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
}
static void
[Rn]{!}. The instruction does not really support stacking or
unstacking, so we have to emulate these by setting appropriate
bits and offsets. */
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
_("this instruction does not support indexing"));
if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
- inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
+ inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
if (!(inst.instruction & INDEX_UP))
- inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
+ inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
{
if (inst.operands[1].writeback)
inst.instruction |= WRITE_BACK;
inst.instruction |= inst.operands[1].reg << 16;
- inst.instruction |= inst.reloc.exp.X_add_number << 4;
+ inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
inst.instruction |= inst.operands[1].imm;
}
else
static void
encode_thumb32_shifted_operand (int i)
{
- unsigned int value = inst.reloc.exp.X_add_number;
+ unsigned int value = inst.relocs[0].exp.X_add_number;
unsigned int shift = inst.operands[i].shift_kind;
constraint (inst.operands[i].immisreg,
inst.instruction |= SHIFT_ROR << 4;
else
{
- constraint (inst.reloc.exp.X_op != O_constant,
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
constraint (value > 32
inst.instruction |= inst.operands[i].imm;
if (inst.operands[i].shifted)
{
- constraint (inst.reloc.exp.X_op != O_constant,
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
- constraint (inst.reloc.exp.X_add_number < 0
- || inst.reloc.exp.X_add_number > 3,
+ constraint (inst.relocs[0].exp.X_add_number < 0
+ || inst.relocs[0].exp.X_add_number > 3,
_("shift out of range"));
- inst.instruction |= inst.reloc.exp.X_add_number << 4;
+ inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
}
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
}
else if (inst.operands[i].preind)
{
if (inst.operands[i].writeback)
inst.instruction |= 0x00000100;
}
- inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
}
else if (inst.operands[i].postind)
{
inst.instruction |= 0x00200000;
else
inst.instruction |= 0x00000900;
- inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
}
else /* unindexed - only for coprocessor */
inst.error = _("instruction does not accept unindexed addressing");
reject_bad_reg (Rd);
inst.instruction |= (Rn << 16) | (Rd << 8);
- inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
}
/* Parse an add or subtract instruction. We get here with inst.instruction
{
inst.instruction = THUMB_OP16(opcode);
inst.instruction |= (Rd << 4) | Rs;
- if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+ if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+ || (inst.relocs[0].type
+ > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
{
if (inst.size_req == 2)
- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
else
inst.relax = opcode;
}
if (inst.size_req == 4
|| (inst.size_req != 2 && !opcode))
{
- constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+ constraint ((inst.relocs[0].type
+ >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
+ && (inst.relocs[0].type
+ <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
THUMB1_RELOC_ONLY);
if (Rd == REG_PC)
{
constraint (add, BAD_PC);
constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
_("only SUBS PC, LR, #const allowed"));
- constraint (inst.reloc.exp.X_op != O_constant,
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
- constraint (inst.reloc.exp.X_add_number < 0
- || inst.reloc.exp.X_add_number > 0xff,
+ constraint (inst.relocs[0].exp.X_add_number < 0
+ || inst.relocs[0].exp.X_add_number > 0xff,
_("immediate value out of range"));
inst.instruction = T2_SUBS_PC_LR
- | inst.reloc.exp.X_add_number;
- inst.reloc.type = BFD_RELOC_UNUSED;
+ | inst.relocs[0].exp.X_add_number;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
return;
}
else if (Rs == REG_PC)
{
/* Always use addw/subw. */
inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
}
else
{
inst.instruction = (inst.instruction & 0xe1ffffff)
| 0x10000000;
if (flags)
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
else
- inst.reloc.type = BFD_RELOC_ARM_T32_ADD_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
}
inst.instruction |= Rd << 8;
inst.instruction |= Rs << 16;
}
else
{
- unsigned int value = inst.reloc.exp.X_add_number;
+ unsigned int value = inst.relocs[0].exp.X_add_number;
unsigned int shift = inst.operands[2].shift_kind;
Rn = inst.operands[2].reg;
inst.instruction = (inst.instruction == T_MNEM_add
? 0x0000 : 0x8000);
inst.instruction |= (Rd << 4) | Rs;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
return;
}
/* Generate a 32-bit opcode. */
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction |= Rd << 8;
- inst.reloc.type = BFD_RELOC_ARM_T32_ADD_PC12;
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
+ inst.relocs[0].pc_rel = 1;
}
else
{
/* Generate a 16-bit opcode. */
inst.instruction = THUMB_OP16 (inst.instruction);
- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
- inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
+ inst.relocs[0].pc_rel = 1;
inst.instruction |= Rd << 4;
}
- if (inst.reloc.exp.X_op == O_symbol
- && inst.reloc.exp.X_add_symbol != NULL
- && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
- && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
- inst.reloc.exp.X_add_number += 1;
+ if (inst.relocs[0].exp.X_op == O_symbol
+ && inst.relocs[0].exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+ inst.relocs[0].exp.X_add_number += 1;
}
/* Arithmetic instructions for which there is just one 16-bit
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
inst.instruction |= Rd << 8;
inst.instruction |= Rs << 16;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
else
{
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
inst.instruction |= Rd << 8;
inst.instruction |= Rs << 16;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
else
{
&& (inst.size_req == 4
|| (inst.size_req != 2
&& (inst.operands[0].hasreloc
- || inst.reloc.exp.X_op == O_constant))))
+ || inst.relocs[0].exp.X_op == O_constant))))
{
inst.instruction = THUMB_OP32(opcode);
if (cond == COND_ALWAYS)
if (unified_syntax && inst.size_req != 2)
inst.relax = opcode;
}
- inst.reloc.type = reloc;
- inst.reloc.pc_rel = 1;
+ inst.relocs[0].type = reloc;
+ inst.relocs[0].pc_rel = 1;
}
/* Actually do the work for Thumb state bkpt and hlt. The only difference
the branch encoding is now needed to deal with TLSCALL relocs.
So if we see a PLT reloc now, put it back to how it used to be to
keep the preexisting behaviour. */
- if (inst.reloc.type == BFD_RELOC_ARM_PLT32)
- inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
+ if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
+ inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
#if defined(OBJ_COFF)
/* If the destination of the branch is a defined symbol which does not have
the THUMB_FUNC attribute, then we must be calling a function which has
the (interfacearm) attribute. We look for the Thumb entry point to that
function and change the branch to refer to that function instead. */
- if ( inst.reloc.exp.X_op == O_symbol
- && inst.reloc.exp.X_add_symbol != NULL
- && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
- && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
- inst.reloc.exp.X_add_symbol =
- find_real_start (inst.reloc.exp.X_add_symbol);
+ if ( inst.relocs[0].exp.X_op == O_symbol
+ && inst.relocs[0].exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
+ && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
+ inst.relocs[0].exp.X_add_symbol
+ = find_real_start (inst.relocs[0].exp.X_add_symbol);
#endif
}
set_it_insn_type (OUTSIDE_IT_INSN);
constraint (inst.operands[0].reg > 7, BAD_HIREG);
inst.instruction |= inst.operands[0].reg;
- inst.reloc.pc_rel = 1;
- inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH7;
+ inst.relocs[0].pc_rel = 1;
+ inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
}
static void
do_t_ldmstm (void)
{
/* This really doesn't seem worth it. */
- constraint (inst.reloc.type != BFD_RELOC_UNUSED,
+ constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
_("expression too complex"));
constraint (inst.operands[1].writeback,
_("Thumb load/store multiple does not support {reglist}^"));
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg << 16;
- inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
}
static void
{
if (Rn == REG_PC)
{
- if (inst.reloc.pc_rel)
+ if (inst.relocs[0].pc_rel)
opcode = T_MNEM_ldr_pc2;
else
opcode = T_MNEM_ldr_pc;
}
inst.instruction |= THUMB_OP16 (opcode);
if (inst.size_req == 2)
- inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
else
inst.relax = opcode;
return;
inst.instruction = T_OPCODE_STR_SP;
inst.instruction |= inst.operands[0].reg << 8;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
return;
}
/* Immediate offset. */
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 3;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
return;
}
{
inst.instruction = THUMB_OP16 (opcode);
inst.instruction |= Rn << 8;
- if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+ if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+ || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
{
if (inst.size_req == 2)
- inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
else
inst.relax = opcode;
}
}
else
{
- constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
- && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+ constraint ((inst.relocs[0].type
+ >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
+ && (inst.relocs[0].type
+ <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
THUMB1_RELOC_ONLY);
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
inst.instruction |= Rn << r0off;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
}
else if (inst.operands[1].shifted && inst.operands[1].immisreg
{
inst.instruction |= Rn;
inst.instruction |= Rm << 3;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
}
else
{
constraint (Rn > 7,
_("only lo regs allowed with immediate"));
inst.instruction |= Rn << 8;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
}
}
bfd_boolean top;
top = (inst.instruction & 0x00800000) != 0;
- if (inst.reloc.type == BFD_RELOC_ARM_MOVW)
+ if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
{
constraint (top, _(":lower16: not allowed in this instruction"));
- inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVW;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
}
- else if (inst.reloc.type == BFD_RELOC_ARM_MOVT)
+ else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
{
constraint (!top, _(":upper16: not allowed in this instruction"));
- inst.reloc.type = BFD_RELOC_ARM_THUMB_MOVT;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
}
Rd = inst.operands[0].reg;
reject_bad_reg (Rd);
inst.instruction |= Rd << 8;
- if (inst.reloc.type == BFD_RELOC_UNUSED)
+ if (inst.relocs[0].type == BFD_RELOC_UNUSED)
{
- imm = inst.reloc.exp.X_add_number;
+ imm = inst.relocs[0].exp.X_add_number;
inst.instruction |= (imm & 0xf000) << 4;
inst.instruction |= (imm & 0x0800) << 15;
inst.instruction |= (imm & 0x0700) << 4;
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
inst.instruction |= Rn << r0off;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
else
{
if (!inst.operands[2].isreg)
{
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
else
{
inst.instruction |= Rm;
if (inst.operands[3].present)
{
- unsigned int val = inst.reloc.exp.X_add_number;
- constraint (inst.reloc.exp.X_op != O_constant,
+ unsigned int val = inst.relocs[0].exp.X_add_number;
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
inst.instruction |= (val & 0x1c) << 10;
inst.instruction |= (val & 0x03) << 6;
constraint (inst.operands[0].writeback,
_("push/pop do not support {reglist}^"));
- constraint (inst.reloc.type != BFD_RELOC_UNUSED,
+ constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
_("expression too complex"));
mask = inst.operands[0].imm;
if (inst.size_req == 4 || !unified_syntax)
narrow = FALSE;
- if (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0)
+ if (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0)
narrow = FALSE;
/* Turn rsb #0 into 16-bit neg. We should probably do this via
relaxation, but it doesn't seem worth the hassle. */
if (narrow)
{
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
inst.instruction = THUMB_OP16 (T_MNEM_negs);
inst.instruction |= Rs << 3;
inst.instruction |= Rd;
else
{
inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
- inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
}
}
else
inst.instruction |= inst.operands[0].reg << 8;
encode_thumb32_shifted_operand (1);
/* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
}
}
else
case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
default: abort ();
}
- inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 3;
}
case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
default: abort ();
}
- inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 3;
}
static void
do_t_smc (void)
{
- unsigned int value = inst.reloc.exp.X_add_number;
+ unsigned int value = inst.relocs[0].exp.X_add_number;
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
_("SMC is not permitted on this architecture"));
- constraint (inst.reloc.exp.X_op != O_constant,
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
inst.instruction |= (value & 0xf000) >> 12;
inst.instruction |= (value & 0x0ff0);
inst.instruction |= (value & 0x000f) << 16;
static void
do_t_hvc (void)
{
- unsigned int value = inst.reloc.exp.X_add_number;
+ unsigned int value = inst.relocs[0].exp.X_add_number;
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
inst.instruction |= (value & 0x0fff);
inst.instruction |= (value & 0xf000) << 4;
}
if (inst.operands[3].present)
{
- offsetT shift_amount = inst.reloc.exp.X_add_number;
+ offsetT shift_amount = inst.relocs[0].exp.X_add_number;
- inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.relocs[0].type = BFD_RELOC_UNUSED;
- constraint (inst.reloc.exp.X_op != O_constant,
+ constraint (inst.relocs[0].exp.X_op != O_constant,
_("expression too complex"));
if (shift_amount != 0)
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].reg << 12;
inst.instruction |= inst.operands[2].reg << 16;
- inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
+ inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
}
static void
static void
do_t_swi (void)
{
- inst.reloc.type = BFD_RELOC_ARM_SWI;
+ inst.relocs[0].type = BFD_RELOC_ARM_SWI;
}
static void
else
{
constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
- constraint (inst.reloc.exp.X_op != O_constant
- || inst.reloc.exp.X_add_number != 0,
+ constraint (inst.relocs[0].exp.X_op != O_constant
+ || inst.relocs[0].exp.X_add_number != 0,
BAD_ADDR_MODE);
if (inst.operands[1].writeback)
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
_(BAD_FPU));
- constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
- unsigned rot = inst.reloc.exp.X_add_number;
+ constraint (inst.relocs[0].exp.X_op != O_constant,
+ _("expression too complex"));
+ unsigned rot = inst.relocs[0].exp.X_add_number;
constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
_("immediate out of range"));
rot /= 90;
{
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
_(BAD_FPU));
- constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex"));
- unsigned rot = inst.reloc.exp.X_add_number;
+ constraint (inst.relocs[0].exp.X_op != O_constant,
+ _("expression too complex"));
+ unsigned rot = inst.relocs[0].exp.X_add_number;
constraint (rot != 90 && rot != 270, _("immediate out of range"));
enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
start of the instruction. */
dwarf2_emit_insn (0);
- switch (inst.reloc.exp.X_op)
+ switch (inst.relocs[0].exp.X_op)
{
case O_symbol:
- sym = inst.reloc.exp.X_add_symbol;
- offset = inst.reloc.exp.X_add_number;
+ sym = inst.relocs[0].exp.X_add_symbol;
+ offset = inst.relocs[0].exp.X_add_number;
break;
case O_constant:
sym = NULL;
- offset = inst.reloc.exp.X_add_number;
+ offset = inst.relocs[0].exp.X_add_number;
break;
default:
- sym = make_expr_symbol (&inst.reloc.exp);
+ sym = make_expr_symbol (&inst.relocs[0].exp);
offset = 0;
break;
}
else
md_number_to_chars (to, inst.instruction, inst.size);
- if (inst.reloc.type != BFD_RELOC_UNUSED)
- fix_new_arm (frag_now, to - frag_now->fr_literal,
- inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
- inst.reloc.type);
+ int r;
+ for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
+ {
+ if (inst.relocs[r].type != BFD_RELOC_UNUSED)
+ fix_new_arm (frag_now, to - frag_now->fr_literal,
+ inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
+ inst.relocs[r].type);
+ }
dwarf2_emit_insn (inst.size);
}
}
memset (&inst, '\0', sizeof (inst));
- inst.reloc.type = BFD_RELOC_UNUSED;
+ int r;
+ for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
+ inst.relocs[r].type = BFD_RELOC_UNUSED;
opcode = opcode_lookup (&p);
if (!opcode)