#include "zasm_GOOS_GOARCH.h"
#include "../../cmd/ld/textflag.h"
#include "syscall_nacl.h"
#define NACL_SYSCALL(code) \
        MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
#define NACL_SYSJMP(code) \
        MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
TEXT runtime·settls(SB),NOSPLIT,$0
        MOVL    DI, TLS 
        RET
TEXT runtime·exit(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_exit)
TEXT runtime·exit1(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_thread_exit)
TEXT runtime·open(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        NACL_SYSJMP(SYS_open)
TEXT runtime·close(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_close)
TEXT runtime·read(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        NACL_SYSJMP(SYS_read)
TEXT syscall·naclWrite(SB), NOSPLIT, $16-20
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        MOVL DI, 0(SP)
        MOVL SI, 4(SP)
        MOVL DX, 8(SP)
        CALL runtime·write(SB)
        MOVL AX, ret+16(FP)
        RET
TEXT runtime·write(SB),NOSPLIT,$16-12
        
        
        MOVQ runtime·timens(SB), AX
        CMPQ AX, $0
        JEQ write
        MOVL arg1+0(FP), DI
        CMPL DI, $1
        JEQ playback
        CMPL DI, $2
        JEQ playback
write:
        
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        NACL_SYSCALL(SYS_write)
        RET
        
        
playback:
        MOVL $1, BX
        XCHGL   runtime·writelock(SB), BX
        CMPL BX, $0
        JNE playback
        
        MOVL $(('B'<<24) | ('P'<<16)), 0(SP)
        BSWAPQ AX
        MOVQ AX, 4(SP)
        MOVL arg3+8(FP), DX
        BSWAPL DX
        MOVL DX, 12(SP)
        MOVL $1, DI 
        MOVL SP, SI
        MOVL $16, DX
        NACL_SYSCALL(SYS_write)
        
        MOVL $1, DI 
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        NACL_SYSCALL(SYS_write)
        
        MOVL    $0, runtime·writelock(SB)
        RET
TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        NACL_SYSJMP(SYS_exception_stack)
TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        NACL_SYSJMP(SYS_exception_handler)
TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_sem_create)
TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_sem_wait)
TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_sem_post)
TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_mutex_create)
TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_mutex_lock)
TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_mutex_trylock)
TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_mutex_unlock)
TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_cond_create)
TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        NACL_SYSJMP(SYS_cond_wait)
TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_cond_signal)
TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        NACL_SYSJMP(SYS_cond_broadcast)
TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        NACL_SYSJMP(SYS_cond_timed_wait_abs)
TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        MOVL arg4+12(FP), CX
        NACL_SYSJMP(SYS_thread_create)
TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
        NACL_SYSCALL(SYS_tls_get)
        SUBL    $8, AX
        MOVL    AX, TLS
        JMP runtime·mstart(SB)
TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        NACL_SYSJMP(SYS_nanosleep)
TEXT runtime·osyield(SB),NOSPLIT,$0
        NACL_SYSJMP(SYS_sched_yield)
TEXT runtime·mmap(SB),NOSPLIT,$8
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        MOVL arg3+8(FP), DX
        MOVL arg4+12(FP), CX
        MOVL arg5+16(FP), R8
        MOVL arg6+20(FP), AX
        MOVQ AX, 0(SP)
        MOVL SP, R9
        NACL_SYSCALL(SYS_mmap)
        CMPL AX, $-4095
        JNA 2(PC)
        NEGL AX
        RET
TEXT time·now(SB),NOSPLIT,$16
        MOVQ runtime·timens(SB), AX
        CMPQ AX, $0
        JEQ realtime
        MOVQ $0, DX
        MOVQ $1000000000, CX
        DIVQ CX
        MOVQ AX, sec+0(FP)
        MOVL DX, nsec+8(FP)
        RET
realtime:
        MOVL $0, DI 
        LEAL 0(SP), AX
        MOVL AX, SI 
        NACL_SYSCALL(SYS_clock_gettime)
        MOVL 0(SP), AX 
        MOVL 4(SP), CX 
        MOVL 8(SP), BX 
        
        MOVL    AX, sec+0(FP)
        MOVL    CX, sec+4(FP)
        MOVL    BX, nsec+8(FP)
        RET
