This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (44/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 02:55:31 -0700
- Subject: Thumb32 assembler (44/69)
Refactor the parsing of coprocessor addresses a little, and remove
more code redundant with md_apply_fix3.
zw
* config/tc-arm.c (CP_WB_OK, CP_NO_WB, cp_byte_address_offset)
(cp_byte_address_required_here): Delete.
(cp_address_offset): Defer processing of immediates to md_apply_fix3.
Add 'reloc' operand for specification of relocation type.
(cp_address_required_here): Add 'reloc' operand for specification of
relocation type.
(do_lstc, do_vfp_sp_ldst, do_vfp_dp_ldst, do_fpa_ldst, do_fpa_ldmstm)
(do_iwmmxt_wldstw, do_mav_ldst): Pass BFD_RELOC_ARM_CP_OFF_IMM to
cp_address_required_here.
(do_iwmmxt_wldst): Use cp_address_required_here with
BFD_RELOC_ARM_CP_OFF_IMM_S2.
(md_apply_fix3 <BFD_RELOC_ARM_CP_OFF_IMM,BFD_RELOC_ARM_CP_OFF_IMM_S2>):
Improve diagnostics.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 46)
+++ gas/config/tc-arm.c (revision 47)
@@ -280,10 +280,6 @@
#define FAIL (-1)
#define SUCCESS (0)
-/* Whether a Co-processor load/store operation accepts write-back forms. */
-#define CP_WB_OK 1
-#define CP_NO_WB 0
-
#define SUFF_S 1
#define SUFF_D 2
#define SUFF_E 3
@@ -2113,52 +2109,24 @@
}
static int
-cp_address_offset (char ** str)
+cp_address_offset (char ** str, int reloc)
{
- int offset;
-
if (! is_immediate_prefix (**str))
{
inst.error = _("immediate expression expected");
return FAIL;
}
-
(*str)++;
-
if (my_get_expression (& inst.reloc.exp, str))
return FAIL;
- if (inst.reloc.exp.X_op == O_constant)
- {
- offset = inst.reloc.exp.X_add_number;
+ inst.reloc.type = reloc;
- if (offset & 3)
- {
- inst.error = _("co-processor address must be word aligned");
- return FAIL;
- }
-
- if (offset > 1023 || offset < -1023)
- {
- inst.error = _("offset too large");
- return FAIL;
- }
-
- if (offset >= 0)
- inst.instruction |= INDEX_UP;
- else
- offset = -offset;
-
- inst.instruction |= offset >> 2;
- }
- else
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
-
return SUCCESS;
}
static int
-cp_address_required_here (char ** str, int wb_ok)
+cp_address_required_here (char ** str, int wb_ok, int reloc)
{
char * p = * str;
int pre_inc = 0;
@@ -2207,7 +2175,7 @@
return FAIL;
}
- if (cp_address_offset (& p) == FAIL)
+ if (cp_address_offset (&p, reloc) == FAIL)
return FAIL;
}
else
@@ -2252,7 +2220,7 @@
pre_inc = PRE_INDEX;
- if (cp_address_offset (& p) == FAIL)
+ if (cp_address_offset (&p, reloc) == FAIL)
return FAIL;
if (*p++ != ']')
@@ -2279,7 +2247,7 @@
if (my_get_expression (&inst.reloc.exp, &p))
return FAIL;
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+ inst.reloc.type = reloc;
inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
inst.reloc.pc_rel = 1;
inst.instruction |= (REG_PC << 16);
@@ -2291,133 +2259,6 @@
return SUCCESS;
}
-static int
-cp_byte_address_offset (char ** str)
-{
- int offset;
-
- if (! is_immediate_prefix (**str))
- {
- inst.error = _("immediate expression expected");
- return FAIL;
- }
-
- (*str)++;
-
- if (my_get_expression (& inst.reloc.exp, str))
- return FAIL;
-
- if (inst.reloc.exp.X_op == O_constant)
- {
- offset = inst.reloc.exp.X_add_number;
-
- if (offset > 255 || offset < -255)
- {
- inst.error = _("offset too large");
- return FAIL;
- }
-
- if (offset >= 0)
- inst.instruction |= INDEX_UP;
- else
- offset = -offset;
-
- inst.instruction |= offset;
- }
- else
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
-
- return SUCCESS;
-}
-
-static int
-cp_byte_address_required_here (char ** str)
-{
- char * p = * str;
- int pre_inc = 0;
- int write_back = 0;
-
- if (*p == '[')
- {
- int reg;
-
- p++;
-
- if ((reg = reg_required_here (&p, 16, REG_TYPE_RN)) == FAIL)
- return FAIL;
-
- if (*p == ']')
- {
- p++;
-
- if (skip_past_comma (& p) == SUCCESS)
- {
- /* [Rn], #expr */
- write_back = WRITE_BACK;
-
- if (reg == REG_PC)
- {
- inst.error = _("pc may not be used in post-increment");
- return FAIL;
- }
-
- if (cp_byte_address_offset (& p) == FAIL)
- return FAIL;
- }
- else
- pre_inc = PRE_INDEX | INDEX_UP;
- }
- else
- {
- /* '['Rn, #expr']'[!] */
-
- if (skip_past_comma (& p) == FAIL)
- {
- inst.error = _("pre-indexed expression expected");
- return FAIL;
- }
-
- pre_inc = PRE_INDEX;
-
- if (cp_byte_address_offset (& p) == FAIL)
- return FAIL;
-
- if (*p++ != ']')
- {
- inst.error = _("missing ]");
- return FAIL;
- }
-
- if (*p == '!')
- {
- if (reg == REG_PC)
- {
- inst.error = _("pc may not be used with write-back");
- return FAIL;
- }
-
- p++;
- write_back = WRITE_BACK;
- }
- }
- }
- else
- {
- if (my_get_expression (&inst.reloc.exp, &p))
- return FAIL;
-
- inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
- inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
- inst.reloc.pc_rel = 1;
- inst.instruction |= (REG_PC << 16);
- pre_inc = PRE_INDEX;
- }
-
- inst.instruction |= write_back | pre_inc;
- *str = p;
- return SUCCESS;
-}
-
/* Parse a Thumb address expression:
[Rl]
@@ -5651,7 +5492,7 @@
reg_or_fail (&str, 12, REG_TYPE_CN);
comma_or_fail (&str);
- if (cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ if (cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM) == FAIL)
return;
end_of_line (str);
}
@@ -6960,7 +6801,7 @@
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_VFS);
comma_or_fail (&str);
- if (cp_address_required_here (&str, CP_NO_WB) == FAIL)
+ if (cp_address_required_here (&str, FALSE, BFD_RELOC_ARM_CP_OFF_IMM) == FAIL)
return;
end_of_line (str);
@@ -6972,7 +6813,7 @@
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_VFD);
comma_or_fail (&str);
- if (cp_address_required_here (&str, CP_NO_WB) == FAIL)
+ if (cp_address_required_here (&str, FALSE, BFD_RELOC_ARM_CP_OFF_IMM) == FAIL)
return;
end_of_line (str);
@@ -7130,7 +6971,7 @@
reg_or_fail (&str, 12, REG_TYPE_FN);
comma_or_fail (&str);
- if (cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ if (cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM) == FAIL)
return;
end_of_line (str);
@@ -7223,7 +7064,8 @@
}
else
{
- if (cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ if (cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM)
+ == FAIL)
return;
}
@@ -7383,7 +7225,7 @@
reg_or_fail (&str, 12, REG_TYPE_MMXWR);
comma_or_fail (&str);
- if (cp_byte_address_required_here (&str) == FAIL)
+ if (cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM_S2) == FAIL)
return;
end_of_line (str);
@@ -7402,7 +7244,7 @@
}
comma_or_fail (&str);
- if (cp_address_required_here (&str, CP_WB_OK) == FAIL)
+ if (cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM) == FAIL)
return;
end_of_line (str);
@@ -7803,7 +7645,7 @@
reg_or_fail (&str, 12, reg0);
comma_or_fail (&str);
- cp_address_required_here (&str, TRUE);
+ cp_address_required_here (&str, TRUE, BFD_RELOC_ARM_CP_OFF_IMM);
end_of_line (str);
}
@@ -10717,7 +10559,7 @@
sign = value >= 0;
if (value < -1023 || value > 1023 || (value & 3))
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("illegal value for co-processor offset"));
+ _("co-processor offset out of range"));
if (value < 0)
value = -value;
newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
@@ -10729,7 +10571,7 @@
sign = value >= 0;
if (value < -255 || value > 255)
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("Illegal value for co-processor offset"));
+ _("co-processor offset out of range"));
if (value < 0)
value = -value;
newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;