2019-07-17 20:26:03 +02:00
|
|
|
// The OS/K Team licenses this file to you under the MIT license.
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
#include <in/instrs.h>
|
|
|
|
|
|
|
|
#define _NEED_ARCH_I
|
2019-07-18 22:49:31 +02:00
|
|
|
#include <ob/arch_i.h>
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-17 22:25:50 +02:00
|
|
|
IMPL_START_3(or) { v1 = v2 | v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(and) { v1 = v2 & v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(xor) { v1 = v2 ^ v3; } IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
IMPL_START_3(shl) { v1 = v2 << v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(shr) { v1 = v2 >> v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(sal) { v1 = (ulong)((long)v2 << (long)v3); } IMPL_OUT;
|
|
|
|
IMPL_START_3(sar) { v1 = (ulong)((long)v2 >> (long)v3); } IMPL_OUT;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-17 22:25:50 +02:00
|
|
|
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(addf) { COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_2(cmp) { COMPARE_SUB(v1, v2); } IMPL_END;
|
2019-07-17 22:25:50 +02:00
|
|
|
IMPL_START_3(sub) { v1 = v2 - v3; } IMPL_OUT;
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(subf){ COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(adcx) { v3 += !!(R(RFX)&CF); COMPARE_ADD(v2, v3); v1 = v2 + v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(sbbx) { v3 += !!(R(RFX)&CF); COMPARE_SUB(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
IMPL_START_3(rem) { v1 = v2 % v3; } IMPL_OUT;
|
|
|
|
IMPL_START_3(div) {
|
|
|
|
if (!v3)
|
|
|
|
_except(ctx, E_DIV, "DIV by 0");
|
|
|
|
v1 = v2 / v3;
|
|
|
|
} IMPL_OUT;
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(idiv) {
|
|
|
|
if (!v3)
|
|
|
|
_except(ctx, E_DIV, "IDIV by 0");
|
|
|
|
v1 = (ulong)((long)v2/(long)v3);
|
|
|
|
} IMPL_OUT;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
2019-07-17 20:26:03 +02:00
|
|
|
{
|
2019-07-18 22:49:31 +02:00
|
|
|
__uint128_t r = (__uint128_t)u * (__uint128_t)v;
|
|
|
|
|
|
|
|
*hi = r >> 64;
|
|
|
|
*lo = r;
|
2019-07-17 20:26:03 +02:00
|
|
|
}
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
IMPL_START_3(mulhi) { __unsigned_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
IMPL_START_3(mulf) {
|
|
|
|
ulong tmp;
|
2019-07-18 22:49:31 +02:00
|
|
|
__unsigned_multiply128(v2, v3, &tmp, &v1);
|
2019-07-17 20:26:03 +02:00
|
|
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
|
|
|
} IMPL_OUT;
|
|
|
|
|
2019-07-18 22:49:31 +02:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo)
|
|
|
|
{
|
|
|
|
__int128_t r = (__int128_t)(long)u * (__int128_t)(long)v;
|
|
|
|
|
|
|
|
*hi = r >> 64;
|
|
|
|
*lo = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_START_3(imulhi) { __signed_multiply128(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|