Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
050a71b5
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
050a71b5
编写于
7月 04, 2019
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_target: avoid negative register counts in the SysV x86_64 ABI.
上级
b43eb423
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
129 addition
and
9 deletion
+129
-9
src/librustc_target/abi/call/x86_64.rs
src/librustc_target/abi/call/x86_64.rs
+24
-9
src/test/auxiliary/rust_test_helpers.c
src/test/auxiliary/rust_test_helpers.c
+23
-0
src/test/run-pass/abi-sysv64-arg-passing.rs
src/test/run-pass/abi-sysv64-arg-passing.rs
+36
-0
src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs
...st/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs
+46
-0
未找到文件。
src/librustc_target/abi/call/x86_64.rs
浏览文件 @
050a71b5
...
...
@@ -167,20 +167,23 @@ fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
target
}
const
MAX_INT_REGS
:
usize
=
6
;
// RDI, RSI, RDX, RCX, R8, R9
const
MAX_SSE_REGS
:
usize
=
8
;
// XMM0-7
pub
fn
compute_abi_info
<
'a
,
Ty
,
C
>
(
cx
:
&
C
,
fty
:
&
mut
FnType
<
'a
,
Ty
>
)
where
Ty
:
TyLayoutMethods
<
'a
,
C
>
+
Copy
,
C
:
LayoutOf
<
Ty
=
Ty
,
TyLayout
=
TyLayout
<
'a
,
Ty
>>
+
HasDataLayout
{
let
mut
int_regs
=
6
;
// RDI, RSI, RDX, RCX, R8, R9
let
mut
sse_regs
=
8
;
// XMM0-7
let
mut
int_regs
=
MAX_INT_REGS
;
let
mut
sse_regs
=
MAX_SSE_REGS
;
let
mut
x86_64_ty
=
|
arg
:
&
mut
ArgType
<
'a
,
Ty
>
,
is_arg
:
bool
|
{
let
mut
cls_or_mem
=
classify_arg
(
cx
,
arg
);
let
mut
needed_int
=
0
;
let
mut
needed_sse
=
0
;
if
is_arg
{
if
let
Ok
(
cls
)
=
cls_or_mem
{
let
mut
needed_int
=
0
;
let
mut
needed_sse
=
0
;
for
&
c
in
&
cls
{
match
c
{
Some
(
Class
::
Int
)
=>
needed_int
+=
1
,
...
...
@@ -188,11 +191,23 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
_
=>
{}
}
}
if
arg
.layout
.is_aggregate
()
&&
(
int_regs
<
needed_int
||
sse_regs
<
needed_sse
)
{
match
(
int_regs
.checked_sub
(
needed_int
),
sse_regs
.checked_sub
(
needed_sse
))
{
(
Some
(
left_int
),
Some
(
left_sse
))
=>
{
int_regs
=
left_int
;
sse_regs
=
left_sse
;
}
_
=>
{
// Not enough registers for this argument, so it will be
// passed on the stack, but we only mark aggregates
// explicitly as indirect `byval` arguments, as LLVM will
// automatically put immediates on the stack itself.
if
arg
.layout
.is_aggregate
()
{
cls_or_mem
=
Err
(
Memory
);
}
}
}
}
}
match
cls_or_mem
{
Err
(
Memory
)
=>
{
...
...
@@ -201,14 +216,14 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
}
else
{
// `sret` parameter thus one less integer register available
arg
.make_indirect
();
// NOTE(eddyb) return is handled first, so no registers
// should've been used yet.
assert_eq!
(
int_regs
,
MAX_INT_REGS
);
int_regs
-=
1
;
}
}
Ok
(
ref
cls
)
=>
{
// split into sized chunks passed individually
int_regs
-=
needed_int
;
sse_regs
-=
needed_sse
;
if
arg
.layout
.is_aggregate
()
{
let
size
=
arg
.layout.size
;
arg
.cast_to
(
cast_target
(
cls
,
size
))
...
...
src/test/auxiliary/rust_test_helpers.c
浏览文件 @
050a71b5
...
...
@@ -215,6 +215,29 @@ uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) {
return
f
.
c
;
}
struct
quad_floats
{
float
a
;
float
b
;
float
c
;
float
d
;
};
float
get_c_exhaust_sysv64_ints
(
void
*
a
,
void
*
b
,
void
*
c
,
void
*
d
,
void
*
e
,
void
*
f
,
// `f` used the last integer register, so `g` goes on the stack.
// It also used to bring the "count of available integer registers" down to
// `-1` which broke the next SSE-only aggregate argument (`h`) - see #62350.
void
*
g
,
struct
quad_floats
h
)
{
return
h
.
c
;
}
// Calculates the average of `(x + y) / n` where x: i64, y: f64. There must be exactly n pairs
// passed as variadic arguments. There are two versions of this function: the
// variadic one, and the one that takes a `va_list`.
...
...
src/test/run-pass/abi-sysv64-arg-passing.rs
浏览文件 @
050a71b5
...
...
@@ -20,6 +20,7 @@
// extern-return-TwoU64s
// foreign-fn-with-byval
// issue-28676
// issue-62350-sysv-neg-reg-counts
// struct-return
// ignore-android
...
...
@@ -83,6 +84,9 @@ pub struct S {
#[derive(Copy,
Clone)]
pub
struct
Quad
{
a
:
u64
,
b
:
u64
,
c
:
u64
,
d
:
u64
}
#[derive(Copy,
Clone)]
pub
struct
QuadFloats
{
a
:
f32
,
b
:
f32
,
c
:
f32
,
d
:
f32
}
#[repr(C)]
#[derive(Copy,
Clone)]
pub
struct
Floats
{
a
:
f64
,
b
:
u8
,
c
:
f64
}
...
...
@@ -108,6 +112,16 @@ pub struct Floats { a: f64, b: u8, c: f64 }
pub
fn
get_z
(
x
:
S
)
->
u64
;
pub
fn
get_c_many_params
(
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
f
:
Quad
)
->
u64
;
pub
fn
get_c_exhaust_sysv64_ints
(
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
h
:
QuadFloats
,
)
->
f32
;
pub
fn
rust_dbg_abi_1
(
q
:
Quad
)
->
Quad
;
pub
fn
rust_dbg_abi_2
(
f
:
Floats
)
->
Floats
;
}
...
...
@@ -263,6 +277,27 @@ pub fn issue_28676() {
test
();
}
fn
test_62350
()
{
use
std
::
ptr
;
unsafe
{
let
null
=
ptr
::
null
();
let
q
=
QuadFloats
{
a
:
10.2
,
b
:
20.3
,
c
:
30.4
,
d
:
40.5
};
assert_eq!
(
get_c_exhaust_sysv64_ints
(
null
,
null
,
null
,
null
,
null
,
null
,
null
,
q
),
q
.c
,
);
}
}
pub
fn
issue_62350
()
{
test_62350
();
}
fn
test1
()
{
unsafe
{
let
q
=
Quad
{
a
:
0xaaaa_aaaa_aaaa_aaaa
,
...
...
@@ -321,6 +356,7 @@ fn main() {
extern_return_twou64s
();
foreign_fn_with_byval
();
issue_28676
();
issue_62350
();
struct_return
();
}
...
...
src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs
0 → 100644
浏览文件 @
050a71b5
// run-pass
#![allow(dead_code)]
#![allow(improper_ctypes)]
// ignore-wasm32-bare no libc to test ffi with
#[derive(Copy,
Clone)]
pub
struct
QuadFloats
{
a
:
f32
,
b
:
f32
,
c
:
f32
,
d
:
f32
}
mod
rustrt
{
use
super
::
QuadFloats
;
#[link(name
=
"rust_test_helpers"
,
kind
=
"static"
)]
extern
{
pub
fn
get_c_exhaust_sysv64_ints
(
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
_
:
*
const
(),
h
:
QuadFloats
,
)
->
f32
;
}
}
fn
test
()
{
unsafe
{
let
null
=
std
::
ptr
::
null
();
let
q
=
QuadFloats
{
a
:
10.2
,
b
:
20.3
,
c
:
30.4
,
d
:
40.5
};
assert_eq!
(
rustrt
::
get_c_exhaust_sysv64_ints
(
null
,
null
,
null
,
null
,
null
,
null
,
null
,
q
),
q
.c
,
);
}
}
pub
fn
main
()
{
test
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录