i am so fucking stupid, how tf did i manage to mess this up

I used the rsp register instead of the rbp register for accessing the
stack variables, rsp is the wrong base and changes constantly

fuck
This commit is contained in:
Robin Bärtschi 2025-03-14 16:40:53 +01:00
parent 13da26acdb
commit 0de27e01fd
4 changed files with 46 additions and 35 deletions

View File

@ -5,13 +5,13 @@ import (
"strings" "strings"
) )
var callConvArgs map[int]Register = map[int]Register{ var callConvArgs []Register = []Register{
1: DI, DI,
2: SI, SI,
3: DX, DX,
4: CX, CX,
5: R8, R8,
6: R9, R9,
} }
type Program struct { type Program struct {
@ -68,7 +68,7 @@ type Function struct {
func (f *Function) Emit() string { func (f *Function) Emit() string {
var builder strings.Builder var builder strings.Builder
builder.WriteString(fmt.Sprintf("%s:\n push rbp\n mov rbp, rsp\n add rsp, %d\n", f.Name, f.StackOffset)) builder.WriteString(fmt.Sprintf("%s:\n push rbp\n mov rbp, rsp\n", f.Name))
for _, inst := range f.Instructions { for _, inst := range f.Instructions {
builder.WriteString(fmt.Sprintf(" %s\n", inst.InstructionString())) builder.WriteString(fmt.Sprintf(" %s\n", inst.InstructionString()))
@ -128,7 +128,7 @@ type SimpleInstruction struct {
func (i *SimpleInstruction) InstructionString() string { func (i *SimpleInstruction) InstructionString() string {
if i.Opcode == Ret { if i.Opcode == Ret {
return fmt.Sprintf("mov rsp, rbp\n pop rbp\n ret\n") return fmt.Sprintf("leave\n ret\n")
} }
// No operands // No operands
@ -316,7 +316,7 @@ func (s Stack) OperandString(size OperandSize) string {
sizeString = "qword" sizeString = "qword"
} }
return fmt.Sprintf("%s [rsp %+d]", sizeString, s) return fmt.Sprintf("%s [rbp %+d]", sizeString, s)
} }
type Pseudo string type Pseudo string

View File

@ -134,7 +134,7 @@ func cgInstruction(i ttir.Instruction) []Instruction {
case *ttir.Copy: case *ttir.Copy:
return []Instruction{comment(i.String()), &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[:min(len(callConvArgs), len(i.Arguments))]
stackArgs := []ttir.Operand{} stackArgs := []ttir.Operand{}
if len(callConvArgs) < len(i.Arguments) { if len(callConvArgs) < len(i.Arguments) {
stackArgs = i.Arguments[len(callConvArgs):len(i.Arguments)] stackArgs = i.Arguments[len(callConvArgs):len(i.Arguments)]
@ -273,7 +273,7 @@ type replacePseudoPass struct {
} }
func replacePseudo(prog Program) Program { func replacePseudo(prog Program) Program {
newFunctions := make([]Function, 0) newFunctions := []Function{}
for _, f := range prog.Functions { for _, f := range prog.Functions {
newFunctions = append(newFunctions, rpFunction(f)) newFunctions = append(newFunctions, rpFunction(f))
@ -283,7 +283,7 @@ func replacePseudo(prog Program) Program {
} }
func rpFunction(f Function) Function { func rpFunction(f Function) Function {
newInstructions := make([]Instruction, 0) newInstructions := []Instruction{}
r := &replacePseudoPass{ r := &replacePseudoPass{
identToOffset: make(map[string]int64), identToOffset: make(map[string]int64),
@ -337,7 +337,7 @@ func pseudoToStack(op Operand, r *replacePseudoPass) Operand {
// Third pass, fixup invalid instructions // Third pass, fixup invalid instructions
func instructionFixup(prog Program) Program { func instructionFixup(prog Program) Program {
newFuncs := make([]Function, 0) newFuncs := []Function{}
for _, f := range prog.Functions { for _, f := range prog.Functions {
newFuncs = append(newFuncs, fixupFunction(f)) newFuncs = append(newFuncs, fixupFunction(f))
@ -348,7 +348,17 @@ func instructionFixup(prog Program) Program {
func fixupFunction(f Function) Function { func fixupFunction(f Function) Function {
// The function will at minimum require the same amount of instructions, but never less // The function will at minimum require the same amount of instructions, but never less
newInstructions := make([]Instruction, 0) newInstructions := []Instruction{}
if f.StackOffset != 0 {
stack := -f.StackOffset
if stack > 0 {
stack = stack + (16 - (stack % 16))
} else {
stack = stack - (16 - (stack % 16))
}
newInstructions = append(newInstructions, comment(fmt.Sprintf("Allocated %d on stack", stack)), AllocateStack(stack))
}
for _, i := range f.Instructions { for _, i := range f.Instructions {
newInstructions = append(newInstructions, fixupInstruction(i)...) newInstructions = append(newInstructions, fixupInstruction(i)...)
@ -363,13 +373,13 @@ func fixupInstruction(i Instruction) []Instruction {
case *SimpleInstruction: case *SimpleInstruction:
switch i.Opcode { switch i.Opcode {
case Mov: case Mov:
if lhs, ok := i.Lhs.(Stack); ok { if dst, ok := i.Lhs.(Stack); ok {
if rhs, ok := i.Rhs.(Stack); ok { if src, ok := i.Rhs.(Stack); ok {
return []Instruction{ return []Instruction{
comment("FIXUP: Stack and Stack for Mov"), comment("FIXUP: Stack and Stack for Mov"),
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: src},
&SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: Register(R10)}, &SimpleInstruction{Opcode: Mov, Lhs: dst, Rhs: R10},
} }
} }
} }
@ -378,9 +388,9 @@ func fixupInstruction(i Instruction) []Instruction {
return []Instruction{ return []Instruction{
comment("FIXUP: Stack as Dst for Imul"), comment("FIXUP: Stack as Dst for Imul"),
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(R11), Rhs: lhs}, &SimpleInstruction{Opcode: Mov, Lhs: R11, Rhs: lhs},
&SimpleInstruction{Opcode: Imul, Lhs: Register(R11), Rhs: i.Rhs}, &SimpleInstruction{Opcode: Imul, Lhs: R11, Rhs: i.Rhs},
&SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: Register(R11)}, &SimpleInstruction{Opcode: Mov, Lhs: lhs, Rhs: R11},
} }
} }
fallthrough fallthrough
@ -390,16 +400,16 @@ func fixupInstruction(i Instruction) []Instruction {
return []Instruction{ return []Instruction{
comment("FIXUP: Stack and Stack for Binary"), comment("FIXUP: Stack and Stack for Binary"),
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: rhs},
&SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: Register(R10)}, &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: R10},
} }
} }
} else if lhs, ok := i.Lhs.(Imm); ok && i.Opcode == Idiv { } else if lhs, ok := i.Lhs.(Imm); ok && i.Opcode == Idiv {
return []Instruction{ return []Instruction{
comment("FIXUP: Imm as Dst for Idiv"), comment("FIXUP: Imm as Dst for Idiv"),
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: lhs}, &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: lhs},
&SimpleInstruction{Opcode: Idiv, Lhs: Register(R10)}, &SimpleInstruction{Opcode: Idiv, Lhs: R10},
} }
} }
case Cmp: case Cmp:
@ -408,8 +418,8 @@ func fixupInstruction(i Instruction) []Instruction {
return []Instruction{ return []Instruction{
comment("FIXUP: Stack and Stack for Cmp"), comment("FIXUP: Stack and Stack for Cmp"),
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{Opcode: Mov, Lhs: Register(R10), Rhs: rhs}, &SimpleInstruction{Opcode: Mov, Lhs: R10, Rhs: rhs},
&SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: Register(R10)}, &SimpleInstruction{Opcode: i.Opcode, Lhs: lhs, Rhs: R10},
} }
} }
} else if lhs, ok := i.Lhs.(Imm); ok { } else if lhs, ok := i.Lhs.(Imm); ok {
@ -418,12 +428,12 @@ func fixupInstruction(i Instruction) []Instruction {
comment(i.InstructionString()), comment(i.InstructionString()),
&SimpleInstruction{ &SimpleInstruction{
Opcode: Mov, Opcode: Mov,
Lhs: Register(R11), Lhs: R11,
Rhs: Imm(lhs), Rhs: lhs,
}, },
&SimpleInstruction{ &SimpleInstruction{
Opcode: Cmp, Opcode: Cmp,
Lhs: Register(R11), Lhs: R11,
Rhs: i.Rhs, Rhs: i.Rhs,
}, },
} }

6
flake.lock generated
View File

@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1739214665, "lastModified": 1741851582,
"narHash": "sha256-26L8VAu3/1YRxS8MHgBOyOM8xALdo6N0I04PgorE7UM=", "narHash": "sha256-cPfs8qMccim2RBgtKGF+x9IBCduRvd/N5F4nYpU0TVE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "64e75cd44acf21c7933d61d7721e812eac1b5a0a", "rev": "6607cf789e541e7873d40d3a8f7815ea92204f32",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -45,8 +45,9 @@
( (
if system == "x86_64-linux" if system == "x86_64-linux"
then [fasm gdb] then [fasm gdb]
else [lldb] else []
) )
lldb
]; ];
}; };
}); });