Bug 49211 - MMIX: Code generation broken, when using global variables
Summary: MMIX: Code generation broken, when using global variables
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.6.0
: P3 blocker
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-28 14:52 UTC by Nils Asmussen
Modified: 2011-05-30 15:22 UTC (History)
2 users (show)

See Also:
Host: Ubuntu on x86_64
Target: MMIX
Build: gcc-4.6.0 with binutils-2.21
Known to work:
Known to fail:
Last reconfirmed: 2011-05-30 14:25:18


Attachments
Contains the object-file and the executable (863 bytes, application/octet-stream)
2011-05-28 14:52 UTC, Nils Asmussen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nils Asmussen 2011-05-28 14:52:48 UTC
Created attachment 24386 [details]
Contains the object-file and the executable

I hope it is no missunderstanding, but as it seems, the code generation is wrong when using global variables (I'm wondering because it is such a basic thing).

For example, take the following C file:
----
struct foo {
	int x,y;
};

static struct foo f;
static int x;

static void func1(int *i) {
}
static void func2(struct foo *pf) {
}

int main(void) {
	int a;
	f.x = 0;
	f.y = 1;
	x = 2;
	func1(&x);
	func1(&a);
	func2(&f);
	return 0;
}
----

I'm using the following commands to build the executable:
$ mmix-elf-escape-gcc -o test.o -c test.c
$ mmix-elf-escape-gcc -nostdlib -o test test.o

The disassembly for the main-function is:
----
0000000000000040 <main>:
  40:	27fefe10 	subu $254,$254,16
  44:	affdfe08 	stou $253,$254,8
  48:	23fdfe10 	addu $253,$254,16
  4c:	fe000004 	get $0,rJ
  50:	e3010000 	setl $1,0x0
  54:	ab01fe00 	sttu $1,$254,0
  58:	e3010001 	setl $1,0x1
  5c:	ab01fe04 	sttu $1,$254,4
  60:	e3010002 	setl $1,0x2
  64:	ab01fe08 	sttu $1,$254,8
  68:	2303fe08 	addu $3,$254,8
  6c:	f302ffe5 	pushj $2,0 <_start.>
  70:	f6040000 	put rJ,$0
  74:	2701fd0c 	subu $1,$253,12
  78:	c1030100 	set $3,$1
  7c:	f302ffe1 	pushj $2,0 <_start.>
  80:	f6040000 	put rJ,$0
  84:	2303fe00 	addu $3,$254,0
  88:	f302ffe6 	pushj $2,20 <func2>
  8c:	f6040000 	put rJ,$0
  90:	e3000000 	setl $0,0x0
  94:	8dfdfe08 	ldo $253,$254,8
  98:	23fefe10 	addu $254,$254,16
  9c:	f8010000 	pop 1,0
----

That means, the code expects, that f is located at $254, offset 0. But $254 is the frame-pointer according to http://www.bitrange.com/mmix/mmixfest-2001/mmixabi.html. The example shows a few other usages, that are wrong for the same reason. Note that it is correct for the local variable.

For the case that it helps, I've attached the object file and the executable.

I hope that the fix is easy. It would be really nice to know shortly how to resolve that, because before that, I think one can't do anything useful with gcc for MMIX :/
Comment 1 Hans-Peter Nilsson 2011-05-30 14:24:52 UTC
With -nostdlib, you're basically disabling the startup code that is supposed to setup everything. If it still doesn't work without -nostdlib, then I'll have a look.
Comment 2 Hans-Peter Nilsson 2011-05-30 14:29:32 UTC
See gcc/config/mmix/crtn.asm, where the global registers used by the ABI are allocated.
Comment 3 Nils Asmussen 2011-05-30 14:47:40 UTC
Thanks for your reply!

Perhaps I miss something, but I've no idea how that should work. Regardless of whether $254 is initialized previously or not (in my case, it's a bootloader, so there is no stdlib and no crt*, but I have to do that myself), using the stack-pointer to access global variables can't work, right? Lets suppose, that the offset in main is correct. That would mean, that x is located at $254 + 8. But $254 is changed (of course) at the beginning and end of a function (and nowhere else). If func2 accesses x as well, gcc generates code to access it at $254 + 8. So, it expects it to be always at offset 8 from $254, but of course that can't work, because $254 changes.
Comment 4 Hans-Peter Nilsson 2011-05-30 14:59:06 UTC
(In reply to comment #3)
> Perhaps I miss something, but I've no idea how that should work.

Writing a bootloader, you really should.

> Regardless of
> whether $254 is initialized previously or not (in my case, it's a bootloader,
> so there is no stdlib and no crt*, but I have to do that myself), using the
> stack-pointer to access global variables can't work, right?

The key words are "setup" and "allocated" not "initialized".

Again, I suggest you have a look at crtn.asm, in particular these lines:

% This must be the last file on the link-line, allocating global registers
% from the top.

% Register $254 is the stack-pointer.
sp GREG

So, if you leave that out, the global-register-allocation machinery in the linker will allocate registers starting from the topmost, which is $254 ($255 being a scratch register).
Comment 5 Nils Asmussen 2011-05-30 15:22:37 UTC
> Again, I suggest you have a look at crtn.asm, in particular these lines:
> 
> % This must be the last file on the link-line, allocating global registers
> % from the top.
> 
> % Register $254 is the stack-pointer.
> sp GREG
> 
> So, if you leave that out, the global-register-allocation machinery in the
> linker will allocate registers starting from the topmost, which is $254 ($255
> being a scratch register).

Oh, ok. I thought in a different direction :/
Then it's perfectly clear. Thanks!