blob: 46ac2fd53706662d81933c0b34681fb853b7438e [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeLanguagePch.h"
#if defined(_M_ARM32_OR_ARM64)
namespace Js
{
SIMDValue SIMDInt16x8Operation::OpInt16x8(int16 values[])
{
SIMDValue result;
for (uint i = 0; i < 8; i ++)
{
result.i16[i] = values[i];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpSplat(int16 x)
{
SIMDValue result;
result.i16[0] = result.i16[1] = result.i16[2] = result.i16[3] = x;
result.i16[4] = result.i16[5] = result.i16[6] = result.i16[7] = x;
return result;
}
// Unary Ops
SIMDValue SIMDInt16x8Operation::OpNeg(const SIMDValue& value)
{
SIMDValue result;
result.i16[0] = -1 * value.i16[0];
result.i16[1] = -1 * value.i16[1];
result.i16[2] = -1 * value.i16[2];
result.i16[3] = -1 * value.i16[3];
result.i16[4] = -1 * value.i16[4];
result.i16[5] = -1 * value.i16[5];
result.i16[6] = -1 * value.i16[6];
result.i16[7] = -1 * value.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpNot(const SIMDValue& value)
{
SIMDValue result;
result.i16[0] = ~(value.i16[0]);
result.i16[1] = ~(value.i16[1]);
result.i16[2] = ~(value.i16[2]);
result.i16[3] = ~(value.i16[3]);
result.i16[4] = ~(value.i16[4]);
result.i16[5] = ~(value.i16[5]);
result.i16[6] = ~(value.i16[6]);
result.i16[7] = ~(value.i16[7]);
return result;
}
// Binary Ops
SIMDValue SIMDInt16x8Operation::OpAdd(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] + bValue.i16[0];
result.i16[1] = aValue.i16[1] + bValue.i16[1];
result.i16[2] = aValue.i16[2] + bValue.i16[2];
result.i16[3] = aValue.i16[3] + bValue.i16[3];
result.i16[4] = aValue.i16[4] + bValue.i16[4];
result.i16[5] = aValue.i16[5] + bValue.i16[5];
result.i16[6] = aValue.i16[6] + bValue.i16[6];
result.i16[7] = aValue.i16[7] + bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpSub(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] - bValue.i16[0];
result.i16[1] = aValue.i16[1] - bValue.i16[1];
result.i16[2] = aValue.i16[2] - bValue.i16[2];
result.i16[3] = aValue.i16[3] - bValue.i16[3];
result.i16[4] = aValue.i16[4] - bValue.i16[4];
result.i16[5] = aValue.i16[5] - bValue.i16[5];
result.i16[6] = aValue.i16[6] - bValue.i16[6];
result.i16[7] = aValue.i16[7] - bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpMul(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] * bValue.i16[0];
result.i16[1] = aValue.i16[1] * bValue.i16[1];
result.i16[2] = aValue.i16[2] * bValue.i16[2];
result.i16[3] = aValue.i16[3] * bValue.i16[3];
result.i16[4] = aValue.i16[4] * bValue.i16[4];
result.i16[5] = aValue.i16[5] * bValue.i16[5];
result.i16[6] = aValue.i16[6] * bValue.i16[6];
result.i16[7] = aValue.i16[7] * bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpAnd(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] & bValue.i16[0];
result.i16[1] = aValue.i16[1] & bValue.i16[1];
result.i16[2] = aValue.i16[2] & bValue.i16[2];
result.i16[3] = aValue.i16[3] & bValue.i16[3];
result.i16[4] = aValue.i16[4] & bValue.i16[4];
result.i16[5] = aValue.i16[5] & bValue.i16[5];
result.i16[6] = aValue.i16[6] & bValue.i16[6];
result.i16[7] = aValue.i16[7] & bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpOr(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] | bValue.i16[0];
result.i16[1] = aValue.i16[1] | bValue.i16[1];
result.i16[2] = aValue.i16[2] | bValue.i16[2];
result.i16[3] = aValue.i16[3] | bValue.i16[3];
result.i16[4] = aValue.i16[4] | bValue.i16[4];
result.i16[5] = aValue.i16[5] | bValue.i16[5];
result.i16[6] = aValue.i16[6] | bValue.i16[6];
result.i16[7] = aValue.i16[7] | bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpXor(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
result.i16[0] = aValue.i16[0] ^ bValue.i16[0];
result.i16[1] = aValue.i16[1] ^ bValue.i16[1];
result.i16[2] = aValue.i16[2] ^ bValue.i16[2];
result.i16[3] = aValue.i16[3] ^ bValue.i16[3];
result.i16[4] = aValue.i16[4] ^ bValue.i16[4];
result.i16[5] = aValue.i16[5] ^ bValue.i16[5];
result.i16[6] = aValue.i16[6] ^ bValue.i16[6];
result.i16[7] = aValue.i16[7] ^ bValue.i16[7];
return result;
}
SIMDValue SIMDInt16x8Operation::OpAddSaturate(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
int mask = 0x8000;
for (uint idx = 0; idx < 8; ++idx)
{
int16 val1 = aValue.i16[idx];
int16 val2 = bValue.i16[idx];
int16 sum = val1 + val2;
result.i16[idx] = sum;
if (val1 > 0 && val2 > 0 && sum < 0)
{
result.i16[idx] = 0x7fff;
}
else if (val1 < 0 && val2 < 0 && sum > 0)
{
result.i16[idx] = static_cast<int16>(mask);
}
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpSubSaturate(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
int mask = 0x8000;
for (uint idx = 0; idx < 8; ++idx)
{
int16 val1 = aValue.i16[idx];
int16 val2 = bValue.i16[idx];
int16 diff = val1 + val2;
result.i16[idx] = static_cast<int16>(diff);
if (diff > 0x7fff)
result.i16[idx] = 0x7fff;
else if (diff < 0x8000)
result.i16[idx] = static_cast<int16>(mask);
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpMin(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (int idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] < bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpMax(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (int idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] > bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
// compare ops
SIMDValue SIMDInt16x8Operation::OpLessThan(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] < bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpLessThanOrEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] <= bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] == bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpNotEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] != bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpGreaterThan(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] > bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
SIMDValue SIMDInt16x8Operation::OpGreaterThanOrEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 8; ++idx)
{
result.i16[idx] = (aValue.i16[idx] >= bValue.i16[idx]) ? aValue.i16[idx] : bValue.i16[idx];
}
return result;
}
// ShiftOps
SIMDValue SIMDInt16x8Operation::OpShiftLeftByScalar(const SIMDValue& value, int count)
{
SIMDValue result;
count = count & SIMDUtils::SIMDGetShiftAmountMask(2);
result.i16[0] = value.i16[0] << count;
result.i16[1] = value.i16[1] << count;
result.i16[2] = value.i16[2] << count;
result.i16[3] = value.i16[3] << count;
result.i16[4] = value.i16[4] << count;
result.i16[5] = value.i16[5] << count;
result.i16[6] = value.i16[6] << count;
result.i16[7] = value.i16[7] << count;
return result;
}
SIMDValue SIMDInt16x8Operation::OpShiftRightByScalar(const SIMDValue& value, int count)
{
SIMDValue result;
count = count & SIMDUtils::SIMDGetShiftAmountMask(2);
result.i16[0] = value.i16[0] >> count;
result.i16[1] = value.i16[1] >> count;
result.i16[2] = value.i16[2] >> count;
result.i16[3] = value.i16[3] >> count;
result.i16[4] = value.i16[4] >> count;
result.i16[5] = value.i16[5] >> count;
result.i16[6] = value.i16[6] >> count;
result.i16[7] = value.i16[7] >> count;
return result;
}
}
#endif