amd64: add comments, still broken btw

This commit is contained in:
Robin Bärtschi 2025-03-13 16:45:13 +01:00
parent 403f02a140
commit e5f576251a
3 changed files with 32 additions and 14 deletions

View File

@ -112,6 +112,12 @@ type Instruction interface {
InstructionString() string InstructionString() string
} }
type Comment string
func (c Comment) InstructionString() string {
return "; " + strings.TrimRight(string(c), "\n")
}
type SimpleInstruction struct { type SimpleInstruction struct {
Opcode Opcode Opcode Opcode
// Dst // Dst

View File

@ -3,11 +3,16 @@ package amd64
import ( import (
"fmt" "fmt"
"slices" "slices"
"strings"
"robaertschi.xyz/robaertschi/tt/ast" "robaertschi.xyz/robaertschi/tt/ast"
"robaertschi.xyz/robaertschi/tt/ttir" "robaertschi.xyz/robaertschi/tt/ttir"
) )
func comment(c string) Comment {
return Comment(strings.ReplaceAll(strings.TrimRight(c, "\n"), "\n", "\n ; "))
}
func toAsmOperand(op ttir.Operand) Operand { func toAsmOperand(op ttir.Operand) Operand {
switch op := op.(type) { switch op := op.(type) {
case *ttir.Constant: case *ttir.Constant:
@ -43,7 +48,7 @@ func CgProgram(prog *ttir.Program) *Program {
} }
func cgFunction(f *ttir.Function) Function { func cgFunction(f *ttir.Function) Function {
newInstructions := []Instruction{} newInstructions := []Instruction{comment(f.String())}
for i, arg := range f.Arguments { for i, arg := range f.Arguments {
if i < len(callConvArgs) { if i < len(callConvArgs) {
@ -79,6 +84,7 @@ func cgInstruction(i ttir.Instruction) []Instruction {
case *ttir.Ret: case *ttir.Ret:
if i.Op != nil { if i.Op != nil {
return []Instruction{ return []Instruction{
comment(i.String()),
&SimpleInstruction{ &SimpleInstruction{
Opcode: Mov, Opcode: Mov,
Lhs: AX, Lhs: AX,
@ -89,14 +95,17 @@ func cgInstruction(i ttir.Instruction) []Instruction {
}, },
} }
} else { } else {
return []Instruction{&SimpleInstruction{Opcode: Ret}} return []Instruction{&SimpleInstruction{Opcode: Ret},
comment(i.String()),
}
} }
case *ttir.Binary: case *ttir.Binary:
return cgBinary(i) return cgBinary(i)
case ttir.Label: case ttir.Label:
return []Instruction{Label(i)} return []Instruction{comment(i.String()), Label(i)}
case *ttir.JumpIfZero: case *ttir.JumpIfZero:
return []Instruction{ return []Instruction{
comment(i.String()),
&SimpleInstruction{ &SimpleInstruction{
Opcode: Cmp, Opcode: Cmp,
Lhs: toAsmOperand(i.Value), Lhs: toAsmOperand(i.Value),
@ -109,6 +118,7 @@ func cgInstruction(i ttir.Instruction) []Instruction {
} }
case *ttir.JumpIfNotZero: case *ttir.JumpIfNotZero:
return []Instruction{ return []Instruction{
comment(i.String()),
&SimpleInstruction{ &SimpleInstruction{
Opcode: Cmp, Opcode: Cmp,
Lhs: toAsmOperand(i.Value), Lhs: toAsmOperand(i.Value),
@ -120,9 +130,9 @@ func cgInstruction(i ttir.Instruction) []Instruction {
}, },
} }
case ttir.Jump: case ttir.Jump:
return []Instruction{JmpInstruction(i)} return []Instruction{comment(i.String()), JmpInstruction(i)}
case *ttir.Copy: case *ttir.Copy:
return []Instruction{&SimpleInstruction{Opcode: Mov, Lhs: toAsmOperand(i.Dst), Rhs: toAsmOperand(i.Src)}} return []Instruction{comment(i.String()), &SimpleInstruction{Opcode: Mov, Lhs: toAsmOperand(i.Dst), Rhs: toAsmOperand(i.Src)}}
case *ttir.Call: case *ttir.Call:
registerArgs := i.Arguments[0:min(len(callConvArgs), len(i.Arguments))] registerArgs := i.Arguments[0:min(len(callConvArgs), len(i.Arguments))]
stackArgs := []ttir.Operand{} stackArgs := []ttir.Operand{}
@ -135,7 +145,7 @@ func cgInstruction(i ttir.Instruction) []Instruction {
stackPadding = 8 stackPadding = 8
} }
instructions := []Instruction{} instructions := []Instruction{comment(i.String())}
if stackPadding > 0 { if stackPadding > 0 {
instructions = append(instructions, AllocateStack(stackPadding)) instructions = append(instructions, AllocateStack(stackPadding))
@ -211,6 +221,7 @@ func cgBinary(b *ttir.Binary) []Instruction {
} }
return []Instruction{ return []Instruction{
comment(b.String()),
&SimpleInstruction{ &SimpleInstruction{
Opcode: Cmp, Opcode: Cmp,
Lhs: toAsmOperand(b.Lhs), Lhs: toAsmOperand(b.Lhs),
@ -238,11 +249,13 @@ func cgBinary(b *ttir.Binary) []Instruction {
} }
return []Instruction{ return []Instruction{
comment(b.String()),
&SimpleInstruction{Opcode: Mov, Lhs: toAsmOperand(b.Dst), Rhs: toAsmOperand(b.Lhs)}, &SimpleInstruction{Opcode: Mov, Lhs: toAsmOperand(b.Dst), Rhs: toAsmOperand(b.Lhs)},
&SimpleInstruction{Opcode: opcode, Lhs: toAsmOperand(b.Dst), Rhs: toAsmOperand(b.Rhs)}, &SimpleInstruction{Opcode: opcode, Lhs: toAsmOperand(b.Dst), Rhs: toAsmOperand(b.Rhs)},
} }
case ast.Divide: case ast.Divide:
return []Instruction{ return []Instruction{
comment(b.String()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(AX), Rhs: toAsmOperand(b.Lhs)}, &SimpleInstruction{Opcode: Mov, Lhs: Register(AX), Rhs: toAsmOperand(b.Lhs)},
&SimpleInstruction{Opcode: Cdq}, &SimpleInstruction{Opcode: Cdq},
&SimpleInstruction{Opcode: Idiv, Lhs: toAsmOperand(b.Rhs)}, &SimpleInstruction{Opcode: Idiv, Lhs: toAsmOperand(b.Rhs)},
@ -301,7 +314,7 @@ func rpInstruction(i Instruction, r *replacePseudoPass) Instruction {
Cond: i.Cond, Cond: i.Cond,
Dst: pseudoToStack(i.Dst, r), Dst: pseudoToStack(i.Dst, r),
} }
case *JumpCCInstruction, JmpInstruction, Label, AllocateStack, DeallocateStack, Call: case *JumpCCInstruction, JmpInstruction, Label, AllocateStack, DeallocateStack, Call, Comment:
return i return i
default: default:
panic(fmt.Sprintf("unexpected amd64.Instruction: %#v", i)) panic(fmt.Sprintf("unexpected amd64.Instruction: %#v", i))
@ -407,9 +420,8 @@ func fixupInstruction(i Instruction) []Instruction {
return []Instruction{i} return []Instruction{i}
case *SetCCInstruction: case *SetCCInstruction:
return []Instruction{i} return []Instruction{i}
case *JumpCCInstruction, JmpInstruction, Label, AllocateStack, DeallocateStack, Call: case *JumpCCInstruction, JmpInstruction, Label, AllocateStack, DeallocateStack, Call, Comment:
return []Instruction{i} return []Instruction{i}
default: default:
panic(fmt.Sprintf("unexpected amd64.Instruction: %#v", i)) panic(fmt.Sprintf("unexpected amd64.Instruction: %#v", i))

10
test.tt
View File

@ -1,12 +1,12 @@
fn main(): i64 = { fn main(): i64 = {
test2(3, 0) factorial(2)
}; };
fn test2(until: i64, i: i64): i64 = { fn factorial(n: i64): i64 = {
if i >= until { if n == 1 {
0 1
} else { } else {
test2(until, i+1) + 1 n * factorial(n - 1)
} }
}; };