blob: fb335ee44db5bebf8ca1254d5ccc87622afee1c4 [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 SIMDInt8x16Operation::OpInt8x16(int8 values[])
{
SIMDValue result = {0, 0, 0, 0};
for (uint8 i = 0; i < 16; i++)
{
result.i8[i] = values[i];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpSplat(int8 x)
{
SIMDValue result;
result.i8[0] = result.i8[1] = result.i8[2] = result.i8[3] = result.i8[4] = result.i8[5] = result.i8[6]= result.i8[7] = result.i8[8] = result.i8[9]= result.i8[10] = result.i8[11] = result.i8[12]= result.i8[13] = result.i8[14] = result.i8[15] = x;
return result;
}
//// Unary Ops
SIMDValue SIMDInt8x16Operation::OpNeg(const SIMDValue& value)
{
SIMDValue result;
result.i8[0] = -1 * value.i8[0];
result.i8[1] = -1 * value.i8[1];
result.i8[2] = -1 * value.i8[2];
result.i8[3] = -1 * value.i8[3];
result.i8[4] = -1 * value.i8[4];
result.i8[5] = -1 * value.i8[5];
result.i8[6] = -1 * value.i8[6];
result.i8[7] = -1 * value.i8[7];
result.i8[8] = -1 * value.i8[8];
result.i8[9] = -1 * value.i8[9];
result.i8[10] = -1 * value.i8[10];
result.i8[11] = -1 * value.i8[11];
result.i8[12] = -1 * value.i8[12];
result.i8[13] = -1 * value.i8[13];
result.i8[14] = -1 * value.i8[14];
result.i8[15] = -1 * value.i8[15];
return result;
}
SIMDValue SIMDInt8x16Operation::OpAdd(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = aValue.i8[idx] + bValue.i8[idx];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpSub(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = aValue.i8[idx] - bValue.i8[idx];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpMul(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = aValue.i8[idx] * bValue.i8[idx];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpAddSaturate(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
int mask = 0x80;
for (uint idx = 0; idx < 16; ++idx)
{
int8 val1 = aValue.i8[idx];
int8 val2 = bValue.i8[idx];
int8 sum = val1 + val2;
result.i8[idx] = sum;
if (val1 > 0 && val2 > 0 && sum < 0)
{
result.i8[idx] = 0x7F;
}
else if (val1 < 0 && val2 < 0 && sum > 0)
{
result.i8[idx] = static_cast<int8>(mask);
}
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpSubSaturate(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
int mask = 0x80;
for (uint idx = 0; idx < 16; ++idx)
{
int8 val1 = aValue.i8[idx];
int8 val2 = bValue.i8[idx];
int16 diff = val1 + val2;
result.i8[idx] = static_cast<int8>(diff);
if (diff > 0x7F)
{
result.i8[idx] = 0x7F;
}
else if (diff < 0x80)
{
result.i8[idx] = static_cast<int8>(mask);
}
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpMin(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] < bValue.i8[idx]) ? aValue.i8[idx] : bValue.i8[idx];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpMax(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] > bValue.i8[idx]) ? aValue.i8[idx] : bValue.i8[idx];
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpLessThan(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] < bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpLessThanOrEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] <= bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] == bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpNotEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] != bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpGreaterThan(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] > bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpGreaterThanOrEqual(const SIMDValue& aValue, const SIMDValue& bValue)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (aValue.i8[idx] >= bValue.i8[idx]) ? 0xff : 0x0;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpShiftLeftByScalar(const SIMDValue& value, int count)
{
SIMDValue result;
count = count & SIMDUtils::SIMDGetShiftAmountMask(1);
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = value.i8[idx] << count;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpShiftRightByScalar(const SIMDValue& value, int count)
{
SIMDValue result;
count = count & SIMDUtils::SIMDGetShiftAmountMask(1);
for(uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = value.i8[idx] >> count;
}
return result;
}
SIMDValue SIMDInt8x16Operation::OpSelect(const SIMDValue& mV, const SIMDValue& tV, const SIMDValue& fV)
{
SIMDValue result;
for (uint idx = 0; idx < 16; ++idx)
{
result.i8[idx] = (mV.i8[idx] == 1) ? tV.i8[idx] : fV.i8[idx];
}
return result;
}
}
#endif