This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (57/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 03:00:30 -0700
- Subject: Thumb32 assembler (57/69)
Now we're finally starting to introduce new syntax. This patch
introduces ARM pseudo-ops corresponding to all Thumb instructions that
didn't already have an ARM correspondent.
zw
* config/tc-arm.c (do_push_pop, do_shift): New functions.
(insns): Add Thumb-compatibility pseudo ops:
cpy lsl lsls lsr lsrs asr asrs ror rors neg negs push pop.
* testsuite/gas/arm/tcompat.s, testsuite/gas/arm/tcompat.d:
New dump test.
* testsuite/gas/arm/arm.exp: Run it.
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 59)
+++ gas/config/tc-arm.c (revision 60)
@@ -4791,6 +4791,17 @@
encode_addr_mode_2_arm (0, /*is_t=*/FALSE);
}
+static void
+do_push_pop (void)
+{
+ inst.operands[1] = inst.operands[0];
+ memset (&inst.operands[0], 0, sizeof inst.operands[0]);
+ inst.operands[0].isreg = 1;
+ inst.operands[0].writeback = 1;
+ inst.operands[0].reg = REG_SP;
+ do_ldmstm ();
+}
+
/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
word at the specified address and the following word
respectively.
@@ -4863,6 +4874,26 @@
}
static void
+do_shift (void)
+{
+ unsigned int Rm = (inst.operands[1].present
+ ? inst.operands[1].reg
+ : inst.operands[0].reg);
+
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= Rm;
+ if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
+ {
+ constraint (inst.operands[0].reg != Rm,
+ _("source1 and dest must be same register"));
+ inst.instruction |= inst.operands[2].reg << 8;
+ inst.instruction |= SHIFT_BY_REG;
+ }
+ else
+ inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+}
+
+static void
do_smi (void)
{
inst.reloc.type = BFD_RELOC_ARM_SMI;
@@ -6342,6 +6373,23 @@
CM(adr,l, 28f0000, 2, (RR, EXP), adrl),
CE(nop, 1a00000, 1, (oI255c), nop),
+ /* Thumb-compatibility pseudo ops. Note that the 16-bit Thumb
+ instruction is equivalent to the s-form of the ARM instruction
+ in all cases where that form exists. */
+ CE(cpy, 1a00000, 2, (RR, RR), rd_rm), /* mov */
+ CE(lsl, 1a00000, 3, (RR, oRR, RR_EXi), shift),
+ CM(lsl,s, 1b00000, 3, (RR, oRR, RR_EXi), shift),
+ CE(lsr, 1a00020, 3, (RR, oRR, RR_EXi), shift),
+ CM(lsr,s, 1b00020, 3, (RR, oRR, RR_EXi), shift),
+ CE(asr, 1a00040, 3, (RR, oRR, RR_EXi), shift),
+ CM(asr,s, 1b00040, 3, (RR, oRR, RR_EXi), shift),
+ CE(ror, 1a00060, 3, (RR, oRR, RR_EXi), shift),
+ CM(ror,s, 1b00060, 3, (RR, oRR, RR_EXi), shift),
+ CE(neg, 2600000, 2, (RR, RR), rd_rn), /* rsbs */
+ CM(neg,s, 2700000, 2, (RR, RR), rd_rn),
+ CE(push, 92d0000, 1, (REGLST), push_pop), /* stmfd */
+ CE(pop, 8bd0000, 1, (REGLST), push_pop), /* ldmfd */
+
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V2 /* ARM 2 - multiplies. */
CE(mul, 0000090, 3, (RRnpc, RRnpc, RR), mul),
===================================================================
Index: gas/testsuite/gas/arm/tcompat.d
--- gas/testsuite/gas/arm/tcompat.d (revision 0)
+++ gas/testsuite/gas/arm/tcompat.d (revision 60)
@@ -0,0 +1,38 @@
+#name: ARM Thumb-compat pseudos
+#objdump: -dr --prefix-addresses --show-raw-insn
+#as:
+
+# Test the ARM pseudo instructions that exist for Thumb source compatibility
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+
+0+00 <[^>]*> 91a00000 ? movls r0, r0
+0+04 <[^>]*> e1a09000 ? mov r9, r0
+0+08 <[^>]*> e1a00009 ? mov r0, r9
+0+0c <[^>]*> e1a0c00e ? mov ip, lr
+0+10 <[^>]*> 91b09019 ? movlss r9, r9, lsl r0
+0+14 <[^>]*> 91a00910 ? movls r0, r0, lsl r9
+0+18 <[^>]*> e1b00880 ? movs r0, r0, lsl #17
+0+1c <[^>]*> e1a00889 ? mov r0, r9, lsl #17
+0+20 <[^>]*> 91b09039 ? movlss r9, r9, lsr r0
+0+24 <[^>]*> 91a00930 ? movls r0, r0, lsr r9
+0+28 <[^>]*> e1b008a0 ? movs r0, r0, lsr #17
+0+2c <[^>]*> e1a008a9 ? mov r0, r9, lsr #17
+0+30 <[^>]*> 91b09059 ? movlss r9, r9, asr r0
+0+34 <[^>]*> 91a00950 ? movls r0, r0, asr r9
+0+38 <[^>]*> e1b008c0 ? movs r0, r0, asr #17
+0+3c <[^>]*> e1a008c9 ? mov r0, r9, asr #17
+0+40 <[^>]*> 91b09079 ? movlss r9, r9, ror r0
+0+44 <[^>]*> 91a00970 ? movls r0, r0, ror r9
+0+48 <[^>]*> e1b008e0 ? movs r0, r0, ror #17
+0+4c <[^>]*> e1a008e9 ? mov r0, r9, ror #17
+0+50 <[^>]*> e2690000 ? rsb r0, r9, #0 ; 0x0
+0+54 <[^>]*> e2709000 ? rsbs r9, r0, #0 ; 0x0
+0+58 <[^>]*> 92600000 ? rsbls r0, r0, #0 ; 0x0
+0+5c <[^>]*> 92799000 ? rsblss r9, r9, #0 ; 0x0
+0+60 <[^>]*> e92d000e ? stmdb sp!, {r1, r2, r3}
+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}
===================================================================
Index: gas/testsuite/gas/arm/tcompat.s
--- gas/testsuite/gas/arm/tcompat.s (revision 0)
+++ gas/testsuite/gas/arm/tcompat.s (revision 60)
@@ -0,0 +1,29 @@
+ @ ARM instructions defined for source compatibility with Thumb.
+ .macro shift op opls ops oplss
+ \oplss r9,r0
+ \opls r0,r0,r9
+ \ops r0,#17
+ \op r0,r9,#17
+ .endm
+ .text
+ .global l
+l:
+ cpyls r0,r0
+ cpy r9,r0
+ cpy r0,r9
+ cpy ip,lr
+
+ shift lsl lslls lsls lsllss
+ shift lsr lsrls lsrs lsrlss
+ shift asr asrls asrs asrlss
+ shift ror rorls rors rorlss
+
+ neg r0,r9
+ negs r9,r0
+ negls r0,r0
+ neglss r9,r9
+
+ push {r1,r2,r3}
+ pushls {r2,r4,r6,r8,pc}
+ pop {r1,r2,r3}
+ popls {r2,r4,r6,r8,pc}
===================================================================
Index: gas/testsuite/gas/arm/arm.exp
--- gas/testsuite/gas/arm/arm.exp (revision 59)
+++ gas/testsuite/gas/arm/arm.exp (revision 60)
@@ -53,6 +53,7 @@
run_dump_test "thumbv6"
run_dump_test "thumbv6k"
run_dump_test "arch6zk"
+ run_dump_test "tcompat"
run_errors_test "vfp-bad" "-mfpu=vfp" "VFP errors"
run_errors_test "req" "-mcpu=arm7m" ".req errors"