Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
cbeebc5b
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
cbeebc5b
编写于
1月 15, 2018
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_trans: take into account primitives larger than 8 bytes.
上级
da569fa9
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
64 addition
and
55 deletion
+64
-55
src/librustc_trans/cabi_x86_64.rs
src/librustc_trans/cabi_x86_64.rs
+43
-55
src/test/run-pass/issue-38763.rs
src/test/run-pass/issue-38763.rs
+21
-0
未找到文件。
src/librustc_trans/cabi_x86_64.rs
浏览文件 @
cbeebc5b
...
...
@@ -16,9 +16,11 @@
use
rustc
::
ty
::
layout
::{
self
,
TyLayout
,
Size
};
#[derive(Clone,
Copy,
PartialEq,
Debug)]
/// Classification of "eightbyte" components.
// NB: the order of the variants is from general to specific,
// such that `unify(a, b)` is the "smaller" of `a` and `b`.
#[derive(Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Debug)]
enum
Class
{
None
,
Int
,
Sse
,
SseUp
...
...
@@ -32,29 +34,10 @@ enum Class {
const
MAX_EIGHTBYTES
:
usize
=
LARGEST_VECTOR_SIZE
/
64
;
fn
classify_arg
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
ArgType
<
'tcx
>
)
->
Result
<
[
Class
;
MAX_EIGHTBYTES
],
Memory
>
{
fn
unify
(
cls
:
&
mut
[
Class
],
off
:
Size
,
c
:
Class
)
{
let
i
=
(
off
.bytes
()
/
8
)
as
usize
;
let
to_write
=
match
(
cls
[
i
],
c
)
{
(
Class
::
None
,
_
)
=>
c
,
(
_
,
Class
::
None
)
=>
return
,
(
Class
::
Int
,
_
)
|
(
_
,
Class
::
Int
)
=>
Class
::
Int
,
(
Class
::
Sse
,
_
)
|
(
_
,
Class
::
Sse
)
=>
Class
::
Sse
,
(
Class
::
SseUp
,
Class
::
SseUp
)
=>
Class
::
SseUp
};
cls
[
i
]
=
to_write
;
}
->
Result
<
[
Option
<
Class
>
;
MAX_EIGHTBYTES
],
Memory
>
{
fn
classify
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
,
cls
:
&
mut
[
Class
],
cls
:
&
mut
[
Option
<
Class
>
],
off
:
Size
)
->
Result
<
(),
Memory
>
{
if
!
off
.is_abi_aligned
(
layout
.align
)
{
...
...
@@ -64,31 +47,20 @@ fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
return
Ok
(());
}
match
layout
.abi
{
layout
::
Abi
::
Uninhabited
=>
{}
let
mut
c
=
match
layout
.abi
{
layout
::
Abi
::
Uninhabited
=>
return
Ok
(()),
layout
::
Abi
::
Scalar
(
ref
scalar
)
=>
{
let
reg
=
match
scalar
.value
{
match
scalar
.value
{
layout
::
Int
(
..
)
|
layout
::
Pointer
=>
Class
::
Int
,
layout
::
F32
|
layout
::
F64
=>
Class
::
Sse
};
unify
(
cls
,
off
,
reg
);
}
layout
::
Abi
::
Vector
{
ref
element
,
count
}
=>
{
unify
(
cls
,
off
,
Class
::
Sse
);
// everything after the first one is the upper
// half of a register.
let
stride
=
element
.value
.size
(
cx
);
for
i
in
1
..
count
{
let
field_off
=
off
+
stride
*
i
;
unify
(
cls
,
field_off
,
Class
::
SseUp
);
}
}
layout
::
Abi
::
Vector
{
..
}
=>
Class
::
Sse
,
layout
::
Abi
::
ScalarPair
(
..
)
|
layout
::
Abi
::
Aggregate
{
..
}
=>
{
match
layout
.variants
{
...
...
@@ -97,12 +69,26 @@ fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let
field_off
=
off
+
layout
.fields
.offset
(
i
);
classify
(
cx
,
layout
.field
(
cx
,
i
),
cls
,
field_off
)
?
;
}
return
Ok
(());
}
layout
::
Variants
::
Tagged
{
..
}
|
layout
::
Variants
::
NicheFilling
{
..
}
=>
return
Err
(
Memory
),
}
}
};
// Fill in `cls` for scalars (Int/Sse) and vectors (Sse).
let
first
=
(
off
.bytes
()
/
8
)
as
usize
;
let
last
=
((
off
.bytes
()
+
layout
.size
.bytes
()
-
1
)
/
8
)
as
usize
;
for
cls
in
&
mut
cls
[
first
..=
last
]
{
*
cls
=
Some
(
cls
.map_or
(
c
,
|
old
|
old
.min
(
c
)));
// Everything after the first Sse "eightbyte"
// component is the upper half of a register.
if
c
==
Class
::
Sse
{
c
=
Class
::
SseUp
;
}
}
Ok
(())
...
...
@@ -113,23 +99,23 @@ fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
return
Err
(
Memory
);
}
let
mut
cls
=
[
Class
::
None
;
MAX_EIGHTBYTES
];
let
mut
cls
=
[
None
;
MAX_EIGHTBYTES
];
classify
(
cx
,
arg
.layout
,
&
mut
cls
,
Size
::
from_bytes
(
0
))
?
;
if
n
>
2
{
if
cls
[
0
]
!=
Class
::
Sse
{
if
cls
[
0
]
!=
Some
(
Class
::
Sse
)
{
return
Err
(
Memory
);
}
if
cls
[
1
..
n
]
.iter
()
.any
(|
&
c
|
c
!=
Class
::
SseUp
)
{
if
cls
[
1
..
n
]
.iter
()
.any
(|
&
c
|
c
!=
Some
(
Class
::
SseUp
)
)
{
return
Err
(
Memory
);
}
}
else
{
let
mut
i
=
0
;
while
i
<
n
{
if
cls
[
i
]
==
Class
::
SseUp
{
cls
[
i
]
=
Class
::
Sse
;
}
else
if
cls
[
i
]
==
Class
::
Sse
{
if
cls
[
i
]
==
Some
(
Class
::
SseUp
)
{
cls
[
i
]
=
Some
(
Class
::
Sse
)
;
}
else
if
cls
[
i
]
==
Some
(
Class
::
Sse
)
{
i
+=
1
;
while
i
!=
n
&&
cls
[
i
]
==
Class
::
SseUp
{
i
+=
1
;
}
while
i
!=
n
&&
cls
[
i
]
==
Some
(
Class
::
SseUp
)
{
i
+=
1
;
}
}
else
{
i
+=
1
;
}
...
...
@@ -139,14 +125,14 @@ fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
Ok
(
cls
)
}
fn
reg_component
(
cls
:
&
[
Class
],
i
:
&
mut
usize
,
size
:
Size
)
->
Option
<
Reg
>
{
fn
reg_component
(
cls
:
&
[
Option
<
Class
>
],
i
:
&
mut
usize
,
size
:
Size
)
->
Option
<
Reg
>
{
if
*
i
>=
cls
.len
()
{
return
None
;
}
match
cls
[
*
i
]
{
Class
::
None
=>
None
,
Class
::
Int
=>
{
None
=>
None
,
Some
(
Class
::
Int
)
=>
{
*
i
+=
1
;
Some
(
match
size
.bytes
()
{
1
=>
Reg
::
i8
(),
...
...
@@ -156,8 +142,10 @@ fn reg_component(cls: &[Class], i: &mut usize, size: Size) -> Option<Reg> {
_
=>
Reg
::
i64
()
})
}
Class
::
Sse
=>
{
let
vec_len
=
1
+
cls
[
*
i
+
1
..
]
.iter
()
.take_while
(|
&&
c
|
c
==
Class
::
SseUp
)
.count
();
Some
(
Class
::
Sse
)
=>
{
let
vec_len
=
1
+
cls
[
*
i
+
1
..
]
.iter
()
.take_while
(|
&&
c
|
c
==
Some
(
Class
::
SseUp
))
.count
();
*
i
+=
vec_len
;
Some
(
if
vec_len
==
1
{
match
size
.bytes
()
{
...
...
@@ -171,11 +159,11 @@ fn reg_component(cls: &[Class], i: &mut usize, size: Size) -> Option<Reg> {
}
})
}
c
=>
bug!
(
"reg_component: unhandled class {:?}"
,
c
)
Some
(
c
)
=>
bug!
(
"reg_component: unhandled class {:?}"
,
c
)
}
}
fn
cast_target
(
cls
:
&
[
Class
],
size
:
Size
)
->
CastTarget
{
fn
cast_target
(
cls
:
&
[
Option
<
Class
>
],
size
:
Size
)
->
CastTarget
{
let
mut
i
=
0
;
let
lo
=
reg_component
(
cls
,
&
mut
i
,
size
)
.unwrap
();
let
offset
=
Size
::
from_bytes
(
8
)
*
(
i
as
u64
);
...
...
@@ -203,8 +191,8 @@ pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tc
Ok
(
ref
cls
)
if
is_arg
=>
{
for
&
c
in
cls
{
match
c
{
Class
::
Int
=>
needed_int
+=
1
,
Class
::
Sse
=>
needed_sse
+=
1
,
Some
(
Class
::
Int
)
=>
needed_int
+=
1
,
Some
(
Class
::
Sse
)
=>
needed_sse
+=
1
,
_
=>
{}
}
}
...
...
src/test/run-pass/issue-38763.rs
0 → 100644
浏览文件 @
cbeebc5b
// Copyright 2018 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.
#![feature(i128_type)]
#[repr(C)]
pub
struct
Foo
(
i128
);
#[no_mangle]
pub
extern
"C"
fn
foo
(
x
:
Foo
)
->
Foo
{
x
}
fn
main
()
{
foo
(
Foo
(
1
));
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录