From a22e5d3accd0846130703c0058a5d39a9990dcbb Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Mon, 27 May 2019 21:33:20 +0200 Subject: [PATCH] mes: Identify 64-bit bug when compiled with MesCC. * src/math.c (divide): Add divide-by-zero error. (modulo): Likewise. * module/mes/guile.scm (%compiler): New variable. * module/mescc/M1.scm (mesc?): New variable. (hex2:immediate8): Use it to avoid divide-by-zero error. * HACKING (Bugs): Add it. --- HACKING | 7 +++++++ module/mes/guile.scm | 3 +++ module/mescc/M1.scm | 11 +++++++---- src/math.c | 12 +++++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/HACKING b/HACKING index 740390fa..84eb5f7d 100644 --- a/HACKING +++ b/HACKING @@ -151,6 +151,13 @@ actual: -./,),(-*,( ** mes+mescc: parse tcc.c->tcc.E works, compile tcc.E -> tcc.M1 segfaults. time GUILE_LOAD_PATH=/home/janneke/src/nyacc/module:$GUILE_LOAD_PATH ../mes/scripts/mescc -E -o tcc.E -I . -I ../mes/lib -I ../mes/include -D 'CONFIG_TCCDIR="usr/lib/tcc"' -D 'CONFIG_TCC_CRTPREFIX="usr/lib:{B}/lib:."' -D 'CONFIG_TCC_ELFINTERP="/gnu/store/70jxsnpffkl7fdb7qv398n8yi1a3w5nx-glibc-2.26.105-g0890d5379c/lib/ld-linux.so.2"' -D 'CONFIG_TCC_LIBPATHS="/home/janneke/src/tinycc/usr/lib:{B}/lib:."' -D 'CONFIG_TCC_SYSINCLUDEPATHS="../mes/include:usr/include:{B}/include"' -D CONFIG_USE_LIBGCC=1 -D 'TCC_LIBGCC="/home/janneke/src/tinycc/usr/lib/libc+tcc-gcc.mlibc-o"' -D CONFIG_TCC_STATIC=1 -D ONE_SOURCE=yes -D TCC_TARGET_I386=1 -D BOOTSTRAP=1 tcc.c time GUILE_LOAD_PATH=/home/janneke/src/nyacc/module:$GUILE_LOAD_PATH MES_ARENA=200000000 ../mes/scripts/mescc -c -o tcc.M1 tcc.E +** mescc: 64 bit compiled mes loses top 4 bytes +*** 64 bit mescc-compiled mes: + #x100000000 => 0 + (modulo 1 #x100000000) => divide-by-zero +*** 64 bit gcc-compiled mes: + #x100000000 => 0 + (modulo 1 #x100000000) => 1 ** mescc: 7n-struct-struct-array.c: struct file f = {"first.h"}; ** test/match.test ("nyacc-simple"): hygiene problem in match * OLD: Booting from LISP-1.5 into Mes diff --git a/module/mes/guile.scm b/module/mes/guile.scm index 9c60077d..451843b4 100644 --- a/module/mes/guile.scm +++ b/module/mes/guile.scm @@ -45,6 +45,7 @@ core:write-error core:write-port core:type + %compiler equal2? pmatch-car pmatch-cdr @@ -83,6 +84,8 @@ (define 11) (define 15) + (define %compiler "gnuc") + (define (core:type x) (cond ((guile:keyword? x) ) ((guile:number? x) ) diff --git a/module/mescc/M1.scm b/module/mescc/M1.scm index ef53ad74..8dbbc304 100644 --- a/module/mescc/M1.scm +++ b/module/mescc/M1.scm @@ -81,13 +81,16 @@ (if hex? (string-append "%0x" (dec->hex o)) (string-append "%" (number->string o)))) +(define mesc? (string=? %compiler "mesc")) + (define (hex2:immediate8 o) - (if hex? (string-append "%0x" (dec->hex (modulo o #x100000000)) + ;; FIXME: #x100000000 => 0 divide-by-zero when compiled with 64 bit mesc + (if hex? (string-append "%0x" (dec->hex (if mesc? 0 (modulo o #x100000000))) " %0x" (if (< o 0) "-1" - (dec->hex (quotient o #x100000000)))) - (string-append "%" (number->string (dec->hex (modulo o #x100000000))) + (dec->hex (if mesc? o (quotient o #x100000000))))) + (string-append "%" (number->string (dec->hex (if mesc? 0 (modulo o #x100000000)))) " %" (if (< o 0) "-1" - (number->string (dec->hex (quotient o #x100000000))))))) + (number->string (dec->hex (if mesc? o (quotient o #x100000000)))))))) (define* (display-join o #:optional (sep "")) (let loop ((o o)) diff --git a/src/math.c b/src/math.c index 3a1c67ce..1241a28e 100644 --- a/src/math.c +++ b/src/math.c @@ -128,9 +128,12 @@ divide (SCM x) ///((name . "/") (arity . n)) while (x != cell_nil) { assert_number ("divide", CAR (x)); + long y = VALUE (CAR (x)); + if (y == 0) + error (cstring_to_symbol ("divide-by-zero"), x); if (!n) break; - n /= VALUE (car (x)); + n /= y; x = cdr (x); } return MAKE_NUMBER (n); @@ -142,9 +145,12 @@ modulo (SCM a, SCM b) assert_number ("modulo", a); assert_number ("modulo", b); long x = VALUE (a); + long y = VALUE (b); + if (y == 0) + error (cstring_to_symbol ("divide-by-zero"), a); while (x < 0) - x += VALUE (b); - x = x ? x % VALUE (b) : 0; + x += y; + x = x ? x % y : 0; return MAKE_NUMBER (x); }