diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index 719ec5e7..d22bd351 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -783,6 +783,17 @@ (list (lambda (f g ta t d) (i386:accu<accu empty) a)) + (base ((expr->base empty) b))) + (clone info #:text + (append text + (.text accu) + (.text base) + (list (lambda (f g ta t d) + (i386:accu>>base))))))) + ((div ,a ,b) (let* ((empty (clone info #:text '())) (accu ((expr->accu empty) a)) @@ -1730,6 +1741,10 @@ (list (lambda (f g ta t d) (i386:base-sub))))))) + ;; HMM + ((lshift . _) ((expr->accu info) o)) + ((rshift . _) ((expr->accu info) o)) + ;; TODO: byte dinges ((Xsub ,a ,b) (let* ((base ((expr->base info) a)) diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes index 9806f0e0..82bc844c 100644 --- a/module/mes/as-i386.mes +++ b/module/mes/as-i386.mes @@ -131,6 +131,11 @@ #x89 #xd1 ; mov %edx,%ecx #xd3 #xe0)) ; shl %cl,%eax +(define (i386:accu>>base) + '(#x31 #xc9 ; xor %ecx,%ecx + #x89 #xd1 ; mov %edx,%ecx + #xd3 #xe8)) ; shr %cl,%eax + (define (i386:accu-or-base) '(#x09 #xd0)) ; or %edx,%eax diff --git a/module/mes/as-i386.scm b/module/mes/as-i386.scm index 7f094c07..2456ad9c 100644 --- a/module/mes/as-i386.scm +++ b/module/mes/as-i386.scm @@ -48,6 +48,7 @@ i386:accu-shl i386:accu-or-base i386:accu<>base i386:base-sub i386:base->accu i386:base->accu-address diff --git a/scaffold/mini-mes.c b/scaffold/mini-mes.c index d5a4bcb4..9032fe8f 100644 --- a/scaffold/mini-mes.c +++ b/scaffold/mini-mes.c @@ -1278,9 +1278,10 @@ ash (SCM n, SCM count) #if __GNUC__ return MAKE_NUMBER ((ccount < 0) ? cn >> -ccount : cn << ccount); #else - //FIXME - assert (ccount >= 0); - return MAKE_NUMBER (cn << ccount); + int x; + if (ccount < 0) x = cn >> INT_MIN - ccount; + else x = cn << ccount; + return MAKE_NUMBER (x); #endif } diff --git a/scaffold/t.c b/scaffold/t.c index 0a620d67..459c6178 100644 --- a/scaffold/t.c +++ b/scaffold/t.c @@ -219,9 +219,22 @@ math_test () puts ("t: 3 << 4\n"); if (3 << 4 != 48) return 3 << 4; + puts ("t: 48 >> 3\n"); + if (48 >> 4 != 3) return 48 >> 4; + + puts ("t: 10 >> 1\n"); + if (10 >> 1 != 5) return 10 >> 1; + puts ("t: 1 | 4\n"); if ((1 | 4) != 5) return 1 | 4; + i = -3; + puts ("t: -i\n"); + if (-i != 3) return -i; + + puts ("t: -1 + 2\n"); + if (-1 + 2 != 1) return -1 + 2; + return read_test (); } @@ -566,6 +579,9 @@ test (char *p) puts ("t: 1 << 3\n"); if (1 << 3 != 8) return 1; + puts ("t: 8 >> 3\n"); + if (8 >> 3 != 1) return 1; + puts ("t: 8 / 4\n"); if (8 / 4 != 2) return 1;