[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lightning] Lightning arm port

From: Paulo César Pereira de Andrade
Subject: [Lightning] Lightning arm port
Date: Tue, 21 Jun 2011 14:15:03 -0300
User-agent: SquirrelMail/1.4.19


  Out of interest of learning more about arm, I made a simple arm
port of lightning, see

  It has been developed and tested only in qemu, but it pass all
the tests I added to the contrib/check subdirectory in my for in

  Some generic arm details:

o arm has 16 registers
o registers 0-3 are used to pass arguments, extra arguments on stack
o registers 0-3 are also used for return values
o registers 4-9 are callee saved registers
o registers 10,11,13,14 are special purpose, stack/base pointer,
  link register, etc
o register 15 is the program counter
o register 12 is the only truly scratch register
o float/double arguments are passed and returned in registers 0-3
o arguments are not packed, so, like in the mips port, it is
  not easy to follow lightning specification of pushing argument
  right to left...

  Some lightning port implementation details:

o JIT_R0-JIT_R3 were mapped to r0-r3, but that means it needs to
  do some "magic". What it does is to save the registers in
  jit_prolog, and read them in jit_getarg. jit_pusharg overwrites
  those stack values, and jit_finish actually loads the stack
  values just before jumping to the called function.
o JIT_V0-JIT_V3 matches the behavior of other ports, and are callee
  saved registers.
o Since it was implemented soft float, actually by explicitly calling
  libgcc and some libm functions, JIT_FPR0-JIT_FPR5 are mapped to
  stack slots, created in jit_prolog, and every float operation will
  load these values and, save for a few trivial float/double
  operations, call a C function to execute the operation. This means
  there is significant overhead.
o It is important to note that to return a float/double, one must
  do jit_movr_{f,d}(JIT_FPRET, <value>); followed by jit_ret().
  This is because JIT_FPRET is mapped to a special value, and only
  jit_mov* will accept it, because it will load the value in r0-r1.

  Possible/desirable rework:

o Use r0-r3 only for arguments. But requiring one to call
  jit_arg*/jit_getarg* before any operation may be overkill,
  so, it would still need to save arguments in prolog.
  To not use r0-r3 as JIT_R(n), it would mean changing JIT_R_NUM
  to 3, from 4, what is ok. That would mean the register used for
  scratch would be "ip" instead of "r8" and "r9" as is being done
  now (not using "ip" as a scratch register is a design flaw :-)
o r0-r3 actually could be mapped to JIT_FPR0 and JIT_FPR1, but
  that probably would just cause more harm, or possibility of
  subtle bugs due to not saving/reloading.

  But note that I did this port mainly interested on having it to
serve as basis for an arm port of my other/new jit code, based on
lightning :-), that I use in my "hobby" project of a C/C++ like,
dynamically typed language, see ejit* and eemit* files in the
include and lib subdirectories of

most of the hardware independent code is at

and also where I implemented most of the things I commented some
time ago, but that would not be feasible in lightning because
that would mean lightning would become a heavily moving target...
I plan to at some point make the new lightning based jit in
a standalone library, but the initial experience with arm shows
the need of some extra redesign, to work with software and/or
missing instructions like div/mod, e.g. either do not use jit
float registers if they map to software, or have some way to use
a memory pointer as place where the value is, to avoid (extra)
memory round trips, what could open a path to actually "hardware
accelerated" memory instructions in the lightning based jit,
e.g. use x86 instructions that allow a memory operand, and
synthesize it elsewhere...


reply via email to

[Prev in Thread] Current Thread [Next in Thread]