提交 5edbe1f5 编写于 作者: H Huon Wilson

Add `Type::int_width` for retrieving integer's bit width.

上级 3d59a476
......@@ -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 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,
......@@ -125,11 +120,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,
......
......@@ -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 @@ pub fn float_width(&self) -> uint {
_ => 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
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册