[Mono-list] Re: mono/mint on powerpc

Miguel de Icaza miguel@ximian.com
09 May 2002 22:32:22 -0400

> Another big task is to port mono jitter to ppc. I've been waiting some
> time before things stabilize enough, one time it looked like we will
> maybe start another jitter, but lately it looks like current gets better
> and better. Ask jitter dudes if they think that jitter is ready for
> porting.

My current feeling is that the JIT architecture we have is fine, but if
your risc CPU has some unusual instruction scheduling restrictions, then
I suggest that you write a "layer" that would perform instruction
scheduling after selection.

Imagine (for a second) that you are writing the JIT production rules for
the sparc, and you have something like this:

reg: coni4 1 {
	sparc_sethi (s->code, tree->reg1, tree->data.i >> 10);
	sparc_or_imm (s->code, FALSE, tree->reg1, tree->data.i & 1023, tree->reg1);

and consider the following "x86" definition:

stmt: BR {
	mono_add_jump_info (s, s->code + 1, MONO_JUMP_INFO_BB, tree->data.bb);
	x86_jump32 (s->code, 0); 

Since the SPARC will always execute the next instruction, you would
write the second example for the sparc  like this (given the current JIT

stmt: BR {
	mono_add_jump_info (s, s->code + 1, MONO_JUMP_INFO_BB, tree->data.bb);
	sparc_jmpl (s->code, 0);
	sparc_nop (s->code);

Notice the ugly extra nop in there.  So what I propose for those
architectures that need instruction scheduling is to not generate code
directly there, but instead write a "list" of operations to generate,
like this:

void sparc_sethi (int reg, int value)
	instructions [pc].type = sethi;
	instructions [pc].reg = reg;
	instructions [pc].value = value;
	instructions [pc].is_jmp = false;

void sparc_jmpl (int target)
	instructions [pc].type = jump;
	instructions [pc].value = target;

Then a second phase walks through the list of instructions to generate,
and since it "knows" what registers are used in each instruction, it can
schedule and move things around (where "is_jmp" is used as a re-order

Now, this is just a general overview of the idea;  Seasoned hackers are
probably replying point-by-point to this email pointing out that all the
information we are encoding can be retrieved from the instruction
stream.  And they are right, in the SPARC case, it is so simple to
decode everything we generate, that all we need to do is generate the
code in the first pass (and possibly track in an out-of-band structure a
`do-not-shuffle-things-around-here' barrier) and then do a scheduling
pass that shuffles things around so you can kill that `nop' after a
jump, or you can put another instruction after the sethi and the or.