Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 10 additions & 20 deletions src/ldo.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,14 @@
*/

#ifdef LUA_TARGET_PSX
#include "lpsxbios.h"
struct JmpBuf { void * regs[12]; };
static inline int syscall_setjmp(struct JmpBuf *buf) {
register int n asm("t1") = 0x13;
__asm__ volatile("" : "=r"(n) : "r"(n));
return ((int (*)(struct JmpBuf * buf))0xa0)(buf);
}

static inline __attribute__((noreturn)) void syscall_longjmp(struct JmpBuf *buf, int ret) {
register int n asm("t1") = 0x14;
__asm__ volatile("" : "=r"(n) : "r"(n));
((void (*)(struct JmpBuf *, int))0xa0)(buf, ret);
__builtin_unreachable();
}
#define LUAI_THROW(L,c) syscall_longjmp(&(c)->b, 1)
#define LUAI_TRY(L,c,a) if (syscall_setjmp(&(c)->b) == 0) { a }
LUAI_PSX_BIOS_THUNK(setjmp, 0xa0, 0x13)
LUAI_PSX_BIOS_EXTERN int __psxlua_bios_setjmp(struct JmpBuf *buf) __attribute__((returns_twice));
LUAI_PSX_BIOS_THUNK(longjmp, 0xa0, 0x14)
LUAI_PSX_BIOS_EXTERN void __psxlua_bios_longjmp(struct JmpBuf *buf, int ret) __attribute__((noreturn));
#define LUAI_THROW(L,c) __psxlua_bios_longjmp(&(c)->b, 1)
#define LUAI_TRY(L,c,a) if (__psxlua_bios_setjmp(&(c)->b) == 0) { a }
#define luai_jmpbuf struct JmpBuf
#else
#include <setjmp.h>
Expand Down Expand Up @@ -99,12 +92,9 @@ static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {


#ifdef LUA_TARGET_PSX
static inline void abort() {
register int n asm("t1") = 0x40;
__asm__ volatile("" : "=r"(n) : "r"(n));
((void (*)())0xa0)();
__builtin_unreachable();
}
LUAI_PSX_BIOS_THUNK(abort, 0xa0, 0x40)
LUAI_PSX_BIOS_EXTERN void __psxlua_bios_abort(void) __attribute__((noreturn));
#define abort() __psxlua_bios_abort()
#else
#include <stdlib.h>
#endif
Expand Down
33 changes: 33 additions & 0 deletions src/lpsxbios.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
** BIOS calls for the PlayStation target.
** Each call goes through a two-instruction thunk, `j 0xa0` with t1 set in its
** delay slot, emitted in every file that includes this header as a weak symbol
** in its own COMDAT section, so the linker keeps one copy of each. To the
** compiler the thunk is a plain function: t1 cannot be reused before the jump,
** and the BIOS returns straight to the caller.
*/

#ifndef lpsxbios_h
#define lpsxbios_h

#include <stddef.h>

#define LUAI_PSX_BIOS_THUNK(name, table, number) \
__asm__(".pushsection .text.__psxlua_bios_" #name ",\"axG\",@progbits,__psxlua_bios_" #name ",comdat\n" \
".weak __psxlua_bios_" #name "\n" \
".type __psxlua_bios_" #name ", @function\n" \
".set push\n.set noreorder\n" \
"__psxlua_bios_" #name ":\n" \
" j " #table "\n" \
" li $t1, " #number "\n" \
".set pop\n" \
".size __psxlua_bios_" #name ", . - __psxlua_bios_" #name "\n" \
".popsection\n");

#ifdef __cplusplus
#define LUAI_PSX_BIOS_EXTERN extern "C"
#else
#define LUAI_PSX_BIOS_EXTERN extern
#endif

#endif
19 changes: 7 additions & 12 deletions src/luaconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,13 @@
*/
#if defined(LUA_LIB) || defined(lua_c)
#ifdef LUA_TARGET_PSX
static inline void syscall_write(int fd, const void * buf, size_t count) {
register int n asm("t1") = 0x03;
__asm__ volatile("" : "=r"(n) : "r"(n));
((void (*)(int, const void *, size_t))0xa0)(fd, buf, count);
}
static inline void syscall_putchar(int c) {
register int n asm("t1") = 0x3c;
__asm__ volatile("" : "=r"(n) : "r"(n));
((void (*)(int))0xa0)(c);
}
#define luai_writestring(s,l) syscall_write(1, (s), (l))
#define luai_writeline() syscall_putchar('\n')
#include "lpsxbios.h"
LUAI_PSX_BIOS_THUNK(write, 0xa0, 0x03)
LUAI_PSX_BIOS_EXTERN size_t __psxlua_bios_write(int fd, const void * buf, size_t count);
LUAI_PSX_BIOS_THUNK(putchar, 0xa0, 0x3c)
LUAI_PSX_BIOS_EXTERN void __psxlua_bios_putchar(int c);
#define luai_writestring(s,l) __psxlua_bios_write(1, (s), (l))
#define luai_writeline() __psxlua_bios_putchar('\n')
#else
#include <stdio.h>
#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
Expand Down
Loading