From 0875ce655a50c470a302a093dcc13260ca764b37 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Wed, 23 Aug 2017 07:08:16 +0200 Subject: [PATCH] mescc: Tinycc support: pointer arithmetic with variable. * module/language/c99/compiler.mes (expr->accu): Support pointer arithmetic with variable: p + i, p - i, p += i, p -= i. * scaffold/tests/76-pointer-arithmetic.c (test): Test it. --- module/language/c99/compiler.mes | 39 +++++++++++++++++++----- scaffold/tests/76-pointer-arithmetic.c | 41 ++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 12544de5..cbc7ca92 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -799,28 +799,42 @@ ((and struct? (= ptr -2)) 4) ((and struct? (= ptr 2)) 4) (else 1)))) - ((binop->accu info) a b (i386:accu+base)))) + (if (= size 1) ((binop->accu info) a b (i386:accu+base)) + (let* ((info ((expr->accu info) b)) + (info (append-text info (wrap-as (i386:value->base size)))) + (info (append-text info (wrap-as (i386:accu*base)))) + (info ((expr->base info) a))) + (append-text info (wrap-as (i386:accu+base))))))) ((sub ,a (p-expr (fixed ,value))) (let* ((ptr (expr->pointer info a)) + (type0 (p-expr->type info a)) + (struct? (memq (type:type (ast-type->type info type0)) '(struct union))) (size (cond ((= ptr 1) (expr->size info a)) ((> ptr 1) 4) + ((and struct? (= ptr -2)) 4) + ((and struct? (= ptr 2)) 4) (else 1))) (info ((expr->accu info) a)) (value (cstring->number value)) (value (* size value))) - (if (not (= size 1)) - (warn (format #f "TODO: pointer arithmetic: ~s\n" o))) (append-text info (wrap-as (i386:accu+value (- value)))))) ((sub ,a ,b) (let* ((ptr (expr->pointer info a)) + (type0 (p-expr->type info a)) + (struct? (memq (type:type (ast-type->type info type0)) '(struct union))) (size (cond ((= ptr 1) (expr->size info a)) ((> ptr 1) 4) + ((and struct? (= ptr -2)) 4) + ((and struct? (= ptr 2)) 4) (else 1)))) - (if (not (= size 1)) - (warn (format #f "TODO: pointer arithmetic: ~s\n" o)))) - ((binop->accu info) a b (i386:accu-base))) + (if (= size 1) ((binop->accu info) a b (i386:accu-base)) + (let* ((info ((expr->accu info) b)) + (info (append-text info (wrap-as (i386:value->base size)))) + (info (append-text info (wrap-as (i386:accu*base)))) + (info ((expr->base info) a))) + (append-text info (wrap-as (i386:accu-base))))))) ((bitwise-and ,a ,b) ((binop->accu info) a b (i386:accu-and-base))) ((bitwise-not ,expr) @@ -908,7 +922,18 @@ (let* ((info (append-text info (ast->comment o))) (info ((expr->accu info) b)) (info (if (equal? op "=") info - (let* ((info (append-text info (wrap-as (i386:push-accu)))) + (let* ((ptr (expr->pointer info a)) + (type0 (p-expr->type info a)) + (struct? (memq (type:type (ast-type->type info type0)) '(struct union))) + (size (cond ((= ptr 1) (expr->size info a)) + ((> ptr 1) 4) + ((and struct? (= ptr -2)) 4) + ((and struct? (= ptr 2)) 4) + (else 1))) + (info (if (= size 1) info + (let ((info (append-text info (wrap-as (i386:value->base size))))) + (append-text info (wrap-as (i386:accu*base)))))) + (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 (cond ((equal? op "+=") (wrap-as (i386:accu+base))) diff --git a/scaffold/tests/76-pointer-arithmetic.c b/scaffold/tests/76-pointer-arithmetic.c index 28b63344..2edb00a4 100644 --- a/scaffold/tests/76-pointer-arithmetic.c +++ b/scaffold/tests/76-pointer-arithmetic.c @@ -23,6 +23,12 @@ char *list[2] = {"foo\n", "bar\n"}; +struct foo { + int a; + int b; + int c; +}; + int test () { @@ -49,10 +55,41 @@ test () char **p = list; ++*p; eputs (*p); - if (strcmp (*p, "oo\n")) return 1; + if (strcmp (*p, "oo\n")) return 13; --*p; eputs (*p); - if (strcmp (*p, "foo\n")) return 2; + if (strcmp (*p, "foo\n")) return 14; + + struct foo* pfoo = 0; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + pfoo++; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo != 12) return 15; + + pfoo--; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo) return 16; + + pfoo++; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo != 12) return 17; + + int one = 1; + pfoo = pfoo - one; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo) return 18; + + pfoo = pfoo + one; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo != 12) return 19; + + pfoo -= one; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo) return 20; + + pfoo += one; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo != 12) return 21; return 0; }