128 lines
3.4 KiB
Zig
128 lines
3.4 KiB
Zig
// ARM specific builtins
|
|
const builtin = @import("builtin");
|
|
|
|
const __divmodsi4 = @import("int.zig").__divmodsi4;
|
|
const __udivmodsi4 = @import("int.zig").__udivmodsi4;
|
|
const __divmoddi4 = @import("int.zig").__divmoddi4;
|
|
const __udivmoddi4 = @import("int.zig").__udivmoddi4;
|
|
|
|
extern fn memset(dest: ?[*]u8, c: u8, n: usize) ?[*]u8;
|
|
extern fn memcpy(noalias dest: ?[*]u8, noalias src: ?[*]const u8, n: usize) ?[*]u8;
|
|
extern fn memmove(dest: ?[*]u8, src: ?[*]const u8, n: usize) ?[*]u8;
|
|
|
|
pub fn __aeabi_memcpy(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
|
@setRuntimeSafety(false);
|
|
_ = memcpy(dest, src, n);
|
|
}
|
|
|
|
pub fn __aeabi_memmove(dest: [*]u8, src: [*]u8, n: usize) callconv(.AAPCS) void {
|
|
@setRuntimeSafety(false);
|
|
_ = memmove(dest, src, n);
|
|
}
|
|
|
|
pub fn __aeabi_memset(dest: [*]u8, n: usize, c: u8) callconv(.AAPCS) void {
|
|
@setRuntimeSafety(false);
|
|
// This is dentical to the standard `memset` definition but with the last
|
|
// two arguments swapped
|
|
_ = memset(dest, c, n);
|
|
}
|
|
|
|
pub fn __aeabi_memclr(dest: [*]u8, n: usize) callconv(.AAPCS) void {
|
|
@setRuntimeSafety(false);
|
|
_ = memset(dest, 0, n);
|
|
}
|
|
|
|
// Dummy functions to avoid errors during the linking phase
|
|
pub fn __aeabi_unwind_cpp_pr0() callconv(.C) void {}
|
|
pub fn __aeabi_unwind_cpp_pr1() callconv(.C) void {}
|
|
pub fn __aeabi_unwind_cpp_pr2() callconv(.C) void {}
|
|
|
|
// This function can only clobber r0 according to the ABI
|
|
pub fn __aeabi_read_tp() callconv(.Naked) void {
|
|
@setRuntimeSafety(false);
|
|
asm volatile (
|
|
\\ mrc p15, 0, r0, c13, c0, 3
|
|
\\ bx lr
|
|
);
|
|
unreachable;
|
|
}
|
|
|
|
// The following functions are wrapped in an asm block to ensure the required
|
|
// calling convention is always respected
|
|
|
|
pub fn __aeabi_uidivmod() callconv(.Naked) void {
|
|
@setRuntimeSafety(false);
|
|
// Divide r0 by r1; the quotient goes in r0, the remainder in r1
|
|
asm volatile (
|
|
\\ push {lr}
|
|
\\ sub sp, #4
|
|
\\ mov r2, sp
|
|
\\ bl __udivmodsi4
|
|
\\ ldr r1, [sp]
|
|
\\ add sp, #4
|
|
\\ pop {pc}
|
|
:
|
|
:
|
|
: "memory"
|
|
);
|
|
unreachable;
|
|
}
|
|
|
|
pub fn __aeabi_uldivmod() callconv(.Naked) void {
|
|
@setRuntimeSafety(false);
|
|
// Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
|
|
asm volatile (
|
|
\\ push {r4, lr}
|
|
\\ sub sp, #16
|
|
\\ add r4, sp, #8
|
|
\\ str r4, [sp]
|
|
\\ bl __udivmoddi4
|
|
\\ ldr r2, [sp, #8]
|
|
\\ ldr r3, [sp, #12]
|
|
\\ add sp, #16
|
|
\\ pop {r4, pc}
|
|
:
|
|
:
|
|
: "memory"
|
|
);
|
|
unreachable;
|
|
}
|
|
|
|
pub fn __aeabi_idivmod() callconv(.Naked) void {
|
|
@setRuntimeSafety(false);
|
|
// Divide r0 by r1; the quotient goes in r0, the remainder in r1
|
|
asm volatile (
|
|
\\ push {lr}
|
|
\\ sub sp, #4
|
|
\\ mov r2, sp
|
|
\\ bl __divmodsi4
|
|
\\ ldr r1, [sp]
|
|
\\ add sp, #4
|
|
\\ pop {pc}
|
|
:
|
|
:
|
|
: "memory"
|
|
);
|
|
unreachable;
|
|
}
|
|
|
|
pub fn __aeabi_ldivmod() callconv(.Naked) void {
|
|
@setRuntimeSafety(false);
|
|
// Divide r1:r0 by r3:r2; the quotient goes in r1:r0, the remainder in r3:r2
|
|
asm volatile (
|
|
\\ push {r4, lr}
|
|
\\ sub sp, #16
|
|
\\ add r4, sp, #8
|
|
\\ str r4, [sp]
|
|
\\ bl __divmoddi4
|
|
\\ ldr r2, [sp, #8]
|
|
\\ ldr r3, [sp, #12]
|
|
\\ add sp, #16
|
|
\\ pop {r4, pc}
|
|
:
|
|
:
|
|
: "memory"
|
|
);
|
|
unreachable;
|
|
}
|