AInstEmitSimdCvt: Half-precision to single-precision conversion (#235)
This commit is contained in:
parent
c590201b2a
commit
1e35b99f74
2 changed files with 40 additions and 4 deletions
|
@ -45,10 +45,10 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
if (SizeF == 0)
|
if (SizeF == 0)
|
||||||
{
|
{
|
||||||
//TODO: This need the half precision floating point type,
|
EmitVectorExtractZx(Context, Op.Rn, Part + Index, 1);
|
||||||
//that is not yet supported on .NET. We should probably
|
Context.Emit(OpCodes.Conv_U2);
|
||||||
//do our own implementation on the meantime.
|
|
||||||
throw new NotImplementedException();
|
Context.EmitCall(typeof(ASoftFloat), nameof(ASoftFloat.ConvertHalfToSingle));
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (SizeF == 1) */
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,5 +225,41 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
return 2.0 + op1 * op2;
|
return 2.0 + op1 * op2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float ConvertHalfToSingle(ushort x)
|
||||||
|
{
|
||||||
|
uint x_sign = (uint)(x >> 15) & 0x0001;
|
||||||
|
uint x_exp = (uint)(x >> 10) & 0x001F;
|
||||||
|
uint x_mantissa = (uint)x & 0x03FF;
|
||||||
|
|
||||||
|
if (x_exp == 0 && x_mantissa == 0)
|
||||||
|
{
|
||||||
|
// Zero
|
||||||
|
return BitConverter.Int32BitsToSingle((int)(x_sign << 31));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x_exp == 0x1F)
|
||||||
|
{
|
||||||
|
// NaN or Infinity
|
||||||
|
return BitConverter.Int32BitsToSingle((int)((x_sign << 31) | 0x7F800000 | (x_mantissa << 13)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int exponent = (int)x_exp - 15;
|
||||||
|
|
||||||
|
if (x_exp == 0)
|
||||||
|
{
|
||||||
|
// Denormal
|
||||||
|
x_mantissa <<= 1;
|
||||||
|
while ((x_mantissa & 0x0400) == 0)
|
||||||
|
{
|
||||||
|
x_mantissa <<= 1;
|
||||||
|
exponent--;
|
||||||
|
}
|
||||||
|
x_mantissa &= 0x03FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint new_exp = (uint)((exponent + 127) & 0xFF) << 23;
|
||||||
|
return BitConverter.Int32BitsToSingle((int)((x_sign << 31) | new_exp | (x_mantissa << 13)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue