jasonful / lcc

The lcc retargetable ANSI C compiler
http://sites.google.com/site/lccretargetablecompiler
95 stars 10 forks source link

op=ARGU4 at foo.c:5 is corrupt. getrule: Assertion `0' failed. #15

Open chlordk opened 1 year ago

chlordk commented 1 year ago

Hi

I have tried the test examples in /tst/ and most of them gives all the getrule: Assertion '0' failed error. Only tst/incr.c and tst/init.c will compile.

I then made a simple example to pin point one kind of error:

 $ cat -n foo.c
 1  void main(void) {
 2    unsigned int i = 3;
 3    unsigned int a = sizeof(i);
 4    while (i++ < 5) {
 5      a = a + bar(a);
 6    }
 7  }
 8  bar(x)
 9  unsigned int x;
10  {
11    return 7+x;
12  }

The full command line output:

ff@ubuntu22lts:~/lcc$ ulpcc foo.c
<command-line>: warning: "__STDC__" redefined
<built-in>: note: this is the location of the previous definition
(414b4c0->op=ARGU4 at foo.c:5 is corrupt.)
rcc: src/gen.c:181: getrule: Assertion `0' failed.

/home/ff/lcc/build/lcc: fatal error in /home/ff/lcc/build/rcc

Another strange thing is that when it does compile, the function bar() without argument a it does not get called in the foo.S file. In line 12 move r2,r0 it is supposed to load the output from bar() into i but register r0 never gets loaded with a value (or I missed it).

 1  void main(void) {
 2    unsigned int i = 3;
 3    unsigned int a = sizeof(i);
 4    while (i++ < 5) {
 5      a = a + bar(); // arg from bar() removed should give error
 6    }
 7  }
 8  bar(x)
 9  unsigned int x;
10  {
11    return 7 /*+x*/;
12  }

The foo.S:

 1      .global main
 2  .text
 3  .bss
 4  main.a:
 5      .space 4
 6  .text
 7  .bss
 8  main.i:
 9      .space 4
10  .text
11  main:
12  move r2,3
13  move r3,main.i
14  st r2,r3,0
15  move r2,4
16  move r3,main.a
17  st r2,r3,0
18  jump L.3
19  L.2:
20  move r1,main.a
21  ld r1,r1,0
22  move r2,r0
23  add r2,r1,r2
24  move r3,main.a
25  st r2,r3,0
26  L.3:
27  move r2,main.i
28  ld r2,r2,0
29  add r1,r2,1
30  move r3,main.i
31  st r1,r3,0
32  move r1,5
33  sub r2,r2,r1 #{ if r2 < r1 goto L.2
34  add r2,r2,r1
35  jump L.2, ov #}
36  L.1:
37  
38      .global bar
39  bar:
40  move r0,7
41  L.5:
42  
43  halt

I'm running on Ubuntu VERSION="22.04.2 LTS (Jammy Jellyfish)".

After reading all the assembler output I kind of learned it but I would prefer to use ulpcc instead. It is a great and promising tool.

jasonful commented 1 year ago

As stated in https://github.com/jasonful/lcc/blob/master/ulpcc/doc/README.md , function calls are not supported, because the chip has no stack pointer.

jasonful commented 1 year ago

(The examples in ulpcc/examples will compile, but the examples in lcc/tst (the ones for the original C compiler) probably will not.)

hanschou commented 1 year ago

function calls are not supported, because the chip has no stack pointer.

Ohh sorry, I missed that one.

I guess one could use a while loop with a switch/case to simulate a function call.

while (not_exit) {
  switch (state) {
    case main:
      if (0 == --count) 
         state = subf;
         ... and so on