1*02217ad4SThomas Weißschuh /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2*02217ad4SThomas Weißschuh /* 3*02217ad4SThomas Weißschuh * SuperH specific definitions for NOLIBC 4*02217ad4SThomas Weißschuh * Copyright (C) 2025 Thomas Weißschuh <linux@weissschuh.net> 5*02217ad4SThomas Weißschuh */ 6*02217ad4SThomas Weißschuh 7*02217ad4SThomas Weißschuh #ifndef _NOLIBC_ARCH_SH_H 8*02217ad4SThomas Weißschuh #define _NOLIBC_ARCH_SH_H 9*02217ad4SThomas Weißschuh 10*02217ad4SThomas Weißschuh #include "compiler.h" 11*02217ad4SThomas Weißschuh #include "crt.h" 12*02217ad4SThomas Weißschuh 13*02217ad4SThomas Weißschuh /* 14*02217ad4SThomas Weißschuh * Syscalls for SuperH: 15*02217ad4SThomas Weißschuh * - registers are 32bit wide 16*02217ad4SThomas Weißschuh * - syscall number is passed in r3 17*02217ad4SThomas Weißschuh * - arguments are in r4, r5, r6, r7, r0, r1, r2 18*02217ad4SThomas Weißschuh * - the system call is performed by calling trapa #31 19*02217ad4SThomas Weißschuh * - syscall return value is in r0 20*02217ad4SThomas Weißschuh */ 21*02217ad4SThomas Weißschuh 22*02217ad4SThomas Weißschuh #define my_syscall0(num) \ 23*02217ad4SThomas Weißschuh ({ \ 24*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 25*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 26*02217ad4SThomas Weißschuh \ 27*02217ad4SThomas Weißschuh __asm__ volatile ( \ 28*02217ad4SThomas Weißschuh "trapa #31" \ 29*02217ad4SThomas Weißschuh : "=r"(_ret) \ 30*02217ad4SThomas Weißschuh : "r"(_num) \ 31*02217ad4SThomas Weißschuh : "memory", "cc" \ 32*02217ad4SThomas Weißschuh ); \ 33*02217ad4SThomas Weißschuh _ret; \ 34*02217ad4SThomas Weißschuh }) 35*02217ad4SThomas Weißschuh 36*02217ad4SThomas Weißschuh #define my_syscall1(num, arg1) \ 37*02217ad4SThomas Weißschuh ({ \ 38*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 39*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 40*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 41*02217ad4SThomas Weißschuh \ 42*02217ad4SThomas Weißschuh __asm__ volatile ( \ 43*02217ad4SThomas Weißschuh "trapa #31" \ 44*02217ad4SThomas Weißschuh : "=r"(_ret) \ 45*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1) \ 46*02217ad4SThomas Weißschuh : "memory", "cc" \ 47*02217ad4SThomas Weißschuh ); \ 48*02217ad4SThomas Weißschuh _ret; \ 49*02217ad4SThomas Weißschuh }) 50*02217ad4SThomas Weißschuh 51*02217ad4SThomas Weißschuh #define my_syscall2(num, arg1, arg2) \ 52*02217ad4SThomas Weißschuh ({ \ 53*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 54*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 55*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 56*02217ad4SThomas Weißschuh register long _arg2 __asm__ ("r5") = (long)(arg2); \ 57*02217ad4SThomas Weißschuh \ 58*02217ad4SThomas Weißschuh __asm__ volatile ( \ 59*02217ad4SThomas Weißschuh "trapa #31" \ 60*02217ad4SThomas Weißschuh : "=r"(_ret) \ 61*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1), "r"(_arg2) \ 62*02217ad4SThomas Weißschuh : "memory", "cc" \ 63*02217ad4SThomas Weißschuh ); \ 64*02217ad4SThomas Weißschuh _ret; \ 65*02217ad4SThomas Weißschuh }) 66*02217ad4SThomas Weißschuh 67*02217ad4SThomas Weißschuh #define my_syscall3(num, arg1, arg2, arg3) \ 68*02217ad4SThomas Weißschuh ({ \ 69*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 70*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 71*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 72*02217ad4SThomas Weißschuh register long _arg2 __asm__ ("r5") = (long)(arg2); \ 73*02217ad4SThomas Weißschuh register long _arg3 __asm__ ("r6") = (long)(arg3); \ 74*02217ad4SThomas Weißschuh \ 75*02217ad4SThomas Weißschuh __asm__ volatile ( \ 76*02217ad4SThomas Weißschuh "trapa #31" \ 77*02217ad4SThomas Weißschuh : "=r"(_ret) \ 78*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3) \ 79*02217ad4SThomas Weißschuh : "memory", "cc" \ 80*02217ad4SThomas Weißschuh ); \ 81*02217ad4SThomas Weißschuh _ret; \ 82*02217ad4SThomas Weißschuh }) 83*02217ad4SThomas Weißschuh 84*02217ad4SThomas Weißschuh #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 85*02217ad4SThomas Weißschuh ({ \ 86*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 87*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 88*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 89*02217ad4SThomas Weißschuh register long _arg2 __asm__ ("r5") = (long)(arg2); \ 90*02217ad4SThomas Weißschuh register long _arg3 __asm__ ("r6") = (long)(arg3); \ 91*02217ad4SThomas Weißschuh register long _arg4 __asm__ ("r7") = (long)(arg4); \ 92*02217ad4SThomas Weißschuh \ 93*02217ad4SThomas Weißschuh __asm__ volatile ( \ 94*02217ad4SThomas Weißschuh "trapa #31" \ 95*02217ad4SThomas Weißschuh : "=r"(_ret) \ 96*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \ 97*02217ad4SThomas Weißschuh : "memory", "cc" \ 98*02217ad4SThomas Weißschuh ); \ 99*02217ad4SThomas Weißschuh _ret; \ 100*02217ad4SThomas Weißschuh }) 101*02217ad4SThomas Weißschuh 102*02217ad4SThomas Weißschuh #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 103*02217ad4SThomas Weißschuh ({ \ 104*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 105*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 106*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 107*02217ad4SThomas Weißschuh register long _arg2 __asm__ ("r5") = (long)(arg2); \ 108*02217ad4SThomas Weißschuh register long _arg3 __asm__ ("r6") = (long)(arg3); \ 109*02217ad4SThomas Weißschuh register long _arg4 __asm__ ("r7") = (long)(arg4); \ 110*02217ad4SThomas Weißschuh register long _arg5 __asm__ ("r0") = (long)(arg5); \ 111*02217ad4SThomas Weißschuh \ 112*02217ad4SThomas Weißschuh __asm__ volatile ( \ 113*02217ad4SThomas Weißschuh "trapa #31" \ 114*02217ad4SThomas Weißschuh : "=r"(_ret) \ 115*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 116*02217ad4SThomas Weißschuh "r"(_arg5) \ 117*02217ad4SThomas Weißschuh : "memory", "cc" \ 118*02217ad4SThomas Weißschuh ); \ 119*02217ad4SThomas Weißschuh _ret; \ 120*02217ad4SThomas Weißschuh }) 121*02217ad4SThomas Weißschuh 122*02217ad4SThomas Weißschuh #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ 123*02217ad4SThomas Weißschuh ({ \ 124*02217ad4SThomas Weißschuh register long _num __asm__ ("r3") = (num); \ 125*02217ad4SThomas Weißschuh register long _ret __asm__ ("r0"); \ 126*02217ad4SThomas Weißschuh register long _arg1 __asm__ ("r4") = (long)(arg1); \ 127*02217ad4SThomas Weißschuh register long _arg2 __asm__ ("r5") = (long)(arg2); \ 128*02217ad4SThomas Weißschuh register long _arg3 __asm__ ("r6") = (long)(arg3); \ 129*02217ad4SThomas Weißschuh register long _arg4 __asm__ ("r7") = (long)(arg4); \ 130*02217ad4SThomas Weißschuh register long _arg5 __asm__ ("r0") = (long)(arg5); \ 131*02217ad4SThomas Weißschuh register long _arg6 __asm__ ("r1") = (long)(arg6); \ 132*02217ad4SThomas Weißschuh \ 133*02217ad4SThomas Weißschuh __asm__ volatile ( \ 134*02217ad4SThomas Weißschuh "trapa #31" \ 135*02217ad4SThomas Weißschuh : "=r"(_ret) \ 136*02217ad4SThomas Weißschuh : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 137*02217ad4SThomas Weißschuh "r"(_arg5), "r"(_arg6) \ 138*02217ad4SThomas Weißschuh : "memory", "cc" \ 139*02217ad4SThomas Weißschuh ); \ 140*02217ad4SThomas Weißschuh _ret; \ 141*02217ad4SThomas Weißschuh }) 142*02217ad4SThomas Weißschuh 143*02217ad4SThomas Weißschuh /* startup code */ 144*02217ad4SThomas Weißschuh void _start_wrapper(void); 145*02217ad4SThomas Weißschuh void __attribute__((weak,noreturn)) __nolibc_entrypoint __no_stack_protector _start_wrapper(void) 146*02217ad4SThomas Weißschuh { 147*02217ad4SThomas Weißschuh __asm__ volatile ( 148*02217ad4SThomas Weißschuh ".global _start\n" /* The C function will have a prologue, */ 149*02217ad4SThomas Weißschuh ".type _start, @function\n" /* corrupting "sp" */ 150*02217ad4SThomas Weißschuh ".weak _start\n" 151*02217ad4SThomas Weißschuh "_start:\n" 152*02217ad4SThomas Weißschuh 153*02217ad4SThomas Weißschuh "mov sp, r4\n" /* save argc pointer to r4, as arg1 of _start_c */ 154*02217ad4SThomas Weißschuh "bsr _start_c\n" /* transfer to c runtime */ 155*02217ad4SThomas Weißschuh "nop\n" /* delay slot */ 156*02217ad4SThomas Weißschuh 157*02217ad4SThomas Weißschuh ".size _start, .-_start\n" 158*02217ad4SThomas Weißschuh ); 159*02217ad4SThomas Weißschuh __nolibc_entrypoint_epilogue(); 160*02217ad4SThomas Weißschuh } 161*02217ad4SThomas Weißschuh 162*02217ad4SThomas Weißschuh #endif /* _NOLIBC_ARCH_SH_H */ 163