-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust_trans: struct argument over ffi were passed incorrectly in some …
…situations on x86_64.
- Loading branch information
Showing
4 changed files
with
395 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-include ../tools.mk | ||
|
||
all: $(call NATIVE_STATICLIB,test) | ||
$(RUSTC) test.rs | ||
$(call RUN,test) || exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#include <assert.h> | ||
#include <stdint.h> | ||
|
||
struct Rect { | ||
int32_t a; | ||
int32_t b; | ||
int32_t c; | ||
int32_t d; | ||
}; | ||
|
||
struct BiggerRect { | ||
struct Rect s; | ||
int32_t a; | ||
int32_t b; | ||
}; | ||
|
||
struct FloatRect { | ||
int32_t a; | ||
int32_t b; | ||
double c; | ||
}; | ||
|
||
struct Huge { | ||
int32_t a; | ||
int32_t b; | ||
int32_t c; | ||
int32_t d; | ||
int32_t e; | ||
}; | ||
|
||
// SysV ABI: | ||
// a, b, c, d, e should be in registers | ||
// s should be byval pointer | ||
void byval_rect(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(c == 3); | ||
assert(d == 4); | ||
assert(e == 5); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b, c, d, e, f, g should be in sse registers | ||
// s should be split across 2 registers | ||
// t should be byval pointer | ||
void byval_rect_floats(float a, float b, double c, float d, float e, | ||
float f, double g, struct Rect s, struct FloatRect t) { | ||
assert(a == 1.); | ||
assert(b == 2.); | ||
assert(c == 3.); | ||
assert(d == 4.); | ||
assert(e == 5.); | ||
assert(f == 6.); | ||
assert(g == 7.); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
assert(t.a == 3489); | ||
assert(t.b == 3490); | ||
assert(t.c == 8.); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b, d, e should be in registers | ||
// c passed via sse registers | ||
// s should be byval pointer | ||
void byval_rect_with_float(int32_t a, int32_t b, float c, int32_t d, | ||
int32_t e, int32_t f, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(c == 3.); | ||
assert(d == 4); | ||
assert(e == 5); | ||
assert(f == 6); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b should be in registers | ||
// s should be split across 2 registers | ||
void split_rect(int32_t a, int32_t b, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b should be in sse registers | ||
// s should be split across int32_t & sse registers | ||
void split_rect_floats(float a, float b, struct FloatRect s) { | ||
assert(a == 1.); | ||
assert(b == 2.); | ||
assert(s.a == 3489); | ||
assert(s.b == 3490); | ||
assert(s.c == 8.); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b, d, f should be in registers | ||
// c, e passed via sse registers | ||
// s should be split across 2 registers | ||
void split_rect_with_floats(int32_t a, int32_t b, float c, | ||
int32_t d, float e, int32_t f, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(c == 3.); | ||
assert(d == 4); | ||
assert(e == 5.); | ||
assert(f == 6); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b, c should be in registers | ||
// s should be split across 2 registers | ||
// t should be a byval pointer | ||
void split_and_byval_rect(int32_t a, int32_t b, int32_t c, struct Rect s, struct Rect t) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(c == 3); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
assert(t.a == 553); | ||
assert(t.b == 554); | ||
assert(t.c == 555); | ||
assert(t.d == 556); | ||
} | ||
|
||
// SysV ABI: | ||
// a, b should in registers | ||
// s and return should be split across 2 registers | ||
struct Rect split_ret_byval_struct(int32_t a, int32_t b, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
return s; | ||
} | ||
|
||
// SysV ABI: | ||
// a, b, c, d should be in registers | ||
// return should be in a hidden sret pointer | ||
// s should be a byval pointer | ||
struct BiggerRect sret_byval_struct(int32_t a, int32_t b, int32_t c, int32_t d, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(c == 3); | ||
assert(d == 4); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
|
||
struct BiggerRect t; | ||
t.s = s; t.a = 27834; t.b = 7657; | ||
return t; | ||
} | ||
|
||
// SysV ABI: | ||
// a, b should be in registers | ||
// return should be in a hidden sret pointer | ||
// s should be split across 2 registers | ||
struct BiggerRect sret_split_struct(int32_t a, int32_t b, struct Rect s) { | ||
assert(a == 1); | ||
assert(b == 2); | ||
assert(s.a == 553); | ||
assert(s.b == 554); | ||
assert(s.c == 555); | ||
assert(s.d == 556); | ||
|
||
struct BiggerRect t; | ||
t.s = s; t.a = 27834; t.b = 7657; | ||
return t; | ||
} | ||
|
||
// SysV ABI: | ||
// s should be byval pointer (since sizeof(s) > 16) | ||
// return should in a hidden sret pointer | ||
struct Huge huge_struct(struct Huge s) { | ||
assert(s.a == 5647); | ||
assert(s.b == 5648); | ||
assert(s.c == 5649); | ||
assert(s.d == 5650); | ||
assert(s.e == 5651); | ||
|
||
return s; | ||
} |
Oops, something went wrong.