Skip to content

Latest commit

 

History

History
134 lines (109 loc) · 4.13 KB

project.org

File metadata and controls

134 lines (109 loc) · 4.13 KB

Lambda-x86 Project Notes

I’ve decided to build a quick-and-dirty compiler following An Incremental Approach to Compiler Construction by Abdulaziz Ghuloum. I can build a bigger compiler later.

I’ve also decided to ditch continuation-passing style for this first draft. I’ll get my head around regular recursive implementations first.

I wanted to use stack-based parameter passing, but I gave up and am just using four registers instead. (I’ve forgotten a bit about how the stack works and I just wanted to move on.)

But using registers for argument passing turned out to be rather complicated, so now I’m back to using the stack.

The type checker/inference engine works alright, but I’m not using it at all right now. It uses bidirectional type checking with inference; I’ll probably rewrite this to do a full Hindley-Milner type checking/inference engine later.

Tasks

Tasks for later

Check the number of arguments to a function at compile time

Fix up type checker

I wonder if there’s a way to use the type information to make my assembler more efficient. (I bet there is; I’ll leave that for an enhancement.)

Use type information to improve instruction choice

Resources

An Incremental Approach to Compiler Construction

Seeing what C compiles something to

Write the C code to a file called foo.c; example:

int main() {
  int foo = 1;
  int bar = 2;
  return foo == bar;
}

Then compile with:

gcc -fomit-frame-pointer -S foo.c

That should give you a file named foo.s that looks like:

  	.section	__TEXT,__text,regular,pure_instructions
	.build_version macos, 10, 15	sdk_version 10, 15, 4
	.globl	_main                   ## -- Begin function main
	.p2align	4, 0x90
_main:                                  ## @main
	.cfi_startproc
## %bb.0:
	movl	$0, -4(%rsp)
	movl	$1, -8(%rsp)
	movl	$2, -12(%rsp)
	movl	-8(%rsp), %eax
	cmpl	-12(%rsp), %eax
	sete	%cl
	andb	$1, %cl
	movzbl	%cl, %eax
	retq
	.cfi_endproc
                                        ## -- End function

.subsections_via_symbols

Notes

Debugging closure calling

addr of closure: 0x0000000100000d28

heap location: 0x0000000101008200

Verdict: I’m jumping to %rdi, not (%rdi); what would happen if I ran *(%rdi)

That works!

(lldb) re r
General Purpose Registers:
       rax = 0x0000000101008200
       rbx = 0x0000000000000000
       rcx = 0x0000000000000000
       rdx = 0x0000000000000010
       rdi = 0x0000000101008200
       rsi = 0x000000010011ba00
       rbp = 0x00007ffeefbff720
       rsp = 0x00007ffeefbff700
        r8 = 0x0000000002000001
        r9 = 0x0000000000000003
       r10 = 0x9e3779b97f4a7c55
       r11 = 0x0000000000000007
       r12 = 0x0000000000000000
       r13 = 0x0000000000000000
       r14 = 0x0000000000000000
       r15 = 0x0000000101008208
       rip = 0x0000000100000d70  a.out`definition_end38349 + 49
    rflags = 0x0000000000000216
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

(lldb) s
Process 46879 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into
    frame #0: 0x0000000101008200
->  0x101008200: subb   %cl, 0x10000(%rip)
    0x101008206: addb   %al, (%rax)
    0x101008208: addb   %al, (%rax)
    0x10100820a: addb   %al, (%rax)
Target 0: (a.out) stopped.
(lldb) d
->  0x101008200: subb   %cl, 0x10000(%rip)
    0x101008206: addb   %al, (%rax)
    0x101008208: addb   %al, (%rax)
    0x10100820a: addb   %al, (%rax)
    0x10100820c: addb   %al, (%rax)
    0x10100820e: addb   %al, (%rax)
    0x101008210: addb   %al, (%rax)
    0x101008212: addb   %al, (%rax)
    0x101008214: addb   %al, (%rax)
    0x101008216: addb   %al, (%rax)
    0x101008218: addb   %al, (%rax)
    0x10100821a: addb   %al, (%rax)
    0x10100821c: addb   %al, (%rax)
    0x10100821e: addb   %al, (%rax)