authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-21 19:50:26-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-21 19:50:26-05:00
log670b4c5c02edc8fdfb4a73e72388ac0a140f8856
treec06a30c37804a58cdae9e12df257d17d68744733
parent271cc52a1619a553212192478d96a7c4bd629424
parent78389af55266d58e699a4d982e00afb6cce7ec64
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13292 from mitchellh/valgrind-arm64

std: valgrind client request support for aarch64

3 files changed, 89 insertions(+), 56 deletions(-)

lib/std/valgrind.zig+11-1
...@@ -30,10 +30,20 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:...@@ -30,10 +30,20 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
30 : "cc", "memory"30 : "cc", "memory"
31 );31 );
32 },32 },
33 .aarch64 => {
34 return asm volatile (
35 \\ ror x12, x12, #3 ; ror x12, x12, #13
36 \\ ror x12, x12, #51 ; ror x12, x12, #61
37 \\ orr x10, x10, x10
38 : [_] "={x3}" (-> usize),
39 : [_] "{x4}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
40 [_] "0" (default),
41 : "cc", "memory"
42 );
43 },
33 // ppc3244 // ppc32
34 // ppc6445 // ppc64
35 // arm46 // arm
36 // arm64
37 // s390x47 // s390x
38 // mips3248 // mips32
39 // mips6449 // mips64
src/codegen/llvm.zig+72-54
...@@ -9839,62 +9839,80 @@ pub const FuncGen = struct {...@@ -9839,62 +9839,80 @@ pub const FuncGen = struct {
9839 const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth());9839 const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth());
9840 const usize_alignment = @intCast(c_uint, Type.usize.abiSize(target));9840 const usize_alignment = @intCast(c_uint, Type.usize.abiSize(target));
98419841
9842 switch (target.cpu.arch) {9842 const array_llvm_ty = usize_llvm_ty.arrayType(6);
9843 .x86_64 => {9843 const array_ptr = fg.valgrind_client_request_array orelse a: {
9844 const array_llvm_ty = usize_llvm_ty.arrayType(6);9844 const array_ptr = fg.buildAlloca(array_llvm_ty, usize_alignment);
9845 const array_ptr = fg.valgrind_client_request_array orelse a: {9845 fg.valgrind_client_request_array = array_ptr;
9846 const array_ptr = fg.buildAlloca(array_llvm_ty, usize_alignment);9846 break :a array_ptr;
9847 fg.valgrind_client_request_array = array_ptr;9847 };
9848 break :a array_ptr;9848 const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 };
9849 };9849 const zero = usize_llvm_ty.constInt(0, .False);
9850 const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 };9850 for (array_elements) |elem, i| {
9851 const zero = usize_llvm_ty.constInt(0, .False);9851 const indexes = [_]*llvm.Value{
9852 for (array_elements) |elem, i| {9852 zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False),
9853 const indexes = [_]*llvm.Value{9853 };
9854 zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False),9854 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");
9855 };9855 const store_inst = fg.builder.buildStore(elem, elem_ptr);
9856 const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, "");9856 store_inst.setAlignment(usize_alignment);
9857 const store_inst = fg.builder.buildStore(elem, elem_ptr);9857 }
9858 store_inst.setAlignment(usize_alignment);9858
9859 }9859 const arch_specific: struct {
98609860 template: [:0]const u8,
9861 const asm_template =9861 constraints: [:0]const u8,
9862 \\rolq $$3, %rdi ; rolq $$13, %rdi9862 } = switch (target.cpu.arch) {
9863 \\rolq $$61, %rdi ; rolq $$51, %rdi9863 .x86 => .{
9864 \\xchgq %rbx,%rbx9864 .template =
9865 ;9865 \\roll $$3, %edi ; roll $$13, %edi
98669866 \\roll $$61, %edi ; roll $$51, %edi
9867 const asm_constraints = "={rdx},{rax},0,~{cc},~{memory}";9867 \\xchgl %ebx,%ebx
98689868 ,
9869 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");9869 .constraints = "={edx},{eax},0,~{cc},~{memory}",
9870 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };9870 },
9871 const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty };9871 .x86_64 => .{
9872 const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False);9872 .template =
9873 const asm_fn = llvm.getInlineAsm(9873 \\rolq $$3, %rdi ; rolq $$13, %rdi
9874 fn_llvm_ty,9874 \\rolq $$61, %rdi ; rolq $$51, %rdi
9875 asm_template,9875 \\xchgq %rbx,%rbx
9876 asm_template.len,9876 ,
9877 asm_constraints,9877 .constraints = "={rdx},{rax},0,~{cc},~{memory}",
9878 asm_constraints.len,9878 },
9879 .True, // has side effects9879 .aarch64, .aarch64_32, .aarch64_be => .{
9880 .False, // alignstack9880 .template =
9881 .ATT,9881 \\ror x12, x12, #3 ; ror x12, x12, #13
9882 .False,9882 \\ror x12, x12, #51 ; ror x12, x12, #61
9883 );9883 \\orr x10, x10, x10
98849884 ,
9885 const call = fg.builder.buildCall(9885 .constraints = "={x3},{x4},0,~{cc},~{memory}",
9886 fn_llvm_ty,
9887 asm_fn,
9888 &args,
9889 args.len,
9890 .C,
9891 .Auto,
9892 "",
9893 );
9894 return call;
9895 },9886 },
9896 else => unreachable,9887 else => unreachable,
9897 }9888 };
9889
9890 const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, "");
9891 const args = [_]*llvm.Value{ array_ptr_as_usize, default_value };
9892 const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty };
9893 const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False);
9894 const asm_fn = llvm.getInlineAsm(
9895 fn_llvm_ty,
9896 arch_specific.template.ptr,
9897 arch_specific.template.len,
9898 arch_specific.constraints.ptr,
9899 arch_specific.constraints.len,
9900 .True, // has side effects
9901 .False, // alignstack
9902 .ATT,
9903 .False, // can throw
9904 );
9905
9906 const call = fg.builder.buildCall(
9907 fn_llvm_ty,
9908 asm_fn,
9909 &args,
9910 args.len,
9911 .C,
9912 .Auto,
9913 "",
9914 );
9915 return call;
9898 }9916 }
9899};9917};
99009918
src/target.zig+6-1
...@@ -211,7 +211,12 @@ pub fn isSingleThreaded(target: std.Target) bool {...@@ -211,7 +211,12 @@ pub fn isSingleThreaded(target: std.Target) bool {
211/// Valgrind supports more, but Zig does not support them yet.211/// Valgrind supports more, but Zig does not support them yet.
212pub fn hasValgrindSupport(target: std.Target) bool {212pub fn hasValgrindSupport(target: std.Target) bool {
213 switch (target.cpu.arch) {213 switch (target.cpu.arch) {
214 .x86_64 => {214 .x86,
215 .x86_64,
216 .aarch64,
217 .aarch64_32,
218 .aarch64_be,
219 => {
215 return target.os.tag == .linux or target.os.tag == .solaris or220 return target.os.tag == .linux or target.os.tag == .solaris or
216 (target.os.tag == .windows and target.abi != .msvc);221 (target.os.tag == .windows and target.abi != .msvc);
217 },222 },