irre-tools devlog
contents
Goals
TODO
completely rewrite compiler to replace clang-leg
TODO test device driver functionality
Plans
Compiler rewrite (clang-leg
to vbcc
)
Problems with clang-leg
(why rewrite?)
-
complex, difficult to debug
-
massive (~10 GB) binary size and build overhead (LLVM)
Alternatives
-
after some surveying, selected vbcc (official website), a portable retargetable C compiler
-
why vbcc?
-
fairly modern and recent (latest commit is 2020)
-
thorough documentation
-
existing example backends
-
portable code and size, thus reduced overall complexity
-
Where to go with vbcc?
-
read vbcc documentation
-
start with the ALPHA backend
-
why ALPHA?
-
Load-Store RISC architecture, very similar to IRRE
-
Extensive documentation
-
Existing sample backend
-
-
duplicate the ALPHA backend and attempt to build the cross-compiler
-
iterate until able to build simple programs
Log
2020-11-29: Analysis of current status
Current status
-
usable assembler, disassembler, emulator
-
sub-functional compiler support
-
using
clang-leg
along withirre-legc
-
arcane codebase, difficult to understand, trace, or maintain
-
several broken features (such as arrays declared within functions)
-
cryptic error messages, very difficult to iterate
-
2020-12-03: Issue with stack layout
here are outputs from codegen log:
sbi sp sp #4
; loc_sz=4, rs_sz=0, ce_sz=-4
ldw r1 sp #-4
Here, we can see that the LDW is trying to load the first param in. However, since the function lowered the stack frame at the prologue, that LDW is now pointing somewhere invalid. (because we already lowered it 4, and it was stored 4 below sp, so now it's pointing 4 below where the variable was actually put)
SOLUTION?
SOLVED by changing stack layout to:
<---------- STACK POINTER
------------------------------------------------
| arguments to called functions [size=callee_argsize] |
------------------------------------------------
| return-address [size=4] |
------------------------------------------------
| caller-save registers [size=rsavesize] |
------------------------------------------------
| local variables [size=localsize] |
------------------------------------------------
<---------- STACK FRAME
------------------------------------------------
| arguments to this function |
------------------------------------------------
2020-12-05: Working hello world!
using a small program (some parts excluded): we can print to console using DMA devices!
/* map the terminal device buffer to an address */
void term_init(int dev_id, volatile char *map_addr) {
__dev_msg(dev_id, TERM_CMD_MAP, (int)map_addr);
}
/* send the flush command to the terminal device */
void term_flush(int dev_id) { __dev_msg(dev_id, TERM_CMD_FLUSH, 0); }
int main() {
volatile char *h_term = TERM_MAP_ADDR;
int device_id = TERM_DEV_ID;
term_init(device_id, h_term);
__memcpy(h_term, msg, MSG_SZ);
term_flush(device_id);
return 0;
}
some really weird issues: if I include a header file, the data in .data
for initialized global vars generated by gen_dc
gets corrupted.
maybe a compiler bug? need to ask dr. barthelmann.
2020-12-05: Fixed header files
Turns out the issue was a bug in gen_dc
, corrected in this commit.