From 272596c65f3a62b2e8d9584d9f2b16f12a264798 Mon Sep 17 00:00:00 2001 From: Takeshi Yoneda Date: Mon, 4 Mar 2024 11:59:13 +0900 Subject: [PATCH] wazevo(amd64): support for memory fence (#2111) Signed-off-by: Takeshi Yoneda --- internal/engine/wazevo/backend/isa/amd64/instr.go | 14 ++++++++++++++ .../wazevo/backend/isa/amd64/instr_encoding.go | 6 ++++++ .../backend/isa/amd64/instr_encoding_test.go | 5 +++++ .../engine/wazevo/backend/isa/amd64/machine.go | 3 +++ internal/engine/wazevo/e2e_test.go | 7 +++---- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/internal/engine/wazevo/backend/isa/amd64/instr.go b/internal/engine/wazevo/backend/isa/amd64/instr.go index bed379ea7a..600ae2b18e 100644 --- a/internal/engine/wazevo/backend/isa/amd64/instr.go +++ b/internal/engine/wazevo/backend/isa/amd64/instr.go @@ -258,6 +258,8 @@ func (i *instruction) String() string { return fmt.Sprintf("xmmcmov%s %s, %s", cond(i.u1), i.op1.format(true), i.op2.format(true)) case blendvpd: return fmt.Sprintf("blendvpd %s, %s, %%xmm0", i.op1.format(false), i.op2.format(false)) + case mfence: + return "mfence" default: panic(fmt.Sprintf("BUG: %d", int(i.kind))) } @@ -754,9 +756,17 @@ const ( // blendvpd is https://www.felixcloutier.com/x86/blendvpd. blendvpd + // mfence is https://www.felixcloutier.com/x86/mfence + mfence + instrMax ) +func (i *instruction) asMFence() *instruction { + i.kind = mfence + return i +} + func (i *instruction) asIdivRemSequence(execCtx, divisor, tmpGp regalloc.VReg, isDiv, signed, _64 bool) *instruction { i.kind = idivRemSequence i.op1 = newOperandReg(execCtx) @@ -978,6 +988,8 @@ func (k instructionKind) String() string { return "xmmCMov" case idivRemSequence: return "idivRemSequence" + case mfence: + return "mfence" default: panic("BUG") } @@ -2218,6 +2230,7 @@ var defKinds = [instrMax]defKind{ xmmCMov: defKindOp2, idivRemSequence: defKindDivRem, blendvpd: defKindNone, + mfence: defKindNone, } // String implements fmt.Stringer. @@ -2293,6 +2306,7 @@ var useKinds = [instrMax]useKind{ xmmCMov: useKindOp1, idivRemSequence: useKindDivRem, blendvpd: useKindBlendvpd, + mfence: useKindNone, } func (u useKind) String() string { diff --git a/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go b/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go index 95de5e8e36..2f99e8b54c 100644 --- a/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go +++ b/internal/engine/wazevo/backend/isa/amd64/instr_encoding.go @@ -1259,6 +1259,12 @@ func (i *instruction) encode(c backend.Compiler) (needsLabelResolution bool) { } i.encode(c) + case mfence: + // https://www.felixcloutier.com/x86/mfence + c.EmitByte(0x0f) + c.EmitByte(0xae) + c.EmitByte(0xf0) + default: panic(fmt.Sprintf("TODO: %v", i.kind)) } diff --git a/internal/engine/wazevo/backend/isa/amd64/instr_encoding_test.go b/internal/engine/wazevo/backend/isa/amd64/instr_encoding_test.go index b3f9ccf766..be85fa7e1e 100644 --- a/internal/engine/wazevo/backend/isa/amd64/instr_encoding_test.go +++ b/internal/engine/wazevo/backend/isa/amd64/instr_encoding_test.go @@ -4046,6 +4046,11 @@ func TestInstruction_format_encode(t *testing.T) { want: "66440f3815f9", wantFormat: "blendvpd %xmm1, %xmm15, %xmm0", }, + { + setup: func(i *instruction) { i.asMFence() }, + want: "0faef0", + wantFormat: "mfence", + }, } { tc := tc t.Run(tc.wantFormat, func(t *testing.T) { diff --git a/internal/engine/wazevo/backend/isa/amd64/machine.go b/internal/engine/wazevo/backend/isa/amd64/machine.go index a22f29e286..29575ee0e6 100644 --- a/internal/engine/wazevo/backend/isa/amd64/machine.go +++ b/internal/engine/wazevo/backend/isa/amd64/machine.go @@ -956,6 +956,9 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) { } m.insert(load) + case ssa.OpcodeFence: + m.insert(m.allocateInstr().asMFence()) + default: panic("TODO: lowering " + op.String()) } diff --git a/internal/engine/wazevo/e2e_test.go b/internal/engine/wazevo/e2e_test.go index ff2ec77300..9807ebbe12 100644 --- a/internal/engine/wazevo/e2e_test.go +++ b/internal/engine/wazevo/e2e_test.go @@ -842,10 +842,9 @@ func TestE2E(t *testing.T) { }, }, { - name: "atomic_fence", - m: testcases.AtomicFence.Module, - features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, - skipAMD64: true, + name: "atomic_fence", + m: testcases.AtomicFence.Module, + features: api.CoreFeaturesV2 | experimental.CoreFeaturesThreads, calls: []callCase{ {params: []uint64{}, expResults: []uint64{}}, },