Jump to page: 1 2
Thread overview
[Issue 24181] dmd compiled tinylisp.c runtime error
Oct 09, 2023
Basile-z
Oct 09, 2023
mw
Oct 18, 2023
Walter Bright
Oct 18, 2023
Walter Bright
Oct 18, 2023
Dennis
Oct 18, 2023
Walter Bright
Oct 18, 2023
mw
Oct 18, 2023
mw
Oct 19, 2023
Walter Bright
[Issue 24181] reading double parameter from RCX rather than XMM1
Oct 19, 2023
Walter Bright
Oct 19, 2023
Dlang Bot
Oct 19, 2023
Dlang Bot
October 09, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ImportC

--
October 09, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

--- Comment #1 from mw <mingwu@gmail.com> ---
BTW,

$ dmd --version
DMD64 D Compiler v2.105.0
Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
written by Walter Bright


And LDC works fine:

$ ldc2 -version
LDC - the LLVM D compiler (1.34.0):
  based on DMD v2.104.2 and LLVM 16.0.6
  built with LDC - the LLVM D compiler (1.34.0)
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver1
  http://dlang.org - http://wiki.dlang.org/LDC

$ ./tinylisp
tinylisp
930>(+ 2 3)
5

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
Unfortunately, it's not a very simple example. It's very dense, compressed code with no comments.

So far, I haven't found where the dmd version diverges from the gcc version. I'll look at it some more tomorrow.

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |backend

--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> ---
Hmm, it does work with -m32, implying a code gen problem.

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

Dennis <dkorpel@live.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dkorpel@live.nl

--- Comment #4 from Dennis <dkorpel@live.nl> ---
I tried reducing it with dustmite, but it's still pretty large:

```
int printf();
int sscanf();
char *strcpy();
int strcmp();
long strlen();

unsigned hp, sp = 1024, ATOM, PRIM, CONS = 0x7ffa, NIL;
double cell[1024], nil, tru, err, env;
double box(unsigned t, unsigned i)
{
        double x;
        *(long *)&x = (long)t << 48 | i;
        return x;
}
unsigned ord(double x) { return *(unsigned *)&x; }
unsigned equ(double x, double y) { return *(unsigned *)&x == *(long *)&y; }
double atom(char *s)
{
        unsigned i = 0;
        while (i < hp && strcmp((char *)cell + i, s))
                i += 1;
        hp += strlen(strcpy((char *)cell + i, s)) + 1;
        return box(ATOM, i);
}
double cons(double x, double y)
{
        cell[--sp] = x;
        cell[--sp] = y;
        return box(CONS, sp);
}
double car(double p)
{
        return p ? cell[ord(p) + 1] : err;
}
double cdr(double p)
{
        return p ? cell[ord(p)] : err;
}
double pair(double v, double x, double e)
{
        return cons(cons(v, x), e);
}
double assoc(double v, double e)
{
        while (e && !equ(v, car(car(e))))
                e = cdr(e);
        return e ? cdr(car(e)) : err;
}
unsigned not(double x) { return x == NIL; }
double f_add(double t)
{
        double n;
        while (!not(t = cdr(t)))
                n += car(t);
        return n;
}
struct
{
        char *s;
        double (*f)();
} prim[] = {
    "-", 0,
    "+", f_add,
};
double apply(double f, double t)
{
        return f ? prim[ord(f)].f(t) : f;
}
double eval(double x, double e)
{
        return *(long *)&x >> 48 == ATOM ? assoc(x, e) : x ? apply(eval(car(x),
e), x) : x;
}
char buf[40], see;
char* input = "(+ 4 4)";
int inputI = 0;
void look()
{
        see = input[inputI++];
}
unsigned seeing(char c) { return c ? see <= c : see; }
char get()
{
        char c = see;
        look();
        return c;
}
char scan()
{
        int i = 0;
        while (seeing(' '))
                look();
        return buf[i++] = get();
}
double parse();
double list()
{
        double x;
        return scan() == ')' ? nil : (x = parse(), cons(x, list()));
}
double atomic()
{
        double n;
        int i;
        return sscanf(buf, "%lg%n", &n, &i) ? n : atom(buf);
}
double parse()
{
        return *buf == '(' ? list() : atomic();
}
void print(double x)
{
        // printf("%016lX\n", *(unsigned long*)&x);
        if (x == ATOM)
                printf("ERR");
        else
                printf("%.10lg", x);
}
int main()
{
        int i;
        for (i = 0; prim[i].s; ++i)
                env = pair(atom(prim[i].s), box(PRIM, i), env);

        double result = eval((scan(), parse()), env);
        print(result);
}
```

This program prints 8 with gcc, but ERR with dmd on linux 64-bit.

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> ---
Ah, thanks Dennis! This is very helpful.

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

--- Comment #6 from mw <mingwu@gmail.com> ---
In the same github repo, there is a equivalent commented .c file (dmd generated binary has the same runtime error):

https://github.com/Robert-van-Engelen/tinylisp

https://github.com/Robert-van-Engelen/tinylisp/blob/main/src/tinylisp-commented.c

and the design doc:

https://github.com/Robert-van-Engelen/tinylisp/blob/main/tinylisp.pdf



gcc works fine:

$ make tinylisp-commented
cc     tinylisp-commented.c   -o tinylisp-commented
(env) zhou@joort:~/project/unzip/tinylisp/src$ ./tinylisp-commented
tinylisp
930>(+ 3 5)
8


$ dmd tinylisp-commented.c
tinylisp-commented.c: Error: module `tinylisp-commented` has non-identifier
characters in filename, use module declaration instead

$ ln -s tinylisp-commented.c tinylisp_commented.c

$ dmd tinylisp_commented.c

$ ./tinylisp_commented
tinylisp
930>(+ 3 5)
ERR


# -m32 works confirmed:
$ dmd -m32 tinylisp_commented.c
$ ./tinylisp_commented
tinylisp
930>(+ 3 5)
8

--
October 18, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

--- Comment #7 from mw <mingwu@gmail.com> ---
BTW, dmd generate binary also have runtime error with this single file lisp:


https://github.com/Robert-van-Engelen/lisp/blob/main/src/lisp.c

src$ dmd lisp.c
src$ ./lisp
lisp
unbound define ERR 3 unbound symbol
8020+2000>


# dmd -m32 works fine:
src$ dmd -m32 lisp.c

$ ./lisp
lisp
null?
number?
...
defmacro
defun
6322+1929>


GCC, and LDC2 works fine.

--
October 19, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> ---
For this:

    unsigned equ(double x, double y) {
        return *(long long *)&x == *(long long *)&y;
    }

The generated code is:

    equ:
                sub     RSP,018h
                movq    [RSP],XMM0
                mov     RAX,[RSP]
                cmp     RAX,RCX     <== ARRRGHHH!!
                setz    AL
                movzx   RAX,AL
                add     RSP,018h
                ret

The `y` parameter is passed in XMM1, not RCX. The cast to long long has fooled the code generator.

I suspected something like this was happening, but it took a while to find it.

--
October 19, 2023
https://issues.dlang.org/show_bug.cgi?id=24181

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|dmd compiled tinylisp.c     |reading double parameter
                   |runtime error               |from RCX rather than XMM1

--
« First   ‹ Prev
1 2