merge pr #7 (take 2)

git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@540 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
IoIxD
2025-11-01 03:37:40 +00:00
parent 141ac076e3
commit 3719f17250
10 changed files with 1053 additions and 0 deletions

125
src/math/math.c Normal file
View File

@@ -0,0 +1,125 @@
#include <Mw/LowLevelMath.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include "math.h"
#include "Mw/BaseTypes.h"
#include "x86intrin.h"
MwLLVec _MwLLVecCreateGeneric(MwLLVecType ty, ...) {
MwLLVecUnion un;
MwLLVec vec;
va_list va;
va_start(va, ty);
// clang-format off
#define _A_B(ty) un.ty.a = va_arg(va, int); un.ty.b = va_arg(va, int);
#define _C_D(ty) un.ty.c = va_arg(va, int); un.ty.d = va_arg(va, int);
#define _E_F(ty) un.ty.e = va_arg(va, int); un.ty.f = va_arg(va, int);
#define _G_H(ty) un.ty.g = va_arg(va, int); un.ty.h = va_arg(va, int);
switch(ty) {
case _MwLLVecTypeU8x8: _A_B(u8); _C_D(u8); _E_F(u8); _G_H(u8); break;
case _MwLLVecTypeU16x4: _A_B(u16); _C_D(u16); break;
case _MwLLVecTypeU32x2: _A_B(u32); break;
case _MwLLVecTypeI8x8: _A_B(i8); _C_D(i8); _E_F(i8); _G_H(i8); break;
case _MwLLVecTypeI16x4: _A_B(i16); _C_D(i16); break;
case _MwLLVecTypeI32x2: _A_B(i32); break;
case _MwLLVecType_Max: break;
}
#undef _A_B
#undef _C_D
#undef _E_F
#undef _G_H
// clang-format on
va_end(va);
vec.ty = ty;
vec.un = un;
return vec;
}
static MwBool hasMMX(void) {
MwU32 eax = 1;
MwU32 ebx, edx;
__asm__ __volatile__(
"cpuid" : "=a"(eax), "=b"(ebx), "=d"(edx)
: "a"(1));
return (edx & (1 << 23)) == (1 << 23);
}
static MwLLMathVTable** mwLLMultiTable;
static MwLLMathVTable* multiTableSetupAndGet(MwLLVecType ty);
static MwLLMathVTable* multiTableGet(MwLLVecType ty);
static MwLLMathVTable* (*mwLLmathFunc)(MwLLVecType ty) = multiTableSetupAndGet;
static MwLLMathVTable* getMultiTable(MwLLVecType ty) {
return mwLLmathFunc(ty);
}
static MwLLMathVTable* multiTableSetupAndGet(MwLLVecType ty) {
mwLLMultiTable = default_multi_table();
#if defined(__i386__) || defined(__x86_64__)
if(hasMMX()) {
mmx_apply(mwLLMultiTable);
}
#endif
mwLLmathFunc = multiTableGet;
return mwLLMultiTable[ty];
}
static MwLLMathVTable* multiTableGet(MwLLVecType ty) {
return mwLLMultiTable[ty];
}
void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->Add(a, b, out);
};
void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->Sub(a, b, out);
};
void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->Multiply(a, b, out);
};
void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out) {
assert(a->ty == out->ty);
return getMultiTable(a->ty)->Reciprocal(a, out);
};
void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) {
assert(a->ty == out->ty);
return getMultiTable(a->ty)->SquareRoot(a, out);
};
void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->ShiftRight(a, b, out);
};
void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->ShiftLeft(a, b, out);
};
void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->Equal(a, b, out);
};
void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty);
return getMultiTable(a->ty)->GreaterThen(a, b, out);
};
void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
out->un.all = a->un.all & b->un.all;
};
void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out) {
out->un.all = a->un.all | b->un.all;
};