From cd02630da82b6b0a59583160b12c286a7aec7f8c Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Mon, 24 Jun 2019 22:32:50 -0700 Subject: [PATCH 1/2] compiler-rt: Support thumb versions older than armv6 Add versions of __aeabi_memset and __aeabi_memclr which do not use mov instructions between low registers, as this is unsupported on thumbv4t and thumbv5. --- std/special/compiler_rt.zig | 43 +++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 46607a3adf..95867d6952 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -471,6 +471,28 @@ test "usesThumb1" { //etc. } +const use_thumb_1_pre_armv6 = usesThumb1PreArmv6(builtin.arch); + +fn usesThumb1PreArmv6(arch: builtin.Arch) bool { + return switch (arch) { + .thumb => switch (arch.thumb) { + .v5, + .v5te, + .v4t, + => true, + else => false, + }, + .thumbeb => switch (arch.thumbeb) { + .v5, + .v5te, + .v4t, + => true, + else => false, + }, + else => false, + }; +} + nakedcc fn __aeabi_memcpy() noreturn { @setRuntimeSafety(false); if (use_thumb_1) { @@ -505,7 +527,16 @@ nakedcc fn __aeabi_memmove() noreturn { nakedcc fn __aeabi_memset() noreturn { @setRuntimeSafety(false); - if (use_thumb_1) { + if (use_thumb_1_pre_armv6) { + asm volatile ( + \\ eors r1, r2 + \\ eors r2, r1 + \\ eors r1, r2 + \\ push {r7, lr} + \\ b memset + \\ pop {r7, pc} + ); + } else if (use_thumb_1) { asm volatile ( \\ mov r3, r1 \\ mov r1, r2 @@ -527,7 +558,15 @@ nakedcc fn __aeabi_memset() noreturn { nakedcc fn __aeabi_memclr() noreturn { @setRuntimeSafety(false); - if (use_thumb_1) { + if (use_thumb_1_pre_armv6) { + asm volatile ( + \\ adds r2, r1, #0 + \\ movs r1, #0 + \\ push {r7, lr} + \\ bl memset + \\ pop {r7, pc} + ); + } else if (use_thumb_1) { asm volatile ( \\ mov r2, r1 \\ movs r1, #0 From f9e26d98711ead110a4c2d2f3032978a5a8c2d9d Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Tue, 25 Jun 2019 22:54:10 -0700 Subject: [PATCH 2/2] compiler-rt: use more idiomatic switch syntax --- std/special/compiler_rt.zig | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 95867d6952..914f9dcb00 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -405,15 +405,15 @@ const use_thumb_1 = usesThumb1(builtin.arch); fn usesThumb1(arch: builtin.Arch) bool { return switch (arch) { - .arm => switch (arch.arm) { + .arm => |sub_arch| switch (sub_arch) { .v6m => true, else => false, }, - .armeb => switch (arch.armeb) { + .armeb => |sub_arch| switch (sub_arch) { .v6m => true, else => false, }, - .thumb => switch (arch.thumb) { + .thumb => |sub_arch| switch (sub_arch) { .v5, .v5te, .v4t, @@ -423,7 +423,7 @@ fn usesThumb1(arch: builtin.Arch) bool { => true, else => false, }, - .thumbeb => switch (arch.thumbeb) { + .thumbeb => |sub_arch| switch (sub_arch) { .v5, .v5te, .v4t, @@ -475,18 +475,12 @@ const use_thumb_1_pre_armv6 = usesThumb1PreArmv6(builtin.arch); fn usesThumb1PreArmv6(arch: builtin.Arch) bool { return switch (arch) { - .thumb => switch (arch.thumb) { - .v5, - .v5te, - .v4t, - => true, + .thumb => |sub_arch| switch (sub_arch) { + .v5, .v5te, .v4t => true, else => false, }, - .thumbeb => switch (arch.thumbeb) { - .v5, - .v5te, - .v4t, - => true, + .thumbeb => |sub_arch| switch (sub_arch) { + .v5, .v5te, .v4t => true, else => false, }, else => false,