Commit 2055656f authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

PPC: [wasm-simd] Implement double precision conversion

Change-Id: Icd46c44519a7cf524eba8a9ee3affdfb8f589bde
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2775716Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#73564}
parent fff95241
This diff is collapsed.
......@@ -3759,6 +3759,70 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
#undef EXT_MUL
case kPPC_F64x2ConvertLowI32x4S: {
__ vupklsw(kScratchSimd128Reg, i.InputSimd128Register(0));
__ xvcvsxddp(i.OutputSimd128Register(), kScratchSimd128Reg);
break;
}
case kPPC_F64x2ConvertLowI32x4U: {
Simd128Register dst = i.OutputSimd128Register();
constexpr int lane_width_in_bytes = 8;
__ vupklsw(dst, i.InputSimd128Register(0));
// Zero extend.
__ mov(ip, Operand(0xFFFFFFFF));
__ mtvsrd(kScratchSimd128Reg, ip);
__ vinsertd(kScratchSimd128Reg, kScratchSimd128Reg,
Operand(1 * lane_width_in_bytes));
__ vand(dst, kScratchSimd128Reg, dst);
__ xvcvuxddp(dst, dst);
break;
}
case kPPC_F64x2PromoteLowF32x4: {
constexpr int lane_number = 8;
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
__ vextractd(kScratchSimd128Reg, src, Operand(lane_number));
__ vinsertw(kScratchSimd128Reg, kScratchSimd128Reg, Operand(lane_number));
__ xvcvspdp(dst, kScratchSimd128Reg);
break;
}
case kPPC_F32x4DemoteF64x2Zero: {
constexpr int lane_number = 8;
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
__ xvcvdpsp(kScratchSimd128Reg, src);
__ vextractuw(dst, kScratchSimd128Reg, Operand(lane_number));
__ vinsertw(kScratchSimd128Reg, dst, Operand(4));
__ vxor(dst, dst, dst);
__ vinsertd(dst, kScratchSimd128Reg, Operand(lane_number));
break;
}
case kPPC_I32x4TruncSatF64x2SZero: {
constexpr int lane_number = 8;
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
// NaN to 0.
__ vor(kScratchSimd128Reg, src, src);
__ xvcmpeqdp(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg);
__ vand(kScratchSimd128Reg, src, kScratchSimd128Reg);
__ xvcvdpsxws(kScratchSimd128Reg, kScratchSimd128Reg);
__ vextractuw(dst, kScratchSimd128Reg, Operand(lane_number));
__ vinsertw(kScratchSimd128Reg, dst, Operand(4));
__ vxor(dst, dst, dst);
__ vinsertd(dst, kScratchSimd128Reg, Operand(lane_number));
break;
}
case kPPC_I32x4TruncSatF64x2UZero: {
constexpr int lane_number = 8;
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
__ xvcvdpuxws(kScratchSimd128Reg, src);
__ vextractuw(dst, kScratchSimd128Reg, Operand(lane_number));
__ vinsertw(kScratchSimd128Reg, dst, Operand(4));
__ vxor(dst, dst, dst);
__ vinsertd(dst, kScratchSimd128Reg, Operand(lane_number));
break;
}
case kPPC_StoreCompressTagged: {
ASSEMBLE_STORE_INTEGER(StoreTaggedField, StoreTaggedFieldX);
break;
......
......@@ -216,6 +216,9 @@ namespace compiler {
V(PPC_F64x2NearestInt) \
V(PPC_F64x2Pmin) \
V(PPC_F64x2Pmax) \
V(PPC_F64x2ConvertLowI32x4S) \
V(PPC_F64x2ConvertLowI32x4U) \
V(PPC_F64x2PromoteLowF32x4) \
V(PPC_F32x4Splat) \
V(PPC_F32x4ExtractLane) \
V(PPC_F32x4ReplaceLane) \
......@@ -244,6 +247,7 @@ namespace compiler {
V(PPC_F32x4Pmax) \
V(PPC_F32x4Qfma) \
V(PPC_F32x4Qfms) \
V(PPC_F32x4DemoteF64x2Zero) \
V(PPC_I64x2Splat) \
V(PPC_I64x2ExtractLane) \
V(PPC_I64x2ReplaceLane) \
......@@ -308,6 +312,8 @@ namespace compiler {
V(PPC_I32x4ExtMulHighI16x8S) \
V(PPC_I32x4ExtMulLowI16x8U) \
V(PPC_I32x4ExtMulHighI16x8U) \
V(PPC_I32x4TruncSatF64x2SZero) \
V(PPC_I32x4TruncSatF64x2UZero) \
V(PPC_I16x8Splat) \
V(PPC_I16x8ExtractLaneU) \
V(PPC_I16x8ExtractLaneS) \
......
......@@ -139,6 +139,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_F64x2NearestInt:
case kPPC_F64x2Pmin:
case kPPC_F64x2Pmax:
case kPPC_F64x2ConvertLowI32x4S:
case kPPC_F64x2ConvertLowI32x4U:
case kPPC_F64x2PromoteLowF32x4:
case kPPC_F32x4Splat:
case kPPC_F32x4ExtractLane:
case kPPC_F32x4ReplaceLane:
......@@ -167,6 +170,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_F32x4NearestInt:
case kPPC_F32x4Pmin:
case kPPC_F32x4Pmax:
case kPPC_F32x4DemoteF64x2Zero:
case kPPC_I64x2Splat:
case kPPC_I64x2ExtractLane:
case kPPC_I64x2ReplaceLane:
......@@ -231,6 +235,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kPPC_I32x4ExtMulHighI16x8S:
case kPPC_I32x4ExtMulLowI16x8U:
case kPPC_I32x4ExtMulHighI16x8U:
case kPPC_I32x4TruncSatF64x2SZero:
case kPPC_I32x4TruncSatF64x2UZero:
case kPPC_I16x8Splat:
case kPPC_I16x8ExtractLaneU:
case kPPC_I16x8ExtractLaneS:
......
......@@ -2257,6 +2257,9 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
V(F64x2Floor) \
V(F64x2Trunc) \
V(F64x2NearestInt) \
V(F64x2ConvertLowI32x4S) \
V(F64x2ConvertLowI32x4U) \
V(F64x2PromoteLowF32x4) \
V(F32x4Abs) \
V(F32x4Neg) \
V(F32x4RecipApprox) \
......@@ -2268,6 +2271,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
V(F32x4Floor) \
V(F32x4Trunc) \
V(F32x4NearestInt) \
V(F32x4DemoteF64x2Zero) \
V(I64x2Neg) \
V(I64x2SConvertI32x4Low) \
V(I64x2SConvertI32x4High) \
......@@ -2283,6 +2287,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
V(I32x4UConvertI16x8High) \
V(I32x4ExtAddPairwiseI16x8S) \
V(I32x4ExtAddPairwiseI16x8U) \
V(I32x4TruncSatF64x2SZero) \
V(I32x4TruncSatF64x2UZero) \
V(I16x8Neg) \
V(I16x8Abs) \
V(I8x16Neg) \
......@@ -2484,24 +2490,6 @@ void InstructionSelector::VisitS128Const(Node* node) {
}
void InstructionSelector::VisitI8x16Popcnt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2ConvertLowI32x4S(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitF64x2ConvertLowI32x4U(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitF64x2PromoteLowF32x4(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitF32x4DemoteF64x2Zero(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitI32x4TruncSatF64x2SZero(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitI32x4TruncSatF64x2UZero(Node* node) {
UNIMPLEMENTED();
}
void InstructionSelector::VisitI64x2GtS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2GeS(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2Abs(Node* node) { UNIMPLEMENTED(); }
......
......@@ -1421,31 +1421,28 @@ void VectorCompareOp(Simulator* sim, Instruction* instr, bool is_fp,
}
}
template <typename B, typename T>
void VectorConverFromFPSaturate(Simulator* sim, Instruction* instr, B min_val,
B max_val) {
template <typename S, typename T>
void VectorConverFromFPSaturate(Simulator* sim, Instruction* instr, T min_val,
T max_val, bool even_lane_result = false) {
int t = instr->RTValue();
int b = instr->RBValue();
FOR_EACH_LANE(i, float) {
B kMinVal = min_val;
B kMaxVal = max_val;
FOR_EACH_LANE(i, S) {
T t_val;
double b_val =
static_cast<double>(sim->get_simd_register_by_lane<float>(b, i));
double b_val = static_cast<double>(sim->get_simd_register_by_lane<S>(b, i));
if (isnan(b_val)) {
t_val = kMinVal;
t_val = min_val;
} else {
// Round Towards Zero.
b_val = std::trunc(b_val);
if (b_val < kMinVal) {
t_val = kMinVal;
} else if (b_val > kMaxVal) {
t_val = kMaxVal;
if (b_val < min_val) {
t_val = min_val;
} else if (b_val > max_val) {
t_val = max_val;
} else {
t_val = static_cast<T>(b_val);
}
}
sim->set_simd_register_by_lane<T>(t, i, t_val);
sim->set_simd_register_by_lane<T>(t, even_lane_result ? 2 * i : i, t_val);
}
}
......@@ -4483,13 +4480,21 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
}
#undef VECTOR_COMPARE_OP
case XVCVSPSXWS: {
VectorConverFromFPSaturate<int64_t, int32_t>(this, instr, kMinInt,
kMaxInt);
VectorConverFromFPSaturate<float, int32_t>(this, instr, kMinInt, kMaxInt);
break;
}
case XVCVSPUXWS: {
VectorConverFromFPSaturate<uint64_t, uint32_t>(this, instr, 0,
kMaxUInt32);
VectorConverFromFPSaturate<float, uint32_t>(this, instr, 0, kMaxUInt32);
break;
}
case XVCVDPSXWS: {
VectorConverFromFPSaturate<double, int32_t>(this, instr, kMinInt, kMaxInt,
true);
break;
}
case XVCVDPUXWS: {
VectorConverFromFPSaturate<double, uint32_t>(this, instr, 0, kMaxUInt32,
true);
break;
}
case XVCVSXWSP: {
......@@ -4510,6 +4515,42 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
}
break;
}
case XVCVSXDDP: {
int t = instr->RTValue();
int b = instr->RBValue();
FOR_EACH_LANE(i, int64_t) {
int64_t b_val = get_simd_register_by_lane<int64_t>(b, i);
set_simd_register_by_lane<double>(t, i, static_cast<double>(b_val));
}
break;
}
case XVCVUXDDP: {
int t = instr->RTValue();
int b = instr->RBValue();
FOR_EACH_LANE(i, uint64_t) {
uint64_t b_val = get_simd_register_by_lane<uint64_t>(b, i);
set_simd_register_by_lane<double>(t, i, static_cast<double>(b_val));
}
break;
}
case XVCVSPDP: {
int t = instr->RTValue();
int b = instr->RBValue();
FOR_EACH_LANE(i, double) {
float b_val = get_simd_register_by_lane<float>(b, 2 * i);
set_simd_register_by_lane<double>(t, i, static_cast<double>(b_val));
}
break;
}
case XVCVDPSP: {
int t = instr->RTValue();
int b = instr->RBValue();
FOR_EACH_LANE(i, double) {
double b_val = get_simd_register_by_lane<double>(b, i);
set_simd_register_by_lane<float>(t, 2 * i, static_cast<float>(b_val));
}
break;
}
#define VECTOR_UNPACK(S, D, if_high_side) \
int t = instr->RTValue(); \
int b = instr->RBValue(); \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment