commit 779c9770ac19438a2cc049a17aef212af518d503
parent a6efd51af02775651a897bdd29e468f369efbe96
Author: Commit-Bot <unknown>
Date:   Wed, 12 May 2010 11:44:39 +0000
Automatic commit from picoLisp.tgz, From: Wed, 12 May 2010 08:44:39 GMT
Diffstat:
13 files changed, 1253 insertions(+), 123 deletions(-)
diff --git a/ReleaseNotes b/ReleaseNotes
@@ -1,4 +1,4 @@
-30apr10abu
+12may10abu
 (c) Software Lab. Alexander Burger
 
 
@@ -27,3 +27,18 @@ D. The 'format' number <-> string conversion function now also accepts a list
       (format Lst)
 
    will also do.
+
+E. There is a partially implemented 32-bit emulator of the 64-bit version in
+   "src64/arch/x86-32.l". It is intended as a demonstration of how to port the
+   assembler to a different CPU (not a very suitable demonstration, though), and
+   a way to thest 64-bit programs on a 32-bit machine. If it ever works, it will
+   be deadly slow, though.
+
+   In case somebody likes to grit his teeth on it, an exprimental executable
+   "bin/emu32" can be built with
+
+      (cd src64; ./mkEmu32)
+
+   Be warned, however, it builds something which doesn't run. Most instructions
+   that return CPU flags, and 128-bit multiplication/division are not right yet.
+   Besides this, there are probably a lot of bugs.
diff --git a/doc/refP.html b/doc/refP.html
@@ -468,7 +468,7 @@ href="refW.html#wr">wr</a></code>.
 <dd>Executes <code>prg</code>, similar to <code><a
 href="refR.html#run">run</a></code>, by evaluating all expressions in
 <code>prg</code> (within the binding environment given by <code>cnt-1</code>).
-As a side effect, all atomics expression will be printed with <code><a
+As a side effect, all atomic expressions will be printed with <code><a
 href="refP.html#prinl">prinl</a></code>. See also <code><a
 href="refE.html#eval">eval</a></code>.
 
diff --git a/doc64/asm b/doc64/asm
@@ -1,4 +1,4 @@
-# 05may10abu
+# 11may10abu
 # (c) Software Lab. Alexander Burger
 
 
@@ -80,7 +80,7 @@
       nop                  # No operation
 
    Move Instructions:
-      ld dst src           # Load 'dst' from 'src'
+      ld dst src           # Load 'dst' from 'src' [---]
       ld2 src              # Load 'A' from two bytes 'src' (unsigned)
       ld4 src              # Load 'A' from four bytes 'src' (unsigned)
       ldc dst src          # Load if Carry 'dst' from 'src'
@@ -117,8 +117,8 @@
       rcl dst src          # Rotate 'dst' with Carry left by 'src' bits
       rcr dst src          # Rotate 'dst' with Carry right by 'src' bits
 
-      mul src              # Multiplication of 'A' and 'src' into 'D'
-      div src              # Division of 'D' by 'src' into 'A', 'C'
+      mul src              # Multiplication of 'A' and 'src' into 'D' [...]
+      div src              # Division of 'D' by 'src' into 'A', 'C' [...]
 
       zxt                  # Zero-extend 'B' to 'A'
 
@@ -128,15 +128,15 @@
       clrz                 # Clear Zero flag
 
    Comparisons:
-      cmp dst src          # Compare 'dst' with 'src'
+      cmp dst src          # Compare 'dst' with 'src' [z.c]
       cmp4 src             # Compare four bytes in 'A' with 'src'
       cmpm dst src end     # Compare 'dst' with with memory between 'src' and 'end'
       cmpn dst src cnt     # Compare 'cnt' bytes 'dst' with 'src'
       slen dst src         # Set 'dst' to the string length of 'src'
       memb src cnt         # Find B in 'cnt' bytes of memory
-      null src             # Compare 'src' with 0
-      zero src             # 'z' if ZERO
-      nul4                 # Compare four bytes in 'A' with 0
+      null src             # Compare 'src' with 0 [zs.]
+      zero src             # Test if ZERO [z..]
+      nul4                 # Compare four bytes in 'A' with 0 [zs.]
 
    Byte addressing:
       set dst src          # Set 'dst' byte to 'src'
@@ -167,8 +167,8 @@
       return src           # Return to C-function
 
    Stack Manipulations:
-      push src             # Push 'src'
-      pop dst              # Pop 'dst'
+      push src             # Push 'src' [---]
+      pop dst              # Pop 'dst' [---]
       link                 # Setup frame
       tuck src             # Extend frame
       drop                 # Drop frame
diff --git a/lib/tags b/lib/tags
@@ -1,13 +1,13 @@
 ! (2560 . "@src64/flow.l")
 $ (2662 . "@src64/flow.l")
-% (2250 . "@src64/big.l")
-& (2471 . "@src64/big.l")
-* (2069 . "@src64/big.l")
-*/ (2126 . "@src64/big.l")
-+ (1851 . "@src64/big.l")
-- (1889 . "@src64/big.l")
+% (2251 . "@src64/big.l")
+& (2472 . "@src64/big.l")
+* (2070 . "@src64/big.l")
+*/ (2127 . "@src64/big.l")
++ (1852 . "@src64/big.l")
+- (1890 . "@src64/big.l")
 -> (3788 . "@src64/subr.l")
-/ (2191 . "@src64/big.l")
+/ (2192 . "@src64/big.l")
 : (2896 . "@src64/sym.l")
 :: (2920 . "@src64/sym.l")
 ; (2822 . "@src64/sym.l")
@@ -22,8 +22,8 @@ $ (2662 . "@src64/flow.l")
 =T (2166 . "@src64/subr.l")
 > (2252 . "@src64/subr.l")
 >= (2282 . "@src64/subr.l")
->> (2305 . "@src64/big.l")
-abs (2395 . "@src64/big.l")
+>> (2306 . "@src64/big.l")
+abs (2396 . "@src64/big.l")
 accept (139 . "@src64/net.l")
 adr (511 . "@src64/main.l")
 alarm (455 . "@src64/main.l")
@@ -32,16 +32,16 @@ and (1637 . "@src64/flow.l")
 any (3758 . "@src64/io.l")
 append (1329 . "@src64/subr.l")
 apply (581 . "@src64/apply.l")
-arg (1873 . "@src64/main.l")
-args (1849 . "@src64/main.l")
-argv (2494 . "@src64/main.l")
+arg (1879 . "@src64/main.l")
+args (1855 . "@src64/main.l")
+argv (2500 . "@src64/main.l")
 as (146 . "@src64/flow.l")
 asoq (2938 . "@src64/subr.l")
 assoc (2903 . "@src64/subr.l")
 at (2122 . "@src64/flow.l")
 atom (2370 . "@src64/subr.l")
 bind (1375 . "@src64/flow.l")
-bit? (2412 . "@src64/big.l")
+bit? (2413 . "@src64/big.l")
 bool (1737 . "@src64/flow.l")
 box (839 . "@src64/flow.l")
 box? (999 . "@src64/sym.l")
@@ -65,7 +65,7 @@ call (2793 . "@src64/flow.l")
 car (5 . "@src64/subr.l")
 case (1978 . "@src64/flow.l")
 catch (2478 . "@src64/flow.l")
-cd (2249 . "@src64/main.l")
+cd (2255 . "@src64/main.l")
 cdaaar (464 . "@src64/subr.l")
 cdaadr (487 . "@src64/subr.l")
 cdaar (179 . "@src64/subr.l")
@@ -87,7 +87,7 @@ chop (1093 . "@src64/sym.l")
 circ (816 . "@src64/subr.l")
 clip (1784 . "@src64/subr.l")
 close (4146 . "@src64/io.l")
-cmd (2476 . "@src64/main.l")
+cmd (2482 . "@src64/main.l")
 cnt (1279 . "@src64/apply.l")
 commit (1503 . "@src64/db.l")
 con (725 . "@src64/subr.l")
@@ -97,19 +97,19 @@ connect (201 . "@src64/net.l")
 cons (747 . "@src64/subr.l")
 copy (1216 . "@src64/subr.l")
 ctl (4086 . "@src64/io.l")
-ctty (2274 . "@src64/main.l")
+ctty (2280 . "@src64/main.l")
 cut (1795 . "@src64/sym.l")
-date (1988 . "@src64/main.l")
+date (1994 . "@src64/main.l")
 dbck (2092 . "@src64/db.l")
 de (551 . "@src64/flow.l")
-dec (2003 . "@src64/big.l")
+dec (2004 . "@src64/big.l")
 def (475 . "@src64/flow.l")
 default (1659 . "@src64/sym.l")
 del (1850 . "@src64/sym.l")
 delete (1392 . "@src64/subr.l")
 delq (1443 . "@src64/subr.l")
 diff (2561 . "@src64/subr.l")
-dir (2407 . "@src64/main.l")
+dir (2413 . "@src64/main.l")
 dm (563 . "@src64/flow.l")
 do (2152 . "@src64/flow.l")
 e (2623 . "@src64/flow.l")
