Skip to content

A Little Bit of Success

August 14, 2015

Poking at llvm again I’ve been able to get call’s working a bit. That involved changing the call definition in instrinfo.td to:

let isCall = 1, Defs = [LR], Uses = [SP] in {
  def COSCall  : InstCOSLBR<(outs), (ins bl_target:$func),
                "SEP 4\n\tDW\t$func",
                [(leg_call tglobaladdr:$func)]>{
        bits<32> func;
        let Inst{7-0} = 0xD4; //SEP 4 call routine
        let Inst{23-8} = func{15-0};
  }

I also had to edit a section of LEGTargetLowering::LowerCall in LEGISelLowering.cpp. The first line below is the LEG original and the section following is adapted from the Z80 target.

//  Callee = DAG.getGlobalAddress(G->getGlobal(), dl, getPointerTy(), 0);
//from z80 below

  // If the callee is a GlobalAddress node (quite common, every direct call is)
  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
  // Likewise ExternalSymbol -> TargetExternalSymbol.
  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);

//end from z80

The leg original loaded the address into R0 then branched to it. The part with the external address is not useful as it stands because the LEG code ahead of it won’t allow it but i’ve just left it for now.

I can now translate a simple C program with a function call:

>cat loop.c
void flipQ(void);

int main(void){
  while(1){
    flipQ();
  }
  return 0;
}
>./ctos.sh loop
>cat loop.s
main:
.LBB0_1:
	SEP 4
	DW	flipQ
	LBR .LBB0_1
$$Ltmp0:
	;size	main, ($$Ltmp0)-main


	;ident	"clang version 3.6.0 "
	.section	".note.GNU-stack","",@progbits
>

It will also go through the motions of generating a .elf file which is neat. I’m not sure whether the contents is useful though. It’s a bit tricky to test this stuff by the way because llvm helpfully optimizes away most simple examples!

Things To Try:

  • switch to big-endian
  • set points and ints to 16 bit
  • describe cosmac registers as 8 and 16 bit
  • lower formal arguments and function prolog
  • asm parser
  • ELF parsing/fixup
Advertisements

From → LLVM

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: