Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[simd/jit]: Implement v128.not and v128.andnot #74

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions src/engine/x86-64/X86_64Interpreter.v3
Original file line number Diff line number Diff line change
Expand Up @@ -2305,26 +2305,15 @@ class X86_64InterpreterGen(ic: X86_64InterpreterCode, w: DataWriter) {
genSimdBinop(Opcode.V128_OR, asm.orps_s_s);

bindHandler(Opcode.V128_NOT); { // XXX: SIMD unop?
asm.pcmpeqq_s_s(r_xmm0, r_xmm0); // all 1s
asm.movdqu_s_m(r_xmm1, vsph[-1].value);
asm.xorpd_s_s(r_xmm0, r_xmm1);
masm.emit_v128_not(r_xmm0, r_xmm1);
asm.movdqu_m_s(vsph[-1].value, r_xmm0);
endHandler();
}
bindHandler(Opcode.V128_ANDNOT); {
// v128.andnot(a: v128, b: v128) -> v128
// Bitwise AND of bits of a and the logical inverse of bits of b.
// This operation is equivalent to v128.and(a, v128.not(b)).
// NOT(b)
asm.pcmpeqq_s_s(r_xmm0, r_xmm0);
asm.movdqu_s_m(r_xmm1, vsph[-1].value);
asm.xorpd_s_s(r_xmm0, r_xmm1);
asm.movdqu_m_s(vsph[-1].value, r_xmm0);
// AND
asm.movdqu_s_m(r_xmm0, vsph[-1].value);
asm.movdqu_s_m(r_xmm1, vsph[-2].value);
asm.andpd_s_s(r_xmm0, r_xmm1);
asm.movdqu_m_s(vsph[-2].value, r_xmm0);
load_v128_xmm0_xmm1();
asm.andnps_s_s(r_xmm1, r_xmm0);
asm.movdqu_m_s(vsph[-2].value, r_xmm1);
decrementVsp();
endHandler();
}
Expand Down
14 changes: 14 additions & 0 deletions src/engine/x86-64/X86_64SinglePassCompiler.v3
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,20 @@ class X86_64SinglePassCompiler extends SinglePassCompiler {
def visit_V128_AND() {do_op2_x_x(ValueKind.V128, asm.andps_s_s); }
def visit_V128_OR() { do_op2_x_x(ValueKind.V128, asm.orps_s_s); }
def visit_V128_XOR() { do_op2_x_x(ValueKind.V128, asm.xorps_s_s); }

def visit_V128_NOT() {
var sv = popRegToOverwrite(), r = X(sv.reg);
var tmp = allocTmp(ValueKind.V128), t = X(tmp);
mmasm.emit_v128_not(r, t);
state.push(sv.kindFlagsMatching(ValueKind.V128, IN_REG), sv.reg, 0);
}

def visit_V128_ANDNOT() {
var b = popRegToOverwrite();
var a = popReg();
asm.andnps_s_s(X(b.reg), X(a.reg));
state.push(b.kindFlagsMatching(ValueKind.V128, IN_REG), b.reg, 0);
}

def visit_I8X16_ADD() { do_op2_x_x(ValueKind.V128, asm.paddb_s_s); }
def visit_I8X16_SUB() { do_op2_x_x(ValueKind.V128, asm.psubb_s_s); }
Expand Down
12 changes: 0 additions & 12 deletions test/regress/simd/v128.andnot.bin.wast
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,6 @@
)
(v128.const i32x4 0x214_1210 0x214_1210 0x214_1210 0x214_1210)
)
(module binary
"\00\61\73\6d\01\00\00\00\01\84\80\80\80\00\01\60"
"\00\00\03\82\80\80\80\00\01\00\05\83\80\80\80\00"
"\01\00\01\07\96\80\80\80\00\01\12\6e\65\73\74\65"
"\64\2d\76\31\32\38\2e\61\6e\64\6e\6f\74\00\00\0a"
"\c7\80\80\80\00\01\c1\80\80\80\00\00\41\00\fd\00"
"\04\00\41\01\fd\00\04\00\fd\4f\41\00\fd\00\04\00"
"\41\01\fd\00\04\00\fd\4f\fd\4f\41\00\fd\00\04\00"
"\41\01\fd\00\04\00\fd\4f\41\00\fd\00\04\00\41\01"
"\fd\00\04\00\fd\4f\fd\4f\fd\4f\1a\0b"
)
(assert_return (invoke "nested-v128.andnot"))
(assert_invalid
(module binary
"\00\61\73\6d\01\00\00\00\01\85\80\80\80\00\01\60"
Expand Down
37 changes: 4 additions & 33 deletions test/regress/simd/v128.andnot.wast
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,7 @@
(v128.const i32x4 0x0_90AB_cdef 0x0_90AB_cdef 0x0_90AB_cdef 0x0_90AB_cdef))
(v128.const i32x4 0x02141210 0x02141210 0x02141210 0x02141210))


(module (memory 1)
(func (export "nested-v128.andnot")
(drop
(v128.andnot
(v128.andnot
(v128.andnot
(v128.load (i32.const 0))
(v128.load (i32.const 1))
)
(v128.andnot
(v128.load (i32.const 0))
(v128.load (i32.const 1))
)
)
(v128.andnot
(v128.andnot
(v128.load (i32.const 0))
(v128.load (i32.const 1))
)
(v128.andnot
(v128.load (i32.const 0))
(v128.load (i32.const 1))
)
)
)
)
)
)

(assert_return (invoke "nested-v128.andnot"))

;; Type check
(assert_invalid
(module
(func $v128.andnot-1st-arg-empty (result v128)
Expand All @@ -85,11 +54,13 @@
)
"type mismatch"
)

;; Test operation with empty argument
(assert_invalid
(module
(func $v128.andnot-arg-empty (result v128)
(v128.andnot)
)
)
"type mismatch"
)
)
15 changes: 14 additions & 1 deletion test/regress/simd/v128.not.wast
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,17 @@
(assert_return (invoke "not" (v128.const i32x4 01_234_567_890 01_234_567_890 01_234_567_890 01_234_567_890))
(v128.const i32x4 3060399405 3060399405 3060399405 3060399405))
(assert_return (invoke "not" (v128.const i32x4 0x0_1234_5678 0x0_1234_5678 0x0_1234_5678 0x0_1234_5678))
(v128.const i32x4 0xedcba987 0xedcba987 0xedcba987 0xedcba987))
(v128.const i32x4 0xedcba987 0xedcba987 0xedcba987 0xedcba987))

;; Type check
(assert_invalid (module (func (result v128) (v128.not (i32.const 0)))) "type mismatch")

;; Test operation with empty argument
(assert_invalid
(module
(func $v128.not-arg-empty (result v128)
(v128.not)
)
)
"type mismatch"
)
Loading