1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
kvisc/vm/in/alu.c

213 lines
5.3 KiB
C
Raw Permalink Normal View History

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-08-14 20:23:05 +02:00
IMPL_START(not, 1) { SRCP(p1); *r1 = ~p1->val; return 1; }
2019-08-16 13:29:38 +02:00
IMPL_START(not, 2) { SRCP(p2); *r1 = ~p2->val; return 1; }
2019-08-08 18:39:12 +02:00
2019-08-14 20:23:05 +02:00
IMPL_START(or, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val | p2->val; return 1; }
2019-08-08 18:39:12 +02:00
IMPL_START(or, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(and, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val & p2->val; return 1; }
2019-08-08 18:39:12 +02:00
IMPL_START(and, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(xor, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val ^ p2->val; return 1; }
2019-08-08 18:39:12 +02:00
IMPL_START(xor, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; }
2019-07-17 20:26:03 +02:00
//----------------------------------------------------------------------------//
2019-08-08 18:39:12 +02:00
IMPL_START(shl, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val << p2->val; return 1; }
IMPL_START(shl, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(shr, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val >> p2->val; return 1; }
2019-08-08 18:39:12 +02:00
IMPL_START(shr, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(sar, 2) {
SRCP(p1); SRCP(p2);
*r1 = (ulong)((long)p1->val >> (long)p2->val);
return 1;
}
IMPL_START(sar, 3) {
SRCP(p2); SRCP(p3);
*r1 = (ulong)((long)p2->val >> (long)p3->val);
return 1;
}
2019-07-17 20:26:03 +02:00
//----------------------------------------------------------------------------//
2019-08-14 20:23:05 +02:00
IMPL_START(neg, 1) { SRCP(p1); *r1 = ~p1->val + 1; return 1; }
2019-08-16 13:29:38 +02:00
IMPL_START(neg, 2) { SRCP(p2); *r1 = ~p2->val + 1; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(negv, 1) {
SRCP(p1);
if (p1->val == (1ul<<63))
_except(E_OVF, "Ineffective NEG operation (NEGV)");
*r1 = ~p1->val + 1;
return 1;
}
2019-08-16 13:29:38 +02:00
IMPL_START(negv, 2) {
SRCP(p2);
if (p2->val == (1ul<<63))
_except(E_OVF, "Ineffective NEG operation (NEGV)");
*r1 = ~p2->val + 1;
return 1;
}
//----------------------------------------------------------------------------//
2019-08-21 16:57:32 +02:00
IMPL_START(inc, 1) { SRCP(p1); *r1 = p1->val + 1; return 1; }
2019-08-08 18:39:12 +02:00
IMPL_START(add, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; }
IMPL_START(add, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; }
2019-07-17 20:26:03 +02:00
2019-08-14 20:23:05 +02:00
IMPL_START(addv, 2) {
2019-08-08 18:39:12 +02:00
SRCP(p1); SRCP(p2);
2019-08-14 20:23:05 +02:00
ulong rs = p1->val + p2->val;
2019-08-08 18:39:12 +02:00
2019-08-14 20:23:05 +02:00
if (((p1->val ^ rs) & (p2->val ^ rs)) >> 63)
_except(E_OVF, "Signed addition overflow (ADDV#2)");
*r1 = rs;
2019-08-08 18:39:12 +02:00
return 1;
}
2019-08-14 20:23:05 +02:00
IMPL_START(addv, 3) {
2019-08-08 18:39:12 +02:00
SRCP(p2); SRCP(p3);
2019-08-03 17:41:44 +02:00
2019-08-14 20:23:05 +02:00
ulong rs = p2->val + p3->val;
if (((p2->val ^ rs) & (p3->val ^ rs)) >> 63)
_except(E_OVF, "Signed addition overflow (ADDV#3)");
2019-07-17 20:26:03 +02:00
2019-08-14 20:23:05 +02:00
*r1 = rs;
2019-07-24 16:52:26 +02:00
return 1;
}
2019-08-14 20:23:05 +02:00
//----------------------------------------------------------------------------//
2019-08-21 16:57:32 +02:00
IMPL_START(dec, 1) { SRCP(p1); *r1 = p1->val - 1; return 1; }
2019-08-14 20:23:05 +02:00
IMPL_START(sub, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; }
IMPL_START(sub, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; }
IMPL_START(subv, 2) {
2019-08-08 18:39:12 +02:00
SRCP(p1); SRCP(p2);
2019-08-14 20:23:05 +02:00
ulong rs = p1->val - p2->val;
2019-08-08 18:39:12 +02:00
2019-08-14 20:23:05 +02:00
if (((p1->val ^ rs) & (p1->val ^ p2->val)) >> 63)
_except(E_OVF, "Signed substraction underflow (SUBV#2)");
*r1 = rs;
2019-08-08 18:39:12 +02:00
return 1;
}
2019-08-14 20:23:05 +02:00
IMPL_START(subv, 3) {
SRCP(p1); SRCP(p2);
ulong rs = p2->val - p3->val;
2019-08-03 17:41:44 +02:00
2019-08-14 20:23:05 +02:00
if (((p2->val ^ rs) & (p2->val ^ p3->val)) >> 63)
_except(E_OVF, "Signed substraction underflow (SUBV#3)");
2019-07-17 20:26:03 +02:00
2019-08-14 20:23:05 +02:00
*r1 = rs;
2019-07-24 16:52:26 +02:00
return 1;
}
2019-07-17 20:26:03 +02:00
//----------------------------------------------------------------------------//
2019-08-08 18:39:12 +02:00
IMPL_START(mul, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val * p2->val; return 1; }
IMPL_START(mul, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; }
2019-07-24 16:52:26 +02:00
2019-08-08 18:39:12 +02:00
IMPL_START(rem, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val % p2->val; return 1; }
IMPL_START(rem, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; }
IMPL_START(div, 2) {
SRCP(p1); SRCP(p2);
if (!p2->val) _except(E_DIV, "DIV by 0");
*r1 = p1->val / p2->val;
return 1;
}
2019-08-03 17:41:44 +02:00
2019-08-08 18:39:12 +02:00
IMPL_START(div, 3) {
SRCP(p2); SRCP(p3);
if (!p3->val) _except(E_DIV, "DIV by 0");
2019-07-24 16:52:26 +02:00
*r1 = p2->val / p3->val;
return 1;
}
2019-08-08 18:39:12 +02:00
IMPL_START(idiv, 2) {
SRCP(p1); SRCP(p2);
if (!p3->val) _except(E_DIV, "IDIV by 0");
*r1 = (ulong)((long)p1->val/(long)p2->val);
return 1;
}
2019-08-03 17:41:44 +02:00
2019-08-08 18:39:12 +02:00
IMPL_START(idiv, 3) {
SRCP(p2); SRCP(p3);
2019-07-24 16:52:26 +02:00
2019-08-08 18:39:12 +02:00
if (!p3->val) _except(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-08-08 18:39:12 +02:00
IMPL_START(mulhi, 3)
2019-07-24 16:52:26 +02:00
{
2019-08-03 17:41:44 +02:00
SRCP(p2);
SRCP(p3);
2019-07-24 16:52:26 +02:00
__unsigned_multiply128(p2->val, p3->val, r1, r2);
return 2;
}
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-08-08 18:39:12 +02:00
IMPL_START(imulhi, 3)
2019-07-24 16:52:26 +02:00
{
2019-08-03 17:41:44 +02:00
SRCP(p2);
SRCP(p3);
2019-07-24 16:52:26 +02:00
__signed_multiply128(p2->val, p3->val, r1, r2);
return 2;
}
2019-07-17 20:26:03 +02:00
//----------------------------------------------------------------------------//