From 12b41e0e8626a47fd21a56ecf591ca731700d8ea Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 6 Aug 2017 12:27:16 +0200 Subject: [PATCH] mescc: Tinycc support: byte and word struct fields. * stage0/x86.M1 (mov____%al,0x8(%edx)): (mov____%ax,(%edx)): (mov____%ax,0x32(%edx)): (mov____%ax,0x8(%edx)): (movzbl_0x32(%eax),%eax): (movzbl_0x8(%eax),%eax): (movzwl_0x32(%eax),%eax): (movzwl_0x8(%eax),%eax): New define. * module/mes/as-i386.mes (i386:word-accu->base-mem): (i386:byte-accu->base-mem+n): (i386:word-accu->base-mem+n): (i386:byte-mem+n->accu): (i386:word-mem+n->accu): New function. * module/mes/as-i386.scm: Export them. * module/language/c99/compiler.mes (struct-field): Use actual size for simple types (WAS: 4). (decl->info): (expr->accu): Respect byte and word struct field sizes. * scaffold/tests/7g-struct-byte-word-field.c: Test it. * make.scm (add-scaffold-test): Build it. --- make.scm | 3 +- module/language/c99/compiler.mes | 55 ++++++++++++++++----- module/mes/as-i386.mes | 21 ++++++++ module/mes/as-i386.scm | 6 +++ scaffold/tests/7g-struct-byte-word-field.c | 56 ++++++++++++++++++++++ stage0/x86.M1 | 8 ++++ 6 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 scaffold/tests/7g-struct-byte-word-field.c diff --git a/make.scm b/make.scm index 5fe89b62..04b05f20 100755 --- a/make.scm +++ b/make.scm @@ -165,7 +165,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$ "7c-dynarray" "7d-cast-char" "7e-struct-array-access" - "7f-struct-pointer-arithmetic")) + "7f-struct-pointer-arithmetic" + "7g-struct-byte-word-field")) (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets))) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 9da74f3c..bd7f914a 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -623,30 +623,40 @@ ((d-sel (ident ,field) (p-expr (ident ,struct))) (let* ((type (ident->type info struct)) (offset (field-offset info type field)) - (ptr (field-pointer info type field))) + (ptr (field-pointer info type field)) + (size (if (= ptr 0) (field-size info type field) + 4))) (if (= ptr -1) (append-text info (append ((ident->accu info) struct) (wrap-as (i386:accu+value offset)))) (append-text info (append ((ident->accu info) struct) - (wrap-as (i386:mem+n->accu offset))))))) - - ((d-sel (ident ,field) (array-ref ,index (p-expr (ident ,array)))) - (let* ((type (ident->type info array)) - (offset (field-offset info type field)) - (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) - (append-text info (wrap-as (i386:mem+n->accu offset))))) + (case size + ((1) (wrap-as (i386:byte-mem+n->accu offset))) + ((2) (wrap-as (i386:word-mem+n->accu offset))) + (else (wrap-as (i386:mem+n->accu offset))))))))) ((i-sel (ident ,field) (p-expr (ident ,struct))) (let* ((type (ident->type info struct)) (offset (field-offset info type field)) - (ptr (field-pointer info type field))) + (ptr (field-pointer info type field)) + (size (if (= ptr 0) (field-size info type field) + 4))) (if (= ptr -1) (append-text info (append ((ident-address->accu info) struct) (wrap-as (i386:mem->accu)) (wrap-as (i386:accu+value offset)))) (append-text info (append ((ident-address->accu info) struct) (wrap-as (i386:mem->accu)) - (wrap-as (i386:mem+n->accu offset))))))) + (case size + ((1) (wrap-as (i386:byte-mem+n->accu offset))) + ((2) (wrap-as (i386:word-mem+n->accu offset))) + (else (wrap-as (i386:mem+n->accu offset))))))))) + + ((d-sel (ident ,field) (array-ref ,index (p-expr (ident ,array)))) + (let* ((type (ident->type info array)) + (offset (field-offset info type field)) + (info ((expr->accu* info) `(array-ref ,index (p-expr (ident ,array)))))) + (append-text info (wrap-as (i386:mem+n->accu offset))))) ((i-sel (ident ,field) (de-ref (p-expr (ident ,array)))) (let* ((type (ident->type info array)) @@ -1589,9 +1599,9 @@ (comp-declr-list (comp-declr (ident ,name)))) (list name `("tag" ,type) 4 0)) ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (ident ,name)))) - (list name type 4 0)) + (list name type (ast-type->size info type) 0)) ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ident ,name)))) - (list name type 4 0)) + (list name type (ast-type->size info type) 0)) ((comp-decl (decl-spec-list (type-spec (typename ,type))) (comp-declr-list (comp-declr (ptr-declr (pointer (pointer)) (ident ,name))))) (list name type 4 2)) ((comp-decl (decl-spec-list (type-spec (fixed-type ,type))) (comp-declr-list (comp-declr (ftn-declr (scope (ptr-declr (pointer) (ident ,name))) (param-list . ,param-list))))) @@ -1939,6 +1949,21 @@ ((decl (decl-spec-list (stor-spec (typedef)) (type-spec (typename ,type))) (init-declr-list (init-declr (ident ,name)))) (clone info #:types (cons (cons name (or (get-type types type) `(typedef ,type))) types))) + ((decl (decl-spec-list (stor-spec (typedef)) (type-spec (typename ,type))) (init-declr-list (init-declr (array-of (ident ,name) ,value)))) + (let* ((type (get-type types type)) + (value (p-expr->number info value)) + (size (* value 4)) + (pointer -1) + (type (make-type 'array size pointer type))) + (clone info #:types (cons (cons name type) types)))) + + ((decl (decl-spec-list (stor-spec (typedef)) (type-spec (struct-ref (ident ,type)))) (init-declr-list (init-declr (ptr-declr ,pointer (ident ,name))))) + (let* ((pointer (expr->pointer info pointer)) + (type (or (get-type types type) `(typedef ,type))) + (size 4) + (type (make-type 'typedef size pointer type))) + (clone info #:types (cons (cons name type) types)))) + ((decl (decl-spec-list (stor-spec (typedef)) (type-spec (struct-def ,field-list))) (init-declr-list (init-declr (ident ,name)))) ((decl->info info) `(decl (decl-spec-list (stor-spec (typedef)) (type-spec (struct-def (ident ,name) ,field-list))) (init-declr-list (init-declr (ident ,name)))))) @@ -2102,6 +2127,7 @@ (let loop ((fields fields) (initzers initzers) (info info)) (if (null? fields) info (let ((offset (field-offset info type (field:name (car fields)))) + (size (field:size (car fields))) (initzer (if (null? initzers) '(p-expr (fixed "0")) (car initzers)))) (loop (cdr fields) (if (null? initzers) '() (cdr initzers)) (clone info #:text @@ -2110,7 +2136,10 @@ ((ident->accu info) name) (wrap-as (append (i386:accu->base))) (.text ((expr->accu empty) initzer)) - (wrap-as (i386:accu->base-mem+n offset))))))))) + (wrap-as (case size + ((1) (i386:byte-accu->base-mem+n offset)) + ((2) (i386:word-accu->base-mem+n offset)) + (else (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)) diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes index 38a61980..0a94de23 100644 --- a/module/mes/as-i386.mes +++ b/module/mes/as-i386.mes @@ -202,11 +202,24 @@ (define (i386:byte-accu->base-mem) '(("mov____%al,(%edx)"))) ; mov %al,(%edx) +(define (i386:word-accu->base-mem) + '(("mov____%ax,(%edx)"))) ; mov %ax,(%edx) + (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))))) +(define (i386:byte-accu->base-mem+n n) + (or n (error "invalid value: accu->base-mem+n: " n)) + `(,(if (< (abs n) #x80) `("mov____%al,0x8(%edx)" (#:immediate1 ,n)) + `("mov____%al,0x32(%edx)" (#:immediate ,n))))) + +(define (i386:word-accu->base-mem+n n) + (or n (error "invalid value: accu->base-mem+n: " n)) + `(,(if (< (abs n) #x80) `("mov____%ax,0x8(%edx)" (#:immediate1 ,n)) + `("mov____%ax,0x32(%edx)" (#:immediate ,n))))) + (define (i386:accu->label label) `(("mov____%eax,0x32" (#:address ,label)))) ; mov %eax,0x