Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
05d66dc7
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
05d66dc7
编写于
2月 14, 2018
作者:
J
James Cowgill
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_trans: add chunked prefix fields to CastTarget
上级
68042ba0
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
53 addition
and
87 deletion
+53
-87
src/librustc_trans/abi.rs
src/librustc_trans/abi.rs
+52
-86
src/librustc_trans/cabi_x86_64.rs
src/librustc_trans/cabi_x86_64.rs
+1
-1
未找到文件。
src/librustc_trans/abi.rs
浏览文件 @
05d66dc7
...
...
@@ -40,7 +40,7 @@
use
rustc
::
ty
::
layout
::{
HasDataLayout
,
LayoutOf
};
use
libc
::
c_uint
;
use
std
::
{
cmp
,
iter
}
;
use
std
::
cmp
;
pub
use
syntax
::
abi
::
Abi
;
pub
use
rustc
::
ty
::
layout
::{
FAT_PTR_ADDR
,
FAT_PTR_EXTRA
};
...
...
@@ -279,30 +279,6 @@ impl Uniform {
pub
fn
align
(
&
self
,
cx
:
&
CodegenCx
)
->
Align
{
self
.unit
.align
(
cx
)
}
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
)
->
Type
{
let
llunit
=
self
.unit
.llvm_type
(
cx
);
if
self
.total
<=
self
.unit.size
{
return
llunit
;
}
let
count
=
self
.total
.bytes
()
/
self
.unit.size
.bytes
();
let
rem_bytes
=
self
.total
.bytes
()
%
self
.unit.size
.bytes
();
if
rem_bytes
==
0
{
return
Type
::
array
(
&
llunit
,
count
);
}
// Only integers can be really split further.
assert_eq!
(
self
.unit.kind
,
RegKind
::
Integer
);
let
args
:
Vec
<
_
>
=
(
0
..
count
)
.map
(|
_
|
llunit
)
.chain
(
iter
::
once
(
Type
::
ix
(
cx
,
rem_bytes
*
8
)))
.collect
();
Type
::
struct_
(
cx
,
&
args
,
false
)
}
}
pub
trait
LayoutExt
<
'tcx
>
{
...
...
@@ -405,91 +381,81 @@ fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg> {
}
#[derive(Clone,
Copy,
PartialEq,
Eq,
Debug)]
pub
enum
CastTarget
{
Uniform
(
Uniform
)
,
Pair
(
Reg
,
Reg
)
,
ChunkedPrefix
{
prefix
:
[
RegKind
;
8
],
chunk
:
Size
,
total
:
Size
}
pub
struct
CastTarget
{
pub
prefix
:
[
Option
<
RegKind
>
;
8
]
,
pub
prefix_chunk
:
Size
,
pub
rest
:
Uniform
,
}
impl
From
<
Reg
>
for
CastTarget
{
fn
from
(
unit
:
Reg
)
->
CastTarget
{
CastTarget
::
Unifor
m
(
Uniform
::
from
(
unit
))
CastTarget
::
fro
m
(
Uniform
::
from
(
unit
))
}
}
impl
From
<
Uniform
>
for
CastTarget
{
fn
from
(
uniform
:
Uniform
)
->
CastTarget
{
CastTarget
::
Uniform
(
uniform
)
CastTarget
{
prefix
:
[
None
;
8
],
prefix_chunk
:
Size
::
from_bytes
(
0
),
rest
:
uniform
}
}
}
impl
CastTarget
{
pub
fn
size
(
&
self
,
cx
:
&
CodegenCx
)
->
Size
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.total
,
CastTarget
::
Pair
(
a
,
b
)
=>
{
(
a
.size
.abi_align
(
a
.align
(
cx
))
+
b
.size
)
.abi_align
(
self
.align
(
cx
))
},
CastTarget
::
ChunkedPrefix
{
total
,
..
}
=>
total
pub
fn
pair
(
a
:
Reg
,
b
:
Reg
)
->
CastTarget
{
CastTarget
{
prefix
:
[
Some
(
a
.kind
),
None
,
None
,
None
,
None
,
None
,
None
,
None
],
prefix_chunk
:
a
.size
,
rest
:
Uniform
::
from
(
b
)
}
}
pub
fn
size
(
&
self
,
cx
:
&
CodegenCx
)
->
Size
{
(
self
.prefix_chunk
*
self
.prefix
.iter
()
.filter
(|
x
|
x
.is_some
())
.count
()
as
u64
)
.abi_align
(
self
.rest
.align
(
cx
))
+
self
.rest.total
}
pub
fn
align
(
&
self
,
cx
:
&
CodegenCx
)
->
Align
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.align
(
cx
),
CastTarget
::
Pair
(
a
,
b
)
=>
{
cx
.data_layout
()
.aggregate_align
.max
(
a
.align
(
cx
))
.max
(
b
.align
(
cx
))
},
CastTarget
::
ChunkedPrefix
{
chunk
,
..
}
=>
{
cx
.data_layout
()
.aggregate_align
.max
(
Reg
{
kind
:
RegKind
::
Integer
,
size
:
chunk
}
.align
(
cx
))
.max
(
Reg
{
kind
:
RegKind
::
Float
,
size
:
chunk
}
.align
(
cx
))
.max
(
Reg
{
kind
:
RegKind
::
Vector
,
size
:
chunk
}
.align
(
cx
))
}
}
self
.prefix
.iter
()
.filter_map
(|
x
|
x
.map
(|
kind
|
Reg
{
kind
:
kind
,
size
:
self
.prefix_chunk
}
.align
(
cx
)))
.fold
(
cx
.data_layout
()
.aggregate_align
.max
(
self
.rest
.align
(
cx
)),
|
acc
,
align
|
acc
.max
(
align
))
}
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
)
->
Type
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.llvm_type
(
cx
),
CastTarget
::
Pair
(
a
,
b
)
=>
{
Type
::
struct_
(
cx
,
&
[
a
.llvm_type
(
cx
),
b
.llvm_type
(
cx
)
],
false
)
},
CastTarget
::
ChunkedPrefix
{
prefix
,
chunk
,
total
}
=>
{
let
total_chunks
=
total
.bytes
()
/
chunk
.bytes
();
let
rem_bytes
=
total
.bytes
()
%
chunk
.bytes
();
let
prefix_chunks
=
total_chunks
.min
(
prefix
.len
()
as
u64
);
let
int_ll_type
=
Reg
{
kind
:
RegKind
::
Integer
,
size
:
chunk
}
.llvm_type
(
cx
);
let
rest_ll_unit
=
self
.rest.unit
.llvm_type
(
cx
);
let
rest_count
=
self
.rest.total
.bytes
()
/
self
.rest.unit.size
.bytes
();
let
rem_bytes
=
self
.rest.total
.bytes
()
%
self
.rest.unit.size
.bytes
();
if
self
.prefix
.iter
()
.all
(|
x
|
x
.is_none
())
{
// Simplify to a single unit when there is no prefix and size <= unit size
if
self
.rest.total
<=
self
.rest.unit.size
{
return
rest_ll_unit
;
}
// Simple cases simplify to an array
if
rem_bytes
==
0
&&
prefix
.into_iter
()
.all
(|
&
kind
|
kind
==
RegKind
::
Integer
)
{
return
Type
::
array
(
&
int_ll_type
,
total_chunks
);
}
// Simplify to array when all chunks are the same size and type
if
rem_bytes
==
0
{
return
Type
::
array
(
&
rest_ll_unit
,
rest_count
);
}
}
// The final structure is made up of:
// Up to 8 chunks of the type specified in the prefix
// Any other complete chunks as integers
// One final integer needed to make up the total structure size
let
mut
args
:
Vec
<
_
>
=
prefix
.into_iter
()
.take
(
prefix_chunks
as
usize
)
.map
(|
&
kind
|
Reg
{
kind
:
kind
,
size
:
chunk
}
.llvm_type
(
cx
))
.chain
((
0
..
total_chunks
-
prefix_chunks
)
.map
(|
_
|
int_ll_type
))
.collect
();
if
rem_bytes
>
0
{
args
.push
(
Type
::
ix
(
cx
,
rem_bytes
*
8
));
}
// Create list of fields in the main structure
let
mut
args
:
Vec
<
_
>
=
self
.prefix
.iter
()
.flat_map
(|
option_kind
|
option_kind
.map
(
|
kind
|
Reg
{
kind
:
kind
,
size
:
self
.prefix_chunk
}
.llvm_type
(
cx
)))
.chain
((
0
..
rest_count
)
.map
(|
_
|
rest_ll_unit
))
.collect
();
Type
::
struct_
(
cx
,
&
args
,
false
)
}
// Append final integer
if
rem_bytes
!=
0
{
// Only integers can be really split further.
assert_eq!
(
self
.rest.unit.kind
,
RegKind
::
Integer
);
args
.push
(
Type
::
ix
(
cx
,
rem_bytes
*
8
));
}
Type
::
struct_
(
cx
,
&
args
,
false
)
}
}
...
...
src/librustc_trans/cabi_x86_64.rs
浏览文件 @
05d66dc7
...
...
@@ -171,7 +171,7 @@ fn cast_target(cls: &[Option<Class>], size: Size) -> CastTarget {
let
mut
target
=
CastTarget
::
from
(
lo
);
if
size
>
offset
{
if
let
Some
(
hi
)
=
reg_component
(
cls
,
&
mut
i
,
size
-
offset
)
{
target
=
CastTarget
::
P
air
(
lo
,
hi
);
target
=
CastTarget
::
p
air
(
lo
,
hi
);
}
}
assert_eq!
(
reg_component
(
cls
,
&
mut
i
,
Size
::
from_bytes
(
0
)),
None
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录