Skip to content

Fewer FP registers than available are used for parameter passing on AArch64

Summary

Looking at MachRegs.h, I got the impression that up to four Double parameters are passed on the registers on AArch64.

But, the actual number of register-passed parameters is just two.

This is because MAX_REAL_DOUBLE_REG is defined to be 2 on AArch64. We should define MAX_REAL_DOUBLE_REG to be 4 in MachRegs.h.

(I think s390x also suffer from a similar problem.)

Steps to reproduce

Compile the following Cmm code for AArch64:

#include "Cmm.h"
foo(D_ a, D_ b, D_ c, D_ d) 
{
    return (%fadd(a, b), %fsub(c, d));
}

Expected behavior

I expected that all four parameters would be passed on the register (d12, d13, d14, d15). But the actual assembly code was

foo$def:                                // @"foo$def"
// %bb.0:                               // %c5
	ldp	d0, d1, [x20]
	ldr	x8, [x20, #16]!
	fadd	d12, d12, d13
	fsub	d0, d0, d1
	mov	v13.16b, v0.16b
	blr	x8
	ret

that is, the first two were on the register (d12, d13), but the rest two were on the stack.

Environment

  • GHC version used: 8.8.3
  • Operating System: Ubuntu 18.04.1
  • System Architecture: AArch64
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information