TEXT syscall·now(SB),NOSPLIT,$0
        JMP time·now(SB)
TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
        MOVL arg1+0(FP), DI
        MOVL arg2+4(FP), SI
        NACL_SYSJMP(SYS_clock_gettime)
TEXT runtime·nanotime(SB),NOSPLIT,$16
        MOVQ runtime·timens(SB), AX
        CMPQ AX, $0
        JEQ 2(PC)
        RET
        MOVL $0, DI 
        LEAL 0(SP), AX
        MOVL AX, SI 
        NACL_SYSCALL(SYS_clock_gettime)
        MOVQ 0(SP), AX 
        MOVL 8(SP), DX 
        
        
        IMULQ   $1000000000, AX
        ADDQ    DX, AX
        RET
TEXT runtime·sigtramp(SB),NOSPLIT,$80
        
        
        
        
        
        
        LEAL ctxt+0(FP), AX
        MOVL (16*4+5*8)(AX), AX
        MOVL    AX, TLS
        
        get_tls(CX)
        MOVL    m(CX), BX
        
        CMPL    BX, $0
        JEQ     nom
        
        MOVL    g(CX), DI
        MOVL    DI, 20(SP)
        
        
        MOVL    m_gsignal(BX), BX
        MOVL    BX, g(CX)
        
        MOVL    $11, 0(SP) 
        MOVL    $0, 4(SP) 
        LEAL    ctxt+0(FP), AX
        MOVL    AX, 8(SP) 
        MOVL    DI, 12(SP) 
        CALL    runtime·sighandler(SB)
        
        get_tls(CX)
        MOVL    20(SP), BX
        MOVL    BX, g(CX)
sigtramp_ret:
        
        NACL_SYSCALL(SYS_exception_clear_flag)
        
        
        LEAL    ctxt+0(FP), SI
        ADDL    $64, SI
        MOVQ    0(SI), AX
        MOVQ    8(SI), CX
        MOVQ    16(SI), DX
        MOVQ    24(SI), BX
        MOVL    32(SI), SP      
        
        
        MOVQ    56(SI), DI
        MOVQ    64(SI), R8
        MOVQ    72(SI), R9
        MOVQ    80(SI), R10
        MOVQ    88(SI), R11
        MOVQ    96(SI), R12
        MOVQ    104(SI), R13
        MOVQ    112(SI), R14
        
        MOVQ    128(SI), SI 
        
        JMP     SI
debughandler:
        
        LEAL    ctxt+0(FP), DI
        MOVL    $runtime·sigtrampf(SB), AX
        MOVL    AX, 0(SP)
        MOVQ    (16*4+16*8)(DI), BX 
        MOVQ    BX, 8(SP)
        MOVQ    (16*4+0*8)(DI), BX 
        MOVQ    BX, 16(SP)
        MOVQ    (16*4+1*8)(DI), BX 
        MOVQ    BX, 24(SP)
        MOVQ    (16*4+2*8)(DI), BX 
        MOVQ    BX, 32(SP)
        MOVQ    (16*4+3*8)(DI), BX 
        MOVQ    BX, 40(SP)
        MOVQ    (16*4+7*8)(DI), BX 
        MOVQ    BX, 48(SP)
        MOVQ    (16*4+15*8)(DI), BX 
        MOVQ    BX, 56(SP)
        MOVQ    (16*4+4*8)(DI), BX 
        MOVQ    0(BX), BX
        MOVQ    BX, 64(SP)
        CALL    runtime·printf(SB)
        
        LEAL    ctxt+0(FP), DI
        MOVQ    (16*4+16*8)(DI), BX 
        MOVL    BX, 0(SP)
        MOVQ    (16*4+4*8)(DI), BX 
        MOVL    BX, 4(SP)
        MOVL    $0, 8(SP)       
        get_tls(CX)
        MOVL    g(CX), BX
        MOVL    BX, 12(SP)      
        CALL    runtime·traceback(SB)
notls:
        MOVL    0, AX
        RET
nom:
        MOVL    0, AX
        RET
MOVL $1, DI; NACL_SYSCALL(SYS_exit)
TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
        RET