This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (58/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 03:01:12 -0700
- Subject: Thumb32 assembler (58/69)
More ARM/Thumb syntax compatibility: teach the ARM encoders to handle
an omitted second oprand, and adjust the way three-operand Thumb MUL
works (it's the third, not the second, operand that needs to equal the
first).
zw
* config/tc-arm.c (do_arit): Handle absent operand 1.
(do_mul): Handle absent operand 2.
(do_t_arit): No longer handles mul.
(do_t_mul): New function.
(insns): Make second argument optional for all "arit" instructions.
Make third argument optional for mul.
(tinsns): Handle mul with t_mul. Handle ror with t_arit, and remove
optional second argument.
* testsuite/gas/arm/tcompat.s, testsuite/gas/arm/tcompat.d:
Test two-operand forms of ARM instructions, three-operand forms
of Thumb instructions.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 60)
+++ gas/config/tc-arm.c (revision 61)
@@ -4274,6 +4274,8 @@
static void
do_arit (void)
{
+ if (!inst.operands[1].present)
+ inst.operands[1].reg = inst.operands[0].reg;
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg << 16;
encode_shifter_operand_arm (2);
@@ -4692,6 +4694,8 @@
static void
do_mul (void)
{
+ if (!inst.operands[2].present)
+ inst.operands[2].reg = inst.operands[0].reg;
inst.instruction |= inst.operands[0].reg << 16;
inst.instruction |= inst.operands[1].reg;
inst.instruction |= inst.operands[2].reg << 8;
@@ -5058,17 +5062,13 @@
inst.instruction |= inst.operands[0].reg << 4;
}
-/* Handle the Format 4 instructions that do not have equivalents in other
- formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
- BIC and MVN. */
+/* Handle the Format 4 instructions that do not have equivalents in
+ other formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN,
+ ORR, BIC and MVN. */
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;
}
@@ -5291,7 +5291,19 @@
}
}
+static void
+do_t_mul (void)
+{
+ constraint (inst.operands[2].present
+ && 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"));
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+}
+
static void
do_t_setend (void)
{
@@ -6292,26 +6304,26 @@
static const struct asm_opcode insns[] =
{
#define ARM_VARIANT ARM_EXT_V1 /* Core ARM Instructions. */
- CE(and, 0000000, 3, (RR, RR, SH), arit),
- CM(and,s, 0100000, 3, (RR, RR, SH), arit),
- CE(eor, 0200000, 3, (RR, RR, SH), arit),
- CM(eor,s, 0300000, 3, (RR, RR, SH), arit),
- CE(sub, 0400000, 3, (RR, RR, SH), arit),
- CM(sub,s, 0500000, 3, (RR, RR, SH), arit),
- CE(rsb, 0600000, 3, (RR, RR, SH), arit),
- CM(rsb,s, 0700000, 3, (RR, RR, SH), arit),
- CE(add, 0800000, 3, (RR, RR, SH), arit),
- CM(add,s, 0900000, 3, (RR, RR, SH), arit),
- CE(adc, 0a00000, 3, (RR, RR, SH), arit),
- CM(adc,s, 0b00000, 3, (RR, RR, SH), arit),
- CE(sbc, 0c00000, 3, (RR, RR, SH), arit),
- CM(sbc,s, 0d00000, 3, (RR, RR, SH), arit),
- CE(rsc, 0e00000, 3, (RR, RR, SH), arit),
- CM(rsc,s, 0f00000, 3, (RR, RR, SH), arit),
- CE(orr, 1800000, 3, (RR, RR, SH), arit),
- CM(orr,s, 1900000, 3, (RR, RR, SH), arit),
- CE(bic, 1c00000, 3, (RR, RR, SH), arit),
- CM(bic,s, 1d00000, 3, (RR, RR, SH), arit),
+ CE(and, 0000000, 3, (RR, oRR, SH), arit),
+ CM(and,s, 0100000, 3, (RR, oRR, SH), arit),
+ CE(eor, 0200000, 3, (RR, oRR, SH), arit),
+ CM(eor,s, 0300000, 3, (RR, oRR, SH), arit),
+ CE(sub, 0400000, 3, (RR, oRR, SH), arit),
+ CM(sub,s, 0500000, 3, (RR, oRR, SH), arit),
+ CE(rsb, 0600000, 3, (RR, oRR, SH), arit),
+ CM(rsb,s, 0700000, 3, (RR, oRR, SH), arit),
+ CE(add, 0800000, 3, (RR, oRR, SH), arit),
+ CM(add,s, 0900000, 3, (RR, oRR, SH), arit),
+ CE(adc, 0a00000, 3, (RR, oRR, SH), arit),
+ CM(adc,s, 0b00000, 3, (RR, oRR, SH), arit),
+ CE(sbc, 0c00000, 3, (RR, oRR, SH), arit),
+ CM(sbc,s, 0d00000, 3, (RR, oRR, SH), arit),
+ CE(rsc, 0e00000, 3, (RR, oRR, SH), arit),
+ CM(rsc,s, 0f00000, 3, (RR, oRR, SH), arit),
+ CE(orr, 1800000, 3, (RR, oRR, SH), arit),
+ CM(orr,s, 1900000, 3, (RR, oRR, SH), arit),
+ CE(bic, 1c00000, 3, (RR, oRR, SH), arit),
+ CM(bic,s, 1d00000, 3, (RR, oRR, SH), arit),
CE(tst, 1100000, 2, (RR, SH), cmp),
CM(tst,s, 1100000, 2, (RR, SH), cmp),
@@ -6392,8 +6404,8 @@
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V2 /* ARM 2 - multiplies. */
- CE(mul, 0000090, 3, (RRnpc, RRnpc, RR), mul),
- CM(mul,s, 0100090, 3, (RRnpc, RRnpc, RR), mul),
+ CE(mul, 0000090, 3, (RRnpc, RRnpc, oRR), mul),
+ CM(mul,s, 0100090, 3, (RRnpc, RRnpc, oRR), mul),
CE(mla, 0200090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
CM(mla,s, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
@@ -7505,13 +7517,13 @@
TI(lsl, 4080, 3, (RL, oRL, RL_EXi), t_shift),
TI(lsr, 40c0, 3, (RL, oRL, RL_EXi), t_shift),
TI(mov, 4600, 2, (RR, RR_EXi), t_mov_cmp),
- TI(mul, 4340, 3, (RL, oRL, RL), t_arit3),
+ TI(mul, 4340, 3, (RL, RL, oRL), t_mul),
TI(mvn, 43c0, 2, (RL, RL), t_arit),
TI(neg, 4240, 2, (RL, RL), t_arit),
TI(orr, 4300, 3, (RL, oRL, RL), t_arit3),
TI(pop, bc00, 1, (REGLST), t_push_pop),
TI(push, b400, 1, (REGLST), t_push_pop),
- TI(ror, 41c0, 3, (RL, oRL, RL), t_arit3),
+ TI(ror, 41c0, 2, (RL, RL), t_arit),
TI(sbc, 4180, 3, (RL, oRL, RL), t_arit3),
TI(stmia, c000, 2, (RLw, REGLST), t_ldmstm),
TI(str, 5000, 2, (RL, ADDR), t_ldst),
===================================================================
Index: gas/testsuite/gas/arm/tcompat.d
--- gas/testsuite/gas/arm/tcompat.d (revision 60)
+++ gas/testsuite/gas/arm/tcompat.d (revision 61)
@@ -36,3 +36,23 @@
0+64 <[^>]*> 992d8154 ? stmlsdb sp!, {r2, r4, r6, r8, pc}
0+68 <[^>]*> e8bd000e ? ldmia sp!, {r1, r2, r3}
0+6c <[^>]*> 98bd8154 ? ldmlsia sp!, {r2, r4, r6, r8, pc}
+0+70 <[^>]*> e0000001 ? and r0, r0, r1
+0+74 <[^>]*> e0200001 ? eor r0, r0, r1
+0+78 <[^>]*> e0400001 ? sub r0, r0, r1
+0+7c <[^>]*> e0600001 ? rsb r0, r0, r1
+0+80 <[^>]*> e0800001 ? add r0, r0, r1
+0+84 <[^>]*> e0a00001 ? adc r0, r0, r1
+0+88 <[^>]*> e0c00001 ? sbc r0, r0, r1
+0+8c <[^>]*> e0e00001 ? rsc r0, r0, r1
+0+90 <[^>]*> e1800001 ? orr r0, r0, r1
+0+94 <[^>]*> e1c00001 ? bic r0, r0, r1
+0+98 <[^>]*> e0000091 ? mul r0, r1, r0
+0+9c <[^>]*> e1a00000 ? nop \(mov r0,r0\)
+0+a0 <[^>]*> 4148 * adc r0, r1
+0+a2 <[^>]*> 4008 * and r0, r1
+0+a4 <[^>]*> 4388 * bic r0, r1
+0+a6 <[^>]*> 4048 * eor r0, r1
+0+a8 <[^>]*> 4348 * mul r0, r1
+0+aa <[^>]*> 4308 * orr r0, r1
+0+ac <[^>]*> 4188 * sbc r0, r1
+0+ae <[^>]*> 46c0 * nop \(mov r8, r8\)
===================================================================
Index: gas/testsuite/gas/arm/tcompat.s
--- gas/testsuite/gas/arm/tcompat.s (revision 60)
+++ gas/testsuite/gas/arm/tcompat.s (revision 61)
@@ -27,3 +27,32 @@
pushls {r2,r4,r6,r8,pc}
pop {r1,r2,r3}
popls {r2,r4,r6,r8,pc}
+
+ @ Two-argument forms of ARM arithmetic instructions.
+ and r0,r1
+ eor r0,r1
+ sub r0,r1
+ rsb r0,r1
+
+ add r0,r1
+ adc r0,r1
+ sbc r0,r1
+ rsc r0,r1
+
+ orr r0,r1
+ bic r0,r1
+ mul r0,r1
+ nop
+
+ @ Three-argument forms of Thumb arithmetic instructions.
+ .global m
+ .thumb_func
+m:
+ adc r0,r0,r1
+ and r0,r0,r1
+ bic r0,r0,r1
+ eor r0,r0,r1
+ mul r0,r1,r0
+ orr r0,r0,r1
+ sbc r0,r0,r1
+ nop