mescc: Tinycc support: pointer arithmetic with pointer-variable.
* module/language/c99/compiler.mes (expr->accu): pointer arithmetic with pointer-variable. * scaffold/tests/76-pointer-arithmetic.c (test): Test it. * mlibc/include/stdarg.h (va_start): Update for fixed pointer arithmetic.
This commit is contained in:
parent
8649f7a923
commit
69073e1954
|
@ -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])
|
||||
|
|
|
@ -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<<base)))
|
||||
(else (error (format #f "mescc: op ~a not supported: ~a\n" op o)))))))))
|
||||
(info (append-text info (wrap-as (i386:pop-base))))
|
||||
(info (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<<base)))
|
||||
(else (error (format #f "mescc: op ~a not supported: ~a\n" op o)))))))
|
||||
(cond ((not (and (= ptr 1) (= ptr-b 1))) info)
|
||||
((equal? op "-=") (append-text info (wrap-as (append (i386:value->base size)
|
||||
(i386:accu/base)))))
|
||||
(else (error (format #f "invalid operands to binary ~s (have ~s* and ~s*)" op type0 (p-expr->type info b)))))))))
|
||||
(pmatch a
|
||||
((p-expr (ident ,name))
|
||||
(append-text info ((accu->ident info) name)))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue