From f266002fe1e9cf262375e9743933a23a39c1d710 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Mon, 4 Mar 2024 11:30:16 +0900 Subject: [PATCH 1/2] wazevo(amd64): support for atomic loads Signed-off-by: Takeshi Yoneda --- .../wazevo/backend/isa/amd64/machine.go | 23 +++++++++++++++++++ internal/engine/wazevo/e2e_test.go | 21 ++++++++--------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/internal/engine/wazevo/backend/isa/amd64/machine.go b/internal/engine/wazevo/backend/isa/amd64/machine.go index 26985995a7..f6eebded14 100644 --- a/internal/engine/wazevo/backend/isa/amd64/machine.go +++ b/internal/engine/wazevo/backend/isa/amd64/machine.go @@ -933,6 +933,29 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { } m.insert(m.allocateInstr().asMovzxRmR(extModeLQ, rn, rd)) + case ssa.OpcodeAtomicLoad: + ptr := instr.Arg() + size := instr.AtomicTargetSize() + dst := m.c.VRegOf(instr.Return()) + + // At this point, the ptr is ensured to be aligned, so using a normal load is atomic. + // https://github.com/golang/go/blob/adead1a93f472affa97c494ef19f2f492ee6f34a/src/runtime/internal/atomic/atomic_amd64.go#L30 + mem := newOperandMem(m.lowerToAddressMode(ptr, 0)) + load := m.allocateInstr() + switch size { + case 8: + load.asMov64MR(mem, dst) + case 4: + load.asMovzxRmR(extModeWQ, mem, dst) + case 2: + load.asMovzxRmR(extModeWQ, mem, dst) + case 1: + load.asMovzxRmR(extModeBQ, mem, dst) + default: + panic("BUG") + } + m.insert(load) + default: panic("TODO: lowering " + op.String()) } diff --git a/internal/engine/wazevo/e2e_test.go b/internal/engine/wazevo/e2e_test.go index c0605a413c..ff2ec77300 100644 --- a/internal/engine/wazevo/e2e_test.go +++ b/internal/engine/wazevo/e2e_test.go @@ -600,10 +600,9 @@ func TestE2E(t *testing.T) { }, }, { - name: "memory_wait32", - m: testcases.MemoryWait32.Module, - features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, - skipAMD64: true, + name: "memory_wait32", + m: testcases.MemoryWait32.Module, + features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, calls: []callCase{ {params: []uint64{0x0, 0xbeef, 0xffffffff}, expResults: []uint64{1}}, // exp not equal, returns 1 {params: []uint64{0x1, 0xbeef, 0xffffffff}, expErr: "unaligned atomic"}, @@ -615,10 +614,9 @@ func TestE2E(t *testing.T) { }, }, { - name: "memory_wait64", - m: testcases.MemoryWait64.Module, - features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, - skipAMD64: true, + name: "memory_wait64", + m: testcases.MemoryWait64.Module, + features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, calls: []callCase{ {params: []uint64{0x0, 0xbeef, 0xffffffff}, expResults: []uint64{1}}, // exp not equal, returns 1 {params: []uint64{0x1, 0xbeef, 0xffffffff}, expErr: "unaligned atomic"}, @@ -634,10 +632,9 @@ func TestE2E(t *testing.T) { }, }, { - name: "memory_notify", - m: testcases.MemoryNotify.Module, - features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, - skipAMD64: true, + name: "memory_notify", + m: testcases.MemoryNotify.Module, + features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, calls: []callCase{ {params: []uint64{0x0, 0x1}, expResults: []uint64{0}}, // no waiters, returns 0 {params: []uint64{0x1, 0x1}, expErr: "unaligned atomic"}, From 652f4e35c3a88d83ae52022ba614ebbbf5ffc0b7 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Mon, 4 Mar 2024 11:36:43 +0900 Subject: [PATCH 2/2] LQ Signed-off-by: Takeshi Yoneda --- internal/engine/wazevo/backend/isa/amd64/machine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/engine/wazevo/backend/isa/amd64/machine.go b/internal/engine/wazevo/backend/isa/amd64/machine.go index f6eebded14..a22f29e286 100644 --- a/internal/engine/wazevo/backend/isa/amd64/machine.go +++ b/internal/engine/wazevo/backend/isa/amd64/machine.go @@ -946,7 +946,7 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { case 8: load.asMov64MR(mem, dst) case 4: - load.asMovzxRmR(extModeWQ, mem, dst) + load.asMovzxRmR(extModeLQ, mem, dst) case 2: load.asMovzxRmR(extModeWQ, mem, dst) case 1: