diff --git a/core/emu.go b/core/emu.go index f0dd075..d64d634 100644 --- a/core/emu.go +++ b/core/emu.go @@ -1223,7 +1223,7 @@ func (i instEmulator) runCmpExport(inst Operation, state *coreState) { Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Src1", fmt.Sprintf("%d(%t)", src1Val.First(), src1Val.Pred), "Src2", fmt.Sprintf("%d(%t)", src2Val.First(), src2Val.Pred), "Result", fmt.Sprintf("%d(%t)", resultVal, finalPred)) } -func (i instEmulator) runSgtExport(inst Operation, state *coreState) { +func (i instEmulator) runLTExport(inst Operation, state *coreState) { src1 := inst.SrcOperands.Operands[0] src2 := inst.SrcOperands.Operands[1] @@ -1231,44 +1231,16 @@ func (i instEmulator) runSgtExport(inst Operation, state *coreState) { src2Struct := i.readOperand(src2, state) src1Val := src1Struct.First() src2Val := src2Struct.First() - src1Pred := src1Struct.Pred src2Pred := src2Struct.Pred resultPred := src1Pred && src2Pred - finalPred := resultPred - - //o + // Convert uint32 to int32 for signed comparison src1Signed := int32(src1Val) src2Signed := int32(src2Val) - if src1Signed > src2Signed { - for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) - } - } else { - for _, dst := range inst.DstOperands.Operands { - i.writeOperand(dst, cgra.NewScalarWithPred(0, finalPred), state) - } - } - Trace("Inst", "Time", state.CurrentTime, "OpCode", inst.OpCode, "ID", inst.ID, "X", state.TileX, "Y", state.TileY, "Pred", finalPred) - // elect no next PC -} - -func (i instEmulator) runLTExport(inst Operation, state *coreState) { - src1 := inst.SrcOperands.Operands[0] - src2 := inst.SrcOperands.Operands[1] - - src1Struct := i.readOperand(src1, state) - src2Struct := i.readOperand(src2, state) - src1Val := src1Struct.First() - src2Val := src2Struct.First() - src1Pred := src1Struct.Pred - src2Pred := src2Struct.Pred - resultPred := src1Pred && src2Pred - finalPred := resultPred - if src1Val < src2Val { + if src1Signed < src2Signed { for _, dst := range inst.DstOperands.Operands { i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) } @@ -1293,8 +1265,12 @@ func (i instEmulator) runGTExport(inst Operation, state *coreState) { src2Pred := src2Struct.Pred resultPred := src1Pred && src2Pred + // Convert uint32 to int32 for signed comparison + src1Signed := int32(src1Val) + src2Signed := int32(src2Val) + finalPred := resultPred - if src1Val > src2Val { + if src1Signed > src2Signed { for _, dst := range inst.DstOperands.Operands { i.writeOperand(dst, cgra.NewScalarWithPred(1, finalPred), state) } @@ -1319,6 +1295,7 @@ func (i instEmulator) runSGEExport(inst Operation, state *coreState) { src2Pred := src2Struct.Pred resultPred := src1Pred && src2Pred + // Convert uint32 to int32 for signed comparison src1Signed := int32(src1Val) src2Signed := int32(src2Val) diff --git a/core/emu_unit_test.go b/core/emu_unit_test.go index d46791a..d0c4dc4 100644 --- a/core/emu_unit_test.go +++ b/core/emu_unit_test.go @@ -84,6 +84,78 @@ var _ = Describe("InstEmulator", func() { }) + Context("Signed Comparison Instructions", func() { + testSignedComparison := func(opcode string, src1Val uint32, src2Val uint32, expectedResult uint32) { + s.Registers[0] = cgra.NewScalar(src1Val) + s.Registers[1] = cgra.NewScalar(src2Val) + inst := InstructionGroup{ + Operations: []Operation{ + { + OpCode: opcode, + SrcOperands: OperandList{ + Operands: []Operand{ + {Color: "RED", Impl: "$0"}, + {Color: "RED", Impl: "$1"}, + }, + }, + DstOperands: OperandList{ + Operands: []Operand{ + {Color: "RED", Impl: "$2"}, + }, + }, + }, + }, + } + s.SelectedBlock = &EntryBlock{ + InstructionGroups: []InstructionGroup{inst}, + } + ie.RunInstructionGroup(inst, &s, 0) + Expect(s.Registers[2].First()).To(Equal(expectedResult)) + } + + Describe("ICMP_SGT", func() { + It("should handle positive > positive", func() { + testSignedComparison("ICMP_SGT", 5, 3, 1) + }) + + It("should handle negative > positive (false)", func() { + testSignedComparison("ICMP_SGT", 0xFFFFFFFF, 0, 0) // -1 > 0 = false + }) + + It("should handle negative > negative", func() { + testSignedComparison("ICMP_SGT", 0xFFFFFFFF, 0xFFFFFFFE, 1) // -1 > -2 = true + }) + }) + + Describe("ICMP_SLT", func() { + It("should handle positive < positive", func() { + testSignedComparison("ICMP_SLT", 3, 5, 1) + }) + + It("should handle positive < negative (false)", func() { + testSignedComparison("ICMP_SLT", 0, 0xFFFFFFFF, 0) // 0 < -1 = false + }) + + It("should handle negative < negative", func() { + testSignedComparison("ICMP_SLT", 0xFFFFFFFE, 0xFFFFFFFF, 1) // -2 < -1 = true + }) + }) + + Describe("ICMP_SGE", func() { + It("should handle equality", func() { + testSignedComparison("ICMP_SGE", 5, 5, 1) + }) + + It("should handle negative >= positive (false)", func() { + testSignedComparison("ICMP_SGE", 0xFFFFFFFF, 0, 0) // -1 >= 0 = false + }) + + It("should handle negative >= negative (equal)", func() { + testSignedComparison("ICMP_SGE", 0xFFFFFFFF, 0xFFFFFFFF, 1) // -1 >= -1 = true + }) + }) + }) + /* Context("Bitwise Instructions", func() { diff --git a/go.mod b/go.mod index 2683c95..46ba714 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,11 @@ toolchain go1.24.0 require ( github.com/golang/mock v1.6.0 + github.com/jedib0t/go-pretty/v6 v6.6.8 github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/sarchlab/akita/v4 v4.0.0 - github.com/tebeka/atexit v0.3.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -21,7 +22,6 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240829160300-da1f7e9f2b25 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/jedib0t/go-pretty/v6 v6.6.8 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect @@ -29,6 +29,7 @@ require ( github.com/rs/xid v1.6.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/syifan/goseth v0.1.2 // indirect + github.com/tebeka/atexit v0.3.0 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect @@ -36,7 +37,6 @@ require ( golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.24.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) //replace gitlab.com/akita/akita/v2 => ../akita diff --git a/go.sum b/go.sum index b2cbcc0..bb193f1 100644 --- a/go.sum +++ b/go.sum @@ -48,9 +48,8 @@ github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKl github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syifan/goseth v0.1.2 h1:b/VG4wboBQNedodAw6wzTz6fdtISSbYIR3ntzRw0J6Q= github.com/syifan/goseth v0.1.2/go.mod h1:XmguXtbJ2+jSQABDvr3X0uDiYo+7gak39C6BHoWDvYo= github.com/tebeka/atexit v0.3.0 h1:jleL99H7Ywt80oJKR+VWmJNnezcCOG0CuzcN3CIpsdI=