llvm-mos

From C64-Wiki
Jump to navigationJump to search
llvm-mos
llvm-mos Logo.png
Developer llvm-mos Team
Company
Publisher
Release 2022
Licence Apache License 2.0 w/ LLVM modifications
Platform Linux, Microsoft Windows, Mac OS
Genre Compiler, Assembler
Operation
Media
Language(s) Language:english
Information http://llvm-mos.org/

The cross-development paket llvm-mos is a fork of LLVM[1] (short for Low Level Virtual Machine) supporting the MOS Technology 65xx series of microprocessors and their clones - also for the C64 and VIC-20, Atari (8-bit), etc. It includes the Clang compiler, LLD linker, GAS (GNU) compatible assembler, ELF object files, and associated utilities.

Description[edit | edit source]

The Clang target is broadly C99/C++11 compatible (freestanding) with the notable exception of float/double and C++ exceptions. Simple runtimes are provided for the Commodore 64, Atari 8-bit, and an included 6502 simulator.

The code generator defaults to link-time whole-program optimization; this allows for the program call graph to be analyzed as a whole (i.e., which functions can call which functions). This in turn allows determining which functions may be recursive; any that cannot be have their stack frames placed in statically global memory. No additional annotations are required for this to work. The standard library is shipped as LLVM bitcode, so it participates in this analysis, and library routines can often be fully folded into their uses.

Example[edit | edit source]

This code is input in the CLANG-compiler:

 #include <stdio.h>

 void main(void) {
   printf("HELLO, 6502!\n");
 }
 

If this was hello.c, you could compile it on the command line with mos-c64-clang -Os -o hello.prg hello.c . This would produce hello.prg, a PRG file for the c64, including a BASIC SYS header. -Os means "optimize for speed, but don't trade size to get it", which is generally what you want for the 6502. -O2 gives "speed at all costs", and -Oz gives "size at all costs."


The compiled assembler code is:

  main:
        ldx     #1
        lda     #72
  .LBB0_1:
        cmp     #10
        beq     .LBB0_4
  .LBB0_2:
        jsr     65490
        lda     .Lstr,x
        inx
        cpx     #13
        bne     .LBB0_1
        lda     #13
        jsr     65490
        rts
  .LBB0_4:
        lda     #13
        jmp     .LBB0_2

  .Lstr:
	.asciz	"HELLO, 6502!"
 

LLVM's high level optimizations detect that this usage of "printf" is equivalent to the faster "puts", so it replaces it. Then, the implementation of puts is inlined into main. The 16-bit pointer loop in puts is optimized by "loop strength reduction" into an 8-bit form to take advantage of the 6502's indexed addressing mode. A c64-specific putchar is also inlined away, leaving only the JSR to the KERNAL.

Links[edit | edit source]


References