Auto merge of #134290 - tgross35:windows-i128-callconv, r=bjorn3,wesl… · rust-lang/rust@66d6064 (original) (raw)

1

``

`-

use rustc_abi::{BackendRepr, Float, Primitive};

`

``

1

`+

use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size};

`

2

2

``

3

3

`use crate::abi:🤙:{ArgAbi, FnAbi, Reg};

`

4

4

`use crate::spec::HasTargetSpec;

`

5

5

``

6

6

`// Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing

`

7

7

``

8

8

`pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {

`

9

``

`-

let fixup = |a: &mut ArgAbi<'_, Ty>| {

`

``

9

`+

let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| {

`

10

10

`match a.layout.backend_repr {

`

11

11

`BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}

`

12

12

`BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => {

`

`@@ -23,11 +23,16 @@ pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<

`

23

23

`// (probably what clang calls "illegal vectors").

`

24

24

`}

`

25

25

`BackendRepr::Scalar(scalar) => {

`

26

``

`` -

// Match what LLVM does for f128 so that compiler-builtins builtins match up

``

27

``

`-

// with what LLVM expects.

`

28

``

`-

if a.layout.size.bytes() > 8

`

``

26

`+

if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) {

`

``

27

`` +

// i128 is returned in xmm0 by Clang and GCC

``

``

28

`` +

// FIXME(#134288): This may change for the -msvc targets in the future.

``

``

29

`+

let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) };

`

``

30

`+

a.cast_to(reg);

`

``

31

`+

} else if a.layout.size.bytes() > 8

`

29

32

` && !matches!(scalar.primitive(), Primitive::Float(Float::F128))

`

30

33

`{

`

``

34

`` +

// Match what LLVM does for f128 so that compiler-builtins builtins match up

``

``

35

`+

// with what LLVM expects.

`

31

36

` a.make_indirect();

`

32

37

`} else {

`

33

38

` a.extend_integer_width_to(32);

`

`@@ -37,8 +42,9 @@ pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<

`

37

42

`};

`

38

43

``

39

44

`if !fn_abi.ret.is_ignore() {

`

40

``

`-

fixup(&mut fn_abi.ret);

`

``

45

`+

fixup(&mut fn_abi.ret, true);

`

41

46

`}

`

``

47

+

42

48

`for arg in fn_abi.args.iter_mut() {

`

43

49

`if arg.is_ignore() && arg.layout.is_zst() {

`

44

50

`// Windows ABIs do not talk about ZST since such types do not exist in MSVC.

`

`@@ -49,7 +55,7 @@ pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<

`

49

55

` arg.make_indirect_from_ignore();

`

50

56

`continue;

`

51

57

`}

`

52

``

`-

fixup(arg);

`

``

58

`+

fixup(arg, false);

`

53

59

`}

`

54

60

`// FIXME: We should likely also do something about ZST return types, similar to above.

`

55

61

`` // However, that's non-trivial due to ().

``