@@ -119,13 +119,13 @@ eof (3317 . "@src64/io.l")
 eol (3308 . "@src64/io.l")
 errno (1206 . "@src64/main.l")
 eval (208 . "@src64/flow.l")
-ext (4861 . "@src64/io.l")
+ext (4853 . "@src64/io.l")
 ext? (1034 . "@src64/sym.l")
 extern (900 . "@src64/sym.l")
 extra (1280 . "@src64/flow.l")
 extract (1084 . "@src64/apply.l")
 fifo (1961 . "@src64/sym.l")
-file (2354 . "@src64/main.l")
+file (2360 . "@src64/main.l")
 fill (3165 . "@src64/subr.l")
 filter (1027 . "@src64/apply.l")
 fin (2018 . "@src64/subr.l")
@@ -134,22 +134,22 @@ find (1188 . "@src64/apply.l")
 fish (1479 . "@src64/apply.l")
 flg? (2417 . "@src64/subr.l")
 flip (1686 . "@src64/subr.l")
-flush (4836 . "@src64/io.l")
+flush (4828 . "@src64/io.l")
 fold (3341 . "@src64/sym.l")
 for (2241 . "@src64/flow.l")
 fork (2960 . "@src64/flow.l")
-format (1769 . "@src64/big.l")
+format (1770 . "@src64/big.l")
 free (2034 . "@src64/db.l")
 from (3336 . "@src64/io.l")
 full (1066 . "@src64/subr.l")
 fun? (734 . "@src64/sym.l")
 gc (378 . "@src64/gc.l")
-ge0 (2371 . "@src64/big.l")
+ge0 (2372 . "@src64/big.l")
 get (2748 . "@src64/sym.l")
 getd (742 . "@src64/sym.l")
 getl (3030 . "@src64/sym.l")
 glue (1232 . "@src64/sym.l")
-gt0 (2382 . "@src64/big.l")
+gt0 (2383 . "@src64/big.l")
 head (1805 . "@src64/subr.l")
 heap (481 . "@src64/main.l")
 hear (3058 . "@src64/io.l")
@@ -160,9 +160,9 @@ if (1818 . "@src64/flow.l")
 if2 (1837 . "@src64/flow.l")
 ifn (1878 . "@src64/flow.l")
 in (3982 . "@src64/io.l")
-inc (1936 . "@src64/big.l")
+inc (1937 . "@src64/big.l")
 index (2609 . "@src64/subr.l")
-info (2311 . "@src64/main.l")
+info (2317 . "@src64/main.l")
 intern (875 . "@src64/sym.l")
 ipid (2905 . "@src64/flow.l")
 isa (976 . "@src64/flow.l")
@@ -187,7 +187,7 @@ loop (2184 . "@src64/flow.l")
 low? (3213 . "@src64/sym.l")
 lowc (3243 . "@src64/sym.l")
 lst? (2387 . "@src64/subr.l")
-lt0 (2360 . "@src64/big.l")
+lt0 (2361 . "@src64/big.l")
 lup (2224 . "@src64/sym.l")
 made (1098 . "@src64/subr.l")
 make (1079 . "@src64/subr.l")
@@ -219,7 +219,7 @@ nand (1672 . "@src64/flow.l")
 native (1214 . "@src64/main.l")
 need (918 . "@src64/subr.l")
 new (850 . "@src64/flow.l")
-next (1856 . "@src64/main.l")
+next (1862 . "@src64/main.l")
 nil (1755 . "@src64/flow.l")
 nond (1955 . "@src64/flow.l")
 nor (1693 . "@src64/flow.l")
@@ -233,7 +233,7 @@ onOff (1611 . "@src64/sym.l")
 one (1644 . "@src64/sym.l")
 open (4108 . "@src64/io.l")
 opid (2921 . "@src64/flow.l")
-opt (2597 . "@src64/main.l")
+opt (2603 . "@src64/main.l")
 or (1653 . "@src64/flow.l")
 out (4002 . "@src64/io.l")
 pack (1144 . "@src64/sym.l")
@@ -249,13 +249,13 @@ poll (3120 . "@src64/io.l")
 pool (657 . "@src64/db.l")
 pop (1771 . "@src64/sym.l")
 port (5 . "@src64/net.l")
-pr (4950 . "@src64/io.l")
+pr (4942 . "@src64/io.l")
 pre? (1409 . "@src64/sym.l")
-prin (4760 . "@src64/io.l")
-prinl (4774 . "@src64/io.l")
-print (4800 . "@src64/io.l")
-println (4831 . "@src64/io.l")
-printsp (4816 . "@src64/io.l")
+prin (4752 . "@src64/io.l")
+prinl (4766 . "@src64/io.l")
+print (4792 . "@src64/io.l")
+println (4823 . "@src64/io.l")
+printsp (4808 . "@src64/io.l")
 prog (1773 . "@src64/flow.l")
 prog1 (1781 . "@src64/flow.l")
 prog2 (1798 . "@src64/flow.l")
@@ -266,26 +266,26 @@ push (1686 . "@src64/sym.l")
 push1 (1722 . "@src64/sym.l")
 put (2696 . "@src64/sym.l")
 putl (2948 . "@src64/sym.l")
-pwd (2238 . "@src64/main.l")
+pwd (2244 . "@src64/main.l")
 queue (1918 . "@src64/sym.l")
 quit (927 . "@src64/main.l")
 quote (141 . "@src64/flow.l")
-rand (2639 . "@src64/big.l")
+rand (2640 . "@src64/big.l")
 range (988 . "@src64/subr.l")
 rank (2966 . "@src64/subr.l")
 raw (433 . "@src64/main.l")
-rd (4878 . "@src64/io.l")
+rd (4870 . "@src64/io.l")
 read (2498 . "@src64/io.l")
 replace (1490 . "@src64/subr.l")
-rest (1902 . "@src64/main.l")
+rest (1908 . "@src64/main.l")
 reverse (1665 . "@src64/subr.l")
-rewind (4844 . "@src64/io.l")
+rewind (4836 . "@src64/io.l")
 rollback (1885 . "@src64/db.l")
 rot (848 . "@src64/subr.l")
-rpc (4983 . "@src64/io.l")
+rpc (4975 . "@src64/io.l")
 run (332 . "@src64/flow.l")
 sect (2513 . "@src64/subr.l")
-seed (2624 . "@src64/big.l")
+seed (2625 . "@src64/big.l")
 seek (1141 . "@src64/apply.l")
 send (1146 . "@src64/flow.l")
 seq (1090 . "@src64/db.l")
@@ -295,7 +295,7 @@ size (2750 . "@src64/subr.l")
 skip (3294 . "@src64/io.l")
 sort (3837 . "@src64/subr.l")
 sp? (711 . "@src64/sym.l")
-space (4778 . "@src64/io.l")
+space (4770 . "@src64/io.l")
 split (1579 . "@src64/subr.l")
 state (2022 . "@src64/flow.l")
 stem (1974 . "@src64/subr.l")
@@ -316,7 +316,7 @@ text (1270 . "@src64/sym.l")
 throw (2504 . "@src64/flow.l")
 tick (2873 . "@src64/flow.l")
 till (3403 . "@src64/io.l")
-time (2121 . "@src64/main.l")
+time (2127 . "@src64/main.l")
 touch (1049 . "@src64/sym.l")
 trim (1746 . "@src64/subr.l")
 try (1187 . "@src64/flow.l")
@@ -329,19 +329,19 @@ up (610 . "@src64/main.l")
 upp? (3228 . "@src64/sym.l")
 uppc (3292 . "@src64/sym.l")
 use (1586 . "@src64/flow.l")
-usec (2226 . "@src64/main.l")
+usec (2232 . "@src64/main.l")
 val (1461 . "@src64/sym.l")
-version (2611 . "@src64/main.l")
+version (2617 . "@src64/main.l")
 wait (2982 . "@src64/io.l")
 when (1897 . "@src64/flow.l")
 while (2074 . "@src64/flow.l")
 wipe (3088 . "@src64/sym.l")
 with (1343 . "@src64/flow.l")
-wr (4967 . "@src64/io.l")
+wr (4959 . "@src64/io.l")
 xchg (1536 . "@src64/sym.l")
 xor (1714 . "@src64/flow.l")
-x| (2551 . "@src64/big.l")
+x| (2552 . "@src64/big.l")
 yoke (1187 . "@src64/subr.l")
 zap (1063 . "@src64/sym.l")
 zero (1629 . "@src64/sym.l")
-| (2511 . "@src64/big.l")
+| (2512 . "@src64/big.l")
diff --git a/src/io.c b/src/io.c
@@ -1,4 +1,4 @@
-/* 28apr10abu
+/* 12may10abu
  * (c) Software Lab. Alexander Burger
  */
 
