* Thumb32 assembler (11/69)
@ 2005-04-26 9:58 Zack Weinberg
2005-04-26 17:36 ` Paul Brook
0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-26 9:58 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 358 bytes --]
Almost all the calls to skip_whitespace in tc-arm.c are unnecessary,
because the input scrubber removes almost all the whitespace before
md_assemble gets called. When it is necessary, it doesn't need to
loop. The skip_whitespace call that used to appear at the beginning
of each and every ->parms function, which is necessary, is hoisted to
md_assemble.
[-- Attachment #2: Type: text/plain, Size: 303 bytes --]
* tc-arm.c (skip_whitespace): No need to skip more than one space.
Most calls to skip_whitespace / SKIP_WHITESPACE deleted, except ...
(decode_shift): Must skip whitespace immediately after the
shifter name.
(do_sxtah): Similarly.
(md_assemble): Skip whitespace before calling ->parms function.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 11.diff.txt --]
[-- Type: text/x-patch; name=11.diff.txt, Size: 33585 bytes --]
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 12)
+++ gas/config/tc-arm.c (revision 13)
@@ -839,13 +839,11 @@
value. */
#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
-#define skip_whitespace(str) while (*(str) == ' ') ++(str)
+#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
static void
end_of_line (char * str)
{
- skip_whitespace (str);
-
if (*str != '\0' && !inst.error)
inst.error = _("garbage following instruction");
}
@@ -1145,8 +1143,6 @@
{
expressionS exp;
- skip_whitespace (*str);
-
if (is_immediate_prefix (**str))
(*str)++;
else if (!prefix_opt)
@@ -1187,7 +1183,6 @@
expressionS exp;
exp.X_op = O_illegal;
- SKIP_WHITESPACE ();
if (is_immediate_prefix (*input_line_pointer))
{
input_line_pointer++;
@@ -1498,8 +1493,6 @@
{
int reg;
- skip_whitespace (str);
-
if ((reg = reg_required_here (& str, -1, REG_TYPE_RN)) == FAIL)
return FAIL;
@@ -1537,7 +1530,6 @@
while (skip_past_comma (&str) != FAIL
|| (in_range = 1, *str++ == '-'));
str--;
- skip_whitespace (str);
if (*str++ != '}')
{
@@ -1588,8 +1580,6 @@
}
}
- skip_whitespace (str);
-
if (*str == '|' || *str == '+')
{
str++;
@@ -1622,7 +1612,6 @@
return FAIL;
(*str)++;
- skip_whitespace (*str);
if (dp)
{
@@ -1664,8 +1653,6 @@
mask |= 1 << new_base;
count++;
- skip_whitespace (*str);
-
if (**str == '-') /* We have the start of a range expression */
{
int high_range;
@@ -1733,8 +1720,6 @@
char * p;
char c;
- skip_whitespace (* str);
-
for (p = * str; ISALPHA (* p); p ++)
;
@@ -1950,8 +1935,6 @@
int value;
expressionS expr;
- skip_whitespace (* str);
-
if (reg_required_here (str, 0, REG_TYPE_RN) != FAIL)
{
if (skip_past_comma (str) == SUCCESS)
@@ -2037,8 +2020,6 @@
static int
fp_op2 (char ** str)
{
- skip_whitespace (* str);
-
if (reg_required_here (str, 0, REG_TYPE_FN) != FAIL)
return SUCCESS;
else
@@ -2050,8 +2031,6 @@
inst.error = NULL;
- skip_whitespace (* str);
-
/* First try and match exact strings, this is to guarantee
that some formats will work even for cross assembly. */
@@ -2264,19 +2243,13 @@
int rn;
int pre_inc = 0;
- skip_whitespace (str);
-
if (* str == '[')
{
str++;
- skip_whitespace (str);
-
if ((rn = reg_required_here (&str, 16, REG_TYPE_RN)) == FAIL)
return FAIL;
- skip_whitespace (str);
-
if (* str == ']')
{
str ++;
@@ -2289,8 +2262,6 @@
}
else /* [Rn] */
{
- skip_whitespace (str);
-
if (* str == '!')
{
str ++;
@@ -2314,16 +2285,12 @@
if (ldst_extend_v4 (&str) == FAIL)
return FAIL;
- skip_whitespace (str);
-
if (* str ++ != ']')
{
inst.error = _("missing ]");
return FAIL;
}
- skip_whitespace (str);
-
if (* str == '!')
{
str ++;
@@ -2492,7 +2459,6 @@
{
int processor;
- skip_whitespace (*str);
if ((processor = arm_reg_parse (str, REG_TYPE_CP)) == FAIL)
{
inst.error = reg_expected_msgs[REG_TYPE_CP];
@@ -2520,8 +2486,6 @@
{
int offset;
- skip_whitespace (* str);
-
if (! is_immediate_prefix (**str))
{
inst.error = _("immediate expression expected");
@@ -2574,19 +2538,14 @@
int reg;
p++;
- skip_whitespace (p);
if ((reg = reg_required_here (&p, 16, REG_TYPE_RN)) == FAIL)
return FAIL;
- skip_whitespace (p);
-
if (*p == ']')
{
p++;
- skip_whitespace (p);
-
if (*p == '\0')
{
/* As an extension to the official ARM syntax we allow:
@@ -2604,8 +2563,6 @@
return FAIL;
}
- skip_whitespace (p);
-
if (*p == '#')
{
if (wb_ok)
@@ -2634,8 +2591,6 @@
if (immediate_required_here (&p, &option, 0, 255, TRUE) == FAIL)
return FAIL;
- skip_whitespace (p);
-
if (*p != '}')
{
inst.error = _("'}' expected at end of 'option' field");
@@ -2669,16 +2624,12 @@
if (cp_address_offset (& p) == FAIL)
return FAIL;
- skip_whitespace (p);
-
if (*p++ != ']')
{
inst.error = _("missing ]");
return FAIL;
}
- skip_whitespace (p);
-
if (wb_ok && *p == '!')
{
if (reg == REG_PC)
@@ -2714,8 +2665,6 @@
{
int offset;
- skip_whitespace (* str);
-
if (! is_immediate_prefix (**str))
{
inst.error = _("immediate expression expected");
@@ -2762,13 +2711,10 @@
int reg;
p++;
- skip_whitespace (p);
if ((reg = reg_required_here (&p, 16, REG_TYPE_RN)) == FAIL)
return FAIL;
- skip_whitespace (p);
-
if (*p == ']')
{
p++;
@@ -2805,16 +2751,12 @@
if (cp_byte_address_offset (& p) == FAIL)
return FAIL;
- skip_whitespace (p);
-
if (*p++ != ']')
{
inst.error = _("missing ]");
return FAIL;
}
- skip_whitespace (p);
-
if (*p == '!')
{
if (reg == REG_PC)
@@ -2875,8 +2817,6 @@
int saw_a_flag = 0;
- skip_whitespace (*str);
-
/* Get the a, f and i flags. */
while (**str && **str != ',')
{
@@ -2931,7 +2871,6 @@
{
int big_endian = 0;
- skip_whitespace (str);
if (strlen (str) < 2)
inst.error = _("missing endian specifier");
else if (strncasecmp (str, "BE", 2) == 0)
@@ -3067,7 +3006,6 @@
char * name;
char saved_char;
- skip_whitespace (input_line_pointer);
name = input_line_pointer;
while (*input_line_pointer != 0
@@ -3405,8 +3343,6 @@
end_name = input_line_pointer;
*end_name = delim;
- SKIP_WHITESPACE ();
-
if (*input_line_pointer != ',')
{
*end_name = 0;
@@ -3819,8 +3755,6 @@
char *p;
valueT highbit;
- SKIP_WHITESPACE ();
-
highbit = 0;
if (*input_line_pointer == '1')
highbit = 0x80000000;
@@ -3828,7 +3762,6 @@
as_bad (_("expected 0 or 1"));
input_line_pointer++;
- SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
as_bad (_("missing comma"));
input_line_pointer++;
@@ -3955,8 +3888,6 @@
if (unwind.personality_routine || unwind.personality_index != -1)
as_bad (_("duplicate .personalityindex directive"));
- SKIP_WHITESPACE ();
-
expression (&exp);
if (exp.X_op != O_constant
@@ -3983,13 +3914,11 @@
if (unwind.personality_routine || unwind.personality_index != -1)
as_bad (_("duplicate .personality directive"));
- SKIP_WHITESPACE ();
name = input_line_pointer;
c = get_symbol_end ();
p = input_line_pointer;
unwind.personality_routine = symbol_find_or_make (name);
*p = c;
- SKIP_WHITESPACE ();
demand_empty_rest_of_line ();
}
@@ -4003,7 +3932,6 @@
long range;
int n;
- SKIP_WHITESPACE ();
range = reg_list (&input_line_pointer);
if (range == FAIL)
{
@@ -4180,7 +4108,6 @@
as_tsktsk (_("register list not in ascending order"));
mask |= 1 << reg;
- SKIP_WHITESPACE ();
if (*input_line_pointer == '-')
{
input_line_pointer++;
@@ -4201,7 +4128,6 @@
}
while (skip_past_comma (&input_line_pointer) != FAIL);
- SKIP_WHITESPACE ();
if (*input_line_pointer == '}')
input_line_pointer++;
@@ -4315,7 +4241,6 @@
as_tsktsk (_("register list not in ascending order"));
mask |= 1 << reg;
- SKIP_WHITESPACE ();
if (*input_line_pointer == '-')
{
input_line_pointer++;
@@ -4336,7 +4261,6 @@
}
while (skip_past_comma (&input_line_pointer) != FAIL);
- SKIP_WHITESPACE ();
if (*input_line_pointer == '}')
input_line_pointer++;
@@ -4370,7 +4294,6 @@
/* Figure out what sort of save we have. */
peek = input_line_pointer;
- skip_whitespace (peek);
if (*peek == '{')
{
@@ -4419,7 +4342,6 @@
int reg;
valueT op;
- SKIP_WHITESPACE ();
reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
if (reg == FAIL)
{
@@ -4531,7 +4453,6 @@
unsigned char op[16];
int count;
- SKIP_WHITESPACE ();
expression (&exp);
if (exp.X_op == O_constant
&& skip_past_comma (&input_line_pointer) != FAIL)
@@ -4648,7 +4569,6 @@
/* This is a pseudo-op of the form "adr rd, label" to be converted
into a relative address of the form "add rd, pc, #label-.-8". */
- skip_whitespace (str);
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
expression_or_fail (&inst.reloc.exp, &str);
@@ -4671,7 +4591,6 @@
add rd, pc, #low(label-.-8)"
add rd, rd, #high(label-.-8)" */
- skip_whitespace (str);
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
expression_or_fail (&inst.reloc.exp, &str);
@@ -4690,7 +4609,6 @@
static void
do_arit (char * str)
{
- skip_whitespace (str);
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
reg_or_fail (&str, 16, REG_TYPE_RN);
@@ -4731,7 +4649,6 @@
static void
do_bfc (char *str)
{
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 12);
bfci_lsb_and_width (str);
}
@@ -4742,7 +4659,6 @@
int rm;
/* Rd. */
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -4772,7 +4688,6 @@
int lsb, width;
/* Rd. */
- skip_whitespace (str);
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -4807,8 +4722,6 @@
{
int number = 0;
- skip_whitespace (str);
-
/* As a convenience we allow 'bkpt' without an operand. */
if (is_immediate_prefix (*str) || ISDIGIT (*str))
if (immediate_required_here (&str, &number, 0, 0xffff, TRUE) == FAIL)
@@ -4919,7 +4832,6 @@
{
int reg;
- skip_whitespace (str);
note_reg_or_fail (reg, &str, 0, REG_TYPE_RN);
end_of_line (str);
@@ -4941,7 +4853,6 @@
{
int rm;
- skip_whitespace (str);
rm = reg_required_here (&str, 0, REG_TYPE_RN);
if (rm != FAIL)
@@ -4979,7 +4890,6 @@
{
int reg;
- skip_whitespace (str);
note_reg_or_fail (reg, &str, 0, REG_TYPE_RN);
end_of_line (str);
@@ -4994,8 +4904,6 @@
static void
do_cdp (char * str)
{
- skip_whitespace (str);
-
if (co_proc_number (&str) == FAIL)
return;
comma_or_fail (&str);
@@ -5027,8 +4935,6 @@
static void
do_clz (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
reg_nonpc_or_fail (&str, 0);
@@ -5038,8 +4944,6 @@
static void
do_cmp (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 16, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5064,8 +4968,6 @@
static void
do_co_reg (char * str)
{
- skip_whitespace (str);
-
if (co_proc_number (&str) == FAIL)
return;
@@ -5109,8 +5011,6 @@
static void
do_co_reg2c (char * str)
{
- skip_whitespace (str);
-
if (co_proc_number (& str) == FAIL)
return;
@@ -5148,10 +5048,8 @@
do_cps_flags (&str, /*thumb_p=*/0);
if (skip_past_comma (&str) == SUCCESS)
- {
- skip_whitespace (str);
- do_cps_mode (&str);
- }
+ do_cps_mode (&str);
+
end_of_line (str);
}
@@ -5161,12 +5059,8 @@
int base_reg;
long range;
- skip_whitespace (str);
-
note_reg_nonpc_or_fail (base_reg, &str, 16);
- skip_whitespace (str);
-
if (*str == '!')
{
inst.instruction |= WRITE_BACK;
@@ -5225,8 +5119,6 @@
int rd;
int rn;
- skip_whitespace (str);
-
note_reg_or_fail (rd, &str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5279,14 +5171,11 @@
static void
do_ldrex (char * str)
{
- skip_whitespace (str);
-
/* Parse Rd. */
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
/* Skip past '['. */
- skip_whitespace (str);
if (*str != '[')
{
inst.error = BAD_ARGS;
@@ -5297,7 +5186,6 @@
reg_nonpc_or_fail (&str, 16);
/* Skip past ']'. */
- skip_whitespace (str);
if (*str != ']')
{
inst.error = BAD_ARGS;
@@ -5314,8 +5202,6 @@
int conflict_reg;
int value;
- skip_whitespace (str);
-
note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5325,15 +5211,11 @@
str++;
- skip_whitespace (str);
-
note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
/* Conflicts can occur on stores as well as loads. */
conflict_reg = (conflict_reg == reg);
- skip_whitespace (str);
-
if (*str == ']')
{
str ++;
@@ -5351,7 +5233,6 @@
else
{
/* [Rn] */
- skip_whitespace (str);
if (*str == '!')
{
@@ -5376,16 +5257,12 @@
if (ldst_extend (&str) == FAIL)
return;
- skip_whitespace (str);
-
if (*str++ != ']')
{
inst.error = _("missing ]");
return;
}
- skip_whitespace (str);
-
if (*str == '!')
{
if (conflict_reg)
@@ -5408,7 +5285,6 @@
/* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
str++;
- skip_whitespace (str);
expression_or_fail (&inst.reloc.exp, &str);
if (inst.reloc.exp.X_op != O_constant
@@ -5484,7 +5360,6 @@
{
int conflict_reg;
- skip_whitespace (str);
note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5494,7 +5369,6 @@
str++;
- skip_whitespace (str);
note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
/* ldrt/strt always use post-indexed addressing, so if the base is
@@ -5504,8 +5378,6 @@
? _("destination register same as write-back base")
: _("source register same as write-back base"));
- skip_whitespace (str);
-
if (*str == ']')
{
str ++;
@@ -5519,7 +5391,6 @@
else
{
/* [Rn] */
- skip_whitespace (str);
/* Skip a write-back '!'. */
if (*str == '!')
@@ -5552,7 +5423,6 @@
int conflict_reg;
int value;
- skip_whitespace (str);
note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5562,15 +5432,11 @@
str++;
- skip_whitespace (str);
-
note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
/* Conflicts can occur on stores as well as loads. */
conflict_reg = (conflict_reg == reg);
- skip_whitespace (str);
-
if (*str == ']')
{
str ++;
@@ -5590,8 +5456,6 @@
/* [Rn] */
inst.instruction |= HWOFFSET_IMM;
- skip_whitespace (str);
-
if (*str == '!')
{
if (conflict_reg)
@@ -5619,16 +5483,12 @@
if (ldst_extend_v4 (&str) == FAIL)
return;
- skip_whitespace (str);
-
if (*str++ != ']')
{
inst.error = _("missing ]");
return;
}
- skip_whitespace (str);
-
if (*str == '!')
{
if (conflict_reg)
@@ -5652,8 +5512,6 @@
/* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
str++;
- skip_whitespace (str);
-
expression_or_fail (&inst.reloc.exp, &str);
if (inst.reloc.exp.X_op != O_constant
@@ -5729,8 +5587,6 @@
{
int conflict_reg;
- skip_whitespace (str);
-
note_reg_or_fail (conflict_reg, &str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5740,7 +5596,6 @@
str++;
- skip_whitespace (str);
note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
/* ldrt/strt always use post-indexed addressing, so if the base is
@@ -5750,7 +5605,6 @@
? _("destination register same as write-back base")
: _("source register same as write-back base"));
- skip_whitespace (str);
if (*str == ']')
{
str ++;
@@ -5764,7 +5618,6 @@
else
{
/* [Rn] */
- skip_whitespace (str);
/* Skip a write-back '!'. */
if (*str == '!')
@@ -5794,8 +5647,6 @@
/* Co-processor register load/store.
Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
- skip_whitespace (str);
-
if (co_proc_number (&str) == FAIL)
return;
@@ -5817,7 +5668,6 @@
int rd, rm;
/* Only one format "rd, rm, rs, rn". */
- skip_whitespace (str);
note_reg_nonpc_or_fail (rd, &str, 16);
comma_or_fail (&str);
@@ -5852,8 +5702,6 @@
static void
do_mov (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -5874,7 +5722,6 @@
{
int val;
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
immediate_or_fail (&str, &val, 0, 65535, FALSE);
@@ -5889,13 +5736,9 @@
do_mrs (char * str)
{
/* Only one syntax. */
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
- skip_whitespace (str);
-
/* Lower case accepted for backwards compatibility. */
if (*str == 'c' || *str == 'C')
; /* SPSR bit is already clear. */
@@ -5930,15 +5773,11 @@
static void
do_msr (char * str)
{
- skip_whitespace (str);
-
if (psr_required_here (&str) == FAIL)
return;
comma_or_fail (&str);
- skip_whitespace (str);
-
if (reg_required_here (&str, 0, REG_TYPE_RN) != FAIL)
{
end_of_line (str);
@@ -5992,7 +5831,6 @@
int rd, rm;
/* Only one format "rd, rm, rs". */
- skip_whitespace (str);
note_reg_nonpc_or_fail (rd, &str, 16);
comma_or_fail (&str);
@@ -6019,8 +5857,6 @@
int rdlo, rdhi, rm;
/* Only one format "rdlo, rdhi, rm, rs". */
- skip_whitespace (str);
-
note_reg_nonpc_or_fail (rdlo, &str, 12);
comma_or_fail (&str);
@@ -6043,7 +5879,6 @@
{
int hint;
- skip_whitespace (str);
if (*str == '{')
{
str++;
@@ -6070,8 +5905,6 @@
{
int rm, rn;
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6129,8 +5962,6 @@
{
int rd;
- skip_whitespace (str);
-
if (* str != '[')
{
inst.error = _("'[' expected after PLD mnemonic");
@@ -6138,17 +5969,13 @@
}
++str;
- skip_whitespace (str);
note_reg_or_fail (rd, &str, 16, REG_TYPE_RN);
- skip_whitespace (str);
-
if (*str == ']')
{
/* [Rn], ... ? */
++str;
- skip_whitespace (str);
/* Post-indexed addressing is not allowed with PLD. */
if (skip_past_comma (&str) == SUCCESS)
@@ -6176,8 +6003,6 @@
if (ldst_extend (&str) == FAIL)
return;
- skip_whitespace (str);
-
if (* str != ']')
{
inst.error = _("missing ]");
@@ -6185,7 +6010,6 @@
}
++ str;
- skip_whitespace (str);
if (* str == '!') /* [Rn]! */
{
@@ -6206,8 +6030,6 @@
static void
do_qadd (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6226,8 +6048,6 @@
static void
do_qadd16 (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6241,7 +6061,6 @@
static void
do_rbit (char *str)
{
- skip_whitespace (str);
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -6258,8 +6077,6 @@
static void
do_rev (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6276,12 +6093,8 @@
static void
do_rfe (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 16);
- skip_whitespace (str);
-
if (*str == '!')
{
inst.instruction |= WRITE_BACK;
@@ -6295,8 +6108,6 @@
{
int val;
- skip_whitespace (str);
-
/* Parse <Rd>, field. */
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6336,8 +6147,6 @@
{
int val;
- skip_whitespace (str);
-
/* Parse the <Rd> field. */
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6382,8 +6191,6 @@
static void
do_smi (char * str)
{
- skip_whitespace (str);
-
/* Allow optional leading '#'. */
if (is_immediate_prefix (*str))
str++;
@@ -6398,8 +6205,6 @@
static void
do_swi (char * str)
{
- skip_whitespace (str);
-
/* Allow optional leading '#'. */
if (is_immediate_prefix (*str))
str++;
@@ -6419,8 +6224,6 @@
static void
do_smla (char * str)
{
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 16);
comma_or_fail (&str);
@@ -6445,8 +6248,6 @@
{
int rdlo, rdhi;
- skip_whitespace (str);
-
note_reg_nonpc_or_fail (rdlo, &str, 12);
comma_or_fail (&str);
@@ -6471,7 +6272,6 @@
static void
do_smul (char * str)
{
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 16);
comma_or_fail (&str);
@@ -6488,9 +6288,9 @@
static void
do_srs (char * str)
{
- char *exclam;
- skip_whitespace (str);
- exclam = strchr (str, '!');
+ /* This is necessary because the generic expression parser will
+ choke on "#16!". */
+ char *exclam = strchr (str, '!');
if (exclam)
*exclam = '\0';
do_cps_mode (&str);
@@ -6512,7 +6312,6 @@
int rd, rm, rn;
/* Parse Rd, Rm,. */
- skip_whitespace (str);
note_reg_nonpc_or_fail (rd, &str, 12);
comma_or_fail (&str);
@@ -6532,7 +6331,6 @@
return;
}
str++;
- skip_whitespace (str);
/* Parse Rn. */
note_reg_nonpc_or_fail (rn, &str, 16);
@@ -6541,7 +6339,6 @@
inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
return;
}
- skip_whitespace (str);
/* Skip past ']'. */
if (*str != ']')
@@ -6559,26 +6356,20 @@
{
int reg;
- skip_whitespace (str);
-
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
reg_nonpc_or_fail (&str, 0);
+ comma_or_fail (&str);
- if (skip_past_comma (&str) == FAIL
- || *str++ != '[')
+ if (*str++ != '[')
{
inst.error = BAD_ARGS;
return;
}
- skip_whitespace (str);
-
note_reg_nonpc_or_fail (reg, &str, 16);
- skip_whitespace (str);
-
if (*str++ != ']')
{
inst.error = _("missing ]");
@@ -6605,7 +6396,6 @@
int rotation_sixteen_mask = 0x00000800;
int rotation_twenty_four_mask = 0x00000c00;
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6625,7 +6415,6 @@
}
/* Move past 'ROR'. */
- skip_whitespace (str);
if (strncasecmp (str, "ROR", 3) == 0)
str += 3;
else
@@ -6680,7 +6469,6 @@
int rotation_sixteen_mask = 0x00000800;
int rotation_twenty_four_mask = 0x00000c00;
- skip_whitespace (str);
reg_nonpc_or_fail (&str, 12);
comma_or_fail (&str);
@@ -6697,7 +6485,6 @@
}
/* Move past 'ROR'. */
- skip_whitespace (str);
if (strncasecmp (str, "ROR", 3) == 0)
str += 3;
else
@@ -6747,8 +6534,6 @@
{
int Rd, Rs, Rn = FAIL;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
|| skip_past_comma (&str) == FAIL)
{
@@ -6913,8 +6698,6 @@
{
int Rd, Rb, Ro = FAIL;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
|| skip_past_comma (&str) == FAIL)
{
@@ -6963,8 +6746,6 @@
/* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
str++;
- skip_whitespace (str);
-
expression_or_fail (& inst.reloc.exp, & str);
end_of_line (str);
@@ -7113,8 +6894,6 @@
{
int Rd, Rs = FAIL;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
|| skip_past_comma (&str) == FAIL)
{
@@ -7198,8 +6977,6 @@
{
int Rd, Rs, Rn = FAIL;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
|| skip_past_comma (&str) == FAIL)
{
@@ -7311,7 +7088,6 @@
/* This is a pseudo-op of the form "adr rd, label" to be converted
into a relative address of the form "add rd, pc, #label-.-4". */
- skip_whitespace (str);
/* Store Rd in temporary location inside instruction. */
if ((reg = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
@@ -7339,8 +7115,6 @@
{
int Rd, Rs, Rn;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
|| skip_past_comma (&str) == FAIL
|| (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
@@ -7396,8 +7170,6 @@
{
int number = 0;
- skip_whitespace (str);
-
/* As a convenience we allow 'bkpt' without an operand. */
if (is_immediate_prefix (*str) || ISDIGIT (*str))
if (immediate_required_here (&str, &number, 0, 255, TRUE) == FAIL)
@@ -7420,8 +7192,6 @@
{
int rm;
- skip_whitespace (str);
-
/* BLX(2) can be applied to any integer register. */
rm = thumb_reg (&str, THUMB_REG_ANY);
@@ -7490,8 +7260,6 @@
{
int reg;
- skip_whitespace (str);
-
if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
return;
@@ -7534,8 +7302,6 @@
int Rb;
long range;
- skip_whitespace (str);
-
if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
return;
@@ -7593,8 +7359,6 @@
{
int Rd, Rb, Ro;
- skip_whitespace (str);
-
if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
|| skip_past_comma (&str) == FAIL
|| *str++ != '['
@@ -7642,8 +7406,6 @@
{
long range;
- skip_whitespace (str);
-
if ((range = reg_list (&str)) == FAIL)
{
if (! inst.error)
@@ -7716,8 +7478,6 @@
static void
do_t_swi (char * str)
{
- skip_whitespace (str);
-
expression_or_fail (&inst.reloc.exp, &str);
inst.reloc.type = BFD_RELOC_ARM_SWI;
@@ -7730,8 +7490,6 @@
static void
do_vfp_sp_monadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
comma_or_fail (&str);
@@ -7742,8 +7500,6 @@
static void
do_vfp_dp_monadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
comma_or_fail (&str);
@@ -7754,8 +7510,6 @@
static void
do_vfp_sp_dyadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
comma_or_fail (&str);
@@ -7769,8 +7523,6 @@
static void
do_vfp_dp_dyadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
comma_or_fail (&str);
@@ -7784,7 +7536,6 @@
static void
do_vfp_sp_compare_z (char * str)
{
- skip_whitespace (str);
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
end_of_line (str);
}
@@ -7792,7 +7543,6 @@
static void
do_vfp_dp_compare_z (char * str)
{
- skip_whitespace (str);
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
end_of_line (str);
}
@@ -7800,8 +7550,6 @@
static void
do_vfp_dp_sp_cvt (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
comma_or_fail (&str);
@@ -7812,8 +7560,6 @@
static void
do_vfp_sp_dp_cvt (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
comma_or_fail (&str);
@@ -7824,8 +7570,6 @@
static void
do_vfp_reg_from_sp (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -7838,8 +7582,6 @@
{
int reg;
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -7860,8 +7602,6 @@
static void
do_vfp_sp_from_reg (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Sn, REG_TYPE_SN);
comma_or_fail (&str);
@@ -7876,8 +7616,6 @@
{
int reg;
- skip_whitespace (str);
-
/* We require exactly two consecutive SP registers. */
if (vfp_parse_reg_list (&str, ®, 0) != 2)
{
@@ -7897,8 +7635,6 @@
static void
do_vfp_reg_from_dp (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -7909,8 +7645,6 @@
static void
do_vfp_reg2_from_dp (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -7924,8 +7658,6 @@
static void
do_vfp_dp_from_reg (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dn, REG_TYPE_DN);
comma_or_fail (&str);
@@ -7936,8 +7668,6 @@
static void
do_vfp_dp_from_reg2 (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dm, REG_TYPE_DN);
comma_or_fail (&str);
@@ -7951,8 +7681,6 @@
static void
do_vfp_reg_from_ctrl (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -7965,8 +7693,6 @@
static void
do_vfp_ctrl_from_reg (char * str)
{
- skip_whitespace (str);
-
if (vfp_psr_required_here (&str) == FAIL)
return;
comma_or_fail (&str);
@@ -7978,8 +7704,6 @@
static void
do_vfp_sp_ldst (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Sd, REG_TYPE_SN);
comma_or_fail (&str);
@@ -7992,8 +7716,6 @@
static void
do_vfp_dp_ldst (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, VFP_REG_Dd, REG_TYPE_DN);
comma_or_fail (&str);
@@ -8010,12 +7732,8 @@
int count;
int reg;
- skip_whitespace (str);
-
reg_or_fail (&str, 16, REG_TYPE_RN);
- skip_whitespace (str);
-
if (*str == '!')
{
inst.instruction |= WRITE_BACK;
@@ -8043,12 +7761,8 @@
int count;
int reg;
- skip_whitespace (str);
-
reg_or_fail (&str, 16, REG_TYPE_RN);
- skip_whitespace (str);
-
if (*str == '!')
{
inst.instruction |= WRITE_BACK;
@@ -8118,8 +7832,6 @@
/* FP control registers.
Format: <WFS|RFS|WFC|RFC>{cond} Rn */
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
end_of_line (str);
}
@@ -8127,8 +7839,6 @@
static void
do_fpa_cmp (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 16, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8141,8 +7851,6 @@
static void
do_fpa_monadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8155,8 +7863,6 @@
static void
do_fpa_dyadic (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8172,8 +7878,6 @@
static void
do_fpa_from_reg (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 16, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8184,8 +7888,6 @@
static void
do_fpa_to_reg (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_RN);
comma_or_fail (&str);
@@ -8196,8 +7898,6 @@
static void
do_fpa_ldst (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8212,8 +7912,6 @@
{
int num_regs;
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_FN);
comma_or_fail (&str);
@@ -8256,11 +7954,7 @@
}
str++;
- skip_whitespace (str);
-
note_reg_or_fail (reg, &str, 16, REG_TYPE_RN);
- skip_whitespace (str);
-
if (*str != ']')
{
inst.error = BAD_ARGS;
@@ -8335,8 +8029,6 @@
inst_error = inst.error;
if (!inst.error)
inst.error = BAD_ARGS;
- skip_whitespace (str);
-
switch (insn_type)
{
case check_rd:
@@ -8606,8 +8298,6 @@
static void
do_iwmmxt_wldst (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_MMXWR);
comma_or_fail (&str);
@@ -8622,8 +8312,6 @@
{
struct reg_entry *reg;
- skip_whitespace (str);
-
if ((reg = arm_reg_parse_multi (&str)) == NULL
|| (reg->type != REG_TYPE_MMXWR && reg->type != REG_TYPE_MMXWC))
{
@@ -8708,7 +8396,6 @@
shift0 = mode & 0xff;
shift1 = (mode >> 8) & 0xff;
- skip_whitespace (str);
reg_or_fail (&str, shift0, reg0);
comma_or_fail (&str);
@@ -8732,7 +8419,6 @@
shift1 = (mode >> 8) & 0xff;
shift2 = (mode >> 16) & 0xff;
- skip_whitespace (str);
reg_or_fail (&str, shift0, reg0);
comma_or_fail (&str);
@@ -8762,7 +8448,6 @@
shift2 = (mode >> 16) & 0xff;
shift3 = (mode >> 24) & 0xff;
- skip_whitespace (str);
reg_or_fail (&str, shift0, reg0);
comma_or_fail (&str);
@@ -8990,8 +8675,6 @@
static void
do_mav_dspsc_1 (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, -1, REG_TYPE_DSPSC);
comma_or_fail (&str);
@@ -9003,8 +8686,6 @@
static void
do_mav_dspsc_2 (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, 12, REG_TYPE_MVDX);
comma_or_fail (&str);
@@ -9023,8 +8704,6 @@
{
int imm, neg = 0;
- skip_whitespace (str);
-
reg_or_fail (&str, 12, reg0);
comma_or_fail (&str);
@@ -9033,8 +8712,6 @@
/* Calculate the immediate operand.
The operand is a 7bit signed number. */
- skip_whitespace (str);
-
if (*str == '#')
++str;
@@ -9096,8 +8773,6 @@
{
int offset, negative;
- skip_whitespace (str);
-
reg_or_fail (&str, 12, reg0);
comma_or_fail (&str);
if (*str++ != '[')
@@ -9190,8 +8865,6 @@
static void
do_xsc_mia (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, -1, REG_TYPE_XSCALE);
comma_or_fail (&str);
@@ -9209,8 +8882,6 @@
static void
do_xsc_mar (char * str)
{
- skip_whitespace (str);
-
reg_or_fail (&str, -1, REG_TYPE_XSCALE);
comma_or_fail (&str);
@@ -9231,8 +8902,6 @@
int rdlo;
int rdhi;
- skip_whitespace (str);
-
note_reg_nonpc_or_fail (rdlo, &str, 12);
comma_or_fail (&str);
@@ -9343,8 +9012,6 @@
memset (&inst, '\0', sizeof (inst));
inst.reloc.type = BFD_RELOC_UNUSED;
- skip_whitespace (str);
-
/* Scan up to the end of the op-code, which must end in white space or
end of string. */
for (p = str; *p != '\0'; p++)
@@ -9375,6 +9042,7 @@
mapping_state (MAP_THUMB);
inst.instruction = opcode->value;
inst.size = opcode->size;
+ skip_whitespace (p);
opcode->parms (p);
output_inst (str);
return;
@@ -9398,6 +9066,7 @@
mapping_state (MAP_ARM);
inst.instruction = opcode->value;
inst.size = INSN_SIZE;
+ skip_whitespace (p);
opcode->parms (p);
output_inst (str);
return;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Thumb32 assembler (11/69)
2005-04-26 9:58 Thumb32 assembler (11/69) Zack Weinberg
@ 2005-04-26 17:36 ` Paul Brook
2005-04-28 10:39 ` Thumb32 assembler (11,58/69) Zack Weinberg
0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2005-04-26 17:36 UTC (permalink / raw)
To: binutils; +Cc: Zack Weinberg
On Tuesday 26 April 2005 10:53, Zack Weinberg wrote:
> Almost all the calls to skip_whitespace in tc-arm.c are unnecessary,
> because the input scrubber removes almost all the whitespace before
> md_assemble gets called. When it is necessary, it doesn't need to
> loop. The skip_whitespace call that used to appear at the beginning
> of each and every ->parms function, which is necessary, is hoisted to
> md_assemble.
This (or something related) breaks libgcc builds. Reduced testcase below:
.macro popret regs
ldmia sp!, {\regs, pc}
.endm
.text
popret "r4, r5"
foo.s: Assembler messages:
foo.s:5: Error: ARM register expected -- `ldmia sp!,{r4, r5,pc}'
Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Thumb32 assembler (11,58/69)
2005-04-26 17:36 ` Paul Brook
@ 2005-04-28 10:39 ` Zack Weinberg
2005-04-29 18:44 ` Paul Brook
0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-28 10:39 UTC (permalink / raw)
To: Paul Brook; +Cc: binutils
Paul Brook <paul@codesourcery.com> writes:
>
> .macro popret regs
> ldmia sp!, {\regs, pc}
> .endm
> .text
> popret "r4, r5"
>
> foo.s: Assembler messages:
> foo.s:5: Error: ARM register expected -- `ldmia sp!,{r4, r5,pc}'
This turns out to be a bug in the generic macro code. do_scrub_chars
needs to be applied to the result of macro expansion, because macro
expansion can generate lines that are not in canonical form.
Richard Earnshaw <rearnsha@gcc.gnu.org> writes:
> On Tue, 2005-04-26 at 17:32, Paul Brook wrote:
>> Unfortunately gcc (incorrectly) outputs the three argument form
>> mul rd, rd, rm
>> I'll fix gcc, but I guess we want to support this for backwards
>> compatibility.
>
> The ARMv6 ARM says that all known implementations of v4t and later can
> handle any register overlap for MUL, so I'm inclined to just relax the
> compiler and assembler constraints entirely.
Easily enough done.
The appended patch applies on top of the previous 69 patches; it fixes
the generic macro expansion bug, allows either source argument of
Thumb mul to equal the destination, and fixes a typo in the handling
of other commutative Thumb arithmetic instructions. Dependencies on
as.h do not appear to be explicitly recorded in the Makefile, so
adding an #include of as.h to sb.c does not require a Makefile
update. (Incidentally, "make DEP" doesn't work for me - DEPA contains
zillions of absolute paths, despite dep.sed supposedly filtering them.)
I am still working on the problem with 'ldr rd, label' at an
unaligned-modulo-4 address. I thought I could use fx_pcrel to
distinguish between that and 'ldr rd, [pc, #4]', but the generic fixup
logic clears fx_pcrel, so another approach is necessary.
zw
gas:
* sb.c: Include as.h.
(sb_to_scrub, scrub_position, scrub_from_sb): New statics.
(sb_scrub_and_add_sb): New interface.
* sb.h: Declare sb_scrub_and_add_sb.
* input-scrub.c (input_scrub_include_sb): Use it.
* config/tc-arm.c (do_t_arit3c): Correct typo in expression.
(do_t_mul): Allow dest to equal either source1 or source2 in
16-bit form; do not complain about dest == source1 in any
case.
gas/testsuite:
* gas/arm/tcompat2.s: Test both dest==source1 and dest==source2
for commutative arithmetic instructions.
* gas/arm/tcompat2.d: Update to match.
* gas/arm/t16-bad.l: Adjust expected diagnostic.
* gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
* gas/arm/arm.exp: Run it.
===================================================================
Index: gas/sb.c
--- gas/sb.c (revision 84)
+++ gas/sb.c (working copy)
@@ -33,6 +33,7 @@
#endif
#include "libiberty.h"
#include "sb.h"
+#include "as.h"
/* These routines are about manipulating strings.
@@ -121,6 +122,37 @@ sb_add_sb (sb *ptr, sb *s)
ptr->len += s->len;
}
+/* helper for below */
+static sb *sb_to_scrub;
+static char *scrub_position;
+static int
+scrub_from_sb (char *buf, int buflen)
+{
+ int copy;
+ copy = sb_to_scrub->len - (scrub_position - sb_to_scrub->ptr);
+ if (copy > buflen)
+ copy = buflen;
+ memcpy (buf, scrub_position, copy);
+ scrub_position += copy;
+ return copy;
+}
+
+/* run the sb at s through do_scrub_chars and add the result to the sb
+ at ptr */
+
+void
+sb_scrub_and_add_sb (sb *ptr, sb *s)
+{
+ sb_to_scrub = s;
+ scrub_position = s->ptr;
+
+ sb_check (ptr, s->len);
+ ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len);
+
+ sb_to_scrub = 0;
+ scrub_position = 0;
+}
+
/* make sure that the sb at ptr has room for another len characters,
and grow it if it doesn't. */
===================================================================
Index: gas/sb.h
--- gas/sb.h (revision 84)
+++ gas/sb.h (working copy)
@@ -82,6 +82,7 @@ extern void sb_build (sb *, int);
extern void sb_new (sb *);
extern void sb_kill (sb *);
extern void sb_add_sb (sb *, sb *);
+extern void sb_scrub_and_add_sb (sb *, sb *);
extern void sb_reset (sb *);
extern void sb_add_char (sb *, int);
extern void sb_add_string (sb *, const char *);
===================================================================
Index: gas/input-scrub.c
--- gas/input-scrub.c (revision 84)
+++ gas/input-scrub.c (working copy)
@@ -280,7 +280,7 @@ input_scrub_include_sb (sb *from, char *
/* Add the sentinel required by read.c. */
sb_add_char (&from_sb, '\n');
}
- sb_add_sb (&from_sb, from);
+ sb_scrub_and_add_sb (&from_sb, from);
sb_index = 1;
/* These variables are reset by input_scrub_push. Restore them
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 84)
+++ gas/config/tc-arm.c (working copy)
@@ -6025,7 +6025,7 @@ do_t_arit3c (void)
if (Rd == Rs)
inst.instruction |= Rn << 3;
else if (Rd == Rn)
- inst.instruction |= Rn << 3;
+ inst.instruction |= Rs << 3;
else
constraint (1, _("dest must overlap one source register"));
}
@@ -6735,15 +6735,18 @@ do_t_mul (void)
{
constraint (!thumb32_mode
&& inst.instruction == T_MNEM_muls, BAD_THUMB32);
- constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, BAD_HIREG);
- constraint (inst.operands[0].reg != inst.operands[2].reg,
- _("dest and source2 must be the same register"));
- if (inst.operands[0].reg == inst.operands[1].reg)
- as_tsktsk (_("dest and source must be different in MUL"));
+ constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
+ BAD_HIREG);
inst.instruction = THUMB_OP16 (inst.instruction);
inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
+
+ if (inst.operands[0].reg == inst.operands[1].reg)
+ inst.instruction |= inst.operands[2].reg << 3;
+ else if (inst.operands[0].reg == inst.operands[2].reg)
+ inst.instruction |= inst.operands[1].reg << 3;
+ else
+ constraint (1, _("dest must overlap one source register"));
}
}
===================================================================
Index: gas/testsuite/gas/arm/tcompat2.s
--- gas/testsuite/gas/arm/tcompat2.s (revision 84)
+++ gas/testsuite/gas/arm/tcompat2.s (working copy)
@@ -1,13 +1,27 @@
@ Three-argument forms of Thumb arithmetic instructions.
+ @ Commutative instructions allow either the second or third
+ @ operand to equal the first.
+
.text
.global m
.thumb_func
m:
adc r0,r0,r1
+ adc r0,r1,r0
+
and r0,r0,r1
- bic r0,r0,r1
+ and r0,r1,r0
+
eor r0,r0,r1
+ eor r0,r1,r0
+
+ mul r0,r0,r1
mul r0,r1,r0
+
orr r0,r0,r1
+ orr r0,r1,r0
+
+ bic r0,r0,r1
+
sbc r0,r0,r1
- nop
+
===================================================================
Index: gas/testsuite/gas/arm/tcompat2.d
--- gas/testsuite/gas/arm/tcompat2.d (revision 84)
+++ gas/testsuite/gas/arm/tcompat2.d (working copy)
@@ -9,10 +9,14 @@
Disassembly of section .text:
0+00 <[^>]*> 4148 * adcs r0, r1
-0+02 <[^>]*> 4008 * ands r0, r1
-0+04 <[^>]*> 4388 * bics r0, r1
-0+06 <[^>]*> 4048 * eors r0, r1
-0+08 <[^>]*> 4348 * muls r0, r1
-0+0a <[^>]*> 4308 * orrs r0, r1
-0+0c <[^>]*> 4188 * sbcs r0, r1
-0+0e <[^>]*> 46c0 * nop \(mov r8, r8\)
+0+02 <[^>]*> 4148 * adcs r0, r1
+0+04 <[^>]*> 4008 * ands r0, r1
+0+06 <[^>]*> 4008 * ands r0, r1
+0+08 <[^>]*> 4048 * eors r0, r1
+0+0a <[^>]*> 4048 * eors r0, r1
+0+0c <[^>]*> 4348 * muls r0, r1
+0+0e <[^>]*> 4348 * muls r0, r1
+0+10 <[^>]*> 4308 * orrs r0, r1
+0+12 <[^>]*> 4308 * orrs r0, r1
+0+14 <[^>]*> 4388 * bics r0, r1
+0+16 <[^>]*> 4188 * sbcs r0, r1
===================================================================
Index: gas/testsuite/gas/arm/t16-bad.l
--- gas/testsuite/gas/arm/t16-bad.l (revision 84)
+++ gas/testsuite/gas/arm/t16-bad.l (working copy)
@@ -70,7 +70,7 @@
[^:]*:53: Error: unshifted register required -- `sbc r0,#12'
[^:]*:53: Error: unshifted register required -- `sbc r0,r1,lsl#2'
[^:]*:53: Error: unshifted register required -- `sbc r0,r1,lsl r3'
-[^:]*:54: Error: dest and source2 must be the same register -- `mul r1,r2,r3'
+[^:]*:54: Error: dest must overlap one source register -- `mul r1,r2,r3'
[^:]*:54: Error: lo register required -- `mul r8,r0'
[^:]*:54: Error: lo register required -- `mul r0,r8'
[^:]*:62: Error: lo register required -- `asr r8,r0,#12'
===================================================================
Index: gas/testsuite/gas/arm/macro1.d
--- gas/testsuite/gas/arm/macro1.d (revision 0)
+++ gas/testsuite/gas/arm/macro1.d (revision 0)
@@ -0,0 +1,9 @@
+# name: Macro scrubbing
+# as:
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+[^:]+: +file format .*arm.*
+
+Disassembly of section .text:
+
+0+0 <[^>]*> e8bd8030 ? ldmia sp!, {r4, r5, pc}
===================================================================
Index: gas/testsuite/gas/arm/macro1.s
--- gas/testsuite/gas/arm/macro1.s (revision 0)
+++ gas/testsuite/gas/arm/macro1.s (revision 0)
@@ -0,0 +1,6 @@
+ @ Test that macro expansions are properly scrubbed.
+ .macro popret regs
+ ldmia sp!, {\regs, pc}
+ .endm
+ .text
+ popret "r4, r5"
===================================================================
Index: gas/testsuite/gas/arm/arm.exp
--- gas/testsuite/gas/arm/arm.exp (revision 84)
+++ gas/testsuite/gas/arm/arm.exp (working copy)
@@ -55,6 +55,7 @@ if {[istarget *arm*-*-*] || [istarget "x
run_dump_test "tcompat"
run_dump_test "tcompat2"
run_dump_test "iwmmxt"
+ run_dump_test "macro1"
run_errors_test "vfp-bad" "-mfpu=vfp" "VFP errors"
run_errors_test "req" "-mcpu=arm7m" ".req errors"
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Thumb32 assembler (11,58/69)
2005-04-28 10:39 ` Thumb32 assembler (11,58/69) Zack Weinberg
@ 2005-04-29 18:44 ` Paul Brook
2005-04-29 19:20 ` Zack Weinberg
0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2005-04-29 18:44 UTC (permalink / raw)
To: binutils; +Cc: Zack Weinberg
> gas:
> * sb.c: Include as.h.
> (sb_to_scrub, scrub_position, scrub_from_sb): New statics.
> (sb_scrub_and_add_sb): New interface.
> * sb.h: Declare sb_scrub_and_add_sb.
> * input-scrub.c (input_scrub_include_sb): Use it.
>
> * config/tc-arm.c (do_t_arit3c): Correct typo in expression.
> (do_t_mul): Allow dest to equal either source1 or source2 in
> 16-bit form; do not complain about dest == source1 in any
> case.
>
> gas/testsuite:
> * gas/arm/tcompat2.s: Test both dest==source1 and dest==source2
> for commutative arithmetic instructions.
> * gas/arm/tcompat2.d: Update to match.
> * gas/arm/t16-bad.l: Adjust expected diagnostic.
> * gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
> * gas/arm/arm.exp: Run it.
I can't comment on the input scrubbing bits, except they seem to work.
The arm bits look ok.
Please apply to binutils-csl-arm-2005q1-branch
Paul
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Thumb32 assembler (11,58/69)
2005-04-29 18:44 ` Paul Brook
@ 2005-04-29 19:20 ` Zack Weinberg
0 siblings, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2005-04-29 19:20 UTC (permalink / raw)
To: Paul Brook; +Cc: binutils
Paul Brook <paul@codesourcery.com> writes:
> Please apply to binutils-csl-arm-2005q1-branch
Done.
zw
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-04-29 17:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-26 9:58 Thumb32 assembler (11/69) Zack Weinberg
2005-04-26 17:36 ` Paul Brook
2005-04-28 10:39 ` Thumb32 assembler (11,58/69) Zack Weinberg
2005-04-29 18:44 ` Paul Brook
2005-04-29 19:20 ` Zack Weinberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).