diff --git a/src/arm/Negate.go b/src/arm/Negate.go new file mode 100644 index 0000000..2e7a33c --- /dev/null +++ b/src/arm/Negate.go @@ -0,0 +1,8 @@ +package arm + +import "git.urbach.dev/cli/q/src/cpu" + +// NegateRegister negates the value in the source register and writes it to the destination register. +func NegateRegister(destination cpu.Register, source cpu.Register) uint32 { + return 0b11001011<<24 | reg3Imm(destination, ZR, source, 0) +} diff --git a/src/arm/Negate_test.go b/src/arm/Negate_test.go new file mode 100644 index 0000000..65f3809 --- /dev/null +++ b/src/arm/Negate_test.go @@ -0,0 +1,26 @@ +package arm_test + +import ( + "testing" + + "git.urbach.dev/cli/q/src/arm" + "git.urbach.dev/cli/q/src/cpu" + "git.urbach.dev/go/assert" +) + +func TestNegateRegister(t *testing.T) { + usagePatterns := []struct { + Destination cpu.Register + Source cpu.Register + Code uint32 + }{ + {arm.X0, arm.X0, 0xCB0003E0}, + {arm.X1, arm.X1, 0xCB0103E1}, + } + + for _, pattern := range usagePatterns { + t.Logf("neg %s, %s", pattern.Destination, pattern.Source) + code := arm.NegateRegister(pattern.Destination, pattern.Source) + assert.DeepEqual(t, code, pattern.Code) + } +} diff --git a/src/asmc/ARM.go b/src/asmc/ARM.go index c6439b3..1d98cb1 100644 --- a/src/asmc/ARM.go +++ b/src/asmc/ARM.go @@ -307,6 +307,13 @@ func (c *compiler) ARM(x asm.Instruction) { panic("not implemented") } + case asm.NEGATE: + switch x.Type { + case asm.TypeRegister: + operands := c.assembler.Param.Register[x.Index] + c.append(arm.NegateRegister(operands.Register, operands.Register)) + } + default: panic("unknown mnemonic: " + x.Mnemonic.String()) }