Skip to content

Commit

Permalink
For #24: Support Loongson CPU arch
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Oct 23, 2021
1 parent 4bca722 commit db42969
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 3 deletions.
5 changes: 5 additions & 0 deletions md.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jb[0]))

#elif defined(__loongarch__)
/* https://github.com/ossrs/state-threads/issues/24 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))

#else
#error "Unknown CPU architecture"
#endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
Expand Down
82 changes: 82 additions & 0 deletions md_linux.S
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,88 @@

/****************************************************************/










#elif defined(__loongarch__)

/****************************************************************/

/*
* Internal __jmp_buf layout
*/
#define JB_SP 0 /* R3, SP, Stack pointer */
#define JB_RA 1 /* R1, RA, Return address */
#define JB_FP 2 /* FP/R22 Frame pointer */
#define JB_S0 3 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S1 4 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S2 5 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S3 6 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S4 7 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S5 8 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S6 9 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S7 10 /* R23-R31, S0-S8, Subroutine register variable */
#define JB_S8 11 /* R23-R31, S0-S8, Subroutine register variable */

.file "md_linux.S"
.text

/* _st_md_cxt_save(__jmp_buf env) */ /* The env is $r4, https://github.com/ossrs/state-threads/issues/24#porting */
.globl _st_md_cxt_save
.type _st_md_cxt_save, %function
.align 2
_st_md_cxt_save:
st.d $r3, $r4, 0 /* Save sp to env[0], *(long*)($r4+0) = sp */
st.d $r1, $r4, 8 /* Save ra to env[1], *(long*)($r4+8) = r1 */
st.d $r22, $r4, 16 /* Save fp to env[2], *(long*)($r4+16) = r22 */
st.d $r23, $r4, 24 /* Save fp to env[3], *(long*)($r4+24) = r23 */
st.d $r24, $r4, 32 /* Save fp to env[4], *(long*)($r4+32) = r24 */
st.d $r25, $r4, 40 /* Save fp to env[5], *(long*)($r4+40) = r25 */
st.d $r26, $r4, 48 /* Save fp to env[6], *(long*)($r4+48) = r26 */
st.d $r27, $r4, 56 /* Save fp to env[7], *(long*)($r4+56) = r27 */
st.d $r28, $r4, 64 /* Save fp to env[8], *(long*)($r4+64) = r28 */
st.d $r29, $r4, 72 /* Save fp to env[9], *(long*)($r4+72) = r29 */
st.d $r30, $r4, 80 /* Save fp to env[10], *(long*)($r4+80) = r30 */
st.d $r31, $r4, 88 /* Save fp to env[11], *(long*)($r4+88) = r31 */
addi.w $r12, $r0, 0 /* Set return value to 0 */
move $r4, $r12 /* Set return value to 0 */
jirl $r0, $r1, 0 /* Return */

.size _st_md_cxt_save, .-_st_md_cxt_save

/****************************************************************/

/* _st_md_cxt_restore(__jmp_buf env, int val) */
.globl _st_md_cxt_restore
.type _st_md_cxt_restore, %function
.align 2
_st_md_cxt_restore:
ld.d $r3, $r4, 0 /* Load sp from env[0], sp=*(long*)($r4+0) */
ld.d $r1, $r4, 8 /* Load ra from env[1], r1=*(long*)($r4+8) */
ld.d $r22, $r4, 16 /* Load ra from env[2], r22=*(long*)($r4+16) */
ld.d $r23, $r4, 24 /* Load ra from env[3], r23=*(long*)($r4+24) */
ld.d $r24, $r4, 32 /* Load ra from env[4], r24=*(long*)($r4+32) */
ld.d $r25, $r4, 40 /* Load ra from env[5], r25=*(long*)($r4+40) */
ld.d $r26, $r4, 48 /* Load ra from env[6], r26=*(long*)($r4+48) */
ld.d $r27, $r4, 56 /* Load ra from env[7], r27=*(long*)($r4+56) */
ld.d $r28, $r4, 64 /* Load ra from env[8], r28=*(long*)($r4+64) */
ld.d $r29, $r4, 72 /* Load ra from env[9], r29=*(long*)($r4+72) */
ld.d $r30, $r4, 80 /* Load ra from env[10], r30=*(long*)($r4+80) */
ld.d $r31, $r4, 88 /* Load ra from env[11], r31=*(long*)($r4+88) */
addi.w $r12, $r0, 1 /* Set return value to 1 */
move $r4, $r12 /* Set return value to 1 */
jirl $r0, $r1, 0 /* Return to the saved return address */

.size _st_md_cxt_restore, .-_st_md_cxt_restore

/****************************************************************/

#endif

#endif
57 changes: 54 additions & 3 deletions tools/porting/porting.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

int foo_return_zero();
int foo_return_one();
int foo_return_one_arg1(int r0);
extern void print_buf(unsigned char* p, int nn_jb);
extern void print_jmpbuf();

