aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/ASoftFloat.cs
diff options
context:
space:
mode:
authorMerry <MerryMage@users.noreply.github.com>2018-07-12 19:51:02 +0100
committergdkchan <gab.dark.100@gmail.com>2018-07-12 15:51:02 -0300
commitb233ae964fcaae900cdefa6ce51b0edb2892dfaf (patch)
tree53968c715100251ac6ced620ea2b6fe04c1a6d1e /ChocolArm64/Instruction/ASoftFloat.cs
parentcd18ab29dfacd1f7a3218d4ec73ce664bccc3887 (diff)
AInstEmitSimdCvt: Half-precision to single-precision conversion (#235)
Diffstat (limited to 'ChocolArm64/Instruction/ASoftFloat.cs')
-rw-r--r--ChocolArm64/Instruction/ASoftFloat.cs36
1 files changed, 36 insertions, 0 deletions
diff --git a/ChocolArm64/Instruction/ASoftFloat.cs b/ChocolArm64/Instruction/ASoftFloat.cs
index e63c82be..27f4f7fb 100644
--- a/ChocolArm64/Instruction/ASoftFloat.cs
+++ b/ChocolArm64/Instruction/ASoftFloat.cs
@@ -225,5 +225,41 @@ namespace ChocolArm64.Instruction
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)));
+ }
}
} \ No newline at end of file