Path: blob/master/tools/include/nolibc/arch-loongarch.h
26289 views
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */1/*2* LoongArch specific definitions for NOLIBC3* Copyright (C) 2023 Loongson Technology Corporation Limited4*/56#ifndef _NOLIBC_ARCH_LOONGARCH_H7#define _NOLIBC_ARCH_LOONGARCH_H89#include "compiler.h"10#include "crt.h"1112/* Syscalls for LoongArch :13* - stack is 16-byte aligned14* - syscall number is passed in a715* - arguments are in a0, a1, a2, a3, a4, a516* - the system call is performed by calling "syscall 0"17* - syscall return comes in a018* - the arguments are cast to long and assigned into the target19* registers which are then simply passed as registers to the asm code,20* so that we don't have to experience issues with register constraints.21*/2223#define _NOLIBC_SYSCALL_CLOBBERLIST \24"memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8"2526#define my_syscall0(num) \27({ \28register long _num __asm__ ("a7") = (num); \29register long _arg1 __asm__ ("a0"); \30\31__asm__ volatile ( \32"syscall 0\n" \33: "=r"(_arg1) \34: "r"(_num) \35: _NOLIBC_SYSCALL_CLOBBERLIST \36); \37_arg1; \38})3940#define my_syscall1(num, arg1) \41({ \42register long _num __asm__ ("a7") = (num); \43register long _arg1 __asm__ ("a0") = (long)(arg1); \44\45__asm__ volatile ( \46"syscall 0\n" \47: "+r"(_arg1) \48: "r"(_num) \49: _NOLIBC_SYSCALL_CLOBBERLIST \50); \51_arg1; \52})5354#define my_syscall2(num, arg1, arg2) \55({ \56register long _num __asm__ ("a7") = (num); \57register long _arg1 __asm__ ("a0") = (long)(arg1); \58register long _arg2 __asm__ ("a1") = (long)(arg2); \59\60__asm__ volatile ( \61"syscall 0\n" \62: "+r"(_arg1) \63: "r"(_arg2), \64"r"(_num) \65: _NOLIBC_SYSCALL_CLOBBERLIST \66); \67_arg1; \68})6970#define my_syscall3(num, arg1, arg2, arg3) \71({ \72register long _num __asm__ ("a7") = (num); \73register long _arg1 __asm__ ("a0") = (long)(arg1); \74register long _arg2 __asm__ ("a1") = (long)(arg2); \75register long _arg3 __asm__ ("a2") = (long)(arg3); \76\77__asm__ volatile ( \78"syscall 0\n" \79: "+r"(_arg1) \80: "r"(_arg2), "r"(_arg3), \81"r"(_num) \82: _NOLIBC_SYSCALL_CLOBBERLIST \83); \84_arg1; \85})8687#define my_syscall4(num, arg1, arg2, arg3, arg4) \88({ \89register long _num __asm__ ("a7") = (num); \90register long _arg1 __asm__ ("a0") = (long)(arg1); \91register long _arg2 __asm__ ("a1") = (long)(arg2); \92register long _arg3 __asm__ ("a2") = (long)(arg3); \93register long _arg4 __asm__ ("a3") = (long)(arg4); \94\95__asm__ volatile ( \96"syscall 0\n" \97: "+r"(_arg1) \98: "r"(_arg2), "r"(_arg3), "r"(_arg4), \99"r"(_num) \100: _NOLIBC_SYSCALL_CLOBBERLIST \101); \102_arg1; \103})104105#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \106({ \107register long _num __asm__ ("a7") = (num); \108register long _arg1 __asm__ ("a0") = (long)(arg1); \109register long _arg2 __asm__ ("a1") = (long)(arg2); \110register long _arg3 __asm__ ("a2") = (long)(arg3); \111register long _arg4 __asm__ ("a3") = (long)(arg4); \112register long _arg5 __asm__ ("a4") = (long)(arg5); \113\114__asm__ volatile ( \115"syscall 0\n" \116: "+r"(_arg1) \117: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \118"r"(_num) \119: _NOLIBC_SYSCALL_CLOBBERLIST \120); \121_arg1; \122})123124#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \125({ \126register long _num __asm__ ("a7") = (num); \127register long _arg1 __asm__ ("a0") = (long)(arg1); \128register long _arg2 __asm__ ("a1") = (long)(arg2); \129register long _arg3 __asm__ ("a2") = (long)(arg3); \130register long _arg4 __asm__ ("a3") = (long)(arg4); \131register long _arg5 __asm__ ("a4") = (long)(arg5); \132register long _arg6 __asm__ ("a5") = (long)(arg6); \133\134__asm__ volatile ( \135"syscall 0\n" \136: "+r"(_arg1) \137: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \138"r"(_num) \139: _NOLIBC_SYSCALL_CLOBBERLIST \140); \141_arg1; \142})143144/* startup code */145void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)146{147__asm__ volatile (148"move $a0, $sp\n" /* save stack pointer to $a0, as arg1 of _start_c */149"bl _start_c\n" /* transfer to c runtime */150);151__nolibc_entrypoint_epilogue();152}153154#endif /* _NOLIBC_ARCH_LOONGARCH_H */155156157