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-24 16:52:26 +02:00
|
|
|
IMPL_START(or) { *r1 = p2->val | p3->val; return 1; }
|
|
|
|
IMPL_START(and) { *r1 = p2->val & p3->val; return 1; }
|
|
|
|
IMPL_START(xor) { *r1 = p2->val ^ p3->val; return 1; }
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(shl) { *r1 = p2->val << p3->val; return 1; }
|
|
|
|
IMPL_START(shr) { *r1 = p2->val >> p3->val; return 1; }
|
|
|
|
IMPL_START(sal) { *r1 = (ulong)((long)p2->val << (long)p3->val); return 1; }
|
|
|
|
IMPL_START(sar) { *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; }
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(add) { *r1 = p2->val + p3->val; return 1; }
|
|
|
|
IMPL_START(addf) { COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; }
|
2019-07-17 20:26:03 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(sub) { *r1 = p2->val - p3->val; return 1; }
|
|
|
|
IMPL_START(subf) { COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; }
|
2019-07-17 20:26:03 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(adcx)
|
|
|
|
{
|
|
|
|
p3->val += !!(R(RFX)&CF);
|
|
|
|
COMPARE_ADD(p2->val, p3->val);
|
|
|
|
*r1 = p2->val + p3->val;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_START(sbbx)
|
|
|
|
{
|
|
|
|
p3->val += !!(R(RFX)&CF);
|
|
|
|
COMPARE_SUB(p2->val, p3->val);
|
|
|
|
*r1 = p2->val - p3->val;
|
2019-07-17 20:26:03 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(mul) { *r1 = p2->val * p3->val; return 1; }
|
|
|
|
IMPL_START(rem) { *r1 = p2->val % p3->val; return 1; }
|
|
|
|
|
|
|
|
IMPL_START(div)
|
|
|
|
{
|
|
|
|
if (!p3->val)
|
2019-07-17 20:26:03 +02:00
|
|
|
_except(ctx, E_DIV, "DIV by 0");
|
2019-07-24 16:52:26 +02:00
|
|
|
*r1 = p2->val / p3->val;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_START(idiv)
|
|
|
|
{
|
|
|
|
if (!p3->val)
|
2019-07-18 22:49:31 +02:00
|
|
|
_except(ctx, E_DIV, "IDIV by 0");
|
2019-07-24 16:52:26 +02:00
|
|
|
|
|
|
|
*r1 = (ulong)((long)p2->val/(long)p3->val);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
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-24 16:52:26 +02:00
|
|
|
IMPL_START(mulhi)
|
|
|
|
{
|
|
|
|
__unsigned_multiply128(p2->val, p3->val, r1, r2);
|
|
|
|
return 2;
|
|
|
|
}
|
2019-07-17 20:26:03 +02:00
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(mulf)
|
|
|
|
{
|
2019-07-17 20:26:03 +02:00
|
|
|
ulong tmp;
|
2019-07-24 16:52:26 +02:00
|
|
|
__unsigned_multiply128(p2->val, p3->val, &tmp, r1);
|
|
|
|
R(RFX) = p2->val ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2019-07-17 20:26:03 +02:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-07-24 16:52:26 +02:00
|
|
|
IMPL_START(imulhi)
|
|
|
|
{
|
|
|
|
__signed_multiply128(p2->val, p3->val, r1, r2);
|
|
|
|
return 2;
|
|
|
|
}
|
2019-07-17 20:26:03 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|