(sb_to_scrub, scrub_position, scrub_from_sb): New statics.
(sb_scrub_and_add_sb): New interface.
* gas/sb.h: Declare sb_scrub_and_add_sb.
* gas/input-scrub.c (input_scrub_include_sb): Use it.
* gas/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/testsuite/gas/arm/tcompat2.d: Update to match.
* gas/testsuite/gas/arm/t16-bad.l: Adjust expected diagnostic.
* gas/testsuite/gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
* gas/testsuite/gas/arm/arm.exp: Run it.
+2005-04-29 Zack Weinberg <zack@codesourcery.com>
+
+ * gas/sb.c: Include as.h.
+ (sb_to_scrub, scrub_position, scrub_from_sb): New statics.
+ (sb_scrub_and_add_sb): New interface.
+ * gas/sb.h: Declare sb_scrub_and_add_sb.
+ * gas/input-scrub.c (input_scrub_include_sb): Use it.
+
+ * gas/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/testsuite/gas/arm/tcompat2.d: Update to match.
+ * gas/testsuite/gas/arm/t16-bad.l: Adjust expected diagnostic.
+ * gas/testsuite/gas/arm/macro1.s, gas/arm/macro1.d: New test pair.
+ * gas/testsuite/gas/arm/arm.exp: Run it.
+
2005-04-25 Zack Weinberg <zack@codesourcery.com>
Thumb32 assembler.
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"));
}
{
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"));
}
}
/* 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
#endif
#include "libiberty.h"
#include "sb.h"
+#include "as.h"
/* These routines are about manipulating strings.
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. */
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 *);
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"
--- /dev/null
+# 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}
--- /dev/null
+ @ Test that macro expansions are properly scrubbed.
+ .macro popret regs
+ ldmia sp!, {\regs, pc}
+ .endm
+ .text
+ popret "r4, r5"
[^:]*: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'
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
@ 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
+