| ... | @@ -9832,62 +9832,80 @@ pub const FuncGen = struct { | ... | @@ -9832,62 +9832,80 @@ pub const FuncGen = struct { |
| 9832 | const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth()); | 9832 | const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth()); |
| 9833 | const usize_alignment = @intCast(c_uint, Type.usize.abiSize(target)); | 9833 | const usize_alignment = @intCast(c_uint, Type.usize.abiSize(target)); |
| 9834 | | 9834 | |
| 9835 | switch (target.cpu.arch) { | 9835 | const array_llvm_ty = usize_llvm_ty.arrayType(6); |
| 9836 | .x86_64 => { | 9836 | const array_ptr = fg.valgrind_client_request_array orelse a: { |
| 9837 | const array_llvm_ty = usize_llvm_ty.arrayType(6); | 9837 | const array_ptr = fg.buildAlloca(array_llvm_ty, usize_alignment); |
| 9838 | const array_ptr = fg.valgrind_client_request_array orelse a: { | 9838 | fg.valgrind_client_request_array = array_ptr; |
| 9839 | const array_ptr = fg.buildAlloca(array_llvm_ty, usize_alignment); | 9839 | break :a array_ptr; |
| 9840 | fg.valgrind_client_request_array = array_ptr; | 9840 | }; |
| 9841 | break :a array_ptr; | 9841 | const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 }; |
| 9842 | }; | 9842 | const zero = usize_llvm_ty.constInt(0, .False); |
| 9843 | const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 }; | 9843 | for (array_elements) |elem, i| { |
| 9844 | const zero = usize_llvm_ty.constInt(0, .False); | 9844 | const indexes = [_]*llvm.Value{ |
| 9845 | for (array_elements) |elem, i| { | 9845 | zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False), |
| 9846 | const indexes = [_]*llvm.Value{ | 9846 | }; |
| 9847 | zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False), | 9847 | const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, ""); |
| 9848 | }; | 9848 | const store_inst = fg.builder.buildStore(elem, elem_ptr); |
| 9849 | const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, ""); | 9849 | store_inst.setAlignment(usize_alignment); |
| 9850 | const store_inst = fg.builder.buildStore(elem, elem_ptr); | 9850 | } |
| 9851 | store_inst.setAlignment(usize_alignment); | 9851 | |
| 9852 | } | 9852 | const arch_specific: struct { |
| 9853 | | 9853 | template: [:0]const u8, |
| 9854 | const asm_template = | 9854 | constraints: [:0]const u8, |
| 9855 | \\rolq $$3, %rdi ; rolq $$13, %rdi | 9855 | } = switch (target.cpu.arch) { |
| 9856 | \\rolq $$61, %rdi ; rolq $$51, %rdi | 9856 | .x86 => .{ |
| 9857 | \\xchgq %rbx,%rbx | 9857 | .template = |
| 9858 | ; | 9858 | \\roll $$3, %edi ; roll $$13, %edi |
| 9859 | | 9859 | \\roll $$61, %edi ; roll $$51, %edi |
| 9860 | const asm_constraints = "={rdx},{rax},0,~{cc},~{memory}"; | 9860 | \\xchgl %ebx,%ebx |
| 9861 | | 9861 | , |
| 9862 | const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, ""); | 9862 | .constraints = "={edx},{eax},0,~{cc},~{memory}", |
| 9863 | const args = [_]*llvm.Value{ array_ptr_as_usize, default_value }; | 9863 | }, |
| 9864 | const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty }; | 9864 | .x86_64 => .{ |
| 9865 | const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False); | 9865 | .template = |
| 9866 | const asm_fn = llvm.getInlineAsm( | 9866 | \\rolq $$3, %rdi ; rolq $$13, %rdi |
| 9867 | fn_llvm_ty, | 9867 | \\rolq $$61, %rdi ; rolq $$51, %rdi |
| 9868 | asm_template, | 9868 | \\xchgq %rbx,%rbx |
| 9869 | asm_template.len, | 9869 | , |
| 9870 | asm_constraints, | 9870 | .constraints = "={rdx},{rax},0,~{cc},~{memory}", |
| 9871 | asm_constraints.len, | 9871 | }, |
| 9872 | .True, // has side effects | 9872 | .aarch64, .aarch64_32, .aarch64_be => .{ |
| 9873 | .False, // alignstack | 9873 | .template = |
| 9874 | .ATT, | 9874 | \\ror x12, x12, #3 ; ror x12, x12, #13 |
| 9875 | .False, | 9875 | \\ror x12, x12, #51 ; ror x12, x12, #61 |
| 9876 | ); | 9876 | \\orr x10, x10, x10 |
| 9877 | | 9877 | , |
| 9878 | const call = fg.builder.buildCall( | 9878 | .constraints = "={x3},{x4},0,~{cc},~{memory}", |
| 9879 | fn_llvm_ty, | | |
| 9880 | asm_fn, | | |
| 9881 | &args, | | |
| 9882 | args.len, | | |
| 9883 | .C, | | |
| 9884 | .Auto, | | |
| 9885 | "", | | |
| 9886 | ); | | |
| 9887 | return call; | | |
| 9888 | }, | 9879 | }, |
| 9889 | else => unreachable, | 9880 | else => unreachable, |
| 9890 | } | 9881 | }; |
| | 9882 | |
| | 9883 | const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, ""); |
| | 9884 | const args = [_]*llvm.Value{ array_ptr_as_usize, default_value }; |
| | 9885 | const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty }; |
| | 9886 | const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False); |
| | 9887 | const asm_fn = llvm.getInlineAsm( |
| | 9888 | fn_llvm_ty, |
| | 9889 | arch_specific.template.ptr, |
| | 9890 | arch_specific.template.len, |
| | 9891 | arch_specific.constraints.ptr, |
| | 9892 | arch_specific.constraints.len, |
| | 9893 | .True, // has side effects |
| | 9894 | .False, // alignstack |
| | 9895 | .ATT, |
| | 9896 | .False, // can throw |
| | 9897 | ); |
| | 9898 | |
| | 9899 | const call = fg.builder.buildCall( |
| | 9900 | fn_llvm_ty, |
| | 9901 | asm_fn, |
| | 9902 | &args, |
| | 9903 | args.len, |
| | 9904 | .C, |
| | 9905 | .Auto, |
| | 9906 | "", |
| | 9907 | ); |
| | 9908 | return call; |
| 9891 | } | 9909 | } |
| 9892 | }; | 9910 | }; |
| 9893 | | 9911 | |