@@ -2232,19 +2232,23 @@ void print1(any x) {
    else if (isNil(x))
       outString("NIL");
    else if (isSym(x)) {
-      int c, d;
+      int c;
+      any y;
 
-      if (!(c = symByte(name(x))))
+      if (!(c = symByte(y = name(x))))
          Env.put('$'),  outWord(num(x)/sizeof(cell));
       else if (isExt(x))
          Env.put('{'),  outSym(c),  Env.put('}');
-      else if (hashed(x, ihash(name(x)), Intern)) {
-         do {
-            d = symByte(NULL);
-            if (strchr(Delim, c)  ||  c == '.' && !d)
-               Env.put('\\');
-            Env.put(c);
-         } while (c = d);
+      else if (hashed(x, ihash(y), Intern)) {
+         if (unDig(y) == '.')
+            Env.put('\\'),  Env.put('.');
+         else {
+            do {
+               if (strchr(Delim, c))
+                  Env.put('\\');
+               Env.put(c);
+            } while (c = symByte(NULL));
+         }
       }
       else {
          bool tsm = isCell(val(Tsm)) && Env.put == putStdout && OutFile->tty;
@@ -2253,7 +2257,7 @@ void print1(any x) {
             Env.put('"');
          else {
             outName(car(val(Tsm)));
-            c = symByte(name(x));
+            c = symByte(y);
          }
          do {
             if (c == '\\'  ||  c == '^'  ||  !tsm && c == '"')
diff --git a/src64/arch/x86-32.l b/src64/arch/x86-32.l
@@ -0,0 +1,1099 @@
+# 11may10abu
+# (c) Software Lab. Alexander Burger
+
+# Byte order
+(on *LittleEndian)
+
+# Register assignments
+(de *Registers
+   (A "HiA" . "%eax") (C "HiC" . "LoC") (E "HiE" . "%ebx")
+   (B . "%al") (D "HiC" "LoC" "HiA" . "%eax")
+   (X "HiX" . "LoX") (Y "HiY" . "LoY") (Z "HiZ" . "LoZ")
+   (L . "%ebp") (S . "%esp")
+   (F . T) )
+# NULL: %edx
+# Temporary + Block operations: %ecx %esi %edi
+
+# Addressing modes
+(de byteReg (Reg)
+   (cdr
+      (assoc Reg
+         (quote
+            (("HiA" . "%eax") . "%al")
+            ("%al" . "%al")
+            (("HiC" . "LoC") . "LoC")
+            (("HiE" . "%ebx") . "%bl")
+            (("%ecx" . "%ecx") . "%cl")
+            (("%edx" . "%edx") . "%dl")
+            (("HiX" . "LoX") . "LoX")
+            (("HiY" . "LoY") . "LoY")
+            (("HiZ" . "LoZ") . "LoZ")
+            ("%ebp" . "%bp")
+            ("%esp" . "%sp") ) ) ) )  # No %spl
+
+(de byteVal (Adr)
+   (or
+      (byteReg Adr)  # Register
+      (fin Adr) ) )  # Byte address
+
+(de lowByte (Adr)
+   (or
+      (byteReg Adr)  # Register
+      (fin Adr) ) )  # Word address
+
+(de highWord (S)
+   (cond
+      ((= `(char "(") (char S))
+         (pack "8" S) )
+      ((>= `(char "9") (char S) `(char "0"))
+         (pack "8+" S) )
+      (T (pack S "+8")) ) )
+
+(de immed32 (Src)
+   (and
+      (pair Src)
+      (member (car Src) '("%edx" "$0" "$~0"))
+      (setq Src (chop (cdr Src)))
+      (= "$" (pop 'Src))
+      (format
+         (if (= "~" (car Src)) (cdr Src) Src) ) ) )
+
+(de target (Adr F)
+   (if
+      (or
+         (not *FPic)
+         (= `(char ".") (char Adr))  # Local label ".1"
+         (use (@L @N)
+            (and
+               (match '(@L "_" @N) (chop Adr))  # Local jump "foo_22"
+               (= @L (chop *Label))
+               (format @N) ) ) )
+      Adr
+      (ifn F
+         (pack Adr "@plt")
+         (prinst "mov" (pack Adr "@GOTPCREL(%eip)") "%esi")
+         "(%esi)") ) )
+
+(de src (Src S)
+   (cond
+      ((=0 S)                                         # Immediate
+         (setq Src (cdr (chop Src)))
+         (let (F (and (= "~" (car Src)) (pop 'Src))  N (format (chop Src)))
+            (and (lt0 N) (inc 'N `(** 2 64)))
+            (let (Hi (/ N `(** 2 32))  Lo (% N `(** 2 32)))
+               (cons
+                  (if (and (=0 Hi) (not F)) "%edx" (pack "$" F Hi))
+                  (if (and (=0 Lo) (not F)) "%edx" (pack "$" F Lo)) ) ) ) )
+      ((not S) Src)                                   # Register
+      ((=T S)                                         # Direct
+         (if (and *FPic (not (pre? "(" Src)))
+            (pack Src "@GOTPCREL(%eip)")
+            (cons "%edx" (pack "$" Src)) ) )
+      ((not (car S))
+         (let R (fin (car Src))
+            (ifn (and *FPic (=T (cdr S)))
+               (prog
+                  (unless (pre? "%" R)
+                     (prinst "mov" R (setq R "%esi")) )
+                  (cons
+                     (pack (cdr Src) (and (cdr Src) "+") "4(" R ")")
+                     (pack (cdr Src) "(" R ")") ) )
+               (prinst "add" (pack (cdr Src) "@GOTPCREL(%eip)") R)
+               (cons "???" (pack "(" R ")")) ) ) )
+      ((=T (car S))
+         (ifn *FPic
+            (let Ofs (and (cdr S) (pack "+" (cdr Src)))
+               (cons (pack (car Src) Ofs "+4") (pack (car Src) Ofs)) )
+            (prinst "mov" (pack (car Src) "@GOTPCREL(%eip)") "%esi")
+            (cons
+               (pack (cdr Src) (and (cdr Src) "+") "4(%esi)")
+               (pack (cdr Src) "(%esi)") ) ) )
+      (T
+         (prinst "mov" (fin (src (car Src) (car S))) "%esi")
+         (ifn (and *FPic (=T (cdr S)))
+            (cons
+               (pack (cdr Src) (and (cdr Src) "+") "4(%esi)")
+               (pack (cdr Src) "(%esi)") )
+            (prinst "add" (pack (cdr Src) "@GOTPCREL(%eip)") "%esi")
+            (cons "4(%esi)" "(%esi)") ) ) ) )
+
+(de lea (Src S Reg)
+   (cond
+      ((not S) (prinst "mov" (fin Src) Reg))  # Register
+      ((=T S) (prinst "mov" (fin (src Src T)) Reg))  # Direct
+      ((not (car S))
+         (cond
+            ((and *FPic (=T (cdr S)))
+               (prinst "add" (pack (cdr Src) "@GOTPCREL(%eip)") (car Src))
+               (prinst "mov" (pack "(" (fin (car Src)) ")") Reg) )
+            ((cdr Src)
+               (let R (fin (car Src))
+                  (if (pre? "%" R)
+                     (prinst "lea" (pack (cdr Src) "(" R ")") Reg)
+                     (prinst "mov" R Reg)
+                     (prinst "lea" (pack (cdr Src) "(" Reg ")") Reg) ) ) )
+            (T (prinst "mov" (fin (car Src)) Reg)) ) )
+      ((=T (car S))
+         (ifn *FPic
+            (prinst "lea"
+               (if (cdr S)
+                  (pack (car Src) "+" (cdr Src))
+                  (car Src) )
+               Reg )
+            (prinst "mov" (pack (car Src) "@GOTPCREL(%eip)") Reg)
+            (prinst "lea" (pack (cdr Src) "(%esi)") Reg) ) )
+      (T
+         (if (cdr S)
+            (prinst "lea" (fin (src Src S)) Reg)
+            (prinst "mov" (fin (src (car Src) (car S))) Reg) ) ) ) )
+
+(de dst (Dst D)
+   (cond
+      ((not D) Dst)                             # Register
+      ((not (car D))
+         (let R (fin (car Dst))
+            (ifn (and *FPic (=T (cdr D)))
+               (prog
+                  (unless (pre? "%" R)
+                     (prinst "mov" R (setq R "%edi")) )
+                  (cons
+                     (pack (cdr Dst) (and (cdr Dst) "+") "4(" R ")")
+                     (pack (cdr Dst) "(" R ")") ) )
+               (prinst "add" (pack (cdr Dst) "@GOTPCREL(%eip)") R)
+               (cons "???" (pack "(" R ")")) ) ) )
+      ((=T (car D))
+         (ifn *FPic
+            (let Ofs (and (cdr D) (pack "+" (cdr Dst)))
+               (cons (pack (car Dst) Ofs "+4") (pack (car Dst) Ofs)) )
+            (prinst "mov" (pack (car Dst) "@GOTPCREL(%eip)") "%edi")
+            (cons
+               (pack (cdr Dst) (and (cdr Dst) "+") "4(%edi)")
+               (pack (cdr Dst) "(%edi)") ) ) )
+      (T
+         (prinst "mov" (fin (dst (car Dst) (car D))) "%edi")
+         (ifn (and *FPic (=T (cdr D)))
+            (cons
+               (pack (cdr Dst) (and (cdr Dst) "+") "4(%edi)")
+               (pack (cdr Dst) "(%edi)") )
+            (prinst "add" (pack (cdr Dst) "@GOTPCREL(%eip)") "%edi")
+            (cons "4(%edi)" "(%edi)") ) ) ) )
+
+(de dstSrcByte (Cmd Dst Src)
+   (cond
+      ((>= 255 (immed32 Src) 0)
+         (prinst
+            (pack Cmd (unless  (= "%esp" Dst) "b"))
+            (fin Src)
+            (lowByte Dst) ) )
+      ((= "%al" Dst)
+         (prinst Cmd (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst Cmd "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst Cmd (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst Cmd Src (fin Dst)) )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst (pack Cmd "l") (cdr Src) (cdr Dst))
+            (prinst Cmd (cdr Src) "%ecx")
+            (prinst Cmd "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst (pack Cmd "l") (car Src) (car Dst))
+            (prinst Cmd (car Src) "%ecx")
+            (prinst Cmd "%ecx" (car Dst)) ) ) ) )
+
+(de dstShift (Cmd Cmd2 Dst Src)
+   (if (= "%al" Dst)
+      (if (pre? "$" (fin Src))
+         (prinst Cmd (fin Src) "%al")
+         (prinst "mov" (byteVal Src) "%cl")
+         (prinst Cmd "%cl" "%al") )
+      (when (= "r" (last (chop Cmd)))
+         (setq Dst (cons (cdr Dst) (car Dst))) )
+      (unless (pre? "%" (cdr Dst))
+         (setq Cmd (pack Cmd "l")) )
+      (unless (pre? "%" (car Dst))
+         (setq Cmd2 (pack Cmd2 "l")) )
+      (if (>= 8 (immed32 Src) 1)
+         (do (immed32 Src)
+            (prinst Cmd "$1" (cdr Dst))
+            (prinst Cmd2 "$1" (car Dst)) )
+         (ifn (= "%al" (fin Src))
+            (prinst "mov" (fin Src) "%ecx")
+            (prinst "mov" "%dx" "%cx")
+            (prinst "mov" "%al" "%cl") )
+         (prinl "1:")
+         (prinst Cmd "$1" (cdr Dst))
+         (prinst Cmd2 "$1" (car Dst))
+         (prinst "loop" "1b") ) ) )
+
+
+### Instruction set ###
+(asm nop ()
+   (prinst "nop") )
+
+# Move data
+(asm ld (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)  # B
+         (prinst "mov" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "mov" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "mov" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "movl" Src (fin Dst))
+         (prinst "mov" "%edx" (car Dst)) )
+      ((pair (cdr Dst))  # D
+         (prinst "mov" (cdr Src) "%eax")
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)))
+            (prinst "movl" (car Src) "HiA")
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "mov" "%ecx" "HiA") )
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)))
+            (prinst "movl" (highWord (cdr Src)) "LoC")
+            (prinst "mov" (highWord (cdr Src)) "%ecx")
+            (prinst "mov" "%ecx" "LoC") )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)))
+            (prinst "movl" (highWord (car Src)) "HiC")
+            (prinst "mov" (highWord (car Src)) "%ecx")
+            (prinst "mov" "%ecx" "HiC") ) )
+      ((pair (cdr Src))  # D
+         (prinst "mov" "%eax" (cdr Dst))
+         (if (or (pre? "$" (car Dst)) (pre? "%" (car Dst)))
+            (prinst "movl" "HiA" (car Dst))
+            (prinst "mov" "HiA" "%ecx")
+            (prinst "mov" "%ecx" (car Dst)) )
+         (if (or (pre? "$" (cdr Dst)) (pre? "%" (cdr Dst)))
+            (prinst "movl" "LoC" (highWord (cdr Dst)))
+            (prinst "mov" "LoC" "%ecx")
+            (prinst "mov" "%ecx" (highWord (cdr Dst))) )
+         (if (or (pre? "$" (car Dst)) (pre? "%" (car Dst)))
+            (prinst "movl" "HiC" (highWord (car Dst)))
+            (prinst "mov" "HiC" "%ecx")
+            (prinst "mov" "%ecx" (highWord (car Dst))) ) )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "movl" (cdr Src) (cdr Dst))
+            (prinst "mov" (cdr Src) "%ecx")
+            (prinst "mov" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "movl" (car Src) (car Dst))
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "mov" "%ecx" (car Dst)) ) ) ) )
+
+(asm ld2 (Src S)
+   (prinst "movzwl" (fin (src Src S)) "%eax")
+   (prinst "mov" "%edx" "HiA") )
+
+(asm ld4 (Src S)
+   (prinst "mov" (fin (src Src S)) "%eax")
+   (prinst "mov" "%edx" "HiA") )
+
+(de _cmov (Cmd Jmp)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (if (atom Dst)
+      (prinst Cmd (fin Src) Dst)
+      (prinst Jmp "1f")
+      (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+         (prinst "movl" (cdr Src) (cdr Dst))
+         (prinst "mov" (cdr Src) "%ecx")
+         (prinst "mov" "%ecx" (cdr Dst)) )
+      (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+         (prinst "movl" (car Src) (car Dst))
+         (prinst "mov" (car Src) "%ecx")
+         (prinst "mov" "%ecx" (car Dst)) )
+      (prinl "1:") ) )
+
+(asm ldc (Dst D Src S)
+   (_cmov "cmovcl" "jnc") )
+
+(asm ldnc (Dst D Src S)
+   (_cmov "cmovncl" "jc") )
+
+(asm ldz (Dst D Src S)
+   (_cmov "cmovzl" "jnz") )
+
+(asm ldnz (Dst D Src S)
+   (_cmov "cmovnzl" "jz") )
+
+(asm lea (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((atom Dst)
+         (prinst "lea" (fin Src) Dst) )
+      ((pre? "%" (cdr Dst))
+         (prinst "lea" (cdr Src) (cdr Dst)) )
+      (T
+         (prinst "lea" (cdr Src) "%esi")
+         (prinst "mov" "%esi" (cdr Dst)) ) ) )
+
+(asm st2 (Dst D)
+   (prinst "mov" "%ax" (fin (dst Dst D))) )
+
+(asm st4 (Dst D)
+   (prinst "mov" "%eax" (fin (dst Dst D))) )
+
+(asm xchg (Dst D Dst2 D2)
+   (setq Dst (dst Dst D)  Dst2 (src Dst2 D2))
+   (cond
+      ((= "%al" Dst)
+         (prinst "xchg" (byteVal Dst2) "%al") )
+      ((= "%al" Dst2)
+         (prinst "xchg" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "xchg" (fin Dst2) Dst) )
+      ((atom Dst2)  # S or L
+         (prinst "xchg" Dst2 (fin Dst)) )
+      (T
+         (if (or (pre? "%" (cdr Dst)) (pre? "%" (cdr Dst2)))
+            (prinst "xchg" (cdr Dst) (cdr Dst2))
+            (prinst "mov" (cdr Dst) "%ecx")
+            (prinst "xchg" "%ecx" (cdr Dst2))
+            (prinst "mov" "%ecx" (cdr Dst)) )
+         (if (or (pre? "%" (car Dst)) (pre? "%" (car Dst2)))
+            (prinst "xchg" (car Dst) (car Dst2))
+            (prinst "mov" (car Dst) "%ecx")
+            (prinst "xchg" "%ecx" (car Dst2))
+            (prinst "mov" "%ecx" (car Dst)) ) ) ) )
+
+(asm movm (Dst D Src S End E)
+   (setq Dst (dst Dst D))
+   (unless (= "(%edi)" (fin Dst))
+      (prinst (if (pre? "%" (fin Dst)) "mov" "lea") (fin Dst) "%edi") )
+   (lea End E "%ecx")
+   (lea Src S "%esi")
+   (prinst "sub" "%esi" "%ecx")
+   (prinst "cld")
+   (prinst "rep movsb") )
+
+(asm movn (Dst D Src S Cnt C)
+   (lea Dst D "%edi")
+   (lea Src S "%esi")
+   (prinst "mov" (fin (src Cnt C)) "%ecx")
+   (prinst "cld")
+   (prinst "rep movsb") )
+
+(asm mset (Dst D Cnt C)
+   (setq Dst (dst Dst D))
+   (unless (= "(%edi)" (fin Dst))
+      (prinst (if (pre? "%" (fin Dst)) "mov" "lea") (fin Dst) "%edi") )
+   (prinst "mov" (fin (src Cnt C)) "%ecx")
+   (prinst "cld")
+   (prinst "rep stosb") )
+
+
+# Arithmetics
+(asm add (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "add" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "add" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "add" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "addl" Src (fin Dst)) )
+      ((pair (cdr Dst))  # D
+         (prinst "add" (cdr Src) "%eax")
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)))
+            (prinst "adcl" (car Src) "HiA")
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "adc" "%ecx" "HiA") )
+         (prinst "adc" "%edx" "LoC")
+         (prinst "adc" "%edx" "HiC") )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "addl" (cdr Src) (cdr Dst))
+            (prinst "mov" (cdr Src) "%ecx")
+            (prinst "add" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "adcl" (car Src) (car Dst))
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "adc" "%ecx" (car Dst)) ) ) ) )
+
+(asm addc (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "adc" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "adc" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "adc" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "addl" Src (fin Dst)) )
+      ((pair (cdr Dst))  # D
+         (prinst "adc" (cdr Src) "%eax")
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)))
+            (prinst "adcl" (car Src) "HiA")
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "adc" "%ecx" "HiA") )
+         (prinst "adc" "%edx" "LoC")
+         (prinst "adc" "%edx" "HiC") )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "adcl" (cdr Src) (cdr Dst))
+            (prinst "mov" (cdr Src) "%ecx")
+            (prinst "adc" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "adcl" (car Src) (car Dst))
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "adc" "%ecx" (car Dst)) ) ) ) )
+
+(asm sub (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "sub" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "sub" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "sub" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "subl" Src (fin Dst)) )
+      ((pair (cdr Dst))  # D
+         (prinst "sub" (cdr Src) "%eax")
+         (prinst "sbbl" (car Src) "HiA")
+         (prinst "sbb" "%edx" "LoC")
+         (prinst "sbb" "%edx" "HiC") )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "subl" (cdr Src) (cdr Dst))
+            (prinst "mov" (cdr Src) "%ecx")
+            (prinst "sub" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "sbbl" (car Src) (car Dst))
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "sbb" "%ecx" (car Dst)) ) ) ) )
+
+(asm subc (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "sbb" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "sbb" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "sbb" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "sbbl" Src (fin Dst)) )
+      ((pair (cdr Dst))  # D
+         (prinst "sbb" (cdr Src) "%eax")
+         (prinst "sbbl" (car Src) "HiA")
+         (prinst "sbb" "%edx" "LoC")
+         (prinst "sbb" "%edx" "HiC") )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "sbbl" (cdr Src) (cdr Dst))
+            (prinst "mov" (cdr Src) "%ecx")
+            (prinst "sbb" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "sbbl" (car Src) (car Dst))
+            (prinst "mov" (car Src) "%ecx")
+            (prinst "sbb" "%ecx" (car Dst)) ) ) ) )
+
+(asm not (Dst D)
+   (setq Dst (dst Dst D))
+   (if (atom Dst)  # B
+      (prinst "not" Dst)
+      (prinst "notl" (cdr Dst))
+      (prinst "notl" (car Dst)) ) )
+
+(asm neg (Dst D)
+   (setq Dst (dst Dst D))
+   (if (atom Dst)  # B
+      (prinst "neg" Dst)
+      (prinst "negl" (cdr Dst))
+      (prinst "adcl" "%edx" (car Dst))
+      (prinst "negl" (car Dst)) ) )
+
+(asm and (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "and" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "and" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "and" (fin Src) Dst) )
+      (T
+         (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)) (pre? "%" (cdr Dst)))
+            (prinst "andl" (cdr Src) (cdr Dst))
+            (prinst "and" (cdr Src) "%ecx")
+            (prinst "and" "%ecx" (cdr Dst)) )
+         (if (or (pre? "$" (car Src)) (pre? "%" (car Src)) (pre? "%" (car Dst)))
+            (prinst "andl" (car Src) (car Dst))
+            (prinst "and" (car Src) "%ecx")
+            (prinst "and" "%ecx" (car Dst)) ) ) ) )
+
+(asm or (Dst D Src S)
+   (dstSrcByte "or" (dst Dst D) (src Src S)) )
+
+(asm xor (Dst D Src S)
+   (dstSrcByte "xor" (dst Dst D) (src Src S)) )
+
+(asm off (Dst D Src S)
+   (dstSrcByte "and" (dst Dst D) (src Src S)) )
+
+(asm test (Dst D Src S)
+   (dstSrcByte "test" (dst Dst D) (src Src S)) )
+
+(asm shl (Dst D Src S)
+   (dstShift "shl" "rcl" (dst Dst D) (src Src S)) )
+
+(asm shr (Dst D Src S)
+   (dstShift "shr" "rcr" (dst Dst D) (src Src S)) )
+
+(asm rol (Dst D Src S)
+   (dstShift "rol" "rcl" (dst Dst D) (src Src S)) )
+
+(asm ror (Dst D Src S)
+   (dstShift "ror" "rcr" (dst Dst D) (src Src S)) )
+
+(asm rcl (Dst D Src S)
+   (dstShift "rcl" "rcl" (dst Dst D) (src Src S)) )
+
+(asm rcr (Dst D Src S)
+   (dstShift "rcr" "rcr" (dst Dst D) (src Src S)) )
+
+(asm mul (Src S)
+   (setq Src (src Src S))
+   (prinst "push" "%ebx")
+   (prinst "mov" "HiA" "%ebx")  # MADA
+   (prinst "mov" (car Src) "%edx")
+   (prinst "mov" (cdr Src) "%ecx")
+   (prinst "imul" "%eax" "%ecx")
+   (prinst "imul" "%edx" "%ebx")
+   (prinst "mul" "%edx")
+   (prinst "add" "%ebx" "%ecx")
+   (prinst "lea" "(%ecx,%edx)" "%edx")
+   (prinst "xor" "%edx" "%edx")
+   (prinst "pop" "%ebx") )
+
+(asm div (Src S)
+   (setq Src (fin (src Src S)))  # MADA
+   (prinst "mov" Src (setq Src "%ecx"))
+   (prinst "divl" Src) )
+
+(asm zxt ()  # 8 bit -> 64 bit
+   (prinst "movzx" "%al" "%eax")
+   (prinst "mov" "%edx" "HiA") )
+
+(asm setc ()
+   (prinst "stc") )
+
+(asm clrc ()
+   (prinst "clc") )
+
+(asm setz ()
+   (prinst "or" "%edx" "%edx") )
+
+(asm clrz ()
+   (prinst "cmp" "%esp" "%edx") )
+
+
+# Comparisons
+(asm cmp (Dst D Src S)
+   (setq Dst (dst Dst D)  Src (src Src S))
+   (cond
+      ((= "%al" Dst)
+         (prinst "cmp" (byteVal Src) "%al") )
+      ((= "%al" Src)
+         (prinst "cmp" "%al" (byteVal Dst)) )
+      ((atom Dst)  # S or L
+         (prinst "cmp" (fin Src) Dst) )
+      ((atom Src)  # Direct, S or L
+         (prinst "cmpl" Src (fin Dst)) )
+      (T
+         (prinst "mov" (cdr Src) "%ecx")
+         (prinst "sub" (cdr Dst) "%ecx")
+         (prinst "mov" (car Src) "%esi")
+         (prinst "sbb" (car Dst) "%esi")
+         (prinst "jnz" "1f")
+         (prinst "or" "%esi" "%ecx")
+         (prinl "1:") ) ) )
+
+
+(asm cmp4 (Src S)
+   (prinst "cmp" (fin (src Src S)) "%eax") )
+
+(asm cmpm (Dst D Src S End E)
+   (setq Dst (dst Dst D))
+   (unless (= "(%edi)" (fin Dst))
+      (prinst (if (pre? "%" (fin Dst)) "mov" "lea") (fin Dst) "%esi") )
+   (lea End E "%ecx")
+   (lea Src S "%edi")
+   (prinst "sub" "%esi" "%ecx")
+   (prinst "cld")
+   (prinst "repnz cmpsb") )
+
+(asm cmpn (Dst D Src S Cnt C)
+   (setq Dst (dst Dst D))
+   (unless (= "(%edi)" (fin Dst))
+      (prinst (if (pre? "%" (fin Dst)) "mov" "lea") (fin Dst) "%esi") )
+   (lea Src S "%edi")
+   (prinst "mov" (fin (src Cnt C)) "%ecx")
+   (prinst "cld")
+   (prinst "repnz cmpsb") )
+
+(asm slen (Dst D Src S)
+   (setq Dst (dst Dst D))
+   (prinst "cld")
+   (prinst "xor" "%ecx" "%ecx")
+   (prinst "not" "%ecx")  # Infinite
+   (lea Src S "%edi")
+   (prinst "xchg" "%al" "%dl")  # Save B
+   (prinst "repnz scasb")
+   (prinst "xchg" "%al" "%dl")  # Restore B
+   (prinst "not" "%ecx")
+   (prinst "dec" "%ecx")
+   (prinst "mov" "%ecx" (fin Dst)) )
+
+(asm memb (Src S Cnt C)
+   (prinst "cld")
+   (lea Src S "%edi")
+   (setq Cnt (src Cnt C))
+   (prinst "mov" (fin Cnt) "%ecx")
+   (prinst "repnz scasb")
+   (unless (and S C)
+      (prinst "jnz" "1f")
+      (unless S
+         (prinst "mov" "%edi" (cdr Src)) )
+      (unless C
+         (prinst "mov" "%edx" (car Cnt))
+         (prinst "mov" "%ecx" (cdr Cnt)) )
+      (prinl "1:") ) )
+
+(asm null (Src S)
+   (setq Src (src Src S))
+   (prinst "cmp" "%edx" (car Src))
+   (prinst "jnz" "1f")
+   (prinst "cmp" "%edx" (cdr Src))
+   (prinst "jz" "1f")
+   (prinst "mov" "$1" "%cl")  # nz, s
+   (prinst "or" "%cl" "%cl")
+   (prinl "1:") )
+
+(asm zero (Src S)
+   (setq Src (src Src S))
+   (prinst "cmp" "%edx" (car Src))
+   (prinst "jnz" "1f")
+   (prinst "cmpl" "$2" (cdr Src))
+   (prinl "1:") )
+
+(asm nul4 ()
+   (prinst "cmp" "%edx" "%eax") )
+
+
+# Byte addressing
+(asm set (Dst D Src S)
+   (setq Dst (lowByte (dst Dst D))  Src (fin (src Src S)))
+   (cond
+      ((= "%edx" Src)
+         (prinst "mov" "%dl" Dst) )
+      ((or (pre? "$" Src) (pre? "%" Src) (pre? "%" Dst))
+         (prinst "movb" Src Dst) )
+      (T
+         (prinst "mov" Src "%cl")
+         (prinst "mov" "%cl" Dst) ) ) )
+
+(asm nul (Src S)
+   (prinst "cmp" "%dl" (fin (src Src S))) )
+
+
+# Types
+(asm cnt (Src S)
+   (prinst
+      (if (= "%esp" Src) "test" "testb")
+      "$0x02"
+      (lowByte (src Src S)) ) )
+
+(asm big (Src S)
+   (prinst
+      (if (= "%esp" Src) "test" "testb")
+      "$0x04"
+      (lowByte (src Src S)) ) )
+
+(asm num (Src S)
+   (prinst
+      (if (= "%esp" Src) "test" "testb")
+      "$0x06"
+      (lowByte (src Src S)) ) )
+
+(asm sym (Src S)
+   (prinst
+      (if (= "%esp" Src) "test" "testb")
+      "$0x08"
+      (lowByte (src Src S)) ) )
+
+(asm atom (Src S)
+   (prinst
+      (if (= "%esp" Src) "test" "testb")
+      "$0x0E"
+      (lowByte (src Src S)) ) )
+
+
+# Flow Control
+(asm call (Adr A)
+   (nond
+      (A (prinst "call" (target Adr)))
+      ((=T A) (prinst "call" (pack "*" (cdr Adr))))
+      (NIL
+         (prinst "mov" (target Adr T) "%ecx")
+         (prinst "call" "*%ecx") ) ) )
+
+(asm jmp (Adr A)
+   (nond
+      (A (prinst "jmp" (target Adr)))
+      ((=T A) (prinst "jmp" (pack "*" (cdr Adr))))
+      (NIL
+         (prinst "mov" (target Adr T) "%ecx")
+         (prinst "jmp" "*%ecx") ) ) )
+
+(de _jmp (Opc Opc2)
+   (ifn A
+      (prinst Opc (target Adr))
+      (prinst Opc2 "1f")
+      (ifn (=T A)
+         (prinst "jmp" (pack "*" (cdr Adr)))
+         (prinst "mov" (target Adr T) "%ecx")
+         (prinst "jmp" "*%ecx") )
+      (prinl "1:") ) )
+
+(asm jz (Adr A)
+   (_jmp "jz" "jnz") )
+
+(asm jeq (Adr A)
+   (_jmp "jz" "jnz") )
+
+(asm jnz (Adr A)
+   (_jmp "jnz" "jz") )
+
+(asm jne (Adr A)
+   (_jmp "jnz" "jz") )
+
+(asm js (Adr A)
+   (_jmp "js" "jns") )
+
+(asm jns (Adr A)
+   (_jmp "jns" "js") )
+
+(asm jsz (Adr A)
+   (_jmp "jle" "jg") )
+
+(asm jnsz (Adr A)
+   (_jmp "jg" "jle") )
+
+(asm jc (Adr A)
+   (_jmp "jc" "jnc") )
+
+(asm jlt (Adr A)
+   (_jmp "jc" "jnc") )
+
+(asm jnc (Adr A)
+   (_jmp "jnc" "jc") )
+
+(asm jge (Adr A)
+   (_jmp "jnc" "jc") )
+
+(asm jcz (Adr A)
+   (_jmp "jbe" "ja") )
+
+(asm jle (Adr A)
+   (_jmp "jbe" "ja") )
+
+(asm jncz (Adr A)
+   (_jmp "ja" "jbe") )
+
+(asm jgt (Adr A)
+   (_jmp "ja" "jbe") )
+
+(asm cc (Adr A Arg M)
+   (if (lst? Arg)
+      (let  Lea NIL
+         (prinst "mov" "%esp" "%edx")
+         (mapc
+            '((Src S)
+               (if (== '& Src)
+                  (on Lea)
+                  (cond
+                     (Lea (lea Src S "%ecx"))
+                     ((== 'pop Src) (prinst "pop" "%ecx"))
+                     (T (prinst "mov" (fin (src Src S)) "%ecx")) )
+                  (prinst "xchg" "%esp" "%edx")
+                  (prinst "push" "%ecx")
+                  (prinst "xchg" "%esp" "%edx")
+                  (off Lea) ) )
+            Arg
+            M ) )
+      (prinl "1:")
+      (prinst "cmp" "%esp" Arg)
+      (prinst "jz" "2f")
+      (prinst "pop" "%ecx")
+      (prinst "xchg" "%esp" "%edx")
+      (prinst "push" "%ecx")
+      (prinst "xchg" "%esp" "%edx")
+      (prinl "2:") )
+   (prinst "xchg" "%esp" "%edi")
+   ((get 'call 'asm) Adr A)
+   (prinst "xchg" "%esp" "%edi")
+   (unless (lst? Arg)
+      (prinst "mov" Arg "%esp") ) )
+
+(asm ret ()
+   (prinst "ret") )
+
+(asm begin (N)
+   (prinst "push" "%ebx")
+   (prinst "push" "%esi")
+   (prinst "push" "%edi")
+   (prinst "xor" "%edx" "%edx")  # NULL register
+   (when (>= N 6)                                  # Z
+      (prinst "pushl" "HiZ")
+      (prinst "pushl" "LoZ")
+      (prinst "movl" "24(%esp)" "%ecx")
+      (prinst "movl" "%ecx" "LoZ") )
+   (when (>= N 5)                                  # Y
+      (prinst "pushl" "HiY")
+      (prinst "pushl" "LoY")
+      (prinst "movl" "20(%esp)" "%ecx")
+      (prinst "movl" "%ecx" "LoY") )
+   (when (>= N 4)                                  # X
+      (prinst "pushl" "HiX")
+      (prinst "pushl" "LoX")
+      (prinst "movl" "16(%esp)" "%ecx")
+      (prinst "movl" "%ecx" "LoX") )
+   (when (>= N 3)                                  # E
+      (prinst "movl" "12(%esp)" "%ebx") )
+   (when (>= N 2)                                  # C
+      (prinst "movl" "8(%esp)" "%ecx")
+      (prinst "movl" "%ecx" "LoC") )
+   (when (>= N 1)                                  # A
+      (prinst "movl" "4(%esp)" "%eax") ) )
+
+(asm return (N)
+   (when (>= N 4)
+      (prinst "popl" "LoX")
+      (prinst "popl" "HiX") )
+   (when (>= N 5)
+      (prinst "popl" "LoY")
+      (prinst "popl" "HiY") )
+   (when (>= N 6)
+      (prinst "popl" "LoZ")
+      (prinst "popl" "HiZ") )
+   (prinst "pop" "%edi")
+   (prinst "pop" "%esi")
+   (prinst "pop" "%ebx")
+   (prinst "ret") )
+
+
+# Stack Manipulations
+(asm push (Src S)
+   (setq Src (src Src S))
+   (cond
+      ((=T Src)
+         (prinst "push" "%edx")
+         (prinst "pushf") )
+      ((atom Src)  # S or L
+         (prinst "push" "%edx")
+         (prinst "push" Src) )
+      (T
+         (prinst (if (pre? "%" (car Src)) "push" "pushl") (car Src))
+         (prinst (if (pre? "%" (cdr Src)) "push" "pushl") (cdr Src)) ) ) )
+
+(asm pop (Dst D)
+   (setq Dst (dst Dst D))
+   (cond
+      ((=T Dst)
+         (prinst "popf")
+         (prinst "pop" "%edi") )
+      ((atom Dst)  # S or L
+         (prinst "pop" Dst)
+         (prinst "pop" "%edi") )
+      (T
+         (prinst (if (pre? "%" (cdr Dst)) "pop" "popl") (cdr Dst))
+         (prinst (if (pre? "%" (car Dst)) "pop" "popl") (car Dst)) ) ) )
+
+(asm link ()
+   (prinst "push" "%edx")
+   (prinst "push" "%ebp")
+   (prinst "mov" "%esp" "%ebp") )
+
+(asm tuck (Src S)
+   (setq Src (src Src S))
+   (prinst "mov" "(%esp)" "%ebp")
+   (if (or (pre? "$" (car Src)) (pre? "%" (car Src)))
+      (prinst "movl" (car Src) "4(%esp)")
+      (prinst "mov" (car Src) "%esi")
+      (prinst "mov" "%esi" "4(%esp)") )
+   (if (or (pre? "$" (cdr Src)) (pre? "%" (cdr Src)))
+      (prinst "movl" (cdr Src) "(%esp)")
+      (prinst "mov" (cdr Src) "%esi")
+      (prinst "mov" "%esi" "(%esp)") ) )
+
+(asm drop ()
+   (prinst "mov" "(%ebp)" "%esp")
+   (prinst "pop" "%ebp")
+   (prinst "pop" "%edi") )
+
+# Evaluation
+(asm eval ()
+   (prinst "test" "$0x06" "%bl")       # Number?
+   (prinst "jnz" "2f")                 # Yes: Skip
+   (prinst "test" "$0x08" "%bl")       # Symbol?
+   (prinst "jz" "1f")
+   (prinst "mov" "4(%ebx)" "%ecx")     # Yes: Get value
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov" "(%ebx)" "%ebx")
+   (prinst "jmp" "2f")                 # and skip
+   (prinl "1:")
+   (prinst "call" (target 'evListE_E)) # Else evaluate list
+   (prinl "2:") )
+
+(asm eval+ ()
+   (prinst "test" "$0x06" "%bl")       # Number?
+   (prinst "jnz" "2f")                 # Yes: Skip
+   (prinst "test" "$0x08" "%bl")       # Symbol?
+   (prinst "jz" "1f")
+   (prinst "mov" "4(%ebx)" "%ecx")     # Yes: Get value
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov" "(%ebx)" "%ebx")
+   (prinst "jmp" "2f")                 # and skip
+   (prinst "push" "%edx")              # Else 'link'
+   (prinst "push" "%ebp")
+   (prinst "mov" "%esp" "%ebp")
+   (prinl "1:")
+   (prinst "call" (target 'evListE_E)) # Evaluate list
+   (prinst "pop" "%ebp")
+   (prinst "pop" "%edi")
+   (prinl "2:") )
+
+(asm eval/ret ()
+   (prinst "test" "$0x06" "%bl")       # Number?
+   (prinst "jnz" "ret")                # Yes: Return
+   (prinst "test" "$0x08" "%bl")       # Symbol?
+   (prinst "jz" 'evListE_E)            # No: Evaluate list
+   (prinst "mov" "4(%ebx)" "%ecx")     # Get value
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov" "(%ebx)" "%ebx")
+   (prinst "ret") )
+
+(asm exec (Reg)
+   (prinl "1:")                        # do
+   (prinst "mov" (cdr Reg) "%esi")     # ld E (R)
+   (prinst "mov"
+      (pack "4(%esi)")
+      "%ecx" )
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov"
+      (pack "(%esi)")
+      "%ebx" )
+   (prinst "mov"                       # ld R (R CDR)
+      (pack "8(%esi)")
+      "%esi" )
+   (prinst "mov" "%esi" (cdr Reg))
+   (prinst "test" "$0x0E" "%bl")       # atom E
+   (prinst "jnz" "2f")
+   (prinst "call" (target 'evListE_E)) # evList
+   (prinl "2:")
+   (prinst "testb"                     # atom R
+      "$0x0E"
+      (byteReg Reg) )
+   (prinst "jz" "1b") )                # until nz
+
+(asm prog (Reg)
+   (prinl "1:")                        # do
+   (prinst "mov" (cdr Reg) "%esi")     # ld E (R)
+   (prinst "mov"
+      (pack "4(%esi)")
+      "%ecx" )
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov"
+      (pack "(%esi)")
+      "%ebx" )
+   (prinst "mov"                       # ld R (R CDR)
+      (pack "8(%esi)")
+      "%esi" )
+   (prinst "mov" "%esi" (cdr Reg))
+   (prinst "test" "$0x06" "%bl")       # eval
+   (prinst "jnz" "3f")
+   (prinst "test" "$0x08" "%bl")
+   (prinst "jz" "2f")
+   (prinst "mov" "4(%ebx)" "%ecx")
+   (prinst "mov" "%ecx" "HiE")
+   (prinst "mov" "(%ebx)" "%ebx")
+   (prinst "jmp" "3f")
+   (prinl "2:")
+   (prinst "call" (target 'evListE_E))
+   (prinl "3:")
+   (prinst "testb"                     # atom R
+      "$0x0E"
+      (byteReg Reg) )
+   (prinst "jz" "1b") )                # until nz
+
+
+# System
+(asm initData ()
+   (prinl "   .globl  HiA")
+   (prinl "HiA: .long 0")
+   (prinl "   .globl  LoC")
+   (prinl "LoC: .long 0")
+   (prinl "   .globl  HiC")
+   (prinl "HiC: .long 0")
+   (prinl "   .globl  HiE")
+   (prinl "HiE: .long 0")
+   (prinl "   .globl  LoX")
+   (prinl "LoX: .long 0")
+   (prinl "   .globl  HiX")
+   (prinl "HiX: .long 0")
+   (prinl "   .globl  LoY")
+   (prinl "LoY: .long 0")
+   (prinl "   .globl  HiY")
+   (prinl "HiY: .long 0")
+   (prinl "   .globl  LoZ")
+   (prinl "LoZ: .long 0")
+   (prinl "   .globl  HiZ")
+   (prinl "HiZ: .long 0") )
+
+(asm initCode ()
+   (prinst "xor" "%edx" "%edx")  # Init NULL register
+   (prinst "mov" "8(%esp)" "%esi")  # Get second argument
+   (prinst "mov" "(%esi)" "%eax")  # Get command
+   (ifn *FPic
+      (prinst "mov" "%eax" "AV0")
+      (prinst "mov" "AV0@GOTPCREL(%eip)" "%edi")
+      (prinst "mov" "%eax" "(%edi)") )
+   (prinst "lea" "4(%esi)" "%esi")  # Get argument vector
+   (ifn *FPic
+      (prinst "mov" "%esi" "AV")
+      (prinst "mov" "AV@GOTPCREL(%eip)" "%edi")
+      (prinst "mov" "%esi" "(%edi)") ) )
+
+
+### Optimizer ###
+# Replace the the next 'cnt' elements with 'lst'
+(de optimize (L))  #> (cnt . lst)
+
+### Patch "src64/lib/asm.l" ###
+(patch (get 'word 'asm) '(prinst ".quad" N)
+   '(if (num? N)
+      (prinst ".quad" N)
+      (prinst ".long" N)
+      (prinst ".long" 0) ) )
+
+(patch (get 'initSym 'asm) '(prinst ".quad" Val)
+   '(if (num? Val)
+      (prinst ".quad" Val)
+      (prinst ".long" Val)
+      (prinst ".long" 0) ) )
+
+(patch (get 'initSym 'asm) '(prinst ".quad" ".+20")
+   '(prog
+      (prinst ".long" Val)
+      (prinst ".long" 0) ) )
+
+# vi:et:ts=3:sw=3
diff --git a/src64/arch/x86-64.l b/src64/arch/x86-64.l
@@ -1,4 +1,4 @@
-# 05may10abu
+# 11may10abu
 # (c) Software Lab. Alexander Burger
 
 # Byte order
@@ -122,7 +122,10 @@
                Reg )
             (prinst "mov" (pack (car Src) "@GOTPCREL(%rip)") Reg)
             (prinst "lea" (pack (cdr Src) "(%r10)") Reg) ) )
-      (T (prinst "mov" (src (car Src) (car S)) Reg)) ) )
+      (T
+         (if (cdr S)
+            (prinst "lea" (src Src S) Reg)
+            (prinst "mov" (src (car Src) (car S)) Reg) ) ) ) )
 
 (de dst (Dst D)
    (cond
@@ -164,12 +167,9 @@
          (prinst Cmd "%r10" Dst) ) ) )
 
 (de dstSrcByte (Cmd Dst Src)
-   (cond
-      ((= "%r12" Src)
-         (prinst Cmd "%r12b" (lowByte Dst)) )
-      ((and (immediate Src) (>= 255 @ 0))
-         (prinst (pack Cmd "b") Src (lowByte Dst)) )
-      (T (dstSrc Cmd Dst Src)) ) )
+   (if (>= 255 (immediate Src) 0)
+      (prinst (pack Cmd "b") Src (lowByte Dst))
+      (dstSrc Cmd Dst Src) ) )
 
 (de dstDst (Cmd Dst Dst2)
    (cond
@@ -233,7 +233,7 @@
       (warn "Using suboptimal emulation code")
       (prinst Jmp "1f")
       (if (pre? "%"  Src)
-         (prinst "movq" Src Dst)
+         (prinst "mov" Src Dst)
          (prinst "mov" Src "%r10")
          (prinst "mov" "%r10" Dst) )
       (prinl "1:") ) )
@@ -254,14 +254,14 @@
    (setq Dst (dst Dst D)  Src (src Src S))
    (if (pre? "%" Dst)
       (prinst "lea" Src Dst)
-      (prinst "lea" Src "%r11")
-      (prinst "mov" "%r11" Dst) ) )
+      (prinst "lea" Src "%r10")
+      (prinst "mov" "%r10" Dst) ) )
 
 (asm st2 (Dst D)
-   (prinst "movw" "%ax" (dst Dst D)) )
+   (prinst "mov" "%ax" (dst Dst D)) )
 
 (asm st4 (Dst D)
-   (prinst "movl" "%eax" (dst Dst D)) )
+   (prinst "mov" "%eax" (dst Dst D)) )
 
 (asm xchg (Dst D Dst2 D2)
    (dstDst "xchg" (dst Dst D) (src Dst2 D2)) )
@@ -270,7 +270,7 @@
    (setq Dst (dst Dst D))
    (prinst (if (pre? "%" Dst) "mov" "lea") Dst "%rdi")
    (lea Src S "%rsi")
-   (prinst "lea" (src End E) "%rcx")
+   (lea End E "%rcx")
    (prinst "sub" "%rsi" "%rcx")
    (prinst "cld")
    (prinst "rep movsb") )
@@ -283,6 +283,7 @@
    (prinst "rep movsb") )
 
 (asm mset (Dst D Cnt C)
+   (setq Dst (dst Dst D))
    (prinst (if (pre? "%" Dst) "mov" "lea") Dst "%rdi")
    (prinst "mov" (src Cnt C) "%rcx")
    (prinst "cld")
@@ -304,7 +305,6 @@
       (prinst "adc" Src (car Dst))
       (prinst "adc" "%r12" (cdr Dst)) ) )
 
-
 (asm sub (Dst D Src S)
    (setq Dst (dst Dst D)  Src (src Src S))
    (ifn (pair Dst)
@@ -377,7 +377,6 @@
 (asm zxt ()  # 8 bit -> 64 bit
    (prinst "movzx" "%al" "%rax") )
 
-
 (asm setc ()
    (prinst "stc") )
 
@@ -402,7 +401,7 @@
    (setq Dst (dst Dst D))
    (prinst (if (pre? "%" Dst) "mov" "lea") Dst "%rsi")
    (lea Src S "%rdi")
-   (prinst "lea" End "%rcx")
+   (lea End E "%rcx")
    (prinst "sub" "%rsi" "%rcx")
    (prinst "cld")
    (prinst "repnz cmpsb") )
@@ -560,7 +559,7 @@
       (prinst "mov" "%rdx" "%r12") )
    (let Reg '("%rdi" "%rsi" "%rdx" "%rcx" "%r8" "%r9")
       (if (lst? Arg)
-         (let  Lea NIL
+         (let Lea NIL
             (when (nth Arg 7)
                (setq  # Maximally 6 args in registers
                   Arg (append (head 6 Arg) (reverse (tail -6 Arg)))
diff --git a/src64/big.l b/src64/big.l
@@ -1,4 +1,4 @@
-# 30apr10abu
+# 10may10abu
 # (c) Software Lab. Alexander Burger
 
 ### Destructive primitives ###
@@ -866,7 +866,8 @@
          xchg A E
          shr A 4  # Normalize
          mul E  # Multiply
-         if nc  # Only lower word
+         null C  # Only lower word?
+         if z  # Yes
             test A (hex "F000000000000000")  # Fit in short number?
             if z  # Yes
                shl A 4  # Make short number
diff --git a/src64/glob.l b/src64/glob.l
@@ -1,4 +1,4 @@
-# 02may10abu
+# 12may10abu
 # (c) Software Lab. Alexander Burger
 
 (data 'Globals 0)
@@ -16,6 +16,7 @@
                word  0
 
 : Stack0       word  0           # Initial stack pointer
+: Link         word  0           # Saved link register
 : Catch        word  0           # Catch frames
 : Termio       word  0           # Raw mode terminal I/O
 : Time         word  0           # Pointer to time structure
diff --git a/src64/io.l b/src64/io.l
@@ -1,4 +1,4 @@
-# 05may10abu
+# 12may10abu
 # (c) Software Lab. Alexander Burger
 
 # Close file descriptor
@@ -1619,7 +1619,7 @@
          add A Z  # Fetch byte
          ld B (A VII)  # from buffer
          cmp B 10  # Newline?
-         if z  # Yes
+         if eq  # Yes
             add (Z IV) 1  # Increment line
          end
          zxt  # Extend into A
@@ -4557,35 +4557,27 @@
       ld Y Intern
       call isInternEXY_F  # Internal symbol?
       if eq  # Yes
-         ld C 0
-         call symByteCX_FACX  # Get first byte
-         do
-            memb Delim "(DelimEnd-Delim)"  # Delimiter?
-            if eq  # Yes
-               push A  # Save char
-               ld B (char "\\")  # Print backslash
-               call (EnvPutB)
-               pop A
-            else
-               cmp B (char ".")  # Dot?
+         cmp X (hex "2E2")  # Dot?
+         if eq  # Yes
+            ld B (char "\\")  # Print backslash
+            call (EnvPutB)
+            ld B (char ".")  # Print dot
+            call (EnvPutB)
+         else
+            ld C 0
+            call symByteCX_FACX  # Get first byte
+            do
+               memb Delim "(DelimEnd-Delim)"  # Delimiter?
                if eq  # Yes
-                  call symByteCX_FACX  # Next byte?
-                  if z  # No
-                     ld B (char "\\")  # Print backslash
-                     call (EnvPutB)
-                     ld B (char ".")  # Print dot
-                     call (EnvPutB)
-                     break T  # Done
-                  end
                   push A  # Save char
-                  ld B (char ".")  # Print dot
+                  ld B (char "\\")  # Print backslash
                   call (EnvPutB)
                   pop A
                end
-            end
-            call (EnvPutB)  # Put byte
-            call symByteCX_FACX  # Next byte
-         until z  # Done
+               call (EnvPutB)  # Put byte
+               call symByteCX_FACX  # Next byte
+            until z  # Done
+         end
       else  # Else transient symbol
          ld Y 0  # 'tsm' flag in Y
          atom (Tsm)  # Transient symbol markup?
diff --git a/src64/main.l b/src64/main.l
@@ -1,4 +1,4 @@
-# 05may10abu
+# 12may10abu
 # (c) Software Lab. Alexander Burger
 
 ### Global return labels ###
@@ -1382,7 +1382,10 @@
    cc (Y) X  # Call C-function
    ld E (Z -II)  # Get result specification
    ld C 0  # No pointer yet
+   push (Link)  # Save L
+   ld (Link) L
    call natRetACE_CE  # Extract return value
+   pop (Link)
    ld (Z -II) E  # Save result
    lea Y (Z -III)  # Clean up allocated C args
    do
@@ -1598,6 +1601,8 @@
 
 (code 'lisp 0)
    begin 6  # Function name in A, arguments in C, E, X, Y and Z
+   push L  # Save C frame pointer
+   ld L (Link)  # Restore link register
    link  # Apply args
    push ZERO  # Space for 'fun'
    xchg C E  # First arg
@@ -1637,6 +1642,7 @@
       neg A  # Yes
    end
    drop
+   pop L  # Restore C frame pointer
    return 6
 
 (code 'execE 0)
diff --git a/src64/mkEmu32 b/src64/mkEmu32
@@ -0,0 +1,13 @@
+# 11may10abu
+# (c) Software Lab. Alexander Burger
+
+./mkAsm x86-32 linux Linux base "" ../dbg.l version.l glob.l main.l sys/linux.code.l gc.l apply.l flow.l sym.l subr.l big.l io.l db.l net.l err.l
+as -o x86-32.linux.base.o x86-32.linux.base.s
+gcc -o ../bin/emu32 -rdynamic -lc -lm -ldl x86-32.linux.base.o
+strip ../bin/emu32
+
+#./mkAsm x86-32 linux Linux ext "" ../dbg.l -fpic ext.l
+
+#./mkAsm x86-32 linux Linux ht "" ../dbg.l -fpic ht.l
+
+mv x86-32.linux.* /tmp
diff --git a/src64/version.l b/src64/version.l
@@ -1,6 +1,6 @@
-# 05may10abu
+# 12may10abu
 # (c) Software Lab. Alexander Burger
 
-(de *Version 3 0 2 18)
+(de *Version 3 0 2 19)
 
 # vi:et:ts=3:sw=3