commit 0adbcafd7f7de0e7a126ad9dfcd82f236d109b85
parent 3eb467143c385dab2a13bedf6c61ad6abf84053d
Author: Alexander Burger <abu@software-lab.de>
Date: Thu, 14 Apr 2011 19:16:40 +0200
Initial 64-bit version for PowerPC (ppc64)
Diffstat:
12 files changed, 1349 insertions(+), 18 deletions(-)
diff --git a/CHANGES b/CHANGES
@@ -1,4 +1,5 @@
* XXjun11 picoLisp-3.0.7
+ 64-bit version for PowerPC (ppc64)
Changed "@.picoHistory" to ".pilHistory"
* 29mar11 picoLisp-3.0.6
diff --git a/INSTALL b/INSTALL
@@ -1,4 +1,4 @@
-08mar11abu
+14apr11abu
(c) Software Lab. Alexander Burger
@@ -28,7 +28,8 @@ Please follow these steps:
$ (cd src; make picolisp)
- or, if you have an x86-64 Linux or SunOS system, build the 64-bit version
+ or - if you have an x86-64/Linux, x86-64/SunOS or ppc64/Linux system - build
+ the 64-bit version
$ (cd src64; make picolisp)
@@ -45,6 +46,7 @@ Please follow these steps:
- http://software-lab.de/x86-64.linux.tgz
- http://software-lab.de/x86-64.sunOs.tgz
+ - http://software-lab.de/ppc64.linux.tgz
- Else, build a 32-bit version first, and use the resulting bin/picolisp to
generate the "*.s" files:
diff --git a/README b/README
@@ -1,4 +1,4 @@
-08mar11abu
+14apr11abu
(c) Software Lab. Alexander Burger
Perfection is attained
@@ -95,7 +95,7 @@ the conditions of the MIT/X11 License (see "COPYING").
It compiles and runs on current 32-bit GNU/Linux, FreeBSD, Mac OS X (Darwin),
Cygwin/Win32 (and possibly other) systems. A native 64-bit version is available
-for Linux and SunOS on x86-64.
+for x86-64/Linux, x86-64/SunOS and ppc64/Linux.
--------------------------------------------------------------------------------
diff --git a/ReleaseNotes b/ReleaseNotes
@@ -1,7 +1,9 @@
-29mar11abu
+14apr11abu
(c) Software Lab. Alexander Burger
Release Notes for picoLisp-3.0.7
================================
+1. A preliminary implementation of the 64-bit version for PowerPC (ppc64).
+ Doesn't run yet, but will hopefully improve until this release is due.
diff --git a/doc64/README b/doc64/README
@@ -1,4 +1,4 @@
-08mar11abu
+14apr11abu
(c) Software Lab. Alexander Burger
@@ -30,7 +30,7 @@ The CPU registers and instruction set of the PicoLisp processor are described in
"doc64/asm", and the internal data structures of the PicoLisp machine in
"doc64/structures".
-Currently, Linux and SunOS on the x86-64 architecture are supported. The
+Currently, x86-64/Linux, x86-64/SunOS and ppc64/Linux are supported. The
platform dependent files are in the "src64/arch/" for the target architecture,
and in "src64/sys/" for the target operating system.
diff --git a/ersatz/picolisp.jar b/ersatz/picolisp.jar
Binary files differ.
diff --git a/src/vers.h b/src/vers.h
@@ -1 +1 @@
-static byte Version[4] = {3,0,6,2};
+static byte Version[4] = {3,0,6,3};
diff --git a/src64/Makefile b/src64/Makefile
@@ -1,4 +1,4 @@
-# 27mar11abu
+# 09apr11abu
# (c) Software Lab. Alexander Burger
.SILENT:
@@ -9,8 +9,15 @@ lib = ../lib
ifeq ($(shell uname), Linux)
OS = Linux
SYS = linux
- ARCH = x86-64
- AS = as
+ ifeq ($(shell uname -m), x86_64)
+ ARCH = x86-64
+ AS = as
+ else
+ ifeq ($(shell uname -m), ppc64)
+ ARCH = ppc64
+ AS = as -mppc64 -a64
+ endif
+ endif
LD-MAIN = gcc -m64 -rdynamic -lc -lm -ldl
LD-SHARED = gcc -m64 -shared -export-dynamic
STRIP = strip
@@ -51,23 +58,33 @@ $(lib)/ht: $(ARCH).$(SYS).ht.o
# Explicit builds for cross-assembly
-x86-64.linux.base.s: $(baseFiles) sys/x86-64.linux.code.l
+x86-64.linux.base.s: lib/asm.l arch/x86-64.l $(baseFiles) sys/x86-64.linux.code.l
./mkAsm x86-64 linux Linux base $(lib)/tags $(baseFiles) sys/x86-64.linux.code.l
-x86-64.linux.ext.s: ext.l
+x86-64.linux.ext.s: lib/asm.l arch/x86-64.l ext.l
./mkAsm x86-64 linux Linux ext "" -fpic ext.l
-x86-64.linux.ht.s: ht.l
+x86-64.linux.ht.s: lib/asm.l arch/x86-64.l ht.l
./mkAsm x86-64 linux Linux ht "" -fpic ht.l
-x86-64.sunOs.base.s: $(baseFiles) sys/x86-64.sunOs.code.l
+ppc64.linux.base.s: lib/asm.l arch/ppc64.l $(baseFiles) sys/ppc64.linux.code.l
+ ./mkAsm ppc64 linux Linux base $(lib)/tags $(baseFiles) sys/ppc64.linux.code.l
+
+ppc64.linux.ext.s: lib/asm.l arch/ppc64.l ext.l
+ ./mkAsm ppc64 linux Linux ext "" -fpic ext.l
+
+ppc64.linux.ht.s: lib/asm.l arch/ppc64.l ht.l
+ ./mkAsm ppc64 linux Linux ht "" -fpic ht.l
+
+
+x86-64.sunOs.base.s: lib/asm.l arch/x86-64.l $(baseFiles) sys/x86-64.sunOs.code.l
./mkAsm x86-64 sunOs SunOS base $(lib)/tags $(baseFiles) sys/x86-64.sunOs.code.l
-x86-64.sunOs.ext.s: ext.l
+x86-64.sunOs.ext.s: lib/asm.l arch/x86-64.l ext.l
./mkAsm x86-64 sunOs SunOS ext "" -fpic ext.l
-x86-64.sunOs.ht.s: ht.l
+x86-64.sunOs.ht.s: lib/asm.l arch/x86-64.l ht.l
./mkAsm x86-64 sunOs SunOS ht "" -fpic ht.l
diff --git a/src64/arch/ppc64.l b/src64/arch/ppc64.l
@@ -0,0 +1,1125 @@
+# 14apr11abu
+# (c) Software Lab. Alexander Burger
+
+# Byte order
+(off *LittleEndian)
+
+# Register assignments
+(de *Registers
+ (A . 3) (C . 14) (E . 15)
+ (B . -3) (D 3 . 14)
+ (X . 16) (Y . 17) (Z . 18)
+ (L . 19) (S . 1)
+ (F . T) )
+
+(de *TempRegs
+ 26 27 28 29 30 )
+
+# TOC: 2
+# C arguments: 3 - 10
+# NULL: 20
+# ONE: 21
+# Data: 22
+# Operands: 23, 24, 25
+# Carry flag: 31
+
+# Temporary register
+(de tmpReg @
+ (let R (pop '(`(apply circ *TempRegs)))
+ (if (find lt0 (rest))
+ (- R)
+ R ) ) )
+
+# Machine specific
+(de boxfun (Adr)
+ (pack Adr "+2") )
+
+# Addressing modes
+(de uimm16 (N)
+ (or
+ (ge0 (setq N (format N)))
+ (+ 65536 N) ) )
+
+(de checkOp (Fun)
+ (unless (Fun Op)
+ (quit "Illegal operation" *Statement) ) )
+
+(de opReg (Op Reg Ofs R)
+ (let Adr (pack Ofs "(" R ")")
+ (cond
+ ((lt0 Reg)
+ (checkOp bool)
+ (cond
+ ((=0 Op)
+ (if (= -3 Reg)
+ (let Byte (tmpReg)
+ (prinst "lbz" Byte Adr)
+ (prinst "insrdi" 3 Byte 8 56) )
+ (prinst "lbz" (abs Reg) Adr) ) )
+ ((=T Op) (prinst "stb" (abs Reg) Adr))
+ (T (prinst Op (abs Reg) Adr)) ) )
+ ((not Op)
+ (unless (and (=0 Ofs) (= Reg R))
+ (prinst "la" Reg Adr) ) )
+ ((=0 Op) (prinst "ld" Reg Adr))
+ ((=T Op) (prinst "std" Reg Adr))
+ (T (prinst Op Reg Adr)) )
+ (cons Adr) ) )
+
+(de opxReg (Op Reg R R2)
+ (let Adr (pack R ", " R2)
+ (cond
+ ((lt0 Reg)
+ (checkOp bool)
+ (cond
+ ((=0 Op)
+ (if (= -3 Reg)
+ (let Byte (tmpReg)
+ (prinst "lbzx" Byte Adr)
+ (prinst "insrdi" 3 Byte 8 56) )
+ (prinst "lbzx" (abs Reg) Adr) ) )
+ ((=T Op) (prinst "stbx" (abs Reg) Adr))
+ (T (prinst (pack Op "x") (abs Reg) Adr)) ) )
+ ((not Op) (prinst "add" Reg Adr))
+ ((=0 Op) (prinst "ldx" Reg R R2))
+ ((=T Op) (prinst "stdx" Reg Adr))
+ (T (prinst (pack Op "x") Reg Adr)) )
+ (cons Adr "x") ) )
+
+(de mvReg (Dst Src)
+ (if (or (lt0 Dst) (lt0 Src))
+ (prinst "insrdi" (abs Dst) (abs Src) 8 56)
+ (prinst "mr" Dst Src) ) )
+
+# Operation 'Op':
+# NIL Lea
+# 0 Fetch
+# T Store
+(de memory (Mem M Reg Op Tmp) #> ([adr [. "x"]])
+ (cond
+ ((=0 M) # Immediate
+ (checkOp =0)
+ (if (= "0" Mem)
+ (if (lt0 Reg)
+ (prinst "insrdi" (abs Reg) 20 8 56)
+ (prinst "li" Reg 0) )
+ (setq Mem
+ (if (pre? "~" Mem)
+ (x| `(hex "FFFFFFFFFFFFFFFF") (format (cdr (chop Mem))))
+ (format Mem) ) )
+ (cond
+ ((lt0 Reg)
+ (prinst "insrdi" (abs Reg) 20 8 56)
+ (prinst "ori" (abs Reg) (abs Reg) (& 255 Mem)) )
+ ((>= 32767 Mem -32768)
+ (prinst "li" Reg Mem) )
+ ((>= 2147483647 Mem -2147483648)
+ (prinst "lis" Reg (>> 16 Mem))
+ (unless (=0 (setq Mem (& 65535 Mem)))
+ (prinst "ori" Reg Reg Mem) ) )
+ (T
+ (prinst "lis" Reg (>> 48 Mem))
+ (unless (=0 (& 65535 (>> 32 Mem)))
+ (prinst "ori" Reg Reg (& 65535 (>> 32 Mem))) )
+ (prinst "sldi" Reg Reg 32)
+ (prinst "lis" Reg (& 65535 (>> 16 Mem)))
+ (unless (=0 (setq Mem (& 65535 Mem)))
+ (prinst "ori" Reg Reg Mem) ) ) ) )
+ NIL )
+ ((not M) # Register
+ (cond
+ ((not Reg) (setq Reg Mem))
+ ((= Mem Reg))
+ ((not Op) (prinst "mr" Reg Mem))
+ ((=0 Op) (mvReg Reg Mem))
+ ((=T Op) (mvReg Mem Reg))
+ (T (prinst Op Reg Mem)) )
+ NIL )
+ ((=T M) # Direct
+ (cond
+ ((sub? "-" Mem) # Label difference
+ (checkOp =0)
+ (prinst "li" Reg Mem)
+ NIL )
+ ((or *FPic (low? Mem)) # -fpic or code label
+ (prinst "ld" Reg (pack Mem "@got(2)")) )
+ (T (opReg NIL Reg (pack Mem "-Data") 22)) ) )
+ ((not (car M)) # Indexed
+ (cond
+ ((not (cdr M)) (opReg Op Reg 0 (car Mem)))
+ ((=0 (cdr M))
+ (if (>= 32767 (cdr Mem) -32768)
+ (opReg Op Reg (cdr Mem) (car Mem))
+ (prinst "lis" (abs Reg) (>> 16 (cdr Mem)))
+ (unless (=0 (& 65535 (cdr Mem)))
+ (prinst "ori" (abs Reg) (abs Reg) (& 65535 (cdr Mem))) )
+ (opxReg Op Reg Reg (car Mem)) ) )
+ ((=T (cdr M))
+ (cond
+ ((sub? "-" (cdr Mem)) # Label difference
+ (opReg Op Reg (cdr Mem) (car Mem)) )
+ ((or *FPic (low? (cdr Mem))) # -fpic or code label
+ (let R (if (lt0 Reg) (tmpReg) Reg)
+ (prinst "ld" R (pack (cdr Mem) "@got(2)"))
+ (opxReg Op Reg R (car Mem)) ) )
+ (T
+ (let R (if (lt0 Reg) (tmpReg) Reg)
+ (prinst "la" R (pack (cdr Mem) "-Data(22)"))
+ (opxReg Op Reg R (car Mem)) ) ) ) ) ) )
+ ((=T (car M)) # Indirect
+ (if (or *FPic (low? (car Mem))) # -fpic or code label
+ (let R (if (lt0 Reg) (tmpReg) Reg)
+ (prinst "ld" R (pack (car Mem) "@got(2)"))
+ (opReg 0 Reg 0 R) )
+ (opReg Op Reg
+ (pack
+ (and (cdr M) (pack (cdr Mem) "+"))
+ (car Mem)
+ "-Data" )
+ 22 ) ) )
+ (T # Combined
+ (let R (or Tmp (tmpReg))
+ (memory (car Mem) (car M) R 0 R)
+ (opReg Op Reg (or (cdr Mem) 0) R) ) ) ) )
+
+(de memory2 (Cmd Reg Ref Ofs)
+ (prinst
+ (pack (if (lt0 Reg) "stb" Cmd) (cdr Ref))
+ (abs Reg)
+ (if Ofs
+ (pack @ "+" (car Ref))
+ (car Ref) ) ) )
+
+(de srcReg (Src S Tmp) #> reg
+ (cond
+ ((not S)
+ (ifn Tmp
+ Src
+ (prinst "mr" Tmp Src)
+ Tmp ) )
+ ((= "0" Src)
+ (ifn Tmp
+ 20
+ (prinst "li" Tmp 0)
+ Tmp ) )
+ ((= "1" Src)
+ (ifn Tmp
+ 21
+ (prinst "li" Tmp 1)
+ Tmp ) )
+ (T
+ (prog1 (or Tmp (tmpReg))
+ (memory Src S @ 0) ) ) ) )
+
+(de srcByteReg (Src S) #> reg
+ (cond
+ ((not S)
+ (prog1 (tmpReg)
+ (prinst "insrdi" @ (abs Src) 8 56) ) )
+ ((n0 S)
+ (prog1 (tmpReg)
+ (memory Src S @ "lbz") ) )
+ ((= "0" Src) 20)
+ ((= "1" Src) 21)
+ (T
+ (prog1 (tmpReg)
+ (prinst "li" @
+ (if (pre? "~" Src)
+ (x| `(hex "FF") (format (cdr (chop Src))))
+ (format Src) ) ) ) ) ) )
+
+(de dstReg (Dst D) #> (NIL dst adr [. "x"])
+ (cond
+ (D
+ (let R (tmpReg)
+ (cons NIL R (memory Dst D R 0)) ) )
+ ((= -3 Dst)
+ (let R (tmpReg)
+ (prinst "extrdi" R 3 8 56)
+ (cons NIL R -3) ) )
+ (T (list NIL Dst)) ) )
+
+(de dstByteReg (Dst D) #> (T dst adr [. "x"])
+ (cond
+ (D
+ (let R (tmpReg)
+ (cons T R (memory Dst D R "lbz")) ) )
+ ((= -3 Dst)
+ (let R (tmpReg)
+ (prinst "extrdi" R 3 8 56)
+ (cons T R -3) ) )
+ (T (list T Dst)) ) )
+
+(de dstSrcReg (Dst D Src S) #> (src flg dst adr [. "x"])
+ (if (or (= -3 Dst) (= -3 Src))
+ (cons
+ (srcByteReg Src S)
+ (dstByteReg Dst D) )
+ (cons
+ (srcReg Src S)
+ (dstReg Dst D) ) ) )
+
+(de regDst (RegRef)
+ (cond
+ ((= -3 (cddr RegRef))
+ (prinst "insrdi" 3 (cadr RegRef) 8 56) )
+ ((car RegRef) # byte-flg
+ (when (cddr RegRef)
+ (memory2 "stb" (cadr RegRef) (cddr RegRef)) ) )
+ ((cddr RegRef)
+ (memory2 "std" (cadr RegRef) (cddr RegRef)) ) ) )
+
+### Instruction set ###
+(asm nop ()
+ (prinst "nop") )
+
+(asm align (N)
+ (prinst ".balign" N) )
+
+(asm skip (N)
+ (when (== 'data *Section)
+ (or (=0 N) (prinst ".space" N)) ) )
+
+(asm ld (Dst D Src S)
+ (nond
+ (D
+ (ifn (= (3 . 14) Dst)
+ (memory Src S Dst 0)
+ (let A (memory Src S 14 0) # D
+ (prinst "ld" 3 (pack "8+" (car A))) ) ) )
+ (S
+ (ifn (= (3 . 14) Src)
+ (memory Dst D Src T)
+ (let A (memory Dst D 14 T) # D
+ (prinst "std" 3 (pack "8+" (car A))) ) ) )
+ (NIL
+ (let R (tmpReg)
+ (memory Src S R 0)
+ (memory Dst D R T) ) ) ) )
+
+(asm ld2 (Src S)
+ (memory Src S 3 "lhz") )
+
+(asm ld4 (Src S)
+ (memory Src S 3 "lwz") )
+
+(asm ldc (Dst D Src S)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (prinst "beq-" "cr1" "1f")
+ (memory Src S Dst 0)
+ (prinl "1:") )
+
+(asm ldnc (Dst D Src S)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (prinst "bne-" "cr1" "1f")
+ (memory Src S Dst 0)
+ (prinl "1:") )
+
+(asm ldz (Dst D Src S)
+ (prinst "bne-" "1f")
+ (memory Src S Dst 0)
+ (prinl "1:") )
+
+(asm ldnz (Dst D Src S)
+ (prinst "beq-" "1f")
+ (memory Src S Dst 0)
+ (prinl "1:") )
+
+(asm lea (Dst D Src S)
+ (ifn D
+ (memory Src S Dst)
+ (let R (tmpReg)
+ (memory Src S R)
+ (memory Dst D R T) ) ) )
+
+(asm st2 (Dst D)
+ (memory Dst D 3 "sth") )
+
+(asm st4 (Dst D)
+ (memory Dst D 3 "stw") )
+
+(asm xchg (Dst D Dst2 D2)
+ (let (Tmp (tmpReg Dst Dst2) A (memory Dst D Tmp 0)) # Tmp = Dst
+ (nond
+ (D
+ (if (memory Dst2 D2 Dst 0) # Dst = Dst2
+ (memory2 "std" Tmp @) # Dst2 = Tmp
+ (mvReg Dst2 Tmp) ) )
+ (D2
+ (memory2 "std" Dst2 A)
+ (mvReg Dst2 Tmp) )
+ (NIL
+ (let (R (tmpReg) B (memory Dst2 D2 R 0))
+ (memory2 "std" R A)
+ (memory2 "std" Tmp B) ) ) ) ) )
+
+(asm movn (Dst D Src S Cnt C)
+ (memory Dst D 23)
+ (memory Src S 24)
+ (memory Cnt C 25 0)
+ (prinst "bl" "call")
+ (prinst ".int" "movn-.") )
+
+(asm mset (Dst D Cnt C)
+ (memory Dst D 23)
+ (memory Cnt C 24 0)
+ (prinst "bl" "call")
+ (prinst ".int" "mset-.") )
+
+(asm movm (Dst D Src S End E)
+ (memory Dst D 25)
+ (memory Src S 23)
+ (memory End E 24)
+ (prinst "bl" "call")
+ (prinst ".int" "save-.") )
+
+(asm save (Src S End E Dst D)
+ (memory Src S 23)
+ (memory End E 24)
+ (memory Dst D 25)
+ (prinst "bl" "call")
+ (prinst ".int" "save-.") )
+
+(asm load (Dst D End E Src S)
+ (memory Dst D 23)
+ (memory End E 24)
+ (memory Src S 25)
+ (prinst "bl" "call")
+ (prinst ".int" "load-.") )
+
+# Arithmetics
+(asm add (Dst D Src S)
+ (ifn (= (3 . 14) Dst)
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (let A (dstReg Dst D)
+ (prinst "addic." (cadr A) (cadr A) Src)
+ (regDst A) )
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "addc." (caddr A) (caddr A) (car A))
+ (regDst (cdr A)) ) )
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (prinst "addic" 3 3 Src)
+ (prinst "addc" 3 3 (srcReg Src S)) )
+ (prinst "addze" 14 14) )
+ (prinst "subfze" 31 21) ) # Set carry
+
+(asm addc (Dst D Src S)
+ (prinst "sradi" 0 31 1) # Get carry
+ (ifn (= (3 . 14) Dst)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "adde." (caddr A) (caddr A) (car A))
+ (regDst (cdr A)) )
+ (prinst "adde" 3 3 (srcReg Src S))
+ (prinst "adde" 14 14 20) )
+ (prinst "subfze" 31 21) ) # Set carry
+
+(asm sub (Dst D Src S)
+ (ifn (= (3 . 14) Dst)
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (let A (dstReg Dst D)
+ (prinst "subic." (cadr A) (cadr A) Src)
+ (regDst A) )
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "subc." (caddr A) (caddr A) (car A))
+ (regDst (cdr A)) ) )
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (prinst "subic" 3 3 Src)
+ (prinst "subc" 3 3 (srcReg Src S)) )
+ (prinst "subfze" 14 14) )
+ (prinst "subfme" 31 21) ) # Set inverted carry
+
+(asm subc (Dst D Src S)
+ (prinst "xori" 0 31 1) # Get inverted carry
+ (prinst "sradi" 0 0 1)
+ (ifn (= (3 . 14) Dst)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "subfe." (caddr A) (car A) (caddr A))
+ (regDst (cdr A)) )
+ (prinst "sube" 3 3 (srcReg Src S))
+ (prinst "sube" 14 14 20) )
+ (prinst "subfme" 31 21) ) # Set inverted carry
+
+(asm inc (Dst D)
+ (let A (dstReg Dst D)
+ (prinst "addic." (cadr A) (cadr A) 1)
+ (regDst A) ) )
+
+(asm dec (Dst D)
+ (let A (dstReg Dst D)
+ (prinst "subic." (cadr A) (cadr A) 1)
+ (regDst A) ) )
+
+(asm not (Dst D)
+ (let A (dstReg Dst D)
+ (prinst "not." (cadr A) (cadr A))
+ (regDst A) ) )
+
+(asm neg (Dst D)
+ (let A (dstReg Dst D)
+ (prinst "neg." (cadr A) (cadr A))
+ (regDst A) ) )
+
+(asm and (Dst D Src S)
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (let A (dstReg Dst D)
+ (prinst "andi." (cadr A) (cadr A) (uimm16 Src))
+ (regDst A) )
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "and." (caddr A) (caddr A) (car A))
+ (regDst (cdr A)) ) ) )
+
+(asm or (Dst D Src S)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "or." (caddr A) (caddr A) (car A)) # 'ori.' doesn't exist
+ (regDst (cdr A)) ) )
+
+(asm xor (Dst D Src S)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "xor." (caddr A) (caddr A) (car A)) # 'xori.' doesn't exist
+ (regDst (cdr A)) ) )
+
+(asm off (Dst D Src S)
+ (let A (dstReg Dst D)
+ (prinst "andi." (cadr A) (cadr A)
+ (x| `(hex "FFFF") (format (cdr (chop Src)))) )
+ (regDst A) ) )
+
+(asm test (Dst D Src S)
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (let A (dstReg Dst D)
+ (prinst "andi." 0 (cadr A) (uimm16 Src)) )
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "and." 0 (caddr A) (car A)) ) ) )
+
+(asm shl (Dst D Src S)
+ (ifn (=0 S)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "sld." (caddr A) (caddr A) (car A)) # Ignore carry
+ (regDst (cdr A)) )
+ (let A (dstReg Dst D)
+ (when (gt0 (dec (format Src)))
+ (prinst "sldi" (cadr A) (cadr A) @) )
+ (prinst "addc." (cadr A) (cadr A) (cadr A))
+ (regDst A)
+ (prinst "subfze" 31 21) ) ) ) # Set carry from MSB
+
+(asm shr (Dst D Src S)
+ (ifn (=0 S)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "srd." (caddr A) (caddr A) (car A)) # Ignore carry
+ (regDst (cdr A)) )
+ (let A (dstReg Dst D)
+ (when (gt0 (dec (format Src)))
+ (prinst "srdi" (cadr A) (cadr A) @) )
+ (prinst "li" 31 -2) # Set carry from LSB
+ (prinst "insrdi" 31 (cadr A) 1 0)
+ (prinst "srdi." (cadr A) (cadr A) 1)
+ (regDst A) ) ) )
+
+(asm rol (Dst D Src S)
+ (ifn (=0 S)
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "rotld" (caddr A) (caddr A) (car A))
+ (regDst (cdr A)) )
+ (let A (dstReg Dst D)
+ (prinst "rotldi" (cadr A) (cadr A) (format Src))
+ (regDst A) ) ) )
+
+(asm ror (Dst D Src S)
+ (ifn (=0 S)
+ (quit "Non-immediate 'ror' not available")
+ (let A (dstReg Dst D)
+ (prinst "rotrdi" (cadr A) (cadr A) (format Src))
+ (regDst A) ) ) )
+
+(asm rcl (Dst D Src S)
+ (ifn (=0 S)
+ (quit "Non-immediate 'rcl' not available")
+ (let A (dstReg Dst D)
+ (prinst "sradi" 0 31 1) # Get carry
+ (do (setq Src (format Src))
+ (prinst "adde." (cadr A) (cadr A) (cadr A)) )
+ (regDst A)
+ (prinst "subfze" 31 21) ) ) ) # Set carry
+
+(asm rcr (Dst D Src S)
+ (ifn (=0 S)
+ (quit "Non-immediate 'rcr' not available")
+ (let A (dstReg Dst D)
+ (let (R1 (tmpReg) R2 (tmpReg))
+ (do (setq Src (format Src))
+ (prinst "mr" 0 (cadr A))
+ (prinst "rotrdi" (cadr A) (cadr A) 1)
+ (prinst "insrdi" (cadr A) 31 1 0)
+ (prinst "insrdi" 31 0 1 63) ) ) )
+ (regDst A) ) )
+
+(asm mul (Src S)
+ (let R (srcReg Src S)
+ (prinst "mulhdu" 14 3 R)
+ (prinst "mulld" 3 3 R) ) )
+
+(asm div (Src S)
+ (srcReg Src S 23)
+ (prinst "bl" "call")
+ (prinst ".int" "div-.") )
+
+(asm zxt () # 8 bit -> 64 bit
+ (prinst "andi." 3 3 255) )
+
+(asm setz ()
+ (prinst "addic." 0 20 0) ) # Add zero to null
+
+(asm clrz ()
+ (prinst "cmpdi" 1 0) ) # Compare stack pointer to zero
+
+(asm setc ()
+ (prinst "li" 31 -1) )
+
+(asm clrc ()
+ (prinst "li" 31 -2) )
+
+# Comparisons
+(asm cmp (Dst D Src S)
+ (if (and (=0 S) (>= 32767 (format Src) -32768))
+ (let A (dstReg Dst D)
+ (prinst "subic." 0 (cadr A) Src) )
+ (let A (dstSrcReg Dst D Src S)
+ (prinst "subc." 0 (caddr A) (car A)) ) )
+ (prinst "subfme" 31 21) ) # Set inverted carry
+
+(asm cmp4 (Src S)
+ (let R (tmpReg)
+ (memory Src S R "lwz")
+ (prinst "subc." 0 3 R) )
+ (prinst "subfme" 31 21) ) # Set inverted carry
+
+(asm cmpn (Dst D Src S Cnt C)
+ (memory Dst D 23)
+ (memory Src S 24)
+ (memory Cnt C 25 0)
+ (prinst "bl" "call")
+ (prinst ".int" "cmpn-.") )
+
+(asm slen (Dst D Src S)
+ (memory Src S 24)
+ (prinst "bl" "call")
+ (prinst ".int" "slen-.")
+ (memory Dst D 23 T) )
+
+(asm memb (Src S Cnt C)
+ (memory Src S 23)
+ (memory Cnt C 24 0)
+ (prinst "bl" "call")
+ (prinst ".int" "memb-.")
+ (unless S (prinst "mr" Src 23))
+ (unless C (prinst "mr" Cnt 24)) )
+
+(asm null (Src S)
+ (prinst "cmpdi" (srcReg Src S) 0) )
+
+(asm nul4 ()
+ (prinst "extldi." 3 3 32 32) )
+
+# Byte addressing
+(asm set (Dst D Src S)
+ (memory Dst D (srcByteReg Src S) "stb") )
+
+(asm nul (Src S)
+ (prinst "cmpdi" (srcByteReg Src S) 0) )
+
+# Types
+(asm cnt (Src S)
+ (prinst "andi." 0 (srcReg Src S) "0x02") )
+
+(asm big (Src S)
+ (prinst "andi." 0 (srcReg Src S) "0x04") )
+
+(asm num (Src S)
+ (prinst "andi." 0 (srcReg Src S) "0x06") )
+
+(asm sym (Src S)
+ (prinst "andi." 0 (srcReg Src S) "0x08") )
+
+(asm atom (Src S)
+ (prinst "andi." 0 (srcReg Src S) "0x0E") )
+
+# Flow Control
+(asm call (Adr A)
+ (nond
+ (A # Absolute
+ (prinst "bl" "call")
+ (prinst ".int" (pack Adr "-.")) )
+ ((=T A) # Indexed: Ignore SUBR
+ (prinst "mtctr" Adr)
+ (prinst "bctrl") )
+ (NIL # Indirect
+ (let R (tmpReg)
+ (prinst "ld" R (pack Adr "-Data(22)"))
+ (prinst "mtctr" R)
+ (prinst "bctrl") ) ) ) )
+
+(de _jmp Args
+ (nond
+ (A
+ (let @Lbl Adr
+ (ifn (cadr Args)
+ (for E (fill (car Args)) # b
+ (apply prinst (cons (pack (pop 'E) (pop 'E)) E)) )
+ (let Back
+ (for (P *Program (n== *Statement (car P)) (cdr P))
+ (T (and (== ': (caar P)) (= Adr (cdar P))) T) )
+ (for E
+ (fill
+ ((if
+ (or
+ (= `(char ".") (char Adr)) # Local label
+ (and
+ (cdr (split (chop Adr) "_"))
+ (format @) ) )
+ car
+ cadr )
+ Args ) )
+ (apply prinst
+ (cons
+ (pack
+ (pop 'E)
+ (case (pop 'E)
+ ("+" (if Back "-" "+"))
+ ("-" (if Back "+" "-")) ) )
+ E ) ) ) ) ) ) )
+ ((=T A) # Ignore SUBR
+ (prinst "mtctr" Adr)
+ (for E (fill (caddr Args))
+ (apply prinst (cons (pack (pop 'E) (pop 'E)) E)) ) )
+ (NIL
+ (let R (tmpReg)
+ (prinst "ld" R (pack Adr "-Data(22)"))
+ (prinst "mtctr" R)
+ (for E (fill (caddr Args))
+ (apply prinst (cons (pack (pop 'E) (pop 'E)) E)) ) ) ) ) )
+
+(asm jmp (Adr A)
+ (_jmp
+ (("b" NIL @Lbl))
+ NIL
+ (("bctr" NIL)) ) )
+
+(asm jz (Adr A)
+ (_jmp
+ (("beq" - @Lbl))
+ (("bne" + ".+8") ("b" NIL @Lbl))
+ (("beqctr" -)) ) )
+
+(asm jeq (Adr A)
+ (_jmp
+ (("beq" - @Lbl))
+ (("bne" + ".+8") ("b" NIL @Lbl))
+ (("beqctr" -)) ) )
+
+(asm jnz (Adr A)
+ (_jmp
+ (("bne" - @Lbl))
+ (("beq" + ".+8") ("b" NIL @Lbl))
+ (("bnectr" -)) ) )
+
+(asm jne (Adr A)
+ (_jmp
+ (("bne" - @Lbl))
+ (("beq" + ".+8") ("b" NIL @Lbl))
+ (("bnectr" -)) ) )
+
+(asm js (Adr A)
+ (_jmp
+ (("blt" - @Lbl))
+ (("bge" + ".+8") ("b" NIL @Lbl))
+ (("bltctr" -)) ) )
+
+(asm jns (Adr A)
+ (_jmp
+ (("bge" - @Lbl))
+ (("blt" + ".+8") ("b" NIL @Lbl))
+ (("bgectr" -)) ) )
+
+(asm jsz (Adr A)
+ (_jmp
+ (("ble" - @Lbl))
+ (("bgt" + ".+8") ("b" NIL @Lbl))
+ (("blectr" -)) ) )
+
+(asm jnsz (Adr A)
+ (_jmp
+ (("bgt" - @Lbl))
+ (("ble" + ".+8") ("b" NIL @Lbl))
+ (("bgtctr" -)) ) )
+
+(asm jc (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" - "cr1" @Lbl))
+ (("beq" + "cr1" ".+8") ("b" NIL @Lbl))
+ (("bnectr" - "cr1")) ) )
+
+(asm jlt (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" - "cr1" @Lbl))
+ (("beq" + "cr1" ".+8") ("b" NIL @Lbl))
+ (("bnectr" - "cr1")) ) )
+
+(asm jnc (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("beq" - "cr1" @Lbl))
+ (("bne" + "cr1" ".+8") ("b" NIL @Lbl))
+ (("beqctr" - "cr1")) ) )
+
+(asm jge (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("beq" - "cr1" @Lbl))
+ (("bne" + "cr1" ".+8") ("b" NIL @Lbl))
+ (("beqctr" - "cr1")) ) )
+
+(asm jcz (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" - "cr1" @Lbl) ("beq" - @Lbl))
+ (("beq" - "cr1" ".+12") ("bne" + ".+8") ("b" NIL @Lbl))
+ (("bnectr" - "cr1") ("beqctr" -) ) ) )
+
+(asm jle (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" - "cr1" @Lbl) ("beq" - @Lbl))
+ (("beq" - "cr1" ".+12") ("bne" + ".+8") ("b" NIL @Lbl))
+ (("bnectr" - "cr1") ("beqctr" -) ) ) )
+
+(asm jncz (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" + "cr1" ".+8") ("bne" - @Lbl))
+ (("bne" + "cr1" ".+12") ("beq" + ".+8") ("b" NIL @Lbl))
+ (("bne" + "cr1" ".+8") ("bnectr" -)) ) )
+
+(asm jgt (Adr A)
+ (prinst "cmpdi" "cr1" 31 -2)
+ (_jmp
+ (("bne" + "cr1" ".+8") ("bne" - @Lbl))
+ (("bne" + "cr1" ".+12") ("beq" + ".+8") ("b" NIL @Lbl))
+ (("bne" + "cr1" ".+8") ("bnectr" NIL)) ) )
+
+(asm dval ()
+ # MADA
+ )
+
+(asm fval ()
+ # MADA
+ )
+
+(asm fix ()
+ # MADA
+ )
+
+(asm cc (Adr A Arg M)
+ (let Reg (3 4 5 6 7 8 9 10) # Support only max. 8 parameters
+ (if (lst? Arg)
+ (let (Lea NIL Tmp NIL)
+ (when (fish '((X) (= 3 X)) (cdr Arg))
+ (prinst "mr" (setq Tmp (tmpReg)) 3) )
+ (mapc
+ '((Src S)
+ (if (== '& Src)
+ (on Lea)
+ (setq Src
+ (recur (Src)
+ (cond
+ ((= 3 Src) (or Tmp 3))
+ ((atom Src) Src)
+ (T (cons (recurse (car Src)) (recurse (cdr Src)))) ) ) )
+ (cond
+ ((not Reg) # 'Src' not stack-relative here!
+ #{MADA}# )
+ ((and (=T S) (== 'pop Src))
+ (prinst "ld" (pop 'Reg) "0(1)")
+ (prinst "addi" 1 1 8) )
+ (Lea (memory Src S (pop 'Reg)))
+ ((= 3 Src) (pop 'Reg))
+ (T (srcReg Src S (pop 'Reg))) )
+ (off Lea) ) )
+ Arg
+ M ) )
+ #{MADA}# ) )
+ (nond
+ (A # Absolute
+ (prinst "mflr" 23)
+ (prinst "stdu" 1 "-112(1)")
+ (prinst "bl" Adr)
+ (prinst "nop")
+ (prinst "addi" 1 1 112)
+ (prinst "mtlr" 23) )
+ ((=T A) # Indexed
+ (prinst "mtctr" Adr)
+ (prinst "bctrl") ) )
+ (and
+ (lst? Arg)
+ (gt0 (- (length Arg) 8))
+ (prinst "addi" 1 1 (* @ 8)) ) )
+
+(asm ret ()
+ (prinst "blr") )
+
+(asm begin (N)
+ (when (>= N 6) # Z
+ (prinst "stdu" 18 "-8(1)")
+ (prinst "mr" 18 8) )
+ (when (>= N 5) # Y
+ (prinst "stdu" 17 "-8(1)")
+ (prinst "mr" 17 7) )
+ (when (>= N 4) # X
+ (prinst "stdu" 16 "-8(1)")
+ (prinst "mr" 16 6) )
+ (when (>= N 3) # E
+ (prinst "stdu" 15 "-8(1)")
+ (prinst "mr" 15 5) )
+ (when (>= N 2) # C
+ (prinst "stdu" 14 "-8(1)")
+ (prinst "mr" 14 4) ) )
+
+(asm return (N)
+ (and (>= N 2) (prinst "ld" 14 "0(1)")) # C
+ (and (>= N 3) (prinst "ld" 15 "8(1)")) # E
+ (and (>= N 4) (prinst "ld" 16 "16(1)")) # X
+ (and (>= N 5) (prinst "ld" 17 "32(1)")) # Y
+ (and (>= N 6) (prinst "ld" 18 "48(1)")) # Z
+ (prinst "addi" 1 1 (* 8 (min 6 (dec N)))) )
+
+# Stack Manipulations
+(asm push (Src S)
+ (ifn (=T Src)
+ (prinst "stdu" (srcReg Src S) "-8(1)")
+ (let R (tmpReg)
+ (prinst "mfocrf" R 128) # Get CR[0]
+ (prinst "insrdi" R 31 1 63) # Carry into LSB
+ (prinst "stdu" R "-8(1)") ) ) )
+
+(asm pop (Dst D)
+ (cond
+ (D
+ (let R (tmpReg)
+ (prinst "ld" R "0(1)")
+ (memory Dst D R T) ) )
+ ((=T Dst)
+ (let R (tmpReg)
+ (prinst "ld" R "0(1)")
+ (prinst "insrdi" 31 R 1 0) # Set carry from LSB
+ (prinst "mtocrf" 128 R) ) ) # Set CR[0] (LT, GT, EQ, SO)
+ (T (prinst "ld" Dst "0(1)")) )
+ (prinst "addi" 1 1 8) )
+
+(asm link ()
+ (prinst "stdu" 19 "-8(1)") # Push L
+ (prinst "mr" 19 1) )
+
+(asm tuck (Src S)
+ (prinst "ld" 19 "0(1)") # Get L
+ (prinst "std" (srcReg Src S) "0(1)") )
+
+(asm drop ()
+ (prinst "ld" 1 "0(19)") # Restore S
+ (prinst "ld" 19 "0(1)") # and L
+ (prinst "addi" 1 1 8) )
+
+# Evaluation
+(asm eval ()
+ (prinst "rldicl." 0 15 63 62) # Number?
+ (prinst "bne-" "2f") # Yes: Skip
+ (prinst "rldicl." 0 15 61 63) # Symbol?
+ (prinst "bne-" "1f") # Yes: Get value
+ (prinst "ld" 15 "0(15)")
+ (prinst "b" "2f") # and skip
+ (prinl "1:")
+ (prinst "bl" "call") # Else evaluate list
+ (prinst ".int" "evListE_E-.")
+ (prinl "2:") )
+
+(asm eval+ ()
+ (prinst "rldicl." 0 15 63 62) # Number?
+ (prinst "bne-" "2f") # Yes: Skip
+ (prinst "rldicl." 0 15 61 63) # Symbol?
+ (prinst "bne-" "1f") # Yes: Get value
+ (prinst "ld" 15 "0(15)")
+ (prinst "b" "2f") # and skip
+ (prinl "1:")
+ (prinst "stdu" 19 "-8(1)") # Else 'link'
+ (prinst "mr" 19 1)
+ (prinst "bl" "call") # Evaluate list
+ (prinst ".int" "evListE_E-.")
+ (prinst "ld" 19 "0(1)") # Pop L
+ (prinst "addi" 1 1 8)
+ (prinl "2:") )
+
+(asm eval/ret ()
+ (prinst "rldicl." 0 15 63 62) # Number?
+ (prinst "bnelr") # Yes: Return
+ (prinst "rldicl." 0 15 61 63) # Symbol?
+ (prinst "bne-" "1f") # No: Evaluate list
+ (prinst "ld" 15 "0(15)") # Get value
+ (prinst "blr")
+ (prinl "1:")
+ (prinst "b" "evListE_E") )
+
+(asm exec (Reg)
+ (prinl "1:") # do
+ (prinst "ld" 15 # ld E (R)
+ (pack "0(" Reg ")") )
+ (prinst "andi." 0 15 "0x0E") # atom E
+ (prinst "bne+" "2f")
+ (prinst "bl" "call") # Evaluate list
+ (prinst ".int" "evListE_E-.")
+ (prinl "2:")
+ (prinst "ld" Reg # ld R (R CDR)
+ (pack "8(" Reg ")") )
+ (prinst "andi." 0 Reg "0x0E") # atom R
+ (prinst "beq+" "1b") ) # until nz
+
+(asm prog (Reg)
+ (prinl "1:") # do
+ (prinst "ld" 15 # ld E (R)
+ (pack "0(" Reg ")") )
+ (prinst "andi." 0 15 "0x06") # eval
+ (prinst "bne-" "2f")
+ (prinst "andi." 0 15 "0x08")
+ (prinst "bne-" "2f")
+ (prinst "ld" 15 "0(15)")
+ (prinst "b" "2f")
+ (prinst "bl" "call") # Evaluate list
+ (prinst ".int" "evListE_E-.")
+ (prinl "2:")
+ (prinst "ld" Reg # ld R (R CDR)
+ (pack "8(" Reg ")") )
+ (prinst "andi." 0 Reg "0x0E") # atom R
+ (prinst "beq+" "1b") ) # until nz
+
+
+# System
+(asm initData ())
+
+(asm initCode ()
+ (prinl "# Subroutine-call emulation")
+ (prinl "call:")
+ (prinst "mflr" 11) # Get return address
+ (prinst "stdu" 11 "-8(1)") # Save it
+ (prinst "lwa" 0 "0(11)") # Target offset
+ (prinst "add" 0 0 11)
+ (prinst "mtlr" 0) # Call target
+ (prinst "blrl")
+ (prinst "ld" 11 "0(1)") # Pop return address
+ (prinst "addi" 1 1 8)
+ (prinst "addi" 0 11 4) # Update return address
+ (prinst "mtctr" 0) # Return
+ (prinst "bctr")
+ (prinl)
+ (prinl "# movn dst src cnt")
+ (prinl "movn:")
+ (prinst "subi" 23 23 1) # Adjust 'dst'
+ (prinst "subi" 24 24 1) # and 'src'
+ (prinl "1:")
+ (prinst "subic." 25 25 1) # Decrement 'cnt'
+ (prinst "bltlr") # Return if done
+ (prinst "lbzu" 26 "1(24)") # Next byte from 'src'
+ (prinst "stbu" 26 "1(23)") # Write to 'dst'
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# mset dst src cnt")
+ (prinl "mset:")
+ (prinst "subi" 23 23 1) # Adjust 'dst'
+ (prinl "1:")
+ (prinst "subic." 24 24 1) # Decrement 'cnt'
+ (prinst "bltlr") # Return if done
+ (prinst "stbu" 3 "1(23)") # Write B to 'dst'
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# save src end dst")
+ (prinl "save:")
+ (prinst "subi" 23 23 8) # Adjust 'src'
+ (prinst "subi" 25 25 8) # and 'dst'
+ (prinl "1:")
+ (prinst "ldu" 26 "8(23)") # Next word from 'src'
+ (prinst "cmpd" 23 24) # Done?
+ (prinst "beqlr") # Yes: Return
+ (prinst "stdu" 26 "8(25)") # Write to 'dst'
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# load dst end src")
+ (prinl "load:")
+ (prinst "subi" 23 23 8) # Adjust 'dst'
+ (prinst "subi" 25 25 8) # and 'src'
+ (prinl "1:")
+ (prinst "ldu" 26 "8(25)") # Next word from 'src'
+ (prinst "cmpd" 25 24) # Done?
+ (prinst "beqlr") # Yes: Return
+ (prinst "stdu" 26 "8(23)") # Write to 'dst'
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# cmpn dst src cnt")
+ (prinl "cmpn:")
+ (prinst "lbz" 26 "0(23)") # First byte from 'dst'
+ (prinst "lbz" 27 "0(24)") # First byte from 'src'
+ (prinl "1:")
+ (prinst "subc." 0 26 27) # Same bytes?
+ (prinst "bnelr") # No: Return 'ne'
+ (prinst "subic." 25 25 1) # Decrement 'cnt'
+ (prinst "beqlr") # Return 'eq' if done
+ (prinst "lbzu" 26 "1(23)") # Next bytes
+ (prinst "lbzu" 27 "1(24)")
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# slen dst src")
+ (prinl "slen:")
+ (prinst "li" 23 0) # Init 'dst' counter
+ (prinst "lbz" 26 "0(24)") # First byte from 'src'
+ (prinl "1:")
+ (prinst "cmpdi" 26 0) # Done?
+ (prinst "beqlr") # Yes: Return
+ (prinst "addi" 23 23 1) # Increment 'cnt'
+ (prinst "lbzu" 26 "1(24)") # Next byte
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# memb src cnt")
+ (prinl "memb:")
+ (prinst "lbz" 26 "0(23)") # First byte from 'src'
+ (prinst "insrdi" 25 3 8 56) # Get B
+ (prinl "1:")
+ (prinst "subic." 24 24 1) # Decrement 'cnt'
+ (prinst "bltlr") # Return 'ne' if done
+ (prinst "cmpd" 26 25) # Found?
+ (prinst "beqlr") # Yes: Return 'eq'
+ (prinst "lbzu" 26 "1(23)") # Next byte
+ (prinst "b" "1b")
+ (prinl)
+ (prinl "# div src")
+ (prinl "div:")
+ (prinst "divdu" 24 3 23) # Only 64-bit division for now
+ (prinst "mr" 3 24) # Quotient
+ (prinst "mulld" 14 24 23) # Remainder
+ (prinst "subf" 14 14 3)
+ (prinl "blr") )
+
+(asm initMain ()
+ (prinst ".quad" "main1" ".TOC.@tocbase" 0)
+ (prinl "main1:")
+ (prinst "li" 20 0) # Init NULL register
+ (prinst "li" 21 1) # Init ONE register
+ (prinst "ld" 22 "Data@got(2)") # Globals base
+ (prinst "ld" 16 "0(4)") # Get command in X
+ (prinst "la" 17 "8(4)") # argument vector in Y
+ (prinst "subi" 3 3 1) # and pointer to last argument in Z
+ (prinst "sldi" 3 3 3)
+ (prinst "add" 18 4 3) )
+
+### Optimizer ###
+# Replace the the next 'cnt' elements with 'lst'
+(de optimize (L)) #> (cnt . lst)
+
+# vi:et:ts=3:sw=3
diff --git a/src64/sys/ppc64.linux.code.l b/src64/sys/ppc64.linux.code.l
@@ -0,0 +1,39 @@
+# 27mar11abu
+# (c) Software Lab. Alexander Burger
+
+# System macros
+(code 'errno_A 0)
+ call __errno_location # Get address of 'errno'
+ ld A (A) # Load value
+ ret
+
+(code 'errnoC 0)
+ call __errno_location # Get address of 'errno'
+ ld (A) C # Store new value
+ ret
+
+(code 's_isdirS_F 0) # S_ISDIR
+ ld4 (S `(+ I ST_MODE)) # Get 'st_mode' from 'stat'
+ and A `S_IFMT
+ cmp A `S_IFDIR
+ ret
+
+(code 'wifstoppedS_F 0) # WIFSTOPPED
+ ld A (S I) # Get status
+ cmp B `(hex "7F") # (((status) & 0xff) == 0x7f)
+ ret
+
+(code 'wifsignaledS_F 0) # WIFSIGNALED
+ ld A (S I) # Get status
+ and B `(hex "7F") # (((status) & 0x7f) + 1) >> 1) > 0)
+ inc B
+ shr B 1
+ ret
+
+(code 'wtermsigS_A 0) # WTERMSIG
+ ld A (S I) # Get status
+ and B `(hex "7F") # ((status) & 0x7f)
+ zxt
+ ret
+
+# vi:et:ts=3:sw=3
diff --git a/src64/sys/ppc64.linux.defs.l b/src64/sys/ppc64.linux.defs.l
@@ -0,0 +1,145 @@
+# 27mar11abu
+# (c) Software Lab. Alexander Burger
+
+# errno
+(equ ENOENT 2) # No such file or directory
+(equ EINTR 4) # Interrupted system call
+(equ EBADF 9) # Bad file number
+(equ EAGAIN 11) # Try again
+(equ EACCES 13) # Permission denied
+(equ EPIPE 32) # Broken pipe
+(equ ECONNRESET 104) # Connection reset by peer
+
+# open/fcntl
+(equ O_RDONLY 0)
+(equ O_WRONLY 1)
+(equ O_RDWR 2)
+(equ O_CREAT 64)
+(equ O_EXCL 128)
+(equ O_TRUNC 512)
+(equ O_APPEND 1024)
+(equ F_GETFD 1)
+(equ F_SETFD 2)
+(equ FD_CLOEXEC 1)
+
+# stdio
+(equ BUFSIZ 8192)
+(equ PIPE_BUF 4096)
+
+(equ MAXPATHLEN 0)
+
+# dlfcn
+(equ RTLD_LAZY 1)
+(equ RTLD_GLOBAL 256)
+
+# fcntl
+(equ FLOCK 32) # File lock structure
+(equ L_TYPE 0) # 2
+(equ L_WHENCE 2) # 2
+(equ L_START 8)
+(equ L_LEN 16)
+(equ L_PID 24)
+(equ SEEK_SET 0)
+(equ SEEK_CUR 1)
+(equ F_RDLCK 0)
+(equ F_WRLCK 1)
+(equ F_UNLCK 2)
+(equ F_GETFL 3)
+(equ F_SETFL 4)
+(equ F_GETLK 5)
+(equ F_SETLK 6)
+(equ F_SETLKW 7)
+(equ F_SETOWN 8)
+(equ O_NONBLOCK 2048)
+(equ O_ASYNC 8192)
+
+# stat
+(equ STAT 144) # File status structure
+(equ ST_MODE 24) # 4
+(equ ST_SIZE 48)
+(equ ST_MTIME 88)
+(equ S_IFMT (hex "F000"))
+(equ S_IFDIR (hex "4000"))
+
+# times
+(equ TMS 32) # 'times' structure
+(equ TMS_UTIME 0)
+(equ TMS_STIME 8)
+
+# termios
+(equ TERMIOS (+ 60 4)) # Terminal I/O structure (+ Padding)
+(equ C_IFLAG 0)
+(equ C_LFLAG 12)
+(equ C_CC 17)
+(equ ISIG 128)
+(equ VMIN 5)
+(equ VTIME 7)
+(equ TCSADRAIN 1)
+
+# signal
+(equ SIGACTION 152) # Sigaction structure
+(equ SIGSET_T 128)
+(equ SA_HANDLER 0)
+(equ SA_MASK 8)
+(equ SA_FLAGS 136)
+
+(equ SIG_DFL 0)
+(equ SIG_IGN 1)
+(equ SIG_UNBLOCK 1)
+
+(equ SIGHUP 1) # Signals
+(equ SIGINT 2)
+(equ SIGUSR1 10)
+(equ SIGUSR2 12)
+(equ SIGPIPE 13)
+(equ SIGALRM 14)
+(equ SIGTERM 15)
+(equ SIGCHLD 17)
+(equ SIGCONT 18)
+(equ SIGSTOP 19)
+(equ SIGTSTP 20)
+(equ SIGTTIN 21)
+(equ SIGTTOU 22)
+(equ SIGIO 29)
+(equ SIGNALS 30) # Highest used signal number plus 1
+
+# wait
+(equ WNOHANG 1)
+(equ WUNTRACED 2)
+
+# select
+(equ FD_SET 128) # 1024 bit
+
+# time
+(equ TM_SEC 0)
+(equ TM_MIN 4)
+(equ TM_HOUR 8)
+(equ TM_MDAY 12)
+(equ TM_MON 16)
+(equ TM_YEAR 20)
+
+# dir
+(equ D_NAME 19)
+
+# Sockets
+(equ HOSTENT 32)
+(equ H_NAME 0)
+(equ H_LENGTH 20)
+(equ H_ADDR_LIST 24)
+
+(equ IN_ADDR 4)
+(equ S_ADDR 0)
+
+(equ SOCKADDR_IN 16)
+(equ SIN_ADDR 4)
+(equ SIN_ADDR.S_ADDR 4)
+(equ SIN_PORT 2)
+(equ SIN_FAMILY 0)
+(equ AF_INET 2)
+(equ SOCK_STREAM 1)
+(equ SOCK_DGRAM 2)
+(equ INADDR_ANY 0)
+(equ SOL_SOCKET 1)
+(equ SO_REUSEADDR 2)
+
+# vi:et:ts=3:sw=3
diff --git a/src64/version.l b/src64/version.l
@@ -1,6 +1,6 @@
# 14apr11abu
# (c) Software Lab. Alexander Burger
-(de *Version 3 0 6 2)
+(de *Version 3 0 6 3)
# vi:et:ts=3:sw=3