mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
227 lines
3.2 KiB
C
227 lines
3.2 KiB
C
// 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>
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
IMPL_START_2(sgn)
|
|
{
|
|
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_2(sgnf)
|
|
{
|
|
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
IMPL_START_1(neg)
|
|
{
|
|
v1 = ~v1 + 1;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_1(negf)
|
|
{
|
|
if (v1 == 0) flg |= CF;
|
|
|
|
else {
|
|
flg &= ~CF;
|
|
|
|
if (v1 == LONG_MIN) flg |= OF;
|
|
else flg &= ~OF;
|
|
}
|
|
|
|
v1 = ~v1 + 1;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
IMPL_START_1(inc)
|
|
{
|
|
v1++;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_1(incf)
|
|
{
|
|
if (v1 == LONG_MAX) flg |= OF;
|
|
else flg &= ~OF;
|
|
|
|
v1++;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
IMPL_START_1(dec)
|
|
{
|
|
v1--;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_1(decf)
|
|
{
|
|
if (v1 == LONG_MIN) flg |= OF;
|
|
else flg &= ~OF;
|
|
|
|
v1--;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
IMPL_START_2(add)
|
|
{
|
|
v1 += v2;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_2(addf)
|
|
{
|
|
if (v1 + v2 < v1) flg |= OF;
|
|
else flg &= ~OF;
|
|
|
|
if ( ((v2 > 0) && (v1 > LONG_MAX - v2))
|
|
|| ((v2 < 0) && (v1 < LONG_MIN - v2)) )
|
|
flg |= CF;
|
|
else flg &= ~CF;
|
|
|
|
v1 += v2;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
IMPL_START_2(sub)
|
|
{
|
|
v1 -= v2;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_2(subf)
|
|
{
|
|
if (v1 < v2) flg |= CF;
|
|
else flg &= ~CF;
|
|
|
|
if ( ((v2 < 0) && (v1 > LONG_MAX + v2))
|
|
|| ((v2 > 0) && (v1 < LONG_MIN + v2)) )
|
|
flg |= OF;
|
|
else flg &= ~OF;
|
|
|
|
v1 -= v2;
|
|
}
|
|
IMPL_OUT_ZSF;
|
|
|
|
//
|
|
// i_subf but discards result
|
|
//
|
|
IMPL_START_2(cmp)
|
|
{
|
|
if (v1 < v2) flg |= CF;
|
|
else flg &= ~CF;
|
|
|
|
if ( ((v2 < 0) && (v1 > LONG_MAX + v2))
|
|
|| ((v2 > 0) && (v1 < LONG_MIN + v2)) )
|
|
flg |= OF;
|
|
else flg &= ~OF;
|
|
|
|
SET_ZSF(v1 - v2);
|
|
}
|
|
IMPL_END;
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
|
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
|
//
|
|
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
|
{
|
|
ulong u1 = (u & 0xffffffff);
|
|
ulong v1 = (v & 0xffffffff);
|
|
ulong t = (u1 * v1);
|
|
ulong w3 = (t & 0xffffffff);
|
|
ulong k = (t >> 32);
|
|
|
|
u >>= 32;
|
|
t = (u * v1) + k;
|
|
k = (t & 0xffffffff);
|
|
ulong w1 = (t >> 32);
|
|
|
|
v >>= 32;
|
|
t = (u1 * v) + k;
|
|
k = (t >> 32);
|
|
|
|
*hi = (u * v) + w1 + k;
|
|
*lo = (t << 32) + w3;
|
|
}
|
|
|
|
IMPL_START_2(mul)
|
|
{
|
|
ulong hi;
|
|
multiply(v1, v2, &hi, &v1);
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_2(mulf)
|
|
{
|
|
ulong hi;
|
|
|
|
multiply(v1, v2, &hi, &v1);
|
|
|
|
if (hi > 0) {
|
|
flg |= CF;
|
|
flg |= OF;
|
|
}
|
|
|
|
else {
|
|
flg &= ~CF;
|
|
flg &= ~OF;
|
|
}
|
|
}
|
|
IMPL_OUT;
|
|
|
|
|
|
IMPL_START_1(mul2)
|
|
{
|
|
multiply(rax, v1, &rdx, &rax);
|
|
}
|
|
IMPL_END;
|
|
|
|
IMPL_START_1(mul2f)
|
|
{
|
|
multiply(rax, v1, &rdx, &rax);
|
|
|
|
if (rdx > 0) {
|
|
flg |= CF;
|
|
flg |= OF;
|
|
}
|
|
|
|
else {
|
|
flg &= ~CF;
|
|
flg &= ~OF;
|
|
}
|
|
}
|
|
IMPL_END;
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
IMPL_START_2(div)
|
|
{
|
|
v1 /= v2;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_2(mod)
|
|
{
|
|
v1 %= v2;
|
|
}
|
|
IMPL_OUT;
|
|
|
|
IMPL_START_1(div2)
|
|
{
|
|
rdx = rax % v1;
|
|
rax = rax / v1;
|
|
}
|
|
IMPL_END;
|
|
|