Re: An assembly question from the past
Thank you Alex, I can see how you would have to end up writing the whole thing in assembly - in the example you shared. Would it be right to say that its only the carry flag that you need or is it just an example and there are other flags too? Can I say that the need is restricted to the use of BigNum? The ability to set/get the stack I presume needs to be compared with setjmp/longjmp - correct? Is setjmp/longjmp insufficient or is it not efficient enough? Regards, Kashyap On Tue, Mar 29, 2022 at 12:31 PM Tomas Hlavaty wrote: > On Tue 29 Mar 2022 at 18:49, Alexander Burger wrote: > > 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))); > [...] > > Concerning the stack, assembly code can handle the hardware stack > pointer just > > like any other register. > > interesting > > Did you consider GCC inline assembly? > What were the reasons you did not use it? > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: An assembly question from the past
On Tue 29 Mar 2022 at 18:49, Alexander Burger wrote: > 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))); [...] > Concerning the stack, assembly code can handle the hardware stack pointer just > like any other register. interesting Did you consider GCC inline assembly? What were the reasons you did not use it? -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: An assembly question from the past
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
An assembly question from the past
Hey Alex, I had reached out to you about the need for assembly in the past and you had mentioned the following - > 'c' implementation of pil32? >> 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. Regards, Kashyap
Re: Bugreport - (sect) passed list with NIL as element
> On Mar 30, 2022, at 0:29, Alexander Burger wrote: > > As Pil64 is obsolete anyway, I strongly recommend to migrate to Pil64. ??? -- Jean-Christophe Helary @brandelune https://mac4translators.blogspot.com https://sr.ht/~brandelune/omegat-as-a-book/ -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Bugreport - (sect) passed list with NIL as element
On Tue, Mar 29, 2022 at 05:29:02PM +0200, Alexander Burger wrote: > As Pil64 is obsolete anyway, I strongly recommend to migrate to Pil64. Oops! Of course I wanted to say "... migrate to Pil21". -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Bugreport - (sect) passed list with NIL as element
Hi Morris, > I might have encountered a bug related to > (sect) and it's handling of NIL as element of > the first passed list: > ... > A possibly related bug can be found with (diff): > ... Thanks for finding these bugs! I was not aware of them. > I encountered this behavior on version 20.7.4 > and am unsure if it already was fixed in a > newer release. Yes, Pil21 shows for all examples the results you expected. As Pil64 is obsolete anyway, I strongly recommend to migrate to Pil64. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Bugreport - (sect) passed list with NIL as element
Hi Alex, I might have encountered a bug related to (sect) and it's handling of NIL as element of the first passed list: : (sect (list NIL) NIL) -> (NIL) # expected () It is not dependent on the second argument being the empty list: : (sect (list 1 2 NIL 4) (list 2 3 4)) -> (2 NIL 4) # expected (2 4) A possibly related bug can be found with (diff): : (diff (list 1 2 NIL 4) NIL) -> (1 2 4) # expected (1 2 NIL 4) : (diff (list 1 2 NIL 4) (list 2 3 4)) -> (1) # expected (1 NIL) I encountered this behavior on version 20.7.4 and am unsure if it already was fixed in a newer release. Thanks, Morris