1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 /* 3 * m68k specific definitions for NOLIBC 4 * Copyright (C) 2025 Daniel Palmer<daniel@thingy.jp> 5 * 6 * Roughly based on one or more of the other arch files. 7 * 8 */ 9 10 #ifndef _NOLIBC_ARCH_M68K_H 11 #define _NOLIBC_ARCH_M68K_H 12 13 #include "compiler.h" 14 #include "crt.h" 15 16 #define _NOLIBC_SYSCALL_CLOBBERLIST "memory" 17 18 #define my_syscall0(num) \ 19 ({ \ 20 register long _num __asm__ ("d0") = (num); \ 21 \ 22 __asm__ volatile ( \ 23 "trap #0\n" \ 24 : "+r"(_num) \ 25 : "r"(_num) \ 26 : _NOLIBC_SYSCALL_CLOBBERLIST \ 27 ); \ 28 _num; \ 29 }) 30 31 #define my_syscall1(num, arg1) \ 32 ({ \ 33 register long _num __asm__ ("d0") = (num); \ 34 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 35 \ 36 __asm__ volatile ( \ 37 "trap #0\n" \ 38 : "+r"(_num) \ 39 : "r"(_arg1) \ 40 : _NOLIBC_SYSCALL_CLOBBERLIST \ 41 ); \ 42 _num; \ 43 }) 44 45 #define my_syscall2(num, arg1, arg2) \ 46 ({ \ 47 register long _num __asm__ ("d0") = (num); \ 48 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 49 register long _arg2 __asm__ ("d2") = (long)(arg2); \ 50 \ 51 __asm__ volatile ( \ 52 "trap #0\n" \ 53 : "+r"(_num) \ 54 : "r"(_arg1), "r"(_arg2) \ 55 : _NOLIBC_SYSCALL_CLOBBERLIST \ 56 ); \ 57 _num; \ 58 }) 59 60 #define my_syscall3(num, arg1, arg2, arg3) \ 61 ({ \ 62 register long _num __asm__ ("d0") = (num); \ 63 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 64 register long _arg2 __asm__ ("d2") = (long)(arg2); \ 65 register long _arg3 __asm__ ("d3") = (long)(arg3); \ 66 \ 67 __asm__ volatile ( \ 68 "trap #0\n" \ 69 : "+r"(_num) \ 70 : "r"(_arg1), "r"(_arg2), "r"(_arg3) \ 71 : _NOLIBC_SYSCALL_CLOBBERLIST \ 72 ); \ 73 _num; \ 74 }) 75 76 #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 77 ({ \ 78 register long _num __asm__ ("d0") = (num); \ 79 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 80 register long _arg2 __asm__ ("d2") = (long)(arg2); \ 81 register long _arg3 __asm__ ("d3") = (long)(arg3); \ 82 register long _arg4 __asm__ ("d4") = (long)(arg4); \ 83 \ 84 __asm__ volatile ( \ 85 "trap #0\n" \ 86 : "+r" (_num) \ 87 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \ 88 : _NOLIBC_SYSCALL_CLOBBERLIST \ 89 ); \ 90 _num; \ 91 }) 92 93 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 94 ({ \ 95 register long _num __asm__ ("d0") = (num); \ 96 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 97 register long _arg2 __asm__ ("d2") = (long)(arg2); \ 98 register long _arg3 __asm__ ("d3") = (long)(arg3); \ 99 register long _arg4 __asm__ ("d4") = (long)(arg4); \ 100 register long _arg5 __asm__ ("d5") = (long)(arg5); \ 101 \ 102 __asm__ volatile ( \ 103 "trap #0\n" \ 104 : "+r" (_num) \ 105 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) \ 106 : _NOLIBC_SYSCALL_CLOBBERLIST \ 107 ); \ 108 _num; \ 109 }) 110 111 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ 112 ({ \ 113 register long _num __asm__ ("d0") = (num); \ 114 register long _arg1 __asm__ ("d1") = (long)(arg1); \ 115 register long _arg2 __asm__ ("d2") = (long)(arg2); \ 116 register long _arg3 __asm__ ("d3") = (long)(arg3); \ 117 register long _arg4 __asm__ ("d4") = (long)(arg4); \ 118 register long _arg5 __asm__ ("d5") = (long)(arg5); \ 119 register long _arg6 __asm__ ("a0") = (long)(arg6); \ 120 \ 121 __asm__ volatile ( \ 122 "trap #0\n" \ 123 : "+r" (_num) \ 124 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 125 "r"(_arg6) \ 126 : _NOLIBC_SYSCALL_CLOBBERLIST \ 127 ); \ 128 _num; \ 129 }) 130 131 void _start(void); 132 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 133 { 134 __asm__ volatile ( 135 "movel %sp, %sp@-\n" 136 "jsr _start_c\n" 137 ); 138 __nolibc_entrypoint_epilogue(); 139 } 140 141 #endif /* _NOLIBC_ARCH_M68K_H */ 142