This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (54/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 03:00:16 -0700
- Subject: Thumb32 assembler (54/69)
We were allowing three arguments for a bunch of Thumb instructions
where the ARM equivalent takes only two. This corrects that error.
zw
* config/tc-arm.c (do_t_arit): Split 3-argument mode out to...
(do_t_arit3): ...this new function.
(do_t_mov_cmp): Forward hireg move/compare to do_t_cpy.
(tinsns): Use do_t_arit3 for adc, and, bic, eor, mul, orr, ror, sbc.
Allow only two arguments for cmn, mvn, neg, tst, rev, rev16, revsh,
sxth, sxtb, uxtb, uxth.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 56)
+++ gas/config/tc-arm.c (revision 57)
@@ -5138,19 +5138,21 @@
static void
do_t_arit (void)
{
+ if (inst.instruction == T_OPCODE_MUL
+ && inst.operands[0].reg == inst.operands[1].reg)
+ as_tsktsk (_("Rs and Rd must be different in MUL"));
+
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+}
+
+/* Fake three-argument form for instructions that take three arguments
+ in ARM mode, e.g. you may write "adc r0,r0,r1" instead of "adc r0,r1". */
+static void
+do_t_arit3 (void)
+{
if (inst.operands[2].present)
{
- /* Three operand format not allowed for TST, CMN, NEG and MVN.
- (It isn't allowed for CMP either, but that isn't handled by this
- function.) */
- if (inst.instruction == T_OPCODE_TST
- || inst.instruction == T_OPCODE_CMN
- || inst.instruction == T_OPCODE_NEG
- || inst.instruction == T_OPCODE_MVN)
- {
- inst.error = BAD_ARGS;
- return;
- }
if (inst.operands[0].reg != inst.operands[1].reg)
{
inst.error = _("dest and source1 must be the same register");
@@ -5158,12 +5160,7 @@
}
inst.operands[1].reg = inst.operands[2].reg;
}
- if (inst.instruction == T_OPCODE_MUL
- && inst.operands[0].reg == inst.operands[2].reg)
- as_tsktsk (_("Rs and Rd must be different in MUL"));
-
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
+ do_t_arit ();
}
/* ARM V5 Thumb BLX (argument parse)
@@ -5396,12 +5393,7 @@
inst.instruction |= inst.operands[1].reg << 3;
}
else
- {
- /* Opcode in inst.instruction is already correct. */
- inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
- inst.instruction |= (inst.operands[0].reg & 0x7);
- inst.instruction |= inst.operands[1].reg << 3;
- }
+ do_t_cpy ();
}
else
{
@@ -7629,9 +7621,9 @@
static const struct asm_opcode tinsns[] =
{
#define THUMB_VARIANT ARM_EXT_V4T /* Thumb v1 (ARMv4T). */
- TI(adc, 4140, 3, (RL, RL, oRL), t_arit),
+ TI(adc, 4140, 3, (RL, RL, oRL), t_arit3),
TI(add, 0000, 3, (RR, RR_EXi, oRR_EXi), t_add_sub),
- TI(and, 4000, 3, (RL, RL, oRL), t_arit),
+ TI(and, 4000, 3, (RL, RL, oRL), t_arit3),
TI(asr, 4100, 3, (RL, RL_EXi, oRL_EXi), t_shift),
TI(b, e7fe, 1, (EXP), t_branch12),
TI(beq, d0fe, 1, (EXP), t_branch9),
@@ -7652,12 +7644,12 @@
TI(bgt, dcfe, 1, (EXP), t_branch9),
TI(ble, ddfe, 1, (EXP), t_branch9),
TI(bal, defe, 1, (EXP), t_branch9),
- TI(bic, 4380, 3, (RL, RL, oRL), t_arit),
+ TI(bic, 4380, 3, (RL, RL, oRL), t_arit3),
TI(bl, f7fffffe, 1, (EXP), t_branch23),
TI(bx, 4700, 1, (RR), t_bx),
- TI(cmn, 42c0, 3, (RL, RL, oRL), t_arit),
+ TI(cmn, 42c0, 2, (RL, RL), t_arit),
TI(cmp, 4280, 2, (RR, RR_EXi), t_mov_cmp),
- TI(eor, 4040, 3, (RL, RL, oRL), t_arit),
+ TI(eor, 4040, 3, (RL, RL, oRL), t_arit3),
TI(ldmia, c800, 2, (RLw, REGLST), t_ldmstm),
TI(ldr, 5800, 2, (RL, ADDR), t_ldst),
TI(ldrb, 5c00, 2, (RL, ADDR), t_ldst),
@@ -7669,21 +7661,21 @@
TI(lsl, 4080, 3, (RL, RL_EXi, oRL_EXi), t_shift),
TI(lsr, 40c0, 3, (RL, RL_EXi, oRL_EXi), t_shift),
TI(mov, 4600, 2, (RR, RR_EXi), t_mov_cmp),
- TI(mul, 4340, 3, (RL, RL, oRL), t_arit),
- TI(mvn, 43c0, 3, (RL, RL, oRL), t_arit),
- TI(neg, 4240, 3, (RL, RL, oRL), t_arit),
- TI(orr, 4300, 3, (RL, RL, oRL), t_arit),
+ TI(mul, 4340, 3, (RL, RL, oRL), t_arit3),
+ TI(mvn, 43c0, 2, (RL, RL), t_arit),
+ TI(neg, 4240, 2, (RL, RL), t_arit),
+ TI(orr, 4300, 3, (RL, RL, oRL), t_arit3),
TI(pop, bc00, 1, (REGLST), t_push_pop),
TI(push, b400, 1, (REGLST), t_push_pop),
- TI(ror, 41c0, 3, (RL, RL, oRL), t_arit),
- TI(sbc, 4180, 3, (RL, RL, oRL), t_arit),
+ TI(ror, 41c0, 3, (RL, RL, oRL), t_arit3),
+ TI(sbc, 4180, 3, (RL, RL, oRL), t_arit3),
TI(stmia, c000, 2, (RLw, REGLST), t_ldmstm),
TI(str, 5000, 2, (RL, ADDR), t_ldst),
TI(strb, 5400, 2, (RL, ADDR), t_ldst),
TI(strh, 5200, 2, (RL, ADDR), t_ldst),
TI(swi, df00, 1, (EXP), t_swi),
TI(sub, 8000, 3, (RR, RR_EXi, oRR_EXi), t_add_sub),
- TI(tst, 4200, 3, (RL, RL, oRL), t_arit),
+ TI(tst, 4200, 2, (RL, RL), t_arit),
/* Pseudo ops: */
TI(adr, 000f, 2, (RL, EXP), t_adr),
TI(nop, 46c0, 0, (), noargs), /* mov r8,r8 */
@@ -7698,14 +7690,14 @@
TI(cpsie, b660, 1, (CPSF), imm0),
TI(cpsid, b670, 1, (CPSF), imm0),
TI(cpy, 4600, 2, (RR, RR), t_cpy),
- TI(rev, ba00, 3, (RL, RL, oRL), t_arit),
- TI(rev16, ba40, 3, (RL, RL, oRL), t_arit),
- TI(revsh, bac0, 3, (RL, RL, oRL), t_arit),
+ TI(rev, ba00, 2, (RL, RL), t_arit),
+ TI(rev16, ba40, 2, (RL, RL), t_arit),
+ TI(revsh, bac0, 2, (RL, RL), t_arit),
TI(setend, b650, 1, (ENDI), t_setend),
- TI(sxth, b200, 3, (RL, RL, oRL), t_arit),
- TI(sxtb, b240, 3, (RL, RL, oRL), t_arit),
- TI(uxth, b280, 3, (RL, RL, oRL), t_arit),
- TI(uxtb, b2c0, 3, (RL, RL, oRL), t_arit),
+ TI(sxth, b200, 2, (RL, RL), t_arit),
+ TI(sxtb, b240, 2, (RL, RL), t_arit),
+ TI(uxth, b280, 2, (RL, RL), t_arit),
+ TI(uxtb, b2c0, 2, (RL, RL), t_arit),
#undef THUMB_VARIANT
#define THUMB_VARIANT ARM_EXT_V6K