-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
exlib, feat: add loong64 context support.
- Loading branch information
Showing
8 changed files
with
433 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include <bits/types/sigset_t.h> | ||
#include <bits/types/stack_t.h> | ||
|
||
typedef struct { | ||
unsigned long long __pc; | ||
unsigned long long __gregs[32]; | ||
unsigned int __flags; | ||
unsigned long long __fpregs[8] __attribute__((__aligned__(16))); | ||
} ctx_mcontext_t; | ||
|
||
typedef struct ctx_ucontext { | ||
unsigned long uc_flags; | ||
struct ctx_ucontext* uc_link; | ||
stack_t uc_stack; | ||
ctx_mcontext_t uc_mcontext; | ||
} ctx_ucontext_t; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#ifndef __ARCH_LOONGARCH64_DEFS_H | ||
#define __ARCH_LOONGARCH64_DEFS_H | ||
|
||
#define REG_SZ (8) | ||
#define FP_REG_SZ (8) | ||
|
||
#define REG_R0 (0) | ||
#define REG_R1 (1) | ||
#define REG_R2 (2) | ||
#define REG_R3 (3) | ||
#define REG_R4 (4) | ||
#define REG_R5 (5) | ||
#define REG_R6 (6) | ||
#define REG_R7 (7) | ||
#define REG_R8 (8) | ||
#define REG_R9 (9) | ||
#define REG_R10 (10) | ||
#define REG_R11 (11) | ||
#define REG_R12 (12) | ||
#define REG_R13 (13) | ||
#define REG_R14 (14) | ||
#define REG_R15 (15) | ||
#define REG_R16 (16) | ||
#define REG_R17 (17) | ||
#define REG_R18 (18) | ||
#define REG_R19 (19) | ||
#define REG_R20 (20) | ||
#define REG_R21 (21) | ||
#define REG_R22 (22) | ||
#define REG_R23 (23) | ||
#define REG_R24 (24) | ||
#define REG_R25 (25) | ||
#define REG_R26 (26) | ||
#define REG_R27 (27) | ||
#define REG_R28 (28) | ||
#define REG_R29 (29) | ||
#define REG_R30 (30) | ||
#define REG_R31 (31) | ||
|
||
/* $a0 is $4 , also $v0, same as $5, $a1 and $v1*/ | ||
#define REG_A0 (4) | ||
|
||
/* stack pointer is actually $3 */ | ||
#define REG_SP (3) | ||
|
||
/* frame pointer is actually $22 */ | ||
#define REG_FP (22) | ||
|
||
/* offset to __gregs in ucontext_t */ | ||
#define MCONTEXT_GREGS (48) | ||
|
||
/* offset to __fpregs in ucontext_t */ | ||
#define MCONTEXT_FPREGS (312) | ||
|
||
/* offset to PC in ucontext_t */ | ||
#define MCONTEXT_PC (40) | ||
|
||
/* offset to uc_link in ucontext_t */ | ||
#define UCONTEXT_UC_LINK (8) | ||
|
||
/* offset to uc_stack.ss_sp in ucontext_t */ | ||
#define UCONTEXT_STACK_PTR (16) | ||
|
||
/* offset to uc_stack.ss_size in ucontext_t */ | ||
#define UCONTEXT_STACK_SIZE (32) | ||
|
||
/* offset to uc_sigmask in ucontext_t */ | ||
#define UCONTEXT_SIGMASK (40) | ||
|
||
/* Stack alignment, from Kernel source */ | ||
#define ALSZ 15 | ||
#define ALMASK ~15 | ||
#define FRAMESZ (((LOCALSZ * REG_SZ) + ALSZ) & ALMASK) | ||
|
||
#define PUSH_FRAME(__proc) \ | ||
addi.d $sp, $sp, -FRAMESZ; | ||
|
||
#define POP_FRAME(__proc) \ | ||
addi.d $sp, $sp, FRAMESZ; | ||
|
||
#define _NSIG8 (4) | ||
|
||
#define SIG_NOP 0 /* 0 is unused to catch errors */ | ||
#define SIG_BLOCK 1 /* Block signals. */ | ||
#define SIG_UNBLOCK 2 /* Unblock signals. */ | ||
#define SIG_SETMASK 3 /* Set the set of blocked signals. */ | ||
|
||
#define __NR_rt_sigprocmask 135 | ||
|
||
#define SYS_ify(syscall_name) __NR_##syscall_name | ||
|
||
#include <common-defs.h> | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#define LOCALSZ (1) | ||
|
||
#include "defs.h" | ||
|
||
ALIAS(getcontext, ctx_getcontext) | ||
|
||
FUNC(ctx_getcontext) | ||
/* copy $sp, $fp to temporary registers so we don't clobber them */ | ||
move $a2, $sp | ||
move $a3, $fp | ||
|
||
PUSH_FRAME(ctx_getcontext) | ||
|
||
/* set registers */ | ||
st.d $s0, $a0, REG_OFFSET(23) | ||
st.d $s1, $a0, REG_OFFSET(24) | ||
st.d $s2, $a0, REG_OFFSET(25) | ||
st.d $s3, $a0, REG_OFFSET(26) | ||
st.d $s4, $a0, REG_OFFSET(27) | ||
st.d $s5, $a0, REG_OFFSET(28) | ||
st.d $s6, $a0, REG_OFFSET(29) | ||
st.d $s7, $a0, REG_OFFSET(30) | ||
st.d $s8, $a0, REG_OFFSET(31) | ||
|
||
st.d $a2, $a0, REG_OFFSET(3) | ||
st.d $a3, $a0, REG_OFFSET(22) | ||
st.d $ra, $a0, REG_OFFSET(1) | ||
|
||
st.d $ra, $a0, (MCONTEXT_PC) | ||
|
||
fst.d $fs0, $a0, FP_REG_OFFSET(0) | ||
fst.d $fs1, $a0, FP_REG_OFFSET(1) | ||
fst.d $fs2, $a0, FP_REG_OFFSET(2) | ||
fst.d $fs3, $a0, FP_REG_OFFSET(3) | ||
fst.d $fs4, $a0, FP_REG_OFFSET(4) | ||
fst.d $fs5, $a0, FP_REG_OFFSET(5) | ||
fst.d $fs6, $a0, FP_REG_OFFSET(6) | ||
fst.d $fs7, $a0, FP_REG_OFFSET(7) | ||
|
||
POP_FRAME(ctx_getcontext) | ||
|
||
jr $ra | ||
END(ctx_getcontext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include "defs.h" | ||
|
||
#define LOCALSZ (6) | ||
|
||
#define A3_OFF (FRAMESZ - (5 * REG_SZ)) | ||
#define A4_OFF (FRAMESZ - (4 * REG_SZ)) | ||
#define A5_OFF (FRAMESZ - (3 * REG_SZ)) | ||
#define A6_OFF (FRAMESZ - (2 * REG_SZ)) | ||
#define A7_OFF (FRAMESZ - (1 * REG_SZ)) | ||
|
||
ALIAS(makecontext, ctx_makecontext) | ||
|
||
FUNC(ctx_makecontext) | ||
PUSH_FRAME(ctx_makecontext) | ||
|
||
move $t5, $a0 | ||
move $t4, $a1 | ||
|
||
/* store $a3 through $a7 to the stack frame. */ | ||
st.d $a3, $sp, A3_OFF | ||
st.d $a4, $sp, A4_OFF | ||
st.d $a5, $sp, A5_OFF | ||
st.d $a6, $sp, A6_OFF | ||
st.d $a7, $sp, A7_OFF | ||
|
||
/* set $zero in the mcontext to 1. */ | ||
addi.d $v0, $zero, 1 | ||
st.d $v0, $t5, REG_OFFSET(0) | ||
|
||
/* ensure the stack is aligned on a quad-word boundary. */ | ||
ld.d $t0, $t5, UCONTEXT_STACK_PTR | ||
ld.d $t2, $t5, UCONTEXT_STACK_SIZE | ||
/* the third argument(from zero), that's the first argument of func() */ | ||
addi.d $t1, $sp, A3_OFF | ||
add.d $t0, $t0, $t2 | ||
|
||
addi.d $t7, $zero, ALMASK | ||
and $t0, $t0, $t7 | ||
|
||
/* number of args */ | ||
beq $a2, $zero, no_more_arguments | ||
bltu $a2, $zero, no_more_arguments | ||
|
||
/* store register arguments. */ | ||
addi.d $t2, $t5, MCONTEXT_GREGS + (4 * REG_SZ) | ||
move $t3, $zero | ||
|
||
store_register_arg: | ||
addi.d $t3, $t3, 1 | ||
ld.d $v1, $t1, 0 | ||
addi.d $t1, $t1, REG_SZ | ||
st.d $v1, $t2, 0 | ||
addi.d $t2, $t2, REG_SZ | ||
addi.d $t6, $zero, 8 | ||
bltu $t3, $t6, store_register_arg | ||
bgeu $t3, $a2, no_more_arguments | ||
|
||
/* make room for stack arguments. */ | ||
sub.d $t2, $a2, $t3 | ||
|
||
addi.d $t6, $zero, 3 | ||
sll.d $t2, $t2, $t6 | ||
|
||
sub.d $t0, $t0, $t2 | ||
|
||
addi.d $t6, $zero, ALMASK | ||
and $t0, $t0, $t6 | ||
|
||
/* store stack arguments. */ | ||
move $t2, $t0 | ||
|
||
store_stack_arg: | ||
addi.d $t3, $t3, 1 | ||
ld.d $v1, $t1, 0 | ||
addi.d $t1, $t1, REG_SZ | ||
st.d $v1, $t2, 0 | ||
addi.d $t2, $t2, REG_SZ | ||
bltu $t3, $a2, store_stack_arg | ||
|
||
no_more_arguments: | ||
/* trampoline setup. */ | ||
la.got $t8, ctx_trampoline | ||
|
||
ld.d $v1, $t5, UCONTEXT_UC_LINK | ||
st.d $v1, $t5, REG_OFFSET(23) | ||
|
||
st.d $t0, $t5, REG_OFFSET(3) | ||
|
||
st.d $t8, $t5, REG_OFFSET(1) | ||
|
||
st.d $t4, $t5, MCONTEXT_PC | ||
|
||
POP_FRAME(ctx_makecontext) | ||
|
||
jr $ra | ||
END(ctx_makecontext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#define LOCALSZ (1) | ||
|
||
#include "defs.h" | ||
|
||
ALIAS(setcontext, ctx_setcontext) | ||
|
||
FUNC(ctx_setcontext) | ||
PUSH_FRAME(ctx_setcontext) | ||
|
||
/* move the context to $v0, in LA, $v0 = $a0 = $4 */ | ||
move $t5, $a0 | ||
|
||
fld.d $fs0, $t5, FP_REG_OFFSET(24) | ||
fld.d $fs1, $t5, FP_REG_OFFSET(25) | ||
fld.d $fs2, $t5, FP_REG_OFFSET(26) | ||
fld.d $fs3, $t5, FP_REG_OFFSET(27) | ||
fld.d $fs4, $t5, FP_REG_OFFSET(28) | ||
fld.d $fs5, $t5, FP_REG_OFFSET(29) | ||
fld.d $fs6, $t5, FP_REG_OFFSET(30) | ||
fld.d $fs7, $t5, FP_REG_OFFSET(31) | ||
|
||
/* load the registers */ | ||
ld.d $a0, $t5, REG_OFFSET(4) | ||
ld.d $a1, $t5, REG_OFFSET(5) | ||
ld.d $a2, $t5, REG_OFFSET(6) | ||
ld.d $a3, $t5, REG_OFFSET(7) | ||
ld.d $a4, $t5, REG_OFFSET(8) | ||
ld.d $a5, $t5, REG_OFFSET(9) | ||
ld.d $a6, $t5, REG_OFFSET(10) | ||
ld.d $a7, $t5, REG_OFFSET(11) | ||
|
||
ld.d $s0, $t5, REG_OFFSET(23) | ||
ld.d $s1, $t5, REG_OFFSET(24) | ||
ld.d $s2, $t5, REG_OFFSET(25) | ||
ld.d $s3, $t5, REG_OFFSET(26) | ||
ld.d $s4, $t5, REG_OFFSET(27) | ||
ld.d $s5, $t5, REG_OFFSET(28) | ||
ld.d $s6, $t5, REG_OFFSET(29) | ||
ld.d $s7, $t5, REG_OFFSET(30) | ||
ld.d $s8, $t5, REG_OFFSET(31) | ||
|
||
ld.d $sp, $t5, REG_OFFSET(3) | ||
ld.d $fp, $t5, REG_OFFSET(22) | ||
ld.d $ra, $t5, REG_OFFSET(1) | ||
|
||
ld.d $t8, $t5, (MCONTEXT_PC) | ||
|
||
jr $t8 | ||
move $v0, $zero | ||
|
||
POP_FRAME(ctx_setcontext) | ||
END(ctx_setcontext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#define LOCALSZ (4) | ||
|
||
#include "defs.h" | ||
|
||
FUNC(ctx_trampoline) | ||
|
||
/* call setcontext */ | ||
move $a0, $s0 | ||
/* we receive our initial ucontext in $s0, so if $s0 is nil, bail */ | ||
beqz $s0, no_linked_context | ||
|
||
la.got $t8, ctx_setcontext | ||
|
||
jr $t8 | ||
|
||
no_linked_context: | ||
move $a0, $zero | ||
la.global $t8, exit | ||
jr $t8 | ||
|
||
END(ctx_trampoline) |
Oops, something went wrong.