mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-10 06:47:34 +00:00
Add Type::int_width
for retrieving integer's bit width.
This commit is contained in:
parent
3d59a476e5
commit
5edbe1f5dd
@ -847,26 +847,24 @@ pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
|
||||
G: FnOnce(ValueRef, Type) -> ValueRef,
|
||||
{
|
||||
// Shifts may have any size int on the rhs
|
||||
unsafe {
|
||||
if ast_util::is_shift_binop(op) {
|
||||
let mut rhs_llty = val_ty(rhs);
|
||||
let mut lhs_llty = val_ty(lhs);
|
||||
if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
|
||||
if lhs_llty.kind() == Vector { lhs_llty = lhs_llty.element_type() }
|
||||
let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty.to_ref());
|
||||
let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty.to_ref());
|
||||
if lhs_sz < rhs_sz {
|
||||
trunc(rhs, lhs_llty)
|
||||
} else if lhs_sz > rhs_sz {
|
||||
// FIXME (#1877: If shifting by negative
|
||||
// values becomes not undefined then this is wrong.
|
||||
zext(rhs, lhs_llty)
|
||||
} else {
|
||||
rhs
|
||||
}
|
||||
if ast_util::is_shift_binop(op) {
|
||||
let mut rhs_llty = val_ty(rhs);
|
||||
let mut lhs_llty = val_ty(lhs);
|
||||
if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
|
||||
if lhs_llty.kind() == Vector { lhs_llty = lhs_llty.element_type() }
|
||||
let rhs_sz = rhs_llty.int_width();
|
||||
let lhs_sz = lhs_llty.int_width();
|
||||
if lhs_sz < rhs_sz {
|
||||
trunc(rhs, lhs_llty)
|
||||
} else if lhs_sz > rhs_sz {
|
||||
// FIXME (#1877: If shifting by negative
|
||||
// values becomes not undefined then this is wrong.
|
||||
zext(rhs, lhs_llty)
|
||||
} else {
|
||||
rhs
|
||||
}
|
||||
} else {
|
||||
rhs
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use llvm;
|
||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
|
||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||
use trans::cabi::{FnType, ArgType};
|
||||
@ -30,11 +29,7 @@ fn align(off: uint, ty: Type) -> uint {
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
@ -61,11 +56,7 @@ fn ty_align(ty: Type) -> uint {
|
||||
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use llvm;
|
||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
|
||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||
use trans::cabi::{FnType, ArgType};
|
||||
@ -37,11 +36,7 @@ fn align(off: uint, ty: Type, align_fn: TyAlignFn) -> uint {
|
||||
|
||||
fn general_ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
@ -75,11 +70,7 @@ fn general_ty_align(ty: Type) -> uint {
|
||||
// /iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
|
||||
fn ios_ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
cmp::min(4, ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8)
|
||||
}
|
||||
}
|
||||
Integer => cmp::min(4, ((ty.int_width() as uint) + 7) / 8),
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 4,
|
||||
@ -106,11 +97,7 @@ fn ios_ty_align(ty: Type) -> uint {
|
||||
|
||||
fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
|
@ -30,11 +30,7 @@ fn align(off: uint, ty: Type) -> uint {
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
@ -61,11 +57,7 @@ fn ty_align(ty: Type) -> uint {
|
||||
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
|
@ -14,7 +14,6 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
use self::RegClass::*;
|
||||
|
||||
use llvm;
|
||||
use llvm::{Integer, Pointer, Float, Double};
|
||||
use llvm::{Struct, Array, Attribute, Vector};
|
||||
use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
|
||||
@ -94,11 +93,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => ((ty.int_width() as uint) + 7) / 8,
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
@ -125,11 +120,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
|
||||
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Integer => (ty.int_width() as uint + 7) / 8,
|
||||
Pointer => 8,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
|
@ -1906,18 +1906,16 @@ fn int_cast(bcx: Block,
|
||||
signed: bool)
|
||||
-> ValueRef {
|
||||
let _icx = push_ctxt("int_cast");
|
||||
unsafe {
|
||||
let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref());
|
||||
let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref());
|
||||
return if dstsz == srcsz {
|
||||
BitCast(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
TruncOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else if signed {
|
||||
SExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else {
|
||||
ZExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
};
|
||||
let srcsz = llsrctype.int_width();
|
||||
let dstsz = lldsttype.int_width();
|
||||
return if dstsz == srcsz {
|
||||
BitCast(bcx, llsrc, lldsttype)
|
||||
} else if srcsz > dstsz {
|
||||
TruncOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else if signed {
|
||||
SExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
} else {
|
||||
ZExtOrBitCast(bcx, llsrc, lldsttype)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,6 +333,13 @@ impl Type {
|
||||
_ => panic!("llvm_float_width called on a non-float type")
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve the bit width of the integer type `self`.
|
||||
pub fn int_width(&self) -> u64 {
|
||||
unsafe {
|
||||
llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user