From 683d5bf1d2e3ed240acd6707141d9b644bc25e52 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 28 Jul 2017 22:45:32 +0200 Subject: [PATCH] mescc: Tinycc support: foo.bar = foo.baz = bla. * module/language/c99/compiler.mes (expr->base*): New function. (expr->accu): Use it to have value in accu for assignments. * scaffold/tests/77-pointer-assign.c (test): Test it. * stage0/x86.M1 (mov____%ecx,(%edx), mov___(%eax),%ecx): New define. * module/mes/as-i386.mes (accu-mem->base->mem): New function. (i386:byte-base->accu-mem+n): (i386:byte-base->accu-mem): (i386:base-mem->accu-mem): (i386:base->accu-mem): (i386:value->accu-mem+n): (i386:value->accu-mem): (i386:accu->base-mem+n): (i386:byte-accu->base-mem): (i386:accu->base-mem): Rename from accu-address, base-address. Update callers. * module/mes/as-i386.scm (mes): Update exports. --- module/language/c99/compiler.mes | 68 +++++++++++++++--------------- module/mes/as-i386.mes | 28 ++++++------ module/mes/as-i386.scm | 19 +++++---- scaffold/tests/77-pointer-assign.c | 9 ++++ stage0/x86.M1 | 2 + 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 00d166da..7ea29a90 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -398,20 +398,20 @@ (size (if (= ptr 1) (ast-type->size info type) 4))) - (wrap-as (append (i386:local->accu (local:id local)) - (if (= size 1) (i386:byte-base->accu-address) - (i386:base->accu-address))))) + (if (= size 1) (i386:byte-base->accu-mem) + (i386:base->accu-mem))))) (let ((ptr (ident->pointer info o)) (size 4)) ;; FIXME size (case ptr ((-2) (wrap-as (append (i386:label->accu `(#:address ,o)) - (if (= size 1) (i386:byte-base->accu-address) - (i386:base->accu-address))))) + (if (= size 1) (i386:byte-base->accu-mem) + (i386:base->accu-mem))))) ((-1) (wrap-as (append (i386:label->accu `(#:address ,o)) - (if (= size 1) (i386:byte-base->accu-address) - (i386:base->accu-address))))) + (if (= size 1) (i386:byte-base->accu-mem) + (i386:base->accu-mem))))) (else (wrap-as (append (i386:label-mem->accu `(#:address ,o)) - (if (= size 1) (i386:byte-base->accu-address) - (i386:base->accu-address))))))))))) + (if (= size 1) (i386:byte-base->accu-mem) + (i386:base->accu-mem))))))))))) (define (value->ident info) (lambda (o value) @@ -930,10 +930,8 @@ ((d-sel (ident ,field) ,p-expr) (let* ((type (p-expr->type info p-expr)) (offset (field-offset info type field)) - (info (append-text info (wrap-as (i386:push-accu)))) - (info ((expr->accu* info) a)) - (info (append-text info (wrap-as (i386:pop-base))))) - (append-text info (wrap-as (i386:base->accu-address))))) ; FIXME: size + (info ((expr->base* info) a))) + (append-text info (wrap-as (i386:accu->base-mem))))) ; FIXME: size ((de-ref (p-expr (ident ,name))) (let* ((type (ident->type info name)) (ptr (ident->pointer info name)) @@ -945,43 +943,35 @@ (let* ((info ((expr->base info) expr)) (ptr (expr->pointer info expr)) (size (expr->size info expr))) - (append-text info (wrap-as (i386:accu->base-address))))) + (append-text info (wrap-as (i386:accu->base-mem))))) ((array-ref ,index (d-sel (ident ,field) (p-expr (ident ,struct)))) - (let* ((info (append-text info (wrap-as (i386:push-accu)))) - (info ((expr->accu* info) a)) - (info (append-text info (wrap-as (i386:pop-base))))) - (append-text info (wrap-as (i386:base->accu-address))))) + (let ((info ((expr->base* info) a))) + (append-text info (wrap-as (i386:accu->base-mem))))) ((array-ref ,index (i-sel (ident ,field) (p-expr (ident ,struct)))) - (let* ((info (append-text info (wrap-as (i386:push-accu)))) - (info ((expr->accu* info) a)) - (info (append-text info (wrap-as (i386:pop-base))))) - (append-text info (wrap-as (i386:base->accu-address))))) + (let ((info ((expr->base* info) a))) + (append-text info (wrap-as (i386:accu->base-mem))))) ((array-ref ,index (p-expr (ident ,array))) (let* ((type (ident->type info array)) (ptr (ident->pointer info array)) (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type) 4)) - (info (append-text info (wrap-as (i386:push-accu)))) - (info ((expr->accu* info) a)) - (info (append-text info (wrap-as (i386:pop-base))))) + (info ((expr->base* info) a))) (append-text info - (append (if (eq? size 1) (wrap-as (i386:byte-base->accu-address)) - (if (<= size 4) (wrap-as (i386:base->accu-address)) + (append (if (eq? size 1) (wrap-as (i386:byte-accu->base-mem)) + (if (<= size 4) (wrap-as (i386:accu->base-mem)) (append - (wrap-as (i386:base-address->accu-address)) + (wrap-as (i386:accu-mem->base-mem)) (wrap-as (append (i386:accu+value 4) (i386:base+value 4) - (i386:base-address->accu-address))) + (i386:accu-mem->base-mem))) (if (<= size 8) '() (wrap-as (append (i386:accu+value 4) (i386:base+value 4) - (i386:base-address->accu-address))))))))))) + (i386:accu-mem->base-mem))))))))))) ((i-sel (ident ,field) ,array) - (let* ((info (append-text info (wrap-as (i386:push-accu)))) - (info ((expr->accu* info) a)) - (info (append-text info (wrap-as (i386:pop-base))))) - (append-text info (wrap-as (i386:base->accu-address))))) + (let ((info ((expr->base* info) a))) + (append-text info (wrap-as (i386:accu->base-mem))))) (_ (error "expr->accu: unsupported assign: " a))))) @@ -994,6 +984,14 @@ (info (append-text info (wrap-as (append (i386:accu->base) (i386:pop-accu)))))) info))) +(define (expr->base* info) + (lambda (o) + (let* ((info (append-text info (wrap-as (i386:push-accu)))) + (info ((expr->accu* info) o)) + (info (append-text info (wrap-as (i386:accu->base)))) + (info (append-text info (wrap-as (i386:pop-accu))))) + info))) + (define (binop->accu info) (lambda (a b c) (let* ((info ((expr->accu info) a)) @@ -1995,7 +1993,7 @@ ((ident->accu info) name) (wrap-as (append (i386:accu->base))) (.text ((expr->accu empty) initzer)) - (wrap-as (i386:accu->base-address+n offset))))))))) + (wrap-as (i386:accu->base-mem+n offset))))))))) (let* ((initzer-globals (filter identity (append-map (initzer->globals globals) initzers))) (global-names (map car globals)) (initzer-globals (filter (lambda (g) (and g (not (member (car g) global-names)))) initzer-globals)) @@ -2034,7 +2032,7 @@ ((ident->accu info) name) (wrap-as (append (i386:accu->base))) (.text ((expr->accu empty) initzer)) - (wrap-as (i386:accu->base-address+n offset))))))))) + (wrap-as (i386:accu->base-mem+n offset))))))))) (let* ((global (make-global-entry name type -2 (append-map (initzer->data info) initzers))) (globals (append globals (list global)))) (clone info #:globals globals))))) diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes index dca7d45c..a683c62b 100644 --- a/module/mes/as-i386.mes +++ b/module/mes/as-i386.mes @@ -196,14 +196,14 @@ (define (i386:accu->base) '(("mov____%eax,%edx"))) ; mov %eax,%edx -(define (i386:accu->base-address) +(define (i386:accu->base-mem) '(("mov____%eax,(%edx)"))) ; mov %eax,(%edx) -(define (i386:byte-accu->base-address) +(define (i386:byte-accu->base-mem) '(("mov____%al,(%edx)"))) ; mov %al,(%edx) -(define (i386:accu->base-address+n n) - (or n (error "invalid value: accu->base-address+n: " n)) +(define (i386:accu->base-mem+n n) + (or n (error "invalid value: accu->base-mem+n: " n)) `(,(if (< (abs n) #x80) `("mov____%eax,0x8(%edx)" (#:immediate1 ,n)) `("mov____%eax,0x32(%edx)" (#:immediate ,n))))) @@ -323,26 +323,30 @@ (or v (error "invalid value: i386:value->accu: " v)) `(("mov____$i32,%eax" (#:immediate ,v)))) ; mov $,%eax -(define (i386:value->accu-address v) +(define (i386:value->accu-mem v) `(("mov____$i32,(%eax)" (#:immediate ,v)))) ; movl $0x,(%eax) -(define (i386:value->accu-address+n n v) - (or v (error "invalid value: i386:value->accu-address+n: " v)) +(define (i386:value->accu-mem+n n v) + (or v (error "invalid value: i386:value->accu-mem+n: " v)) `(,(if (< (abs v) #x80) `("mov____$i32,0x8(%eax)" (#:immediate1 ,n) (#:immediate ,v)) `("mov____$i32,0x32(%eax)" (#:immediate ,n) (#:immediate ,v))))) -(define (i386:base->accu-address) +(define (i386:base->accu-mem) '(("mov____%edx,(%eax)"))) ; mov %edx,(%eax) -(define (i386:base-address->accu-address) +(define (i386:accu-mem->base-mem) + '(("mov____(%eax),%ecx") + ("mov____%ecx,(%edx)"))) + +(define (i386:base-mem->accu-mem) '(("mov____(%edx),%ecx") ; mov (%edx),%ecx ("mov____%ecx,(%eax)"))) ; mov %ecx,(%eax) -(define (i386:byte-base->accu-address) +(define (i386:byte-base->accu-mem) '(("mov____%dl,(%eax)"))) ; mov %dl,(%eax) -(define (i386:byte-base->accu-address+n n) - (or n (error "invalid value: byte-base->accu-address+n: " n)) +(define (i386:byte-base->accu-mem+n n) + (or n (error "invalid value: byte-base->accu-mem+n: " n)) `(,(if (< (abs n) #x80) `("mov____%dl,0x8(%eax)" (#:immediate1 ,n)) `("mov____%dl,0x32(%eax)" (#:immediate ,n))))) diff --git a/module/mes/as-i386.scm b/module/mes/as-i386.scm index a792b207..3ebe0943 100644 --- a/module/mes/as-i386.scm +++ b/module/mes/as-i386.scm @@ -34,14 +34,15 @@ i386:accu+base i386:accu+value i386:accu->base - i386:accu->base-address - i386:accu->base-address+n + i386:accu->base-mem + i386:accu->base-mem+n i386:accu->label i386:accu->local i386:accu-and-base i386:accu-base i386:accu-cmp-value i386:accu-mem-add + i386:accu-mem->base-mem i386:accu-negate i386:accu-not i386:accu-or-base @@ -55,16 +56,16 @@ i386:accu>>base i386:base+value i386:base->accu - i386:base->accu-address + i386:base->accu-mem i386:base->label i386:base->local - i386:base-address->accu-address + i386:base-mem->accu-mem i386:base-mem+n->accu i386:base-mem->accu i386:base-sub - i386:byte-accu->base-address - i386:byte-base->accu-address - i386:byte-base->accu-address+n + i386:byte-accu->base-mem + i386:byte-base->accu-mem + i386:byte-base->accu-mem+n i386:byte-base-mem->accu i386:byte-base-sub i386:byte-local->accu @@ -120,8 +121,8 @@ i386:sub-base i386:test-base i386:value->accu - i386:value->accu-address - i386:value->accu-address+n + i386:value->accu-mem + i386:value->accu-mem+n i386:value->base i386:value->label i386:value->local diff --git a/scaffold/tests/77-pointer-assign.c b/scaffold/tests/77-pointer-assign.c index c54ed886..6d2b0136 100644 --- a/scaffold/tests/77-pointer-assign.c +++ b/scaffold/tests/77-pointer-assign.c @@ -22,6 +22,7 @@ struct baz { int i; + int j; }; struct foo { @@ -87,5 +88,13 @@ test () *hash_ident = 0; memset (hash_ident, 0, 10); + struct baz b; + b.i = b.j = 1; + if (b.i != 1) return 4; + + struct baz *pb = &b; + pb->i = pb->j = 1; + if (pb->i != 1) return 5; + return 0; } diff --git a/stage0/x86.M1 b/stage0/x86.M1 index 1a70ff22..1f739156 100644 --- a/stage0/x86.M1 +++ b/stage0/x86.M1 @@ -87,6 +87,7 @@ DEFINE mov____%ebp,%eax 89e8 DEFINE mov____%ebp,%ecx 89e9 DEFINE mov____%ebp,%edx 89ea DEFINE mov____%ecx,(%eax) 8908 +DEFINE mov____%ecx,(%edx) 890a DEFINE mov____%edx,%eax 89d0 DEFINE mov____%edx,%ebx 89d3 DEFINE mov____%edx,%ecx 89d1 @@ -95,6 +96,7 @@ DEFINE mov____%edx,0x32(%ebp) 8995 DEFINE mov____%edx,0x8(%ebp) 8955 DEFINE mov____%esp,%ebp 89e5 DEFINE mov____(%eax),%eax 8b00 +DEFINE mov____(%eax),%ecx 8b08 DEFINE mov____(%edx),%ecx 8b0a DEFINE mov____(%edx),%edx 8b12 DEFINE mov____0x32(%eax),%eax 8b80