This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]