mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
112 lines
3.6 KiB
C
112 lines
3.6 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>
|
|
|
|
#define _NEED_ARCH_I
|
|
#include <in/arch_i.h>
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_2(not) { v1 = ~v2; } IMPL_OUT;
|
|
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;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_3(orn) { v1 = v2 | ~v3; } IMPL_OUT;
|
|
IMPL_START_3(nor) { v1 = ~(v2 | v3); } IMPL_OUT;
|
|
IMPL_START_3(andn) { v1 = v2 & ~v3; } IMPL_OUT;
|
|
IMPL_START_3(nand) { v1 = ~(v2 & v3); } IMPL_OUT;
|
|
IMPL_START_3(xorn) { v1 = v2 ^ ~v3; } IMPL_OUT;
|
|
IMPL_START_3(xnor) { v1 = ~(v2 ^ v3); } IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
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;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_2(sgn) { v1 = (!v2 ? 0: ((long)v2 < 0 ? (ulong)-1L : 1)); } IMPL_OUT;
|
|
IMPL_START_2(neg) { v1 = ~v2 + 1; } IMPL_OUT;
|
|
IMPL_START_1(inc) { v1++; } IMPL_OUT;
|
|
IMPL_START_1(dec) { v1--; } IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_3(add) { v1 = v2 + v3; } IMPL_OUT;
|
|
IMPL_START_3(addf) { COMPARE(v2, ~v3+1); v1 = v2 + v3; } IMPL_OUT;
|
|
IMPL_START_3(addo) { COMPARE(v2, ~v3+1); v1 = v2 + v3; INTO(); } IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_2(cmp) { COMPARE(v1, v2); } IMPL_END;
|
|
IMPL_START_3(sub) { v1 = v2 - v3; } IMPL_OUT;
|
|
IMPL_START_3(subf){ COMPARE(v2, v3); v1 = v2 - v3; } IMPL_OUT;
|
|
IMPL_START_3(subo){ COMPARE(v2, v3); v1 = v2 - v3; INTO(); } IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
IMPL_START_3(adcx) { v1 = v2 + v3 + !!(R(RFX)&CF); } IMPL_OUT;
|
|
IMPL_START_3(adox) { v1 = v2 + v3 + !!(R(RFX)&OF); } IMPL_OUT;
|
|
IMPL_START_3(sbbx) { v1 = v2 - v3 - !!(R(RFX)&CF); } IMPL_OUT;
|
|
IMPL_START_3(sbox) { v1 = v2 - v3 - !!(R(RFX)&OF); } IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
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;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
//
|
|
// 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);
|
|
|
|
if (hi) *hi = (u * v) + w1 + k;
|
|
if (lo) *lo = (t << 32) + w3;
|
|
}
|
|
|
|
IMPL_START_3(mul) { v1 = v2 * v3; } IMPL_OUT;
|
|
IMPL_START_3(mulhi) { multiply(v2, v3, &v1, &v2); } IMPL_OUT_2;
|
|
|
|
IMPL_START_3(mulf) {
|
|
ulong tmp;
|
|
multiply(v2, v3, &tmp, &v1);
|
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
|
} IMPL_OUT;
|
|
|
|
IMPL_START_3(mulo) {
|
|
ulong tmp;
|
|
multiply(v2, v3, &tmp, &v1);
|
|
R(RFX) = v2 ? (R(RFX)|CF|OF) : R(RFX)&~(CF|OF);
|
|
INTO();
|
|
} IMPL_OUT;
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|