diff --git a/src/asm/Assembler.go b/src/asm/Assembler.go index 6cc94fc..2a4323b 100644 --- a/src/asm/Assembler.go +++ b/src/asm/Assembler.go @@ -78,7 +78,12 @@ func (a *Assembler) Merge(b *Assembler) { } a.Instructions = append(a.Instructions, b.Instructions[skip:]...) - maps.Copy(a.Data, b.Data) + + if a.Data == nil { + a.Data = b.Data + } else { + maps.Copy(a.Data, b.Data) + } for library := range b.Libraries.All() { for _, fn := range library.Functions { diff --git a/src/asm/Assembler_test.go b/src/asm/Assembler_test.go index ced676e..fa09104 100644 --- a/src/asm/Assembler_test.go +++ b/src/asm/Assembler_test.go @@ -6,6 +6,7 @@ import ( "git.urbach.dev/cli/q/src/asm" "git.urbach.dev/cli/q/src/config" "git.urbach.dev/cli/q/src/cpu" + "git.urbach.dev/cli/q/src/token" "git.urbach.dev/go/assert" ) @@ -18,11 +19,13 @@ func TestAssembler(t *testing.T) { a.Append(&asm.Jump{Label: "d"}) a.Append(&asm.Jump{Label: "e"}) a.Append(&asm.Jump{Label: "f"}) + a.Append(&asm.Jump{Label: "g"}) a.Append(&asm.Call{Label: "b"}) a.Append(&asm.Call{Label: "c"}) a.Append(&asm.Call{Label: "d"}) a.Append(&asm.Call{Label: "e"}) a.Append(&asm.Call{Label: "f"}) + a.Append(&asm.Call{Label: "g"}) a.Append(&asm.StackFrameEnd{}) a.Append(&asm.Return{}) @@ -54,11 +57,13 @@ func TestAssembler(t *testing.T) { d := &asm.Assembler{} d.Append(&asm.Label{Name: "d"}) + d.SetData("message", []byte("Hello")) d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "a"}) d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "b"}) d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "c"}) d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "d"}) d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "e"}) + d.Append(&asm.MoveRegisterLabel{Destination: 0, Label: "message"}) d.Append(&asm.MoveRegisterNumber{Destination: 0, Number: 123}) d.Append(&asm.MoveRegisterRegister{Destination: 0, Source: 1}) d.Append(&asm.Return{}) @@ -81,6 +86,18 @@ func TestAssembler(t *testing.T) { f.Append(&asm.StackFrameEnd{FramePointer: true}) f.Append(&asm.Return{}) + g := &asm.Assembler{} + g.Append(&asm.Label{Name: "g"}) + g.Append(&asm.Call{Label: "a"}) + g.Append(&asm.CompareRegisterRegister{SourceA: 0, SourceB: 1}) + g.Append(&asm.Jump{Label: "a", Condition: token.Equal}) + g.Append(&asm.Jump{Label: "a", Condition: token.NotEqual}) + g.Append(&asm.Jump{Label: "a", Condition: token.Greater}) + g.Append(&asm.Jump{Label: "a", Condition: token.GreaterEqual}) + g.Append(&asm.Jump{Label: "a", Condition: token.Less}) + g.Append(&asm.Jump{Label: "a", Condition: token.LessEqual}) + g.Append(&asm.Return{}) + final := asm.Assembler{} final.Merge(a) final.Merge(b) @@ -88,6 +105,7 @@ func TestAssembler(t *testing.T) { final.Merge(d) final.Merge(e) final.Merge(f) + final.Merge(g) code, _, _ := final.Compile(&config.Build{Arch: config.ARM}) assert.NotNil(t, code) diff --git a/src/asm/compilerARM.go b/src/asm/compilerARM.go index 31f74c4..7601cf4 100644 --- a/src/asm/compilerARM.go +++ b/src/asm/compilerARM.go @@ -75,7 +75,20 @@ func (c *compilerARM) Compile(instr Instruction) { offset := (address - patch.start) / 4 - if offset != (offset & 0b11_11111111_11111111_11111111) { + var ( + minOffset int + maxOffset int + ) + + if instr.Condition == token.Invalid { + minOffset = -(1 << 25) + maxOffset = (1 << 25) - 1 + } else { + minOffset = -(1 << 18) + maxOffset = (1 << 18) - 1 + } + + if offset < minOffset || offset > maxOffset { panic("not implemented: long jumps") } diff --git a/src/cpu/Register_test.go b/src/cpu/Register_test.go index a7dd3d8..78eed90 100644 --- a/src/cpu/Register_test.go +++ b/src/cpu/Register_test.go @@ -8,6 +8,9 @@ import ( ) func TestRegisterString(t *testing.T) { - register := cpu.Register(1) - assert.Equal(t, "r1", register.String()) + r1 := cpu.Register(1) + assert.Equal(t, r1.String(), "r1") + + undefined := cpu.Register(-1) + assert.Equal(t, undefined.String(), "r?") } \ No newline at end of file