From 49866e970b547f5bf8321c46e9409b6dc3f6abbf Mon Sep 17 00:00:00 2001 From: DrChat Date: Fri, 2 Mar 2018 16:34:57 -0600 Subject: [PATCH] [JIT] VectorConvertX2X unsigned support --- .../compiler/passes/constant_propagation_pass.cc | 7 +++++-- src/xenia/cpu/hir/value.cc | 16 ++++++++++++---- src/xenia/cpu/hir/value.h | 4 ++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index 5a208f589..616df2563 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -701,14 +701,17 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { case OPCODE_VECTOR_CONVERT_F2I: if (i->src1.value->IsConstant()) { v->set_zero(VEC128_TYPE); - v->VectorConvertF2I(i->src1.value); + v->VectorConvertF2I(i->src1.value, + !!(i->flags & ARITHMETIC_UNSIGNED), + !!(i->flags & ARITHMETIC_SATURATE)); i->Remove(); } break; case OPCODE_VECTOR_CONVERT_I2F: if (i->src1.value->IsConstant()) { v->set_zero(VEC128_TYPE); - v->VectorConvertI2F(i->src1.value); + v->VectorConvertI2F(i->src1.value, + !!(i->flags & ARITHMETIC_SATURATE)); i->Remove(); } break; diff --git a/src/xenia/cpu/hir/value.cc b/src/xenia/cpu/hir/value.cc index 7342bf112..de70ffc35 100644 --- a/src/xenia/cpu/hir/value.cc +++ b/src/xenia/cpu/hir/value.cc @@ -1079,19 +1079,27 @@ void Value::VectorCompareUGE(Value* other, TypeName type) { } } -void Value::VectorConvertI2F(Value* other) { +void Value::VectorConvertI2F(Value* other, bool is_unsigned) { assert_true(type == VEC128_TYPE); for (int i = 0; i < 4; i++) { - constant.v128.f32[i] = (float)other->constant.v128.i32[i]; + if (is_unsigned) { + constant.v128.f32[i] = (float)other->constant.v128.u32[i]; + } else { + constant.v128.f32[i] = (float)other->constant.v128.i32[i]; + } } } -void Value::VectorConvertF2I(Value* other) { +void Value::VectorConvertF2I(Value* other, bool is_unsigned, bool saturate) { assert_true(type == VEC128_TYPE); // FIXME(DrChat): This does not saturate! for (int i = 0; i < 4; i++) { - constant.v128.i32[i] = (int32_t)other->constant.v128.f32[i]; + if (is_unsigned) { + constant.v128.u32[i] = (uint32_t)other->constant.v128.f32[i]; + } else { + constant.v128.i32[i] = (int32_t)other->constant.v128.f32[i]; + } } } diff --git a/src/xenia/cpu/hir/value.h b/src/xenia/cpu/hir/value.h index 2088fa374..f4d7a9f8b 100644 --- a/src/xenia/cpu/hir/value.h +++ b/src/xenia/cpu/hir/value.h @@ -526,8 +526,8 @@ class Value { void VectorCompareSGE(Value* other, TypeName type); void VectorCompareUGT(Value* other, TypeName type); void VectorCompareUGE(Value* other, TypeName type); - void VectorConvertI2F(Value* other); - void VectorConvertF2I(Value* other); + void VectorConvertI2F(Value* other, bool is_unsigned); + void VectorConvertF2I(Value* other, bool is_unsigned, bool saturate); void VectorShl(Value* other, TypeName type); void VectorShr(Value* other, TypeName type); void VectorRol(Value* other, TypeName type);