mujs/System/FFI/LibC.HC

373 lines
5.4 KiB
HolyC

asm {
_SETJMP::
MOV [RDI], RBX // Store caller saved registers
MOV [RDI+8], RBP // ^
MOV [RDI+16], R12 // ^
MOV [RDI+24], R13 // ^
MOV [RDI+32], R14 // ^
MOV [RDI+40], R15 // ^
LEA RDX, [RSP+8] // go one value up (as if setjmp wasn't called)
MOV [RDI+48], RDX // Store the new rsp pointer in env[7]
MOV RDX, [RSP] // go one value up (as if setjmp wasn't called)
MOV [RDI+56], RDX // Store the address we will resume at in env[8]
XOR EAX, EAX // Always return 0
RET
_LONGJMP::
XOR EAX, EAX
CMP ESI, 1
ADC EAX, ESI
MOV RBX, [RDI]
MOV RBP, [RDI + 8]
MOV R12, [RDI + 16]
MOV R13, [RDI + 24]
MOV R14, [RDI + 32]
MOV R15, [RDI + 40]
MOV RSP, [RDI + 48]
JMP U64 [RDI + 56]
}
_extern _SETJMP U64 _setjmp(U64 jmp_buf);
_extern _LONGJMP U64 longjmp(U64 jmp_buf, U64 ret);
U0 free()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
Free(p0);
POP_SYSV_REGS
}
U0 putchar()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
PutChars(p0);
POP_SYSV_REGS
}
U64 @localtime(U64 p0)
{
// FIXME: implement this?
no_warn p0;
return 0;
}
U0 localtime()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@localtime(p0);
POP_SYSV_REGS
}
I64 @strncmp(U8* s1, U8* s2, I32 n)
{
U64 u1, u2;
while (n-- > 0) {
u1 = *s1++;
u2 = *s2++;
u1 = u1 & 0xff;
u2 = u2 & 0xff;
if (u1 != u2)
return u1 - u2;
if (u1 == '\0')
return 0;
}
return 0;
}
U0 strncmp()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@strncmp(p0, p1, p2);
POP_SYSV_REGS
}
U0 strcpy()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
StrCpy(p0, p1);
POP_SYSV_REGS
}
U0 fprintf()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
Print(p1, p2, p3, p4, p5);
POP_SYSV_REGS
}
U0 printf()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
Print(p0, p1, p2, p3, p4, p5);
POP_SYSV_REGS
}
U0 puts()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
PutS(p0);
"\n";
POP_SYSV_REGS
}
U0 fputs()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
PutS(p0);
POP_SYSV_REGS
}
U0 fputc()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
PutChars(p0);
POP_SYSV_REGS
}
U64 @fwrite(U8* buffer, I64 size, I64 count, U64 stream)
{
if (!buffer || !size || !count || !stream)
return NULL;
I64 bytes = size * count;
switch (stream) {
case 1...2:
U8* s = CAlloc(bytes + 1);
MemCpy(s, buffer, bytes);
"%s", s;
Free(s);
break;
default:
break;
}
return bytes;
}
U0 fwrite()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@fwrite(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 strerror()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
"strerror: %d\n", p0;
PressAKey;
POP_SYSV_REGS
}
U0 strlen()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
StrLen(p0);
POP_SYSV_REGS
}
U8 *@strchr(U8 *str, I64 chr) {
while (*str) {
if (*str == chr) {
return str;
}
str++;
}
return NULL;
}
U0 strchr()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@strchr(p0, p1);
POP_SYSV_REGS
}
U8* @strrchr(U8 *str, I64 chr) {
U8* str2 = str + (StrLen(str) - 1);
while (str2 > str - 1) {
if (*str2 == chr) {
return str2;
}
str2--;
}
return NULL;
}
U0 strrchr()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@strrchr(p0, p1);
POP_SYSV_REGS
}
U0 strcmp()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
//"strcmp: '%s', '%s'\n", p0, p1;
StrCmp(p0, p1);
POP_SYSV_REGS
}
U0 memcpy()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
MemCpy(p0, p1, p2);
POP_SYSV_REGS
}
U0 memset()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
MemSet(p0, p1, p2);
POP_SYSV_REGS
}
U0 malloc()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
MAlloc(p0);
POP_SYSV_REGS
}
U8* @realloc(U8* ptr, I64 size)
{
U8* new;
if (!ptr) {
new = MAlloc(size);
} else {
new = MAlloc(size);
MemCpy(new, ptr, size);
Free(ptr);
}
return new;
}
U0 realloc()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@realloc(p0, p1);
POP_SYSV_REGS
}
#define MY_TIME_OFFSET 9488
public
I64 CDate2Unix(CDate dt)
{ // TempleOS datetime to Unix timestamp.
return ToI64((dt - Str2Date("1/1/1970")) / CDATE_FREQ) - MY_TIME_OFFSET;
}
I64 @time(I64* ptr)
{
no_warn ptr;
return CDate2Unix(Now);
}
U0 time()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@time(p0);
POP_SYSV_REGS
}
U64 @gettimeofday(U64* tv)
{
if (!tv)
return 0;
U64 seconds = CDate2Unix(Now);
tv[0] = seconds;
tv[1] = NULL;
return 0;
}
U0 gettimeofday()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@gettimeofday(p0);
POP_SYSV_REGS
}
U0 @fgets(U8* p0, I64 p1)
{
GetS(p0, p1);
while (*p0) {
if (*p0 == 0x1f)
*p0 = 0x20;
++p0;
}
Print("");
}
U0 fgets()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@fgets(p0, p1);
POP_SYSV_REGS
}
U64 @ferror()
{
return 0;
}
U0 ferror()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@ferror;
POP_SYSV_REGS
}
U64 @strcat(U8* dst, U8* src)
{
StrCpy(dst + StrLen(dst), src);
return 0;
}
U0 strcat()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
@strcat(p0, p1);
POP_SYSV_REGS
}
U0 strstr()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
StrFind(p1, p0);
POP_SYSV_REGS
}
U0 sprintf()
{
PUSH_SYSV_REGS
GET_SYSV_ARGS
StrPrint(p0, p1, p2, p3, p4, p5);
POP_SYSV_REGS
}