-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sparc ABI issue when C program calls Rust function which returns structure #52638
Comments
On 32-bit SPARC structs are always returned indirectly (extra pointer passed to the function at the start of the parameter array, although on 32-bit SPARC this is always a reserved slot) and will set GetMyStruct: ; sparc32-linux-gnu
ld [%sp+64], %g1 ; Load return value pointer
mov 1, %g2 ; Put true in register
mov %g1, %o0 ; Put pointer in %o0 for caller
jmp %o7+12 ; Return (skipping over unimp)
stb %g2, [%g1] ; Write true to struct (delay slot) GetMyStruct: ; sparc64-linux-gnu
mov 1, %o0 ; Put true in register
jmp %o7+8 ; Return (no unimp on sparc64)
sllx %o0, 56, %o0 ; Move true to top byte (delay slot) Note that 32-bit SPARC has an immediate of 12 for its jump (i.e. skipping over 3 instructions, not just the call/delay slot pair), as a call site which is expecting a struct return value includes an |
I'm building 64bit code (Rust on Solaris supports just 64bits).
|
Where g++ compiles following:
into:
|
I don't know why it's spilling |
@jrtc27 I think I understand now need to shift. Is there any similar code I could leverage? I'm still rust beginner.. Thanks! |
I'm experimenting with following and few my test cases work with it:
|
Is there a normative document on SPARC ABI anywhere? cc @eddyb (as you fiddle around the cabi a lot) |
Yes, the SPARC Compliance Definition; for 64-bit, the latest is SCD 2.4.1 (2.3 for 32-bit). They're available from http://sparc.org/technical-documents/. |
(EDIT: ignore whatever stupid stuff I said here, this stupid stuff has been removed since) Test code#![feature(no_core, lang_items)]
#![no_core]
#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }
#[repr(C)]
pub struct Bool {
b: bool,
}
pub fn plainbool() -> bool {
true
}
pub fn structbool() -> Bool {
Bool { b: true }
} when compiled as such: rustc llvm-ir
as opposed to the following IR as generated by clang: clang llvm-ir
This is extremely weird behaviour, and will probably be fairly difficult to implement. I’m honestly fairly surprised that the patch above does work. |
@psumbera The patch above is fine. Do you want to submit a PR with it? |
sparc ABI issue - structure returning from function is returned in 64bit registers (with tests) Fixes rust-lang#52638 Supersedes rust-lang#52730 cc @psumbera
This was original encountered with Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1476252
Following is sample program which builds on https://github.com/alexcrichton/rust-ffi-examples
The issue is that on Sparc (tested on Solaris) the returing structure contains just zeros (on intel Solaris it works as expected).
The text was updated successfully, but these errors were encountered: