From b16c9dbf16e0bc769cde3ede44ad60a4729db12d Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Tue, 8 Aug 2017 10:00:13 +0200 Subject: [PATCH] mescc: Tinycc support: word array assignment. * stage0/x86.M1 (movzwl_(%eax),%eax): New define. * module/mes/as-i386.mes (i386:word-mem->accu): New function. * module/mes/as-i386.scm: Export it. * module/language/c99/compiler.mes (expr->accu): word array assignment. (expr->accu*): word array assignment. * scaffold/tests/7a-struct-char-array.c (test): Test it. --- module/language/c99/compiler.mes | 75 +++++++++++++++------------ module/mes/as-i386.mes | 3 ++ module/mes/as-i386.scm | 2 + scaffold/tests/7a-struct-char-array.c | 22 ++++++++ stage0/x86.M1 | 1 + 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index f9620849..a7f06ee8 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -517,8 +517,8 @@ ((sizeof-expr (p-expr (string ,string))) (append-text info (wrap-as (i386:value->accu (1+ (string-length string)))))) - ((sizeof-expr (i-sel (ident ,field) (p-expr (ident ,array)))) - (let* ((type (ident->type info array)) + ((sizeof-expr (i-sel (ident ,field) (p-expr (ident ,struct)))) + (let* ((type (ident->type info struct)) (size (field-size info type field))) (append-text info (wrap-as (i386:value->accu size))))) @@ -550,16 +550,16 @@ (let ((size 4)) (append-text info (wrap-as (i386:value->accu size))))) - ;; c+p expr->arg - ;; g_cells[] + ;; foo[bar] ((array-ref ,index (p-expr (ident ,array))) - (let* ((type (ident->type info array)) + (let* ((info ((expr->accu* info) o)) + (type (ident->type info array)) (ptr (ident->pointer info array)) (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type) - 4)) - (info ((expr->accu* info) o))) + 4))) (append-text info (wrap-as (case size ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) ((4) (i386:mem->accu)) (else '())))))) @@ -573,6 +573,7 @@ 4))) (append-text info (wrap-as (case size ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) (else (i386:mem->accu))))))) ;; foo->bar[baz]) @@ -585,6 +586,7 @@ 4))) (append-text info (wrap-as (case size ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) (else (i386:mem->accu))))))) ;; [baz] @@ -593,8 +595,10 @@ (ptr (expr->pointer info array)) (size (if (= ptr 1) (expr->size info array) 4))) - (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) - (i386:mem->accu)))))) + (append-text info (wrap-as (case size + ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) + (else (i386:mem->accu))))))) ;; bar.f.i ((d-sel (ident ,field1) (d-sel (ident ,field0) (p-expr (ident ,struct0)))) @@ -688,8 +692,10 @@ 4))) (append-text info (append (if (or #t (assoc-ref locals name)) ((ident->accu info) name) ((ident-address->accu info) name)) - (wrap-as (if (= size 1) (i386:byte-mem->accu) - (i386:mem->accu))))))) + (wrap-as (case size + ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) + (else (i386:mem->accu)))))))) ((de-ref (post-inc (p-expr (ident ,name)))) (let* ((info ((expr->accu info) `(de-ref (p-expr (ident ,name))))) @@ -704,8 +710,10 @@ (ptr (expr->pointer info expr)) (size (if (= ptr 1) (expr->size info expr) 4))) - (append-text info (wrap-as (if (= size 1) (i386:byte-mem->accu) - (i386:mem->accu)))))) + (append-text info (wrap-as (case size + ((1) (i386:byte-mem->accu)) + ((2) (i386:word-mem->accu)) + (else (i386:mem->accu))))))) ((fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)) (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list)))) ;; FIXME @@ -1031,17 +1039,19 @@ 4)) (info ((expr->base* info) a))) (append-text info - (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:accu-mem->base-mem)) - (wrap-as (append (i386:accu+value 4) - (i386:base+value 4) - (i386:accu-mem->base-mem))) - (if (<= size 8) '() - (wrap-as (append (i386:accu+value 4) - (i386:base+value 4) - (i386:accu-mem->base-mem))))))))))) + (append (case size + ((1) (wrap-as (i386:byte-accu->base-mem))) + ((2) (wrap-as (i386:word-accu->base-mem))) + (else (if (<= size 4) (wrap-as (i386:accu->base-mem)) + (append + (wrap-as (i386:accu-mem->base-mem)) + (wrap-as (append (i386:accu+value 4) + (i386:base+value 4) + (i386:accu-mem->base-mem))) + (if (<= size 8) '() + (wrap-as (append (i386:accu+value 4) + (i386:base+value 4) + (i386:accu-mem->base-mem)))))))))))) (_ (error "expr->accu: unsupported assign: " a))))) (_ (error "expr->accu: unsupported: " o)))))) @@ -1080,7 +1090,7 @@ (define (expr->accu* info) (lambda (o) (pmatch o - ;; g_cells[] + ;; foo[bar] ((array-ref ,index (p-expr (ident ,array))) (let* ((info ((expr->accu info) index)) (type (ident->type info array)) @@ -1088,13 +1098,14 @@ (size (if (or (= ptr 1) (= ptr -1)) (ast-type->size info type) 4))) (append-text info (append (wrap-as (append (i386:accu->base) - (if (eq? size 1) '() - (append - (if (<= size 4) '() - (i386:accu+accu)) - (if (<= size 8) '() - (i386:accu+base)) - (i386:accu-shl 2))))) + (case size + ((1) '()) + ((2) (i386:accu+accu)) + (else (append (if (<= size 4) '() + (i386:accu+accu)) + (if (<= size 8) '() + (i386:accu+base)) + (i386:accu-shl 2)))))) ((ident->base info) array) (wrap-as (i386:accu+base)))))) diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes index 3200d5ef..30baed23 100644 --- a/module/mes/as-i386.mes +++ b/module/mes/as-i386.mes @@ -321,6 +321,9 @@ (define (i386:byte-mem->accu) '(("movzbl_(%eax),%eax"))) ; movzbl (%eax),%eax +(define (i386:word-mem->accu) + '(("movzwl_(%eax),%eax"))) + (define (i386:byte-mem->base) '(("movzbl_(%edx),%edx"))) ; movzbl (%edx),%edx diff --git a/module/mes/as-i386.scm b/module/mes/as-i386.scm index 54a7bcd0..9649194b 100644 --- a/module/mes/as-i386.scm +++ b/module/mes/as-i386.scm @@ -69,6 +69,7 @@ i386:base-mem->accu i386:base-sub i386:byte-accu->base-mem + i386:word-accu->base-mem i386:byte-base->accu-mem i386:byte-base->accu-mem+n i386:byte-base-mem->accu @@ -76,6 +77,7 @@ i386:byte-local->accu i386:byte-local->base i386:byte-mem->accu + i386:word-mem->accu i386:byte-mem->base i386:byte-sub-base i386:byte-test-base diff --git a/scaffold/tests/7a-struct-char-array.c b/scaffold/tests/7a-struct-char-array.c index 9c0d0084..11cef4c0 100644 --- a/scaffold/tests/7a-struct-char-array.c +++ b/scaffold/tests/7a-struct-char-array.c @@ -118,5 +118,27 @@ test () if (p[8] != ' ') return 32; if (p[9] != '9') return 33; + short *ps; + ps = pfile->buffer; + p = pfile->buffer; + + strcpy (file.buffer, "0123456789\n"); + eputs (file.buffer); + memcpy (ps + 1, " ", 2); + eputs (file.buffer); + eputs (itoa (ps[1])); eputs ("\n"); + eputs (itoa (((' ' << 8) + ' '))); eputs ("\n"); + if (ps[1] != ((' ' << 8) + ' ')) return 40; + if (p[4] != '4') return 41; + + strcpy (file.buffer, "0123456789\n"); + eputs (file.buffer); + ps[2] = ((' ' << 8) + ' '); + eputs (file.buffer); + eputs (itoa (ps[2])); eputs ("\n"); + eputs (itoa (((' ' << 8) + ' '))); eputs ("\n"); + if (ps[2] != ((' ' << 8) + ' ')) return 42; + if (p[6] != '6') return 43; + return 0; } diff --git a/stage0/x86.M1 b/stage0/x86.M1 index bb68b670..8543a12f 100644 --- a/stage0/x86.M1 +++ b/stage0/x86.M1 @@ -139,6 +139,7 @@ DEFINE movzbl_0x32(%ebp),%eax 0fb685 DEFINE movzbl_0x8(%eax),%eax 0fb640 DEFINE movzbl_0x8(%ebp),%eax 0fb645 DEFINE movzbl_0x8(%ebp),%edx 0fb655 +DEFINE movzwl_(%eax),%eax 0fb700 DEFINE movzwl_0x32(%eax),%eax 0fb780 DEFINE movzwl_0x8(%eax),%eax 0fb740 DEFINE mul____%edx f7e2