public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Thumb32 assembler (58/69)
@ 2005-04-26 10:18 Zack Weinberg
  2005-04-26 16:32 ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2005-04-26 10:18 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]


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


[-- Attachment #2: Type: text/plain, Size: 512 bytes --]


	* 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.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 58.diff.txt --]
[-- Type: text/x-patch; name=58.diff.txt, Size: 7141 bytes --]

===================================================================
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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (58/69)
  2005-04-26 10:18 Thumb32 assembler (58/69) Zack Weinberg
@ 2005-04-26 16:32 ` Paul Brook
  2005-04-26 16:34   ` Paul Brook
  2005-04-26 17:03   ` Richard Earnshaw
  0 siblings, 2 replies; 5+ messages in thread
From: Paul Brook @ 2005-04-26 16:32 UTC (permalink / raw)
  To: binutils; +Cc: Zack Weinberg, binutils

On Tuesday 26 April 2005 11:01, Zack Weinberg wrote:
> 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).

Unfortunately gcc (incorrectly) outputs the three argument form
mul rd, rd, rm
I'll fix gcc, but I guess we want to support this for backwards compatibility.

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (58/69)
  2005-04-26 16:32 ` Paul Brook
@ 2005-04-26 16:34   ` Paul Brook
  2005-04-26 17:03   ` Richard Earnshaw
  1 sibling, 0 replies; 5+ messages in thread
From: Paul Brook @ 2005-04-26 16:34 UTC (permalink / raw)
  To: binutils; +Cc: Zack Weinberg, binutils

On Tuesday 26 April 2005 11:01, Zack Weinberg wrote:
> 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).

Unfortunately gcc (incorrectly) outputs the three argument form
mul rd, rd, rm
I'll fix gcc, but I guess we want to support this for backwards compatibility.

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (58/69)
  2005-04-26 16:32 ` Paul Brook
  2005-04-26 16:34   ` Paul Brook
@ 2005-04-26 17:03   ` Richard Earnshaw
  2005-04-26 17:07     ` Richard Earnshaw
  1 sibling, 1 reply; 5+ messages in thread
From: Richard Earnshaw @ 2005-04-26 17:03 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils, Zack Weinberg, binutils

On Tue, 2005-04-26 at 17:32, Paul Brook wrote:
> On Tuesday 26 April 2005 11:01, Zack Weinberg wrote:
> > 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).
> 
> Unfortunately gcc (incorrectly) outputs the three argument form
> mul rd, rd, rm
> I'll fix gcc, but I guess we want to support this for backwards compatibility.
> 
> Paul

I think the restriction should be just lifted entirely for Thumb[1].

The ARMv6 ARM says that all known implementations of v4t and later can
handle any register overlap for MUL, so I'm inclined to just relax the
compiler and assembler constraints entirely.

R.

[1] The restriction came about because of the way the multiplier was
implemented on the first ARM devices, making use of the barrel shifter
and multiple iterations through the ALU.  With the addition of a
dedicated mulitplier unit in the arm7m this restriction effectively went
away.  All Thumb devices have been implemented with a dedicated multiply
unit.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thumb32 assembler (58/69)
  2005-04-26 17:03   ` Richard Earnshaw
@ 2005-04-26 17:07     ` Richard Earnshaw
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Earnshaw @ 2005-04-26 17:07 UTC (permalink / raw)
  To: Paul Brook; +Cc: binutils, Zack Weinberg, binutils

On Tue, 2005-04-26 at 17:32, Paul Brook wrote:
> On Tuesday 26 April 2005 11:01, Zack Weinberg wrote:
> > 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).
> 
> Unfortunately gcc (incorrectly) outputs the three argument form
> mul rd, rd, rm
> I'll fix gcc, but I guess we want to support this for backwards compatibility.
> 
> Paul

I think the restriction should be just lifted entirely for Thumb[1].

The ARMv6 ARM says that all known implementations of v4t and later can
handle any register overlap for MUL, so I'm inclined to just relax the
compiler and assembler constraints entirely.

R.

[1] The restriction came about because of the way the multiplier was
implemented on the first ARM devices, making use of the barrel shifter
and multiple iterations through the ALU.  With the addition of a
dedicated mulitplier unit in the arm7m this restriction effectively went
away.  All Thumb devices have been implemented with a dedicated multiply
unit.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-26 16:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-26 10:18 Thumb32 assembler (58/69) Zack Weinberg
2005-04-26 16:32 ` Paul Brook
2005-04-26 16:34   ` Paul Brook
2005-04-26 17:03   ` Richard Earnshaw
2005-04-26 17:07     ` Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).