diff --git a/mlibc/include/stdarg.h b/mlibc/include/stdarg.h index fa5a6332..211ec36f 100644 --- a/mlibc/include/stdarg.h +++ b/mlibc/include/stdarg.h @@ -35,7 +35,7 @@ typedef char* va_list; #define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1)) #else // !__GNUC__ typedef int va_list; -#define va_start(ap, last) (void)((ap) = (char*)(&(last) + 4)) +#define va_start(ap, last) (void)((ap) = (char*)(&(last) + 1)) #endif // !__GNUC__ #define va_arg(ap, type) (type)(((int*)((ap) = ((ap) + 4)))[-1]) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index c64429b7..99c430e7 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -792,6 +792,7 @@ ((add ,a ,b) (let* ((ptr (expr->pointer info a)) + (ptr-b (expr->pointer info b)) (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)) @@ -799,11 +800,12 @@ ((and struct? (= ptr -2)) 4) ((and struct? (= ptr 2)) 4) (else 1)))) - (if (= size 1) ((binop->accu info) a b (i386:accu+base)) + (if (or (= 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))) + (info (append-text info (wrap-as (append (i386:value->base size) + (i386:accu*base) + (i386:accu->base))))) + (info ((expr->accu info) a))) (append-text info (wrap-as (i386:accu+base))))))) ((sub ,a (p-expr (fixed ,value))) @@ -822,6 +824,7 @@ ((sub ,a ,b) (let* ((ptr (expr->pointer info a)) + (ptr-b (expr->pointer info b)) (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)) @@ -829,11 +832,15 @@ ((and struct? (= ptr -2)) 4) ((and struct? (= ptr 2)) 4) (else 1)))) - (if (= size 1) ((binop->accu info) a b (i386:accu-base)) + (if (or (= size 1) (= ptr-b 1)) (let ((info ((binop->accu info) a b (i386:accu-base)))) + (if (not (= ptr-b 1)) info + (append-text info (wrap-as (append (i386:value->base size) + (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))) + (info (append-text info (wrap-as (append (i386:value->base size) + (i386:accu*base) + (i386:accu->base))))) + (info ((expr->accu info) a))) (append-text info (wrap-as (i386:accu-base))))))) ((bitwise-and ,a ,b) ((binop->accu info) a b (i386:accu-and-base))) @@ -923,6 +930,7 @@ (info ((expr->accu info) b)) (info (if (equal? op "=") info (let* ((ptr (expr->pointer info a)) + (ptr-b (expr->pointer info b)) (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)) @@ -930,23 +938,27 @@ ((and struct? (= ptr -2)) 4) ((and struct? (= ptr 2)) 4) (else 1))) - (info (if (= size 1) info + (info (if (or (= size 1) (= ptr-b 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))) - ((equal? op "-=") (wrap-as (i386:accu-base))) - ((equal? op "*=") (wrap-as (i386:accu*base))) - ((equal? op "/=") (wrap-as (i386:accu/base))) - ((equal? op "%=") (wrap-as (i386:accu%base))) - ((equal? op "&=") (wrap-as (i386:accu-and-base))) - ((equal? op "|=") (wrap-as (i386:accu-or-base))) - ((equal? op "^=") (wrap-as (i386:accu-xor-base))) - ((equal? op ">>=") (wrap-as (i386:accu>>base))) - ((equal? op "<<=") (wrap-as (i386:accu<>=") (wrap-as (i386:accu>>base))) + ((equal? op "<<=") (wrap-as (i386:accu<type info b))))))))) (pmatch a ((p-expr (ident ,name)) (append-text info ((accu->ident info) name))) diff --git a/scaffold/tests/76-pointer-arithmetic.c b/scaffold/tests/76-pointer-arithmetic.c index 39469d43..712bea03 100644 --- a/scaffold/tests/76-pointer-arithmetic.c +++ b/scaffold/tests/76-pointer-arithmetic.c @@ -27,6 +27,7 @@ struct foo { int a; int b; int c; + unsigned char *d; }; int @@ -64,7 +65,7 @@ test () eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); pfoo++; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); - if (pfoo != 12) return 15; + if (pfoo != 16) return 15; pfoo--; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); @@ -72,7 +73,7 @@ test () pfoo++; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); - if (pfoo != 12) return 17; + if (pfoo != 16) return 17; int one = 1; int two = 2; @@ -82,7 +83,7 @@ test () pfoo = pfoo + one; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); - if (pfoo != 12) return 19; + if (pfoo != 16) return 19; pfoo -= one; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); @@ -90,9 +91,36 @@ test () pfoo += one; eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); - if (pfoo != 12) return 21; + if (pfoo != 16) return 21; if (&one - 1 != &two) return 22; + struct foo* sym = 32; + int d = 16; + int i = sym + 16; + eputs ("i="); eputs (itoa (i)); eputs ("\n"); + if (i != 288) return 23; + + i = sym + d; + eputs ("i="); eputs (itoa (i)); eputs ("\n"); + if (i != 288) return 24; + + i = sym - 16; + eputs ("i="); eputs (itoa (i)); eputs ("\n"); + if (i != -224) return 25; + + i = sym - d; + eputs ("i="); eputs (itoa (i)); eputs ("\n"); + if (i != -224) return 26; + + i = sym - (struct foo*)d; + eputs ("i="); eputs (itoa (i)); eputs ("\n"); + if (i != 1) return 27; + + pfoo = sym + 1; + pfoo -= sym; + eputs ("pfoo="); eputs (itoa (pfoo)); eputs ("\n"); + if (pfoo != 1) return 28; + return 0; }