Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
de3e581e
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,发现更多精彩内容 >>
提交
de3e581e
编写于
9月 23, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: support u128 discriminant ranges.
上级
018323ff
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
70 addition
and
101 deletion
+70
-101
src/librustc/lib.rs
src/librustc/lib.rs
+1
-0
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+15
-19
src/librustc_trans/builder.rs
src/librustc_trans/builder.rs
+10
-18
src/librustc_trans/common.rs
src/librustc_trans/common.rs
+2
-2
src/librustc_trans/meth.rs
src/librustc_trans/meth.rs
+2
-1
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/block.rs
+6
-5
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+4
-4
src/librustc_trans/mir/lvalue.rs
src/librustc_trans/mir/lvalue.rs
+25
-47
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/mir/rvalue.rs
+5
-5
未找到文件。
src/librustc/lib.rs
浏览文件 @
de3e581e
...
...
@@ -46,6 +46,7 @@
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![feature(i128)]
#![feature(i128_type)]
#![feature(inclusive_range)]
#![feature(inclusive_range_syntax)]
...
...
src/librustc/ty/layout.rs
浏览文件 @
de3e581e
...
...
@@ -20,7 +20,7 @@
use
std
::
cmp
;
use
std
::
fmt
;
use
std
::
i
64
;
use
std
::
i
128
;
use
std
::
iter
;
use
std
::
mem
;
use
std
::
ops
::{
Add
,
Sub
,
Mul
,
AddAssign
,
Deref
,
RangeInclusive
};
...
...
@@ -467,7 +467,7 @@ pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, signed: bool) -> Ty<'tcx> {
}
/// Find the smallest Integer type which can represent the signed value.
pub
fn
fit_signed
(
x
:
i
64
)
->
Integer
{
pub
fn
fit_signed
(
x
:
i
128
)
->
Integer
{
match
x
{
-
0x0000_0000_0000_0001
...
0x0000_0000_0000_0000
=>
I1
,
-
0x0000_0000_0000_0080
...
0x0000_0000_0000_007f
=>
I8
,
...
...
@@ -479,7 +479,7 @@ pub fn fit_signed(x: i64) -> Integer {
}
/// Find the smallest Integer type which can represent the unsigned value.
pub
fn
fit_unsigned
(
x
:
u
64
)
->
Integer
{
pub
fn
fit_unsigned
(
x
:
u
128
)
->
Integer
{
match
x
{
0
...
0x0000_0000_0000_0001
=>
I1
,
0
...
0x0000_0000_0000_00ff
=>
I8
,
...
...
@@ -495,7 +495,7 @@ pub fn for_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Option<Integer> {
let
dl
=
cx
.data_layout
();
let
wanted
=
align
.abi
();
for
&
candidate
in
&
[
I8
,
I16
,
I32
,
I64
]
{
for
&
candidate
in
&
[
I8
,
I16
,
I32
,
I64
,
I128
]
{
let
ty
=
Int
(
candidate
,
false
);
if
wanted
==
ty
.align
(
dl
)
.abi
()
&&
wanted
==
ty
.size
(
dl
)
.bytes
()
{
return
Some
(
candidate
);
...
...
@@ -522,19 +522,19 @@ pub fn from_attr<C: HasDataLayout>(cx: C, ity: attr::IntType) -> Integer {
/// Find the appropriate Integer type and signedness for the given
/// signed discriminant range and #[repr] attribute.
/// N.B.: u
64 values above i64
::MAX will be treated as signed, but
/// N.B.: u
128 values above i128
::MAX will be treated as signed, but
/// that shouldn't affect anything, other than maybe debuginfo.
fn
repr_discr
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
repr
:
&
ReprOptions
,
min
:
i
64
,
max
:
i
64
)
min
:
i
128
,
max
:
i
128
)
->
(
Integer
,
bool
)
{
// Theoretically, negative values could be larger in unsigned representation
// than the unsigned representation of the signed minimum. However, if there
// are any negative values, the only valid unsigned representation is u
64
// which can fit all i
64
values, so the result remains unaffected.
let
unsigned_fit
=
Integer
::
fit_unsigned
(
cmp
::
max
(
min
as
u
64
,
max
as
u64
));
// are any negative values, the only valid unsigned representation is u
128
// which can fit all i
128
values, so the result remains unaffected.
let
unsigned_fit
=
Integer
::
fit_unsigned
(
cmp
::
max
(
min
as
u
128
,
max
as
u128
));
let
signed_fit
=
cmp
::
max
(
Integer
::
fit_signed
(
min
),
Integer
::
fit_signed
(
max
));
let
mut
min_from_extern
=
None
;
...
...
@@ -782,11 +782,11 @@ pub enum Variants {
Tagged
{
discr
:
Primitive
,
/// Inclusive wrap-around range of discriminant values, that is,
/// if min > max, it represents min..=u
64
::MAX followed by 0..=max.
/// if min > max, it represents min..=u
128
::MAX followed by 0..=max.
// FIXME(eddyb) always use the shortest range, e.g. by finding
// the largest space between two consecutive discriminants and
// taking everything else as the (shortest) discriminant range.
discr_range
:
RangeInclusive
<
u
64
>
,
discr_range
:
RangeInclusive
<
u
128
>
,
variants
:
Vec
<
CachedLayout
>
,
},
...
...
@@ -1375,14 +1375,12 @@ enum StructKind {
}
}
let
(
mut
min
,
mut
max
)
=
(
i
64
::
max_value
(),
i64
::
min_value
());
let
(
mut
min
,
mut
max
)
=
(
i
128
::
max_value
(),
i128
::
min_value
());
for
discr
in
def
.discriminants
(
tcx
)
{
let
x
=
discr
.to_u128_unchecked
()
as
i
64
;
let
x
=
discr
.to_u128_unchecked
()
as
i
128
;
if
x
<
min
{
min
=
x
;
}
if
x
>
max
{
max
=
x
;
}
}
// FIXME: should handle i128? signed-value based impl is weird and hard to
// grok.
let
(
min_ity
,
signed
)
=
Integer
::
repr_discr
(
tcx
,
ty
,
&
def
.repr
,
min
,
max
);
let
mut
align
=
dl
.aggregate_align
;
...
...
@@ -1479,9 +1477,7 @@ enum StructKind {
tcx
.intern_layout
(
CachedLayout
{
variants
:
Variants
::
Tagged
{
discr
,
// FIXME: should be u128?
discr_range
:
(
min
as
u64
)
..=
(
max
as
u64
),
discr_range
:
(
min
as
u128
)
..=
(
max
as
u128
),
variants
},
// FIXME(eddyb): using `FieldPlacement::Arbitrary` here results
...
...
src/librustc_trans/builder.rs
浏览文件 @
de3e581e
...
...
@@ -24,6 +24,7 @@
use
std
::
borrow
::
Cow
;
use
std
::
ffi
::
CString
;
use
std
::
ops
::
Range
;
use
std
::
ptr
;
use
syntax_pos
::
Span
;
...
...
@@ -549,35 +550,26 @@ pub fn atomic_load(&self, ptr: ValueRef, order: AtomicOrdering, align: Align) ->
}
pub
fn
load_range_assert
(
&
self
,
ptr
:
ValueRef
,
lo
:
u64
,
hi
:
u64
,
signed
:
llvm
::
Bool
,
align
:
Option
<
Align
>
)
->
ValueRef
{
let
value
=
self
.load
(
ptr
,
align
);
pub
fn
range_metadata
(
&
self
,
load
:
ValueRef
,
range
:
Range
<
u128
>
)
{
unsafe
{
let
t
=
llvm
::
LLVMGetElementType
(
llvm
::
LLVMTypeOf
(
ptr
)
);
let
min
=
llvm
::
LLVMConstInt
(
t
,
lo
,
signed
);
let
max
=
llvm
::
LLVMConstInt
(
t
,
hi
,
signed
);
let
v
=
[
min
,
max
];
let
llty
=
val_ty
(
load
);
let
v
=
[
C_uint_big
(
llty
,
range
.start
),
C_uint_big
(
llty
,
range
.end
)
];
llvm
::
LLVMSetMetadata
(
value
,
llvm
::
MD_range
as
c_uint
,
llvm
::
LLVMSetMetadata
(
load
,
llvm
::
MD_range
as
c_uint
,
llvm
::
LLVMMDNodeInContext
(
self
.ccx
.llcx
(),
v
.as_ptr
(),
v
.len
()
as
c_uint
));
}
value
}
pub
fn
load_nonnull
(
&
self
,
ptr
:
ValueRef
,
align
:
Option
<
Align
>
)
->
ValueRef
{
let
value
=
self
.load
(
ptr
,
align
);
pub
fn
nonnull_metadata
(
&
self
,
load
:
ValueRef
)
{
unsafe
{
llvm
::
LLVMSetMetadata
(
value
,
llvm
::
MD_nonnull
as
c_uint
,
llvm
::
LLVMSetMetadata
(
load
,
llvm
::
MD_nonnull
as
c_uint
,
llvm
::
LLVMMDNodeInContext
(
self
.ccx
.llcx
(),
ptr
::
null
(),
0
));
}
value
}
pub
fn
store
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
,
align
:
Option
<
Align
>
)
->
ValueRef
{
...
...
src/librustc_trans/common.rs
浏览文件 @
de3e581e
...
...
@@ -178,9 +178,9 @@ pub fn C_uint(t: Type, i: u64) -> ValueRef {
}
}
pub
fn
C_
big_integral
(
t
:
Type
,
u
:
u128
)
->
ValueRef
{
pub
fn
C_
uint_big
(
t
:
Type
,
u
:
u128
)
->
ValueRef
{
unsafe
{
let
words
=
[
u
as
u64
,
u
.wrapping_shr
(
64
)
as
u64
];
let
words
=
[
u
as
u64
,
(
u
>>
64
)
as
u64
];
llvm
::
LLVMConstIntOfArbitraryPrecision
(
t
.to_ref
(),
2
,
words
.as_ptr
())
}
}
...
...
src/librustc_trans/meth.rs
浏览文件 @
de3e581e
...
...
@@ -40,7 +40,8 @@ pub fn get_fn(self, bcx: &Builder<'a, 'tcx>,
debug!
(
"get_fn({:?}, {:?})"
,
Value
(
llvtable
),
self
);
let
llvtable
=
bcx
.pointercast
(
llvtable
,
fn_ty
.llvm_type
(
bcx
.ccx
)
.ptr_to
()
.ptr_to
());
let
ptr
=
bcx
.load_nonnull
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.ccx
,
self
.0
)]),
None
);
let
ptr
=
bcx
.load
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.ccx
,
self
.0
)]),
None
);
bcx
.nonnull_metadata
(
ptr
);
// Vtable loads are invariant
bcx
.set_invariant_load
(
ptr
);
ptr
...
...
src/librustc_trans/mir/block.rs
浏览文件 @
de3e581e
...
...
@@ -666,17 +666,18 @@ fn trans_argument(&mut self,
if
by_ref
&&
!
arg
.is_indirect
()
{
// Have to load the argument, maybe while casting it.
if
arg
.layout.ty
==
bcx
.tcx
()
.types.bool
{
llval
=
bcx
.load_range_assert
(
llval
,
0
,
2
,
llvm
::
False
,
None
);
// We store bools as i8 so we need to truncate to i1.
llval
=
base
::
to_immediate
(
bcx
,
llval
,
arg
.layout
);
}
else
if
let
Some
(
ty
)
=
arg
.cast
{
if
let
Some
(
ty
)
=
arg
.cast
{
llval
=
bcx
.load
(
bcx
.pointercast
(
llval
,
ty
.llvm_type
(
bcx
.ccx
)
.ptr_to
()),
(
align
|
Alignment
::
Packed
(
arg
.layout.align
))
.non_abi
());
}
else
{
llval
=
bcx
.load
(
llval
,
align
.non_abi
());
}
if
arg
.layout.ty
==
bcx
.tcx
()
.types.bool
{
bcx
.range_metadata
(
llval
,
0
..
2
);
// We store bools as i8 so we need to truncate to i1.
llval
=
base
::
to_immediate
(
bcx
,
llval
,
arg
.layout
);
}
}
llargs
.push
(
llval
);
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
de3e581e
...
...
@@ -28,7 +28,7 @@
use
callee
;
use
builder
::
Builder
;
use
common
::{
self
,
CrateContext
,
const_get_elt
,
val_ty
};
use
common
::{
C_array
,
C_bool
,
C_bytes
,
C_int
,
C_uint
,
C_
big_integral
,
C_u32
,
C_u64
};
use
common
::{
C_array
,
C_bool
,
C_bytes
,
C_int
,
C_uint
,
C_
uint_big
,
C_u32
,
C_u64
};
use
common
::{
C_null
,
C_struct
,
C_str_slice
,
C_undef
,
C_usize
,
C_vector
,
C_fat_ptr
};
use
common
::
const_to_opt_u128
;
use
consts
;
...
...
@@ -70,13 +70,13 @@ pub fn from_constint(ccx: &CrateContext<'a, 'tcx>, ci: &ConstInt) -> Const<'tcx>
I16
(
v
)
=>
(
C_int
(
Type
::
i16
(
ccx
),
v
as
i64
),
tcx
.types.i16
),
I32
(
v
)
=>
(
C_int
(
Type
::
i32
(
ccx
),
v
as
i64
),
tcx
.types.i32
),
I64
(
v
)
=>
(
C_int
(
Type
::
i64
(
ccx
),
v
as
i64
),
tcx
.types.i64
),
I128
(
v
)
=>
(
C_
big_integral
(
Type
::
i128
(
ccx
),
v
as
u128
),
tcx
.types.i128
),
I128
(
v
)
=>
(
C_
uint_big
(
Type
::
i128
(
ccx
),
v
as
u128
),
tcx
.types.i128
),
Isize
(
v
)
=>
(
C_int
(
Type
::
isize
(
ccx
),
v
.as_i64
()),
tcx
.types.isize
),
U8
(
v
)
=>
(
C_uint
(
Type
::
i8
(
ccx
),
v
as
u64
),
tcx
.types.u8
),
U16
(
v
)
=>
(
C_uint
(
Type
::
i16
(
ccx
),
v
as
u64
),
tcx
.types.u16
),
U32
(
v
)
=>
(
C_uint
(
Type
::
i32
(
ccx
),
v
as
u64
),
tcx
.types.u32
),
U64
(
v
)
=>
(
C_uint
(
Type
::
i64
(
ccx
),
v
),
tcx
.types.u64
),
U128
(
v
)
=>
(
C_
big_integral
(
Type
::
i128
(
ccx
),
v
),
tcx
.types.u128
),
U128
(
v
)
=>
(
C_
uint_big
(
Type
::
i128
(
ccx
),
v
),
tcx
.types.u128
),
Usize
(
v
)
=>
(
C_uint
(
Type
::
isize
(
ccx
),
v
.as_u64
()),
tcx
.types.usize
),
};
Const
{
llval
:
llval
,
ty
:
ty
}
...
...
@@ -994,7 +994,7 @@ unsafe fn cast_const_float_to_int(ccx: &CrateContext,
let
err
=
ConstEvalErr
{
span
:
span
,
kind
:
ErrKind
::
CannotCast
};
err
.report
(
ccx
.tcx
(),
span
,
"expression"
);
}
C_
big_integral
(
int_ty
,
cast_result
.value
)
C_
uint_big
(
int_ty
,
cast_result
.value
)
}
unsafe
fn
cast_const_int_to_float
(
ccx
:
&
CrateContext
,
...
...
src/librustc_trans/mir/lvalue.rs
浏览文件 @
de3e581e
...
...
@@ -14,10 +14,9 @@
use
rustc
::
mir
;
use
rustc
::
mir
::
tcx
::
LvalueTy
;
use
rustc_data_structures
::
indexed_vec
::
Idx
;
use
abi
;
use
base
;
use
builder
::
Builder
;
use
common
::{
self
,
CrateContext
,
C_usize
,
C_u8
,
C_u32
,
C_uint
,
C_int
,
C_null
,
val_ty
};
use
common
::{
self
,
CrateContext
,
C_usize
,
C_u8
,
C_u32
,
C_uint
,
C_int
,
C_null
};
use
consts
;
use
type_of
::
LayoutLlvmExt
;
use
type_
::
Type
;
...
...
@@ -140,30 +139,7 @@ pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
return
OperandRef
::
new_zst
(
bcx
.ccx
,
self
.layout
);
}
let
val
=
if
common
::
type_is_fat_ptr
(
bcx
.ccx
,
self
.layout.ty
)
{
let
data
=
self
.project_field
(
bcx
,
abi
::
FAT_PTR_ADDR
);
let
lldata
=
if
self
.layout.ty
.is_region_ptr
()
||
self
.layout.ty
.is_box
()
{
bcx
.load_nonnull
(
data
.llval
,
data
.alignment
.non_abi
())
}
else
{
bcx
.load
(
data
.llval
,
data
.alignment
.non_abi
())
};
let
extra
=
self
.project_field
(
bcx
,
abi
::
FAT_PTR_EXTRA
);
let
meta_ty
=
val_ty
(
extra
.llval
);
// If the 'extra' field is a pointer, it's a vtable, so use load_nonnull
// instead
let
llextra
=
if
meta_ty
.element_type
()
.kind
()
==
llvm
::
TypeKind
::
Pointer
{
bcx
.load_nonnull
(
extra
.llval
,
extra
.alignment
.non_abi
())
}
else
{
bcx
.load
(
extra
.llval
,
extra
.alignment
.non_abi
())
};
OperandValue
::
Pair
(
lldata
,
llextra
)
}
else
if
common
::
type_is_imm_pair
(
bcx
.ccx
,
self
.layout.ty
)
{
OperandValue
::
Pair
(
self
.project_field
(
bcx
,
0
)
.load
(
bcx
)
.pack_if_pair
(
bcx
)
.immediate
(),
self
.project_field
(
bcx
,
1
)
.load
(
bcx
)
.pack_if_pair
(
bcx
)
.immediate
())
}
else
if
self
.layout
.is_llvm_immediate
()
{
let
val
=
if
self
.layout
.is_llvm_immediate
()
{
let
mut
const_llval
=
ptr
::
null_mut
();
unsafe
{
let
global
=
llvm
::
LLVMIsAGlobalVariable
(
self
.llval
);
...
...
@@ -174,22 +150,26 @@ pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
let
llval
=
if
!
const_llval
.is_null
()
{
const_llval
}
else
if
self
.layout.ty
.is_bool
()
{
bcx
.load_range_assert
(
self
.llval
,
0
,
2
,
llvm
::
False
,
self
.alignment
.non_abi
())
}
else
if
self
.layout.ty
.is_char
()
{
// a char is a Unicode codepoint, and so takes values from 0
// to 0x10FFFF inclusive only.
bcx
.load_range_assert
(
self
.llval
,
0
,
0x10FFFF
+
1
,
llvm
::
False
,
self
.alignment
.non_abi
())
}
else
if
self
.layout.ty
.is_region_ptr
()
||
self
.layout.ty
.is_box
()
||
self
.layout.ty
.is_fn
()
{
bcx
.load_nonnull
(
self
.llval
,
self
.alignment
.non_abi
())
}
else
{
bcx
.load
(
self
.llval
,
self
.alignment
.non_abi
())
let
load
=
bcx
.load
(
self
.llval
,
self
.alignment
.non_abi
());
if
self
.layout.ty
.is_bool
()
{
bcx
.range_metadata
(
load
,
0
..
2
);
}
else
if
self
.layout.ty
.is_char
()
{
// a char is a Unicode codepoint, and so takes values from 0
// to 0x10FFFF inclusive only.
bcx
.range_metadata
(
load
,
0
..
0x10FFFF
+
1
);
}
else
if
self
.layout.ty
.is_region_ptr
()
||
self
.layout.ty
.is_box
()
||
self
.layout.ty
.is_fn
()
{
bcx
.nonnull_metadata
(
load
);
}
load
};
OperandValue
::
Immediate
(
base
::
to_immediate
(
bcx
,
llval
,
self
.layout
))
}
else
if
common
::
type_is_imm_pair
(
bcx
.ccx
,
self
.layout.ty
)
{
OperandValue
::
Pair
(
self
.project_field
(
bcx
,
0
)
.load
(
bcx
)
.pack_if_pair
(
bcx
)
.immediate
(),
self
.project_field
(
bcx
,
1
)
.load
(
bcx
)
.pack_if_pair
(
bcx
)
.immediate
())
}
else
{
OperandValue
::
Ref
(
self
.llval
,
self
.alignment
)
};
...
...
@@ -314,28 +294,26 @@ pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> Valu
layout
::
Variants
::
Tagged
{
ref
discr_range
,
..
}
=>
{
(
discr_range
.start
,
discr_range
.end
)
}
_
=>
(
0
,
u64
::
max_value
()
),
_
=>
(
0
,
!
0
),
};
let
max_next
=
max
.wrapping_add
(
1
);
let
bits
=
discr_scalar
.size
(
bcx
.ccx
)
.bits
();
assert
!
(
bits
<=
64
);
let
mask
=
!
0u64
>>
(
64
-
bits
);
let
lldiscr
=
match
discr_scalar
{
assert
!
(
bits
<=
128
);
let
mask
=
!
0u128
>>
(
128
-
bits
);
let
lldiscr
=
bcx
.load
(
discr
.llval
,
discr
.alignment
.non_abi
());
match
discr_scalar
{
// For a (max) discr of -1, max will be `-1 as usize`, which overflows.
// However, that is fine here (it would still represent the full range),
layout
::
Int
(
..
)
if
max_next
&
mask
!=
min
&
mask
=>
{
// llvm::ConstantRange can deal with ranges that wrap around,
// so an overflow on (max + 1) is fine.
bcx
.load_range_assert
(
discr
.llval
,
min
,
max_next
,
/* signed: */
llvm
::
True
,
discr
.alignment
.non_abi
())
bcx
.range_metadata
(
lldiscr
,
min
..
max_next
);
}
_
=>
{
// i.e., if the range is everything. The lo==hi case would be
// rejected by the LLVM verifier (it would mean either an
// empty set, which is impossible, or the entire range of the
// type, which is pointless).
bcx
.load
(
discr
.llval
,
discr
.alignment
.non_abi
())
}
};
match
self
.layout.variants
{
...
...
src/librustc_trans/mir/rvalue.rs
浏览文件 @
de3e581e
...
...
@@ -23,7 +23,7 @@
use
builder
::
Builder
;
use
callee
;
use
common
::{
self
,
val_ty
};
use
common
::{
C_bool
,
C_u8
,
C_i32
,
C_u32
,
C_u64
,
C_null
,
C_usize
,
C_uint
,
C_
big_integral
};
use
common
::{
C_bool
,
C_u8
,
C_i32
,
C_u32
,
C_u64
,
C_null
,
C_usize
,
C_uint
,
C_
uint_big
};
use
consts
;
use
monomorphize
;
use
type_
::
Type
;
...
...
@@ -289,7 +289,7 @@ pub fn trans_rvalue_operand(&mut self,
base
::
call_assume
(
&
bcx
,
bcx
.icmp
(
llvm
::
IntULE
,
llval
,
C_uint
(
ll_t_in
,
discr_range
.end
)
C_uint
_big
(
ll_t_in
,
discr_range
.end
)
));
}
_
=>
{}
...
...
@@ -807,7 +807,7 @@ fn cast_int_to_float(bcx: &Builder,
if
is_u128_to_f32
{
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
// and for everything else LLVM's uitofp works just fine.
let
max
=
C_
big_integral
(
int_ty
,
MAX_F32_PLUS_HALF_ULP
);
let
max
=
C_
uint_big
(
int_ty
,
MAX_F32_PLUS_HALF_ULP
);
let
overflow
=
bcx
.icmp
(
llvm
::
IntUGE
,
x
,
max
);
let
infinity_bits
=
C_u32
(
bcx
.ccx
,
ieee
::
Single
::
INFINITY
.to_bits
()
as
u32
);
let
infinity
=
consts
::
bitcast
(
infinity_bits
,
float_ty
);
...
...
@@ -934,8 +934,8 @@ fn int_min(signed: bool, int_ty: Type) -> i128 {
// performed is ultimately up to the backend, but at least x86 does perform them.
let
less_or_nan
=
bcx
.fcmp
(
llvm
::
RealULT
,
x
,
f_min
);
let
greater
=
bcx
.fcmp
(
llvm
::
RealOGT
,
x
,
f_max
);
let
int_max
=
C_
big_integral
(
int_ty
,
int_max
(
signed
,
int_ty
));
let
int_min
=
C_
big_integral
(
int_ty
,
int_min
(
signed
,
int_ty
)
as
u128
);
let
int_max
=
C_
uint_big
(
int_ty
,
int_max
(
signed
,
int_ty
));
let
int_min
=
C_
uint_big
(
int_ty
,
int_min
(
signed
,
int_ty
)
as
u128
);
let
s0
=
bcx
.select
(
less_or_nan
,
int_min
,
fptosui_result
);
let
s1
=
bcx
.select
(
greater
,
int_max
,
s0
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录