mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			201 lines
		
	
	
		
			No EOL
		
	
	
		
			7.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			No EOL
		
	
	
		
			7.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* SPDX-License-Identifier: MIT */
 | 
						||
/* Copyright (c) 2021-2022 The SRS Authors */
 | 
						||
 | 
						||
/* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */
 | 
						||
#if !defined(MD_ST_NO_ASM)
 | 
						||
 | 
						||
#if defined(__amd64__) || defined(__x86_64__)
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
 | 
						||
    /*
 | 
						||
     * Internal __jmp_buf layout
 | 
						||
     */
 | 
						||
    #define JB_RBX  0
 | 
						||
    #define JB_RBP  1
 | 
						||
    #define JB_R12  2                   /* The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9. */
 | 
						||
    #define JB_R13  3                   /* If the callee wishes to use registers RBX, RSP, RBP, and R12–R15, it must restore their original values before returning control to the caller. */
 | 
						||
    #define JB_R14  4                   /* @see https://en.wikipedia.org/wiki/X86_calling_conventions */
 | 
						||
    #define JB_R15  5                   /* @see https://www.cnblogs.com/Five100Miles/p/8458561.html */
 | 
						||
    #define JB_RSP  6
 | 
						||
    #define JB_PC   7
 | 
						||
 | 
						||
    .file "md_darwin.S"
 | 
						||
    .text
 | 
						||
 | 
						||
    /* _st_md_cxt_save(__jmp_buf env) */ /* The env is rdi, https://en.wikipedia.org/wiki/X86_calling_conventions */
 | 
						||
    .globl __st_md_cxt_save
 | 
						||
        .align 16
 | 
						||
    __st_md_cxt_save:
 | 
						||
        /*
 | 
						||
         * Save registers.
 | 
						||
         */
 | 
						||
        movq %rbx, (JB_RBX*8)(%rdi)     /* Save rbx to env[0], *(int64_t*)(rdi+0)=rbx */
 | 
						||
        movq %rbp, (JB_RBP*8)(%rdi)     /* Save rbp to env[1], *(int64_t*)(rdi+1)=rbp */
 | 
						||
        movq %r12, (JB_R12*8)(%rdi)     /* Save r12 to env[2], *(int64_t*)(rdi+2)=r12 */
 | 
						||
        movq %r13, (JB_R13*8)(%rdi)     /* Save r13 to env[3], *(int64_t*)(rdi+3)=r13 */
 | 
						||
        movq %r14, (JB_R14*8)(%rdi)     /* Save r14 to env[4], *(int64_t*)(rdi+4)=r14 */
 | 
						||
        movq %r15, (JB_R15*8)(%rdi)     /* Save r15 to env[5], *(int64_t*)(rdi+5)=r15 */
 | 
						||
        /* Save SP */
 | 
						||
        leaq 8(%rsp), %r8              /* Save *(int64_t*)(rsp+8) to r8, https://github.com/ossrs/state-threads/issues/11#issuecomment-888709759 */
 | 
						||
        movq %r8, (JB_RSP*8)(%rdi)     /* Save r8(rsp) to env[6], *(int64_t*)(rdi+6)=r8 */
 | 
						||
        /* Save PC we are returning to */
 | 
						||
        movq (%rsp), %r9               /* Save PC(parent function address) %(rsp) to r9 */
 | 
						||
        movq %r9, (JB_PC*8)(%rdi)      /* Save r9(PC) to env[7], *(int64_t*)(rdi+7)=r9 */
 | 
						||
        xorq %rax, %rax                 /* Reset rax to 0 */
 | 
						||
        ret
 | 
						||
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
 | 
						||
    /* _st_md_cxt_restore(__jmp_buf env, int val) */ /* The env is rdi, val is esi/rsi, https://en.wikipedia.org/wiki/X86_calling_conventions */
 | 
						||
    .globl __st_md_cxt_restore
 | 
						||
        .align 16
 | 
						||
    __st_md_cxt_restore:
 | 
						||
        /*
 | 
						||
         * Restore registers.
 | 
						||
         */
 | 
						||
        movq (JB_RBX*8)(%rdi), %rbx     /* Load rbx from env[0] */
 | 
						||
        movq (JB_RBP*8)(%rdi), %rbp     /* Load rbp from env[1] */
 | 
						||
        movq (JB_R12*8)(%rdi), %r12     /* Load r12 from env[2] */
 | 
						||
        movq (JB_R13*8)(%rdi), %r13     /* Load r13 from env[3] */
 | 
						||
        movq (JB_R14*8)(%rdi), %r14     /* Load r14 from env[4] */
 | 
						||
        movq (JB_R15*8)(%rdi), %r15     /* Load r15 from env[5] */
 | 
						||
        /* Set return value */          /* The esi is param1 val, the eax is return value */
 | 
						||
        test %esi, %esi                 /*      if (!val) {         */
 | 
						||
        mov $01, %eax                   /*          val=1;          */
 | 
						||
        cmove %eax, %esi                /*      }                   */
 | 
						||
        mov %esi, %eax                  /*      return val;         */
 | 
						||
        /* Restore PC and RSP */
 | 
						||
        movq (JB_PC*8)(%rdi), %r8      /* Load r8(PC) from env[7] */
 | 
						||
        movq (JB_RSP*8)(%rdi), %rsp     /* Load rsp from env[6] */
 | 
						||
        /* Jump to saved PC */
 | 
						||
        jmpq *%r8                      /* Jump to r8(PC) */
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
#elif defined(__aarch64__)
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
    /* See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms */
 | 
						||
    /* See https://developer.arm.com/documentation/102374/0100/Function-calls */
 | 
						||
    /* See https://developer.arm.com/documentation/102374/0100/Procedure-Call-Standard */
 | 
						||
    /* See https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#machine-registers */
 | 
						||
    /* See https://wiki.cdot.senecacollege.ca/wiki/AArch64_Register_and_Instruction_Quick_Start */
 | 
						||
    /*
 | 
						||
     * See setjmp.h of Darwin.
 | 
						||
     *
 | 
						||
     * _JBLEN is the number of ints required to save the following:
 | 
						||
     * r21-r29, sp, fp, lr == 12 registers, 8 bytes each. d8-d15
 | 
						||
     * are another 8 registers, each 8 bytes long. (aapcs64 specifies
 | 
						||
     * that only 64-bit versions of FP registers need to be saved).
 | 
						||
     * Finally, two 8-byte fields for signal handling purposes.
 | 
						||
     */
 | 
						||
 | 
						||
    /* The called routine is expected to preserve r19-r28 *** These registers are generally
 | 
						||
        safe to use in your program. */
 | 
						||
    #define JB_X19            0
 | 
						||
    #define JB_X20            1
 | 
						||
    #define JB_X21            2
 | 
						||
    #define JB_X22            3
 | 
						||
    #define JB_X23            4
 | 
						||
    #define JB_X24            5
 | 
						||
    #define JB_X25            6
 | 
						||
    #define JB_X26            7
 | 
						||
    #define JB_X27            8
 | 
						||
    #define JB_X28            9
 | 
						||
    /* r29 and r30 are used as the frame register and link register (avoid) */
 | 
						||
    #define JB_X29           10
 | 
						||
    #define JB_LR            11
 | 
						||
    /* Register '31' is one of two registers depending on the instruction context:
 | 
						||
        For instructions dealing with the stack, it is the stack pointer, named rsp */
 | 
						||
    #define JB_SP   13
 | 
						||
 | 
						||
    /* FP registers */
 | 
						||
    #define JB_D8   14
 | 
						||
    #define JB_D9   15
 | 
						||
    #define JB_D10   16
 | 
						||
    #define JB_D11   17
 | 
						||
    #define JB_D12   18
 | 
						||
    #define JB_D13   19
 | 
						||
    #define JB_D14   20
 | 
						||
    #define JB_D15   21
 | 
						||
 | 
						||
     .file "md.S"
 | 
						||
     .text
 | 
						||
 | 
						||
     /* _st_md_cxt_save(__jmp_buf env) */
 | 
						||
     .globl __st_md_cxt_save
 | 
						||
     .align 4
 | 
						||
    __st_md_cxt_save:
 | 
						||
        stp x19, x20, [x0, #JB_X19<<3]
 | 
						||
        stp x21, x22, [x0, #JB_X21<<3]
 | 
						||
        stp x23, x24, [x0, #JB_X23<<3]
 | 
						||
        stp x25, x26, [x0, #JB_X25<<3]
 | 
						||
        stp x27, x28, [x0, #JB_X27<<3]
 | 
						||
        stp x29, x30, [x0, #JB_X29<<3]
 | 
						||
 | 
						||
        stp  d8,  d9, [x0, #JB_D8<<3]
 | 
						||
        stp d10, d11, [x0, #JB_D10<<3]
 | 
						||
        stp d12, d13, [x0, #JB_D12<<3]
 | 
						||
        stp d14, d15, [x0, #JB_D14<<3]
 | 
						||
        mov x2,  sp
 | 
						||
        str x2,  [x0, #JB_SP<<3]
 | 
						||
 | 
						||
        mov x0, #0
 | 
						||
        ret
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
 | 
						||
     /* _st_md_cxt_restore(__jmp_buf env, int val) */
 | 
						||
     .globl __st_md_cxt_restore
 | 
						||
     .align 4
 | 
						||
    __st_md_cxt_restore:
 | 
						||
        ldp x19, x20, [x0, #JB_X19<<3]
 | 
						||
        ldp x21, x22, [x0, #JB_X21<<3]
 | 
						||
        ldp x23, x24, [x0, #JB_X23<<3]
 | 
						||
        ldp x25, x26, [x0, #JB_X25<<3]
 | 
						||
        ldp x27, x28, [x0, #JB_X27<<3]
 | 
						||
 | 
						||
        ldp x29, x30, [x0, #JB_X29<<3]
 | 
						||
 | 
						||
        ldp  d8,  d9, [x0, #JB_D8<<3]
 | 
						||
        ldp d10, d11, [x0, #JB_D10<<3]
 | 
						||
        ldp d12, d13, [x0, #JB_D12<<3]
 | 
						||
        ldp d14, d15, [x0, #JB_D14<<3]
 | 
						||
 | 
						||
        ldr x5, [x0, #JB_SP<<3]
 | 
						||
        mov sp, x5
 | 
						||
 | 
						||
        /* x0 = (x1 || 1); */
 | 
						||
        cmp x1, #0
 | 
						||
        mov x0, #1
 | 
						||
        csel x0, x1, x0, ne
 | 
						||
 | 
						||
        ret
 | 
						||
 | 
						||
    /****************************************************************/
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
#endif
 | 
						||
 | 
						||
#endif |