Expand All @@ -22,11 +23,14 @@ int main(int argc, char** argv)
printf("\nCPU specs:\n");
#ifdef __mips__
// https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf
printf("__mips__: %d, __mips:%d, _MIPSEL:%d\n", __mips__, __mips, _MIPSEL);
printf("__mips__: %d, __mips: %d, _MIPSEL: %d\n", __mips__, __mips, _MIPSEL);
#endif
#ifdef __x86_64__
printf("__x86_64__: %d\n", __x86_64__);
#endif
#ifdef __loongarch__
printf("__loongarch__: %d, __loongarch64 :%d\n", __loongarch__, __loongarch64);
#endif

printf("\nCompiler specs:\n");
#ifdef __GLIBC__
Expand All @@ -36,13 +40,14 @@ int main(int argc, char** argv)
printf("sizeof(long long int)=%d\n", (int)sizeof(long long int));
printf("sizeof(void*)=%d\n", (int)sizeof(void*));
#ifdef __ptr_t
printf("sizeof(__ptr_t)=%d\n", sizeof(__ptr_t));
printf("sizeof(__ptr_t)=%d\n", (int)sizeof(__ptr_t));
#endif

printf("\nReturn value:\n");
int r0 = foo_return_zero();
int r1 = foo_return_one();
printf("foo_return_zero=%d, foo_return_one=%d\n", r0, r1);
int r2 = foo_return_one_arg1(r1);
printf("foo_return_zero=%d, foo_return_one=%d, foo_return_one_arg1=%d\n", r0, r1, r2);

printf("\nCalling conventions:\n");
print_jmpbuf();
Expand All @@ -60,6 +65,11 @@ int foo_return_one()
return 1;
}

int foo_return_one_arg1(int r0)
{
return r0 + 2;
}

#ifdef __linux__
#ifdef __mips__
void print_jmpbuf()
Expand Down Expand Up @@ -102,6 +112,47 @@ void print_jmpbuf()
unsigned char* p = (unsigned char*)ctx[0].__jb;
print_buf(p, nn_jb);
}
#elif __loongarch__
void print_jmpbuf()
{
// https://github.com/ossrs/state-threads/issues/24#porting
register void* ra asm("r1"); // r1, ra, Return address
register void* sp asm("r3"); // r3, sp, Stack pointer
register void* fp asm("r22"); // r22, fp, Frame pointer
// r23-r31, s0-s8, Subroutine register variable
register void* s0 asm("r23");
register void* s1 asm("r24");
register void* s2 asm("r25");
register void* s3 asm("r26");
register void* s4 asm("r27");
register void* s5 asm("r28");
register void* s6 asm("r29");
register void* s7 asm("r30");
register void* s8 asm("r31");

/*
struct __jmp_buf_tag {
__jmp_buf __jmpbuf;
int __mask_was_saved;
__sigset_t __saved_mask;
};
typedef struct __jmp_buf_tag jmp_buf[1];
*/
jmp_buf ctx = {0};
int r0 = setjmp(ctx);
if (!r0) {
longjmp(ctx, 1);
}

printf("ra=%p, sp=%p, fp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, s7=%p\n",
ra, sp, fp, s0, s1, s2, s3, s4, s5, s6, s7, s8);

int nn_jb = sizeof(ctx[0].__jmpbuf);
printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8);

unsigned char* p = (unsigned char*)ctx[0].__jmpbuf;
print_buf(p, nn_jb);
}
#endif
#endif

Expand Down
31 changes: 31 additions & 0 deletions tools/verify/verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,37 @@ void verify_jmpbuf()
unsigned char* p = (unsigned char*)ctx[0].__jb;
print_buf(p, nn_jb);
}
#elif __loongarch__
void verify_jmpbuf()
{
// https://github.com/ossrs/state-threads/issues/24#porting
register void* ra asm("r1"); // r1, ra, Return address
register void* sp asm("r3"); // r3, sp, Stack pointer
register void* fp asm("r22"); // r22, fp, Frame pointer
// r23-r31, s0-s8, Subroutine register variable
register void* s0 asm("r23");
register void* s1 asm("r24");
register void* s2 asm("r25");
register void* s3 asm("r26");
register void* s4 asm("r27");
register void* s5 asm("r28");
register void* s6 asm("r29");
register void* s7 asm("r30");
register void* s8 asm("r31");

jmp_buf ctx = {0};
int r0 = _st_md_cxt_save(ctx);
if (!r0) {
_st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1.
}

printf("sp=%p, ra=%p, fp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, s7=%p\n",
sp, ra, fp, s0, s1, s2, s3, s4, s5, s6, s7, s8);

int nn_jb = sizeof(ctx[0].__jmpbuf);
unsigned char* p = (unsigned char*)ctx[0].__jmpbuf;
print_buf(p, nn_jb);
}
#endif
#endif

Expand Down

0 comments on commit db42969

Please sign in to comment.