Hi Kashyap,

> 
> >> Pil32 and miniPicoLisp are written in C, and C does not support calling 
> >> other functions in a generic way. This is one of the reasons pil64 was 
> >> written in assembly (in addition to stack control and CPU status bits).
> 
> Could you please throw some more light on the "stack control" and "CPU
> status bits". I imagine that "CPU status bits" should be easy with
> inline assembly right? (although potentially introducing a bunch of
> #ifdef's for individual platform/compiler). I am not sure of the stack
> control though.

Yes, with inline assembly you gain access to the CPU status bits. But it does
not help much, as these bits need to be handled by the code all over the
function (and even across function calls, see below), so you probably end up
writing *all* in inline assemtly.

As an example, take the addition of multi-word numbers (bignums). At each step,
you add two single words from each number, *plus* the carry bit (a CPU status
register bit), and you get a new carry bit for the next step.

As C does not allow access to the carry bit, you have to do ugly and inefficient
tricks, by looking at the most significant bit of the result and trying to
detect an overflow. For example, in bigAdd() in pil32's src/big.c:

   carry = (unDig(src) & ~1) > num(setDig(dst, (unDig(src) & ~1) + (unDig(dst) 
& ~1)));


The assembly code in Pil64 does not only use the carry bit, but also the zero-
and sign bits. This makes it possible to pass and return these bits to/from
functions, and have them tested by the caller directly:

   call fun  # fun returns the zero bit set or unset
   jz bar    # Conditional jump

C code does not support this. Instead, a number is returned in a register, this
number needs in turn to be *compared* to zero by the caller, to obtain the same
zero-bit as was directly returned in the assembly version.


Concerning the stack, assembly code can handle the hardware stack pointer just
like any other register. You can read it

   ld A S  # Get stack pointer into A

or set it

   ld S A  # Store A in stack pointer

Such operations are needed for example to set and restore the stacks in
coroutine switching, or to check for stack overflows.


LLVM as advantages here, as it at least supports a kind of carry bit (though not
other CPU flags), and has operators to get and set the stack pointer. Thus,
Pil21, which compiles to LLVM-IR, is a kind of compromize between an
implementation in C and a full-control assembly implementation.

☺/ A!ex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to