[gnu.gcc.bug] ns32k shifting in gcc 1.34

franzen@UUNET.UU.NET ("Marco Franzen") (03/22/89)

Gcc generates ASHi/LSHi instructions for the 32000 series with shift
amounts greater (or equal?) than the operand sizes. According to the
Instruction Set Reference Manual this is wrong (and doesn't work
indeed on the 32332 and 32016), e.g.:

	The count operand value must be within the range -7 to +7 for
	the ASHB form, -15 to +15 for the ASHW form, and -31 to +31
	for the ASHD form.


The ns32k.md contains definitions like

(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "=g")
	(ashift:SI (match_operand:SI 1 "general_operand" "0")
		   (and:SI (match_operand:SI 2 "general_operand" "rmn")
			   (const_int 31))))]
  ""
  "ashd %2,%0")

that lead it to generate too big shift amounts. Instead of the and:SI
a constraint (which?) should have been used.


I have encountered this in bison/machine.h:

# define	SETBIT(x, i)	((x)[(i)>>5] |= (1<<((i) & 31)))

When optimizing, the `& 31' doesn't take place. It generates

	movd r2,r0
	ashd -5,r0
	movqd 1,r1
	ashd r2,r1	<------- r2 & 31 implicitly assumed!
	ord r1,0(r7)[r0:d]

(instead of simply sbitd r2,0(r7) for this whole block).

Marco Franzen	                           franzen@tubsibr.UUCP
SINIX-Referenzzentrum         franzen%tubsibr.UUCP@uni-dortmund.DE
Institut fuer Betriebssysteme  	           franzen@dbsinf6.BITNET
	und Rechnerverbund
Techn. Univ. Braunschweig
Bueltenweg 74/75
D-3300 Braunschweig