Skip to content

sparc64: passing structures with floats in registers should use floating point registers #57103

Open
@karcherm

Description

@karcherm

librustc_target/abi/call/sparc64.rs passes structures as Uniform, which get allocated to stack or "promoted" to integer registers by LLVM. According to the SPARC v9 64 Bit ABI definition in the SPARC Compliance Definition, floating point members should be promoted into floating point registers instead of integer registers, see page 47 in SCD 2.4.1. This also affects returning of structures, and makes run-pass/structs-enums/struct-return.rs fail. gcc returns the members of struct Floats in %d0, %o1 and %d4, whereas Rust expects the members to be in %o0, %o1 and %o2.

I guess we need to create a CastTarget that contains a mixture of Int and Float registers in the prefix with an empty tail. As structures with at most 256 bits (8 * 32 bits) can be returned in registers, the eight class items in the prefix are enough. I expect that the structures needs to be flattened, so a structure containing a structure containing a float also has the float value passed in a floating point register.

Unaligned Floats and Doubles (with __attribute__((packed))) end up being put in integer registers by gcc and clang, whereas "accidently" aligned floating point members get passed in integer registers by gcc and floating point registers by clang:

// Structure without "packed" declaration
struct str1 {
  float f;  // passed in %f0
  int i;    // passed in least-significant half of %o0
};

// Structure that gets misalignment due to packed declaration
struct str2 {
  short s;  // passed in bits 48..63 of %o0
  float f;  // passed in bits 16..47 of %o0 (due to misalignment)
} __attribute__((packed));

// Layout exactly as str1, but has alignof() 1. Different behaviour between gcc 8.2 and clang 7.0
struct str3 {
  float f;  // passed in most-significant half of %o0 (gcc) or in %f0 (clang)
  int i;    // passed in least-significant half of %o0
} __attribute__((packed));

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-SPARCTarget: SPARC processorsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions