From 080a0f8026951913ca87c277db29e561e87b7820 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 13:00:00 -0700 Subject: [PATCH] Fixing vsel. --- src/alloy/backend/x64/x64_sequences.cc | 29 ++++++++++++++++++++-- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 3 +-- src/alloy/hir/hir_builder.cc | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 0a9de3fbc..2bbb56190 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1913,7 +1913,7 @@ EMITTER(SELECT_F64, MATCH(I, I8<>, F64<>, F64<>>)) { e.vpor(i.dest, e.xmm1); } }; -EMITTER(SELECT_V128, MATCH(I, I8<>, V128<>, V128<>>)) { +EMITTER(SELECT_V128_I8, MATCH(I, I8<>, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { // TODO(benvanik): find a shorter sequence. // xmm0 = src1 != 0 ? 1111... : 0000.... @@ -1927,6 +1927,30 @@ EMITTER(SELECT_V128, MATCH(I, I8<>, V128<>, V128<>>)) { e.vpor(i.dest, e.xmm1); } }; +EMITTER(SELECT_V128_V128, MATCH(I, V128<>, V128<>, V128<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): could be made shorter when consts involved. + if (i.src2.is_constant) { + if (i.src2.value->IsConstantZero()) { + e.vpxor(e.xmm1, e.xmm1); + } else { + assert_always(); + } + } else { + e.vpandn(e.xmm1, i.src1, i.src2); + } + if (i.src3.is_constant) { + if (i.src3.value->IsConstantZero()) { + e.vpxor(i.dest, i.dest); + } else { + assert_always(); + } + } else { + e.vpand(i.dest, i.src1, i.src3); + } + e.vpor(i.dest, e.xmm1); + } +}; EMITTER_OPCODE_TABLE( OPCODE_SELECT, SELECT_I8, @@ -1935,7 +1959,8 @@ EMITTER_OPCODE_TABLE( SELECT_I64, SELECT_F32, SELECT_F64, - SELECT_V128); + SELECT_V128_I8, + SELECT_V128_V128); // ============================================================================ diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index d62886946..453fd1ec0 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1332,8 +1332,7 @@ XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { - Value* c = f.LoadVR(vc); - Value* v = f.Or(f.And(f.LoadVR(va), f.Not(c)), f.And(f.LoadVR(vb), c)); + Value* v = f.Select(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; } diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index ccc089eb8..58929fd2d 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1182,7 +1182,7 @@ Value* HIRBuilder::VectorMin(Value* value1, Value* value2, TypeName part_type, } Value* HIRBuilder::Select(Value* cond, Value* value1, Value* value2) { - assert_true(cond->type == INT8_TYPE); // for now + assert_true(cond->type == INT8_TYPE || cond->type == VEC128_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); if (cond->IsConstant()) {