diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index b709403256..514a360a66 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -11595,29 +11595,81 @@ pub const FuncGen = struct { template: [:0]const u8, constraints: [:0]const u8, } = switch (target.cpu.arch) { - .x86 => .{ + .arm, .armeb, .thumb, .thumbeb => .{ .template = - \\roll $$3, %edi ; roll $$13, %edi - \\roll $$61, %edi ; roll $$51, %edi - \\xchgl %ebx,%ebx + \\ mov r12, r12, ror #3 ; mov r12, r12, ror #13 + \\ mov r12, r12, ror #29 ; mov r12, r12, ror #19 + \\ orr r10, r10, r10 , - .constraints = "={edx},{eax},0,~{cc},~{memory}", - }, - .x86_64 => .{ - .template = - \\rolq $$3, %rdi ; rolq $$13, %rdi - \\rolq $$61, %rdi ; rolq $$51, %rdi - \\xchgq %rbx,%rbx - , - .constraints = "={rdx},{rax},0,~{cc},~{memory}", + .constraints = "={r3},{r4},{r3},~{cc},~{memory}", }, .aarch64, .aarch64_be => .{ .template = - \\ror x12, x12, #3 ; ror x12, x12, #13 - \\ror x12, x12, #51 ; ror x12, x12, #61 - \\orr x10, x10, x10 + \\ ror x12, x12, #3 ; ror x12, x12, #13 + \\ ror x12, x12, #51 ; ror x12, x12, #61 + \\ orr x10, x10, x10 , - .constraints = "={x3},{x4},0,~{cc},~{memory}", + .constraints = "={x3},{x4},{x3},~{cc},~{memory}", + }, + .mips, .mipsel => .{ + .template = + \\ srl $$0, $$0, 13 + \\ srl $$0, $$0, 29 + \\ srl $$0, $$0, 3 + \\ srl $$0, $$0, 19 + \\ or $$13, $$13, $$13 + , + .constraints = "={$11},{$12},{$11},~{memory}", + }, + .mips64, .mips64el => .{ + .template = + \\ dsll $$0, $$0, 3 ; dsll $$0, $$0, 13 + \\ dsll $$0, $$0, 29 ; dsll $$0, $$0, 19 + \\ or $$13, $$13, $$13 + , + .constraints = "={$11},{$12},{$11},~{memory}", + }, + .powerpc, .powerpcle => .{ + .template = + \\ rlwinm 0, 0, 3, 0, 31 ; rlwinm 0, 0, 13, 0, 31 + \\ rlwinm 0, 0, 29, 0, 31 ; rlwinm 0, 0, 19, 0, 31 + \\ or 1, 1, 1 + , + .constraints = "={r3},{r4},{r3},~{cc},~{memory}", + }, + .powerpc64, .powerpc64le => .{ + .template = + \\ rotldi 0, 0, 3 ; rotldi 0, 0, 13 + \\ rotldi 0, 0, 61 ; rotldi 0, 0, 51 + \\ or 1, 1, 1 + , + .constraints = "={r3},{r4},{r3},~{cc},~{memory}", + }, + .s390x => .{ + .template = + \\ lr %r15, %r15 + \\ lr %r1, %r1 + \\ lr %r2, %r2 + \\ lr %r3, %r3 + \\ lr %r2, %r2 + , + .constraints = "={r3},{r2},{r3},~{cc},~{memory}", + }, + .x86 => .{ + .template = + \\ roll $$3, %edi ; roll $$13, %edi + \\ roll $$61, %edi ; roll $$51, %edi + \\ xchgl %ebx, %ebx + , + .constraints = "={edx},{eax},{edx},~{cc},~{memory}", + }, + .x86_64 => .{ + .template = + \\ rolq $$3, %rdi ; rolq $$13, %rdi + \\ rolq $$61, %rdi ; rolq $$51, %rdi + \\ xchgq %rbx, %rbx + , + .constraints = "={rdx},{rax},{edx},~{cc},~{memory}", }, else => unreachable, }; diff --git a/src/target.zig b/src/target.zig index 2327ff0c4a..aba1fffcbc 100644 --- a/src/target.zig +++ b/src/target.zig @@ -79,19 +79,45 @@ pub fn defaultSingleThreaded(target: std.Target) bool { return false; } -/// Valgrind supports more, but Zig does not support them yet. pub fn hasValgrindSupport(target: std.Target) bool { - switch (target.cpu.arch) { - .x86, - .x86_64, - .aarch64, - .aarch64_be, - => { - return target.os.tag == .linux or target.os.tag == .solaris or target.os.tag == .illumos or - (target.os.tag == .windows and target.abi.isGnu()); + // We can't currently output the necessary Valgrind client request assembly when using the C + // backend and compiling with an MSVC-like compiler. + const ofmt_c_msvc = (target.abi == .msvc or target.abi == .itanium) and target.ofmt == .c; + + return switch (target.cpu.arch) { + .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) { + .linux => true, + else => false, }, - else => return false, - } + .aarch64, .aarch64_be => switch (target.os.tag) { + .linux, .freebsd => true, + else => false, + }, + .mips, .mipsel, .mips64, .mips64el => switch (target.os.tag) { + .linux => true, + else => false, + }, + .powerpc, .powerpcle, .powerpc64, .powerpc64le => switch (target.os.tag) { + .linux => true, + else => false, + }, + .s390x => switch (target.os.tag) { + .linux => true, + else => false, + }, + .x86 => switch (target.os.tag) { + .linux, .freebsd, .solaris, .illumos => true, + .windows => !ofmt_c_msvc, + else => false, + }, + .x86_64 => switch (target.os.tag) { + .linux => target.abi != .gnux32 and target.abi != .muslx32, + .freebsd, .solaris, .illumos => true, + .windows => !ofmt_c_msvc, + else => false, + }, + else => false, + }; } /// The set of targets that LLVM has non-experimental support for.