🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Andrew Klossner Fri, 08 Sep 1989 20:44
inline function result store causes 'bus error'
#401
Author: Andrew Klossner
Date: Fri, 08 Sep 1989 20:44
98 lines
3117 bytes
At the end of this note is a program which was whittled down from
libg++/src/BitStream.cc.  It illustrates a problem which causes G++ to
generate a fullword store to an address that is not fullword aligned.
GCC does not share this problem.  This is from GCC 1.35 and G++ 1.35.1-,
with m88k back-end work from Michael Meissner (meissner@dg-rtp.DG.COM).

qq() is an inline function which returns an unsigned short.
e is a local variable, declared unsigned short.
The statement

	unsigned short e = qq(p, b, 0, 0);

compiles to code which, on the 88k, ends with

	st	 r24,r30,0x2a  {write r24 to offset 0x2a from the FP}

which is improper because 0x2a is not a multiple of 4.
I have observed similar bad code from a 68k G++ compiler.

While expanding the inline function, integrate.c does this:

      /* If function's value was promoted before return,
	 avoid machine mode mismatch when we substitute INLINE_TARGET.
	 But TARGET is what we will return to the caller.  */
      if (arriving_mode != departing_mode)
	inline_target = gen_rtx (SUBREG, arriving_mode, target, 0);

and so builds this insn:

	(insn/i 37 36 38 (set (subreg:SI (reg/v:HI 37) 0)
	       (reg:SI 56)) -1 (nil)
	   (nil))

then, while spilling registers, reload changes it to

(insn 217 221 41 (set (subreg:SI (mem:HI (plus:SI (reg:SI 30)
                   (const_int 44))) 0)
       (reg:SI 24)) -1 (nil)
   (nil))

Then final calls alter_subreg to replace the (subreg ...) with

	(mem:SI (plus:SI (reg:SI 30)
	        (const_int 42)))

My gut feel is that the (set (subreg ...)) shouldn't have been built in
the first place, but I'm not fluent in GCC/G++ internals.  I would be
grateful for any suggestions.

============================== the program ==============================
static inline unsigned short pp(int a)
{
	return a;
}

static inline unsigned short qq(unsigned short a[], int b, int c, int d)
{
	if (b < c)
		return (a[b] >> 1) |
		       (a[b+1] << (16 - d));
	else
		return (a[b] >> d);
}

int search(unsigned short* p)
{
	int a;
	int b;
	int c;
	int d;
	int x;
	unsigned short e = qq(p, b, 0, 0);
	unsigned short g;
	unsigned short h;

	for (;;)
	{
		if (a == e)
		{
			int f = b;
			for (;;)
			{
				if (++f > d || ++d > c)
					return 0;
				g = qq(0, 0, c, c);
				h = qq(p, 0, a, a);
				x += h;
				g &= pp(2 - a);
				if (g != h)
					break;
			}
		}
	}
}
========================================================================

  -=- Andrew Klossner   (uunet!tektronix!frip.WV.TEK!andrew)    [UUCP]
                        (andrew%frip.wv.tek.com@relay.cs.net)   [ARPA]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads