picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

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:
MReleaseNotes | 17++++++++++++++++-
Mdoc/refP.html | 2+-
Mdoc64/asm | 20++++++++++----------
Mlib/tags | 100++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/io.c | 26+++++++++++++++-----------
Asrc64/arch/x86-32.l | 1099+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc64/arch/x86-64.l | 35+++++++++++++++++------------------
Msrc64/big.l | 5+++--
Msrc64/glob.l | 3++-
Msrc64/io.l | 44++++++++++++++++++--------------------------
Msrc64/main.l | 8+++++++-
Asrc64/mkEmu32 | 13+++++++++++++
Msrc64/version.l | 4++--
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