Assembler

LLVM IR

  • Low level optimization passes
  • Has a number of backends already:
    • x86 64
    • Arm 64
    • RISC-V
    • WebAssembly (in progress)
    • XTensa LX6 (in progress)
fact n return: isZero n base recurse
    base: return 1
    recurse: sub n 1 step1
        step1 m: fact m step2
        step2 f: mul n f return

main return1: fact 5 m0
    m0 f: print f m1
    m1: return1

TODO: For every declaration we need to know * all the calls that can lead to the declaration, and * all the declarations it can call to. This should be done in a Control Flow Graph pass.

If there is a strong correlation between incoming and outgoing edges, it makes sense to duplicate the function. Then both copies have unconditional calls. In the codegen they can simply be concatenated.

define void @olus(void) {
    
    br label main
    
fact:
    
base:
    
recurse:
    
step1:
    
step2:
    
main:
    
m0:
    
m1:
    
    
; Builtins
    
mul:
    
    indirectbr i8* %mul_return, [ label %bb1, label %bb2, label %bb3 ...mul targets ]
    
exit:
    ret
    
alloc:
    @llvm.lifetime.start(i64 %size, i8* nocapture ptr)
    
free:
    @llvm.lifetime.end(i64 %size, i8* nocapture %ptr)
}

http://llvm.org/docs/LangRef.html

WebAssembly

SPIR-V

https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_binary_a_binary_form

x86 64

https://wiki.osdev.org/X86-64_Instruction_Encoding

ARM 64

  • 31 64bit general purpose registers
  • 32 128bit floating point registers
  • NEON

https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf

https://kitoslab-eng.blogspot.com/2012/10/armv8-aarch64-instruction-encoding.html

https://github.com/kov4l3nko/ARM64JSON

https://llvm.org/devmtg/2012-11/Northover-AArch64.pdf

ESP 32 (Xtensa LX6)

http://0x04.net/~mwk/doc/xtensa.pdf

RISC-V