From 8d1e001ab22dbc6006f08487e44d9e62dd1844d6 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 6 Jan 2017 00:20:05 +0100 Subject: [PATCH] mescc: Have micro-mes use strcmp to print help. * doc/examples/micro-mes.c (main): Add --help. * module/language/c99/compiler.mes (info?): New function. (expr->accu): Handle function call and sub. (ast->info): Handle if not, and, de-ref, eq, sub, return f (). * module/mes/libc-i386.mes (i386:accu-zero?, i386:Xmem-byte->accu, i386:Xmem-byte->base, i386:jump-byte-nz, i386:jump-byte-z, i386:test-byte-base, i386:Xjump-byte-z, i386:sub-byte-base): New functions. * module/mes/libc-i386.scm: Export them. --- module/language/c99/compiler.mes | 107 ++++++++++++++++++++++++++++--- module/mes/libc-i386.mes | 100 ++++++++++++++++++++--------- module/mes/libc-i386.scm | 8 +++ scaffold/micro-mes.c | 20 +----- 4 files changed, 177 insertions(+), 58 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 7388bec5..f8106e66 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -179,8 +179,10 @@ (pmatch o ((p-expr (fixed ,value)) (string->number value)) ((p-expr (ident ,name)) ((ident->accu (.locals info)) name)) + ((fctn-call . _) ((ast->info info) `(expr-stmt ,o))) + ((sub . _) ((ast->info info) o)) ;; FIXME: expr-stmt (_ - (format (current-error-port) "SKIP expr-accu=~a\n" o) + (format (current-error-port) "SKIP expr->accu=~a\n" o) 0) ))) @@ -221,7 +223,7 @@ ((fctn-defn . _) ((function->info info) o)) ((comment . _) info) ((cpp-stmt (define (name ,name) (repl ,value))) - (stderr "SKIP: #define ~a ~a\n" name value) + (stderr "SKIP: #define ~s ~s\n" name value) info) ((compd-stmt (block-item-list . ,statements)) ((ast-list->info info) statements)) @@ -264,6 +266,24 @@ body-text) #:globals (.globals body-info)))) + ((if (not (fctn-call . ,call)) ,body) + (let* ((call-info ((ast->info info) `(expr-stmt (fctn-call . ,call)))) + (info (clone info #:text '())) + (body-info ((ast->info info) body)) + (body-text (.text body-info)) + (body-length (length (text->list body-text)))) + + (clone info #:text + (append (.text call-info) + (list (lambda (f g t d) + (append + ;;(i386:local-test (assoc-ref locals name) 0) + ;;(i386:accu-test (assoc-ref locals name) 0) + (i386:jump-nz body-length)))) + body-text) + #:globals (append (.globals call-info) + (.globals body-info))))) + (;;(for ,init ,test ,step ,body) (for ,init ;; FIXME: ,test @@ -298,7 +318,7 @@ body-text step-text ;;test-text - ;;(list (lambda (f g t d) (i386:jump-nz (- (+ body-length test-length))))) + ;;(list (lambda (f g t d) (i386:jump-byte-nz (- (+ body-length test-length))))) (list (lambda (f g t d) (append (i386:local-test (assoc-ref init-locals name) value) @@ -323,8 +343,55 @@ (list (lambda (f g t d) (i386:jump body-length))) body-text test-text - (list (lambda (f g t d) (i386:jump-nz (- (+ body-length test-length)))))) - #:globals (.globals body-info)))) + (list (lambda (f g t d) (i386:jump-byte-nz (- (+ body-length test-length)))))) + #:globals (append globals (.globals body-info))))) + + ;;(and (and (de-ref (p-expr (ident "a"))) (de-ref (p-expr (ident "b")))) (eq (de-ref (p-expr (ident "a"))) (de-ref (p-expr (ident "b"))))) + + ((de-ref (p-expr (ident ,name))) + (clone info #:text + (append text + (list (lambda (f g t d) + (append (i386:local->accu (assoc-ref locals name)) + (i386:Xmem-byte->accu))))))) + + ((and ,a ,b) + (let* ((info (clone info #:text '())) + (a-info ((ast->info info) a)) + (a-text (.text a-info)) + (a-length (length (text->list a-text))) + + (b-info ((ast->info info) b)) + (b-text (.text b-info)) + (b-length (length (text->list b-text)))) + + (clone info #:text + (append text + a-text + (list (lambda (f g t d) (i386:jump-byte-z (+ b-length + 2)))) ;; FIXME: need jump after last test + b-text)))) + + ((eq (de-ref (p-expr (ident ,a))) (de-ref (p-expr (ident ,b)))) + (clone info #:text + (append text + (list (lambda (f g t d) + (append + (append (i386:local->accu (assoc-ref locals a)) + (i386:Xmem-byte->base) + (i386:local->accu (assoc-ref locals b)) + (i386:Xmem-byte->accu) + (i386:test-byte-base)))))))) + + ((sub (de-ref (p-expr (ident ,a))) (de-ref (p-expr (ident ,b)))) + (clone info #:text + (append text + (list (lambda (f g t d) + (append (i386:local->accu (assoc-ref locals a)) + (i386:Xmem-byte->base) + (i386:local->accu (assoc-ref locals b)) + (i386:Xmem-byte->accu) + (i386:sub-byte-base))))))) ((array-ref (p-expr (fixed ,value)) (p-expr (ident ,name))) (let ((value (string->number value))) @@ -356,8 +423,12 @@ (i386:local-add (assoc-ref locals name) 1)))))) ((return ,expr) - (clone info #:text - (append text (list (i386:ret ((expr->accu info) expr)))))) + (let ((accu ((expr->accu info) expr))) + (if (info? accu) + (clone accu #:text + (append (.text accu) (list (i386:ret (lambda _ '()))))) + (clone info #:text + (append text (list (i386:ret ((expr->accu info) expr)))))))) ;; int i; ((decl (decl-spec-list (type-spec (fixed-type ,type))) (init-declr-list (init-declr (ident ,name)))) @@ -414,7 +485,7 @@ (clone info #:text (append (.text info) (list (lambda (f g t d) (i386:ret-local (assoc-ref locals name)))))))) (_ - (format (current-error-port) "SKIP statement=~a\n" o) + (format (current-error-port) "SKIP statement=~s\n" o) info))))) (define (info->exe info) @@ -557,6 +628,23 @@ puts (char const* s) parse-c99))) ast)) +(define strcmp + (let* ((ast (with-input-from-string + " +int +strcmp (char const* a, char const* b) +{ + while (*a && *b && *a == *b) + { + a++;b++; + } + return *a - *b; +} +" +;;paredit:" + parse-c99))) + ast)) + (define i386:libc (list (cons "exit" (list i386:exit)) @@ -567,7 +655,8 @@ puts (char const* s) strlen eputs fputs - puts)) + puts + strcmp)) (define (compile) (let* ((ast (mescc)) diff --git a/module/mes/libc-i386.mes b/module/mes/libc-i386.mes index 0a0d02a1..91fbfa83 100644 --- a/module/mes/libc-i386.mes +++ b/module/mes/libc-i386.mes @@ -73,6 +73,9 @@ (or n al) `(#x89 #x45 ,(- 0 (* 4 n)))) ; mov ,%eax,-<0xn>(%ebp) +(define (i386:accu-zero?) + `(#x85 #xc0)) ; cmpl %eax,%eax + (define (i386:local->accu n) (or n la) `(#x8b #x45 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%eax @@ -85,6 +88,12 @@ '(#x01 #xd0 ; add %edx,%eax #x0f #xb6 #x00)) ; movzbl (%eax),%eax +(define (i386:Xmem-byte->accu) + '(#x0f #xb6 #x00)) ; movzbl (%eax),%eax + +(define (i386:Xmem-byte->base) + '(#x0f #xb6 #x10)) ; movzbl (%eax),%edx + (define (i386:mem->accu) '(#x01 #xd0 ; add %edx,%eax #x8b #x00)) ; mov (%eax),%eax @@ -171,55 +180,82 @@ (define (i386:jump-le n) `(#x7e ,(if (>= n 0) n (- n 4)))) ; jle -(define (i386:jump-nz n) +(define (i386:jump-byte-nz n) `(#x84 #xc0 ; test %al,%al #x75 ,(if (>= n 0) n (- n 4)))) ; jne +(define (i386:jump-nz n) + `(#x85 #xc0 ; test %eax,%eax + #x75 ,(if (>= n 0) n (- n 4)))) ; jne + +(define (i386:jump-byte-z n) + `(#x84 #xc0 ; test %al,%al + #x74 ,(if (>= n 0) n (- n 4)))) ; jne + +(define (i386:test-byte-base) + `(#x38 #xc2)) ; cmp %al,%dl + +(define (i386:Xjump-byte-z n) + `(#x74 ,(if (>= n 0) n (- n 2)))) ; je + +(define (i386:sub-byte-base) + `(#x28 #xd0)) ; sub %dl,%al + +;;28 d0 sub %dl,%al +;;28 c2 sub %al,%dl +;;29 d0 sub %edx,%eax +;;29 c2 sub %eax,%edx + #! int strcmp (char const* a, char const* b) { - while (*a && *b && *a == *b) {*a++;b++; - } + while (*a && *b && *a == *b) + { + a++;b++; + } return *a == *b; } 08048150 : 8048150: 55 push %ebp 8048151: 89 e5 mov %esp,%ebp - 8048153: eb 0d jmp 8048162 + + 8048153: eb 08 jmp 804815d - 8048155: 8b 45 08 mov 0x8(%ebp),%eax - 8048158: 83 c0 01 add $0x1,%eax - 804815b: 89 45 08 mov %eax,0x8(%ebp) - 804815e: 83 45 0c 01 addl $0x1,0xc(%ebp) + 8048155: 83 45 08 01 addl $0x1,0x8(%ebp) + 8048159: 83 45 0c 01 addl $0x1,0xc(%ebp) - 8048162: 8b 45 08 mov 0x8(%ebp),%eax - 8048165: 0f b6 00 movzbl (%eax),%eax - 8048168: 84 c0 test %al,%al - 804816a: 74 1a je 8048186 + 804815d: 8b 45 08 mov 0x8(%ebp),%eax + 8048160: 0f b6 00 movzbl (%eax),%eax + 8048163: 84 c0 test %al,%al + 8048165: 74 1a je 8048181 - 804816c: 8b 45 0c mov 0xc(%ebp),%eax - 804816f: 0f b6 00 movzbl (%eax),%eax - 8048172: 84 c0 test %al,%al - 8048174: 74 10 je 8048186 + 8048167: 8b 45 0c mov 0xc(%ebp),%eax + 804816a: 0f b6 00 movzbl (%eax),%eax + 804816d: 84 c0 test %al,%al + 804816f: 74 10 je 8048181 - 8048176: 8b 45 08 mov 0x8(%ebp),%eax - 8048179: 0f b6 10 movzbl (%eax),%edx - 804817c: 8b 45 0c mov 0xc(%ebp),%eax - 804817f: 0f b6 00 movzbl (%eax),%eax - 8048182: 38 c2 cmp %al,%dl - 8048184: 74 cf je 8048155 + 8048171: 8b 45 08 mov 0x8(%ebp),%eax + 8048174: 0f b6 10 movzbl (%eax),%edx + 8048177: 8b 45 0c mov 0xc(%ebp),%eax + 804817a: 0f b6 00 movzbl (%eax),%eax + 804817d: 38 c2 cmp %al,%dl + 804817f: 74 d4 je 8048155 - - 8048186: 8b 45 08 mov 0x8(%ebp),%eax - 8048189: 0f b6 10 movzbl (%eax),%edx - 804818c: 8b 45 0c mov 0xc(%ebp),%eax - 804818f: 0f b6 00 movzbl (%eax),%eax - 8048192: 38 c2 cmp %al,%dl - 8048194: 0f 94 c0 sete %al - 8048197: 0f b6 c0 movzbl %al,%eax - 804819a: 5d pop %ebp - 804819b: c3 ret + + 8048181: 8b 45 08 mov 0x8(%ebp),%eax + 8048184: 0f b6 00 movzbl (%eax),%eax + 8048187: 0f be d0 movsbl %al,%edx + + 804818a: 8b 45 0c mov 0xc(%ebp),%eax + 804818d: 0f b6 00 movzbl (%eax),%eax + 8048190: 0f be c0 movsbl %al,%eax + + 8048193: 29 c2 sub %eax,%edx + 8048195: 89 d0 mov %edx,%eax + + 8048197: 5d pop %ebp + 8048198: c3 ret !# diff --git a/module/mes/libc-i386.scm b/module/mes/libc-i386.scm index 9095076e..06a40ff8 100644 --- a/module/mes/libc-i386.scm +++ b/module/mes/libc-i386.scm @@ -35,6 +35,8 @@ i386:function-locals i386:eputs i386:jump + i386:jump-byte-nz + i386:jump-byte-z i386:jump-nz i386:jump-le i386:local-add @@ -44,6 +46,7 @@ i386:local-test i386:mem->accu i386:mem-byte->accu + i386:Xmem-byte->accu i386:push-accu i386:puts i386:ref-global @@ -52,6 +55,11 @@ i386:ret-local i386:value->accu i386:write + + i386:test-byte-base + i386:Xmem-byte->base + i386:Xjump-byte-z + i386:sub-byte-base )) (cond-expand diff --git a/scaffold/micro-mes.c b/scaffold/micro-mes.c index 97b646c6..b4522477 100644 --- a/scaffold/micro-mes.c +++ b/scaffold/micro-mes.c @@ -30,13 +30,13 @@ #define NYACC2 nyacc2 #endif +#if __GNUC__ typedef long size_t; void *malloc (size_t i); int open (char const *s, int mode); int read (int fd, int n); void write (int fd, char const* s, int n); -#if __GNUC__ void exit (int code) { @@ -99,7 +99,6 @@ free (void *p) int *n = (int*)p-1; //munmap ((void*)p, *n); } -#endif #define EOF -1 #define STDIN 0 @@ -112,7 +111,6 @@ free (void *p) int g_stdin; -#if __GNUC__ size_t strlen (char const* s) { @@ -224,29 +222,17 @@ main (int argc, char *argv[]) { puts ("\narg1="); puts (argv[1]); + if (!strcmp (argv[1], "--help")) return puts ("Usage: mes [--dump|--load] < FILE"); } puts ("\n"); eputs ("Strlen...\n"); puts ("Bye micro\n"); int i = argc; + //int i = strcmp (argv[1], "1"); return i; } #if __GNUC__ -// int -// test1() -// { -// return 9; -// } - -// void -// test() -// { -// int r; -// r=7; -// r=test1(); -// } - void _start () {