| ... | @@ -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)); |
| 9841 | | 9841 | |
| 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 { |
| 9860 | | 9860 | template: [:0]const u8, |
| 9861 | const asm_template = | 9861 | constraints: [:0]const u8, |
| 9862 | \\rolq $$3, %rdi ; rolq $$13, %rdi | 9862 | } = switch (target.cpu.arch) { |
| 9863 | \\rolq $$61, %rdi ; rolq $$51, %rdi | 9863 | .x86 => .{ |
| 9864 | \\xchgq %rbx,%rbx | 9864 | .template = |
| 9865 | ; | 9865 | \\roll $$3, %edi ; roll $$13, %edi |
| 9866 | | 9866 | \\roll $$61, %edi ; roll $$51, %edi |
| 9867 | const asm_constraints = "={rdx},{rax},0,~{cc},~{memory}"; | 9867 | \\xchgl %ebx,%ebx |
| 9868 | | 9868 | , |
| 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 effects | 9879 | .aarch64, .aarch64_32, .aarch64_be => .{ |
| 9880 | .False, // alignstack | 9880 | .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 |
| 9884 | | 9884 | , |
| 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 | }; |
| 9900 | | 9918 | |