1 //! arm Linux system calls. 2 3 use crate::backend::reg::{ 4 ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, 5 }; 6 use core::arch::asm; 7 8 #[inline] 9 pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> { 10 let r0; 11 asm!( 12 "svc 0", 13 in("r7") nr.to_asm(), 14 lateout("r0") r0, 15 options(nostack, preserves_flags, readonly) 16 ); 17 FromAsm::from_asm(r0) 18 } 19 20 #[inline] 21 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> { 22 let r0; 23 asm!( 24 "svc 0", 25 in("r7") nr.to_asm(), 26 inlateout("r0") a0.to_asm() => r0, 27 options(nostack, preserves_flags) 28 ); 29 FromAsm::from_asm(r0) 30 } 31 32 #[inline] 33 pub(in crate::backend) unsafe fn syscall1_readonly( 34 nr: SyscallNumber<'_>, 35 a0: ArgReg<'_, A0>, 36 ) -> RetReg<R0> { 37 let r0; 38 asm!( 39 "svc 0", 40 in("r7") nr.to_asm(), 41 inlateout("r0") a0.to_asm() => r0, 42 options(nostack, preserves_flags, readonly) 43 ); 44 FromAsm::from_asm(r0) 45 } 46 47 #[inline] 48 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { 49 asm!( 50 "svc 0", 51 in("r7") nr.to_asm(), 52 in("r0") a0.to_asm(), 53 options(noreturn) 54 ) 55 } 56 57 #[inline] 58 pub(in crate::backend) unsafe fn syscall2( 59 nr: SyscallNumber<'_>, 60 a0: ArgReg<'_, A0>, 61 a1: ArgReg<'_, A1>, 62 ) -> RetReg<R0> { 63 let r0; 64 asm!( 65 "svc 0", 66 in("r7") nr.to_asm(), 67 inlateout("r0") a0.to_asm() => r0, 68 in("r1") a1.to_asm(), 69 options(nostack, preserves_flags) 70 ); 71 FromAsm::from_asm(r0) 72 } 73 74 #[inline] 75 pub(in crate::backend) unsafe fn syscall2_readonly( 76 nr: SyscallNumber<'_>, 77 a0: ArgReg<'_, A0>, 78 a1: ArgReg<'_, A1>, 79 ) -> RetReg<R0> { 80 let r0; 81 asm!( 82 "svc 0", 83 in("r7") nr.to_asm(), 84 inlateout("r0") a0.to_asm() => r0, 85 in("r1") a1.to_asm(), 86 options(nostack, preserves_flags, readonly) 87 ); 88 FromAsm::from_asm(r0) 89 } 90 91 #[inline] 92 pub(in crate::backend) unsafe fn syscall3( 93 nr: SyscallNumber<'_>, 94 a0: ArgReg<'_, A0>, 95 a1: ArgReg<'_, A1>, 96 a2: ArgReg<'_, A2>, 97 ) -> RetReg<R0> { 98 let r0; 99 asm!( 100 "svc 0", 101 in("r7") nr.to_asm(), 102 inlateout("r0") a0.to_asm() => r0, 103 in("r1") a1.to_asm(), 104 in("r2") a2.to_asm(), 105 options(nostack, preserves_flags) 106 ); 107 FromAsm::from_asm(r0) 108 } 109 110 #[inline] 111 pub(in crate::backend) unsafe fn syscall3_readonly( 112 nr: SyscallNumber<'_>, 113 a0: ArgReg<'_, A0>, 114 a1: ArgReg<'_, A1>, 115 a2: ArgReg<'_, A2>, 116 ) -> RetReg<R0> { 117 let r0; 118 asm!( 119 "svc 0", 120 in("r7") nr.to_asm(), 121 inlateout("r0") a0.to_asm() => r0, 122 in("r1") a1.to_asm(), 123 in("r2") a2.to_asm(), 124 options(nostack, preserves_flags, readonly) 125 ); 126 FromAsm::from_asm(r0) 127 } 128 129 #[inline] 130 pub(in crate::backend) unsafe fn syscall4( 131 nr: SyscallNumber<'_>, 132 a0: ArgReg<'_, A0>, 133 a1: ArgReg<'_, A1>, 134 a2: ArgReg<'_, A2>, 135 a3: ArgReg<'_, A3>, 136 ) -> RetReg<R0> { 137 let r0; 138 asm!( 139 "svc 0", 140 in("r7") nr.to_asm(), 141 inlateout("r0") a0.to_asm() => r0, 142 in("r1") a1.to_asm(), 143 in("r2") a2.to_asm(), 144 in("r3") a3.to_asm(), 145 options(nostack, preserves_flags) 146 ); 147 FromAsm::from_asm(r0) 148 } 149 150 #[inline] 151 pub(in crate::backend) unsafe fn syscall4_readonly( 152 nr: SyscallNumber<'_>, 153 a0: ArgReg<'_, A0>, 154 a1: ArgReg<'_, A1>, 155 a2: ArgReg<'_, A2>, 156 a3: ArgReg<'_, A3>, 157 ) -> RetReg<R0> { 158 let r0; 159 asm!( 160 "svc 0", 161 in("r7") nr.to_asm(), 162 inlateout("r0") a0.to_asm() => r0, 163 in("r1") a1.to_asm(), 164 in("r2") a2.to_asm(), 165 in("r3") a3.to_asm(), 166 options(nostack, preserves_flags, readonly) 167 ); 168 FromAsm::from_asm(r0) 169 } 170 171 #[inline] 172 pub(in crate::backend) unsafe fn syscall5( 173 nr: SyscallNumber<'_>, 174 a0: ArgReg<'_, A0>, 175 a1: ArgReg<'_, A1>, 176 a2: ArgReg<'_, A2>, 177 a3: ArgReg<'_, A3>, 178 a4: ArgReg<'_, A4>, 179 ) -> RetReg<R0> { 180 let r0; 181 asm!( 182 "svc 0", 183 in("r7") nr.to_asm(), 184 inlateout("r0") a0.to_asm() => r0, 185 in("r1") a1.to_asm(), 186 in("r2") a2.to_asm(), 187 in("r3") a3.to_asm(), 188 in("r4") a4.to_asm(), 189 options(nostack, preserves_flags) 190 ); 191 FromAsm::from_asm(r0) 192 } 193 194 #[inline] 195 pub(in crate::backend) unsafe fn syscall5_readonly( 196 nr: SyscallNumber<'_>, 197 a0: ArgReg<'_, A0>, 198 a1: ArgReg<'_, A1>, 199 a2: ArgReg<'_, A2>, 200 a3: ArgReg<'_, A3>, 201 a4: ArgReg<'_, A4>, 202 ) -> RetReg<R0> { 203 let r0; 204 asm!( 205 "svc 0", 206 in("r7") nr.to_asm(), 207 inlateout("r0") a0.to_asm() => r0, 208 in("r1") a1.to_asm(), 209 in("r2") a2.to_asm(), 210 in("r3") a3.to_asm(), 211 in("r4") a4.to_asm(), 212 options(nostack, preserves_flags, readonly) 213 ); 214 FromAsm::from_asm(r0) 215 } 216 217 #[inline] 218 pub(in crate::backend) unsafe fn syscall6( 219 nr: SyscallNumber<'_>, 220 a0: ArgReg<'_, A0>, 221 a1: ArgReg<'_, A1>, 222 a2: ArgReg<'_, A2>, 223 a3: ArgReg<'_, A3>, 224 a4: ArgReg<'_, A4>, 225 a5: ArgReg<'_, A5>, 226 ) -> RetReg<R0> { 227 let r0; 228 asm!( 229 "svc 0", 230 in("r7") nr.to_asm(), 231 inlateout("r0") a0.to_asm() => r0, 232 in("r1") a1.to_asm(), 233 in("r2") a2.to_asm(), 234 in("r3") a3.to_asm(), 235 in("r4") a4.to_asm(), 236 in("r5") a5.to_asm(), 237 options(nostack, preserves_flags) 238 ); 239 FromAsm::from_asm(r0) 240 } 241 242 #[inline] 243 pub(in crate::backend) unsafe fn syscall6_readonly( 244 nr: SyscallNumber<'_>, 245 a0: ArgReg<'_, A0>, 246 a1: ArgReg<'_, A1>, 247 a2: ArgReg<'_, A2>, 248 a3: ArgReg<'_, A3>, 249 a4: ArgReg<'_, A4>, 250 a5: ArgReg<'_, A5>, 251 ) -> RetReg<R0> { 252 let r0; 253 asm!( 254 "svc 0", 255 in("r7") nr.to_asm(), 256 inlateout("r0") a0.to_asm() => r0, 257 in("r1") a1.to_asm(), 258 in("r2") a2.to_asm(), 259 in("r3") a3.to_asm(), 260 in("r4") a4.to_asm(), 261 in("r5") a5.to_asm(), 262 options(nostack, preserves_flags, readonly) 263 ); 264 FromAsm::from_asm(r0) 265 } 266