[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.3.2 A simple function call to printf

Again, here is the code for the example:

 
#include <stdio.h>
#include "lightning.h"

static jit_insn codeBuffer[1024];

typedef void (*pvfi)(int);      /* Pointer to Void Function of Int */

int main()
{
  pvfi          myFunction;             /* ptr to generated code */
  char          *start, *end;           /* a couple of labels */
  int           in;                     /* to get the argument */

  myFunction = (pvfi) (jit_set_ip(codeBuffer).vptr);
  start = jit_get_ip().ptr;
  jit_prolog(1);
  in = jit_arg_i();
  jit_movi_p(JIT_R0, "generated %d bytes\n");
  jit_getarg_i(JIT_R1, in);
  jit_prepare(2);
    jit_pusharg_i(JIT_R1);              /* push in reverse order */
    jit_pusharg_p(JIT_R0);
  jit_finish(printf);
  jit_ret();
  end = jit_get_ip().ptr;

  /* call the generated code, passing its size as argument */
  jit_flush_code(start, end);
  myFunction(end - start);
}

The function shows how many bytes were generated. Most of the code is not very interesting, as it resembles very closely the program presented in A function which increments a number by one.

For this reason, we're going to concentrate on just a few statements.

start = jit_get_ip().ptr;
...
end = jit_get_ip().ptr;
These two instruction call the jit_get_ip macro which was mentioned in A function which increments a number by one too. In this case we use the only field of jit_code that is not a function pointer: ptr, which is a simple char *.

jit_movi_p(JIT_R0, "generated %d bytes\n");
Note the use of the `p' type specifier, which automatically casts the second parameter to an unsigned long to make the code more clear and less cluttered by typecasts.

jit_prepare(2);
jit_pusharg_i(JIT_R1);
jit_pusharg_p(JIT_R0);
jit_finish(printf);
Once the arguments to printf have been put in general-purpose registers, we can start a prepare/pusharg/finish sequence that moves the argument to either the stack or registers, then calls printf, then cleans up the stack. Note how GNU lightning abstracts the differences between different architectures and ABI's -- the client program does not know how parameter passing works on the host architecture.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Alistair Turnbull on April, 12 2005 using texi2html