提交 c4205313 编写于 作者: O Oliver Schneider

Replace `ScalarKind` with `Primitive`

上级 cc60a22b
......@@ -10,7 +10,7 @@
pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
pub use self::value::{Scalar, ScalarKind, Value, ConstValue};
pub use self::value::{Scalar, Value, ConstValue};
use std::fmt;
use mir;
......
......@@ -202,16 +202,6 @@ pub enum Scalar {
Ptr(Pointer),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ScalarKind {
I8, I16, I32, I64, I128,
U8, U16, U32, U64, U128,
F32, F64,
Ptr, FnPtr,
Bool,
Char,
}
impl<'tcx> Scalar {
pub fn undef() -> Self {
Scalar::Bits { bits: 0, defined: 0 }
......@@ -264,59 +254,3 @@ pub fn to_bool(self) -> EvalResult<'tcx, bool> {
}
}
}
impl ScalarKind {
pub fn is_int(self) -> bool {
use self::ScalarKind::*;
match self {
I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
_ => false,
}
}
pub fn is_signed_int(self) -> bool {
use self::ScalarKind::*;
match self {
I8 | I16 | I32 | I64 | I128 => true,
_ => false,
}
}
pub fn is_float(self) -> bool {
use self::ScalarKind::*;
match self {
F32 | F64 => true,
_ => false,
}
}
pub fn from_uint_size(size: Size) -> Self {
match size.bytes() {
1 => ScalarKind::U8,
2 => ScalarKind::U16,
4 => ScalarKind::U32,
8 => ScalarKind::U64,
16 => ScalarKind::U128,
_ => bug!("can't make uint with size {}", size.bytes()),
}
}
pub fn from_int_size(size: Size) -> Self {
match size.bytes() {
1 => ScalarKind::I8,
2 => ScalarKind::I16,
4 => ScalarKind::I32,
8 => ScalarKind::I64,
16 => ScalarKind::I128,
_ => bug!("can't make int with size {}", size.bytes()),
}
}
pub fn is_ptr(self) -> bool {
use self::ScalarKind::*;
match self {
Ptr | FnPtr => true,
_ => false,
}
}
}
......@@ -11,7 +11,7 @@
use session::{self, DataTypeKind};
use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
use syntax::ast::{self, FloatTy, IntTy, UintTy};
use syntax::ast::{self, IntTy, UintTy};
use syntax::attr;
use syntax_pos::DUMMY_SP;
......@@ -130,8 +130,8 @@ impl PrimitiveExt for Primitive {
fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
match *self {
Int(i, signed) => i.to_ty(tcx, signed),
F32 => tcx.types.f32,
F64 => tcx.types.f64,
Float(FloatTy::F32) => tcx.types.f32,
Float(FloatTy::F64) => tcx.types.f64,
Pointer => tcx.mk_mut_ptr(tcx.mk_nil()),
}
}
......@@ -488,8 +488,7 @@ enum StructKind {
ty::TyUint(ity) => {
scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
}
ty::TyFloat(FloatTy::F32) => scalar(F32),
ty::TyFloat(FloatTy::F64) => scalar(F64),
ty::TyFloat(fty) => scalar(Float(fty)),
ty::TyFnPtr(_) => {
let mut ptr = scalar_unit(Pointer);
ptr.valid_range = 1..=*ptr.valid_range.end();
......@@ -1908,8 +1907,7 @@ fn hash_stable<W: StableHasherResult>(&self,
impl_stable_hash_for!(enum ::ty::layout::Primitive {
Int(integer, signed),
F32,
F64,
Float(fty),
Pointer
});
......
......@@ -15,6 +15,7 @@
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
use rustc_target::spec::PanicStrategy;
use rustc_target::abi::FloatTy;
use mono_item::DefPathBasedNames;
use type_::Type;
......@@ -324,8 +325,8 @@ fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
scalar: &layout::Scalar, offset: Size) -> Type {
match scalar.value {
layout::Int(i, _) => Type::from_integer(cx, i),
layout::F32 => Type::f32(cx),
layout::F64 => Type::f64(cx),
layout::Float(FloatTy::F32) => Type::f32(cx),
layout::Float(FloatTy::F64) => Type::f64(cx),
layout::Pointer => {
// If we know the alignment, pick something better than i8.
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
......
......@@ -14,7 +14,7 @@
use syntax::codemap::{self, Span};
use syntax::ast::Mutability;
use rustc::mir::interpret::{
GlobalId, Value, Scalar, ScalarKind,
GlobalId, Value, Scalar,
EvalError, EvalResult, EvalErrorKind, Pointer, ConstValue,
};
use std::mem;
......@@ -230,13 +230,7 @@ pub fn cur_frame(&self) -> usize {
pub fn str_to_value(&mut self, s: &str) -> EvalResult<'tcx, Value> {
let ptr = self.memory.allocate_bytes(s.as_bytes());
Ok(Value::ScalarPair(
Scalar::Ptr(ptr),
Scalar::Bits {
bits: s.len() as u128,
defined: self.tcx.data_layout.pointer_size.bits() as u8,
},
))
Ok(Scalar::Ptr(ptr).to_value_with_len(s.len() as u64, self.tcx.tcx))
}
pub fn const_value_to_value(
......@@ -1271,72 +1265,11 @@ pub fn write_value_to_ptr(
}
}
pub fn ty_to_scalar_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, ScalarKind> {
use syntax::ast::FloatTy;
let kind = match ty.sty {
ty::TyBool => ScalarKind::Bool,
ty::TyChar => ScalarKind::Char,
ty::TyInt(int_ty) => {
use syntax::ast::IntTy::*;
let size = match int_ty {
I8 => Size::from_bytes(1),
I16 => Size::from_bytes(2),
I32 => Size::from_bytes(4),
I64 => Size::from_bytes(8),
I128 => Size::from_bytes(16),
Isize => self.memory.pointer_size(),
};
ScalarKind::from_int_size(size)
}
ty::TyUint(uint_ty) => {
use syntax::ast::UintTy::*;
let size = match uint_ty {
U8 => Size::from_bytes(1),
U16 => Size::from_bytes(2),
U32 => Size::from_bytes(4),
U64 => Size::from_bytes(8),
U128 => Size::from_bytes(16),
Usize => self.memory.pointer_size(),
};
ScalarKind::from_uint_size(size)
}
ty::TyFloat(FloatTy::F32) => ScalarKind::F32,
ty::TyFloat(FloatTy::F64) => ScalarKind::F64,
ty::TyFnPtr(_) => ScalarKind::FnPtr,
ty::TyRef(_, ty, _) |
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if self.type_is_sized(ty) => {
ScalarKind::Ptr
}
ty::TyAdt(def, _) if def.is_box() => ScalarKind::Ptr,
ty::TyAdt(..) => {
match self.layout_of(ty)?.abi {
layout::Abi::Scalar(ref scalar) => {
use rustc::ty::layout::Primitive::*;
match scalar.value {
Int(i, false) => ScalarKind::from_uint_size(i.size()),
Int(i, true) => ScalarKind::from_int_size(i.size()),
F32 => ScalarKind::F32,
F64 => ScalarKind::F64,
Pointer => ScalarKind::Ptr,
}
}
_ => return err!(TypeNotPrimitive(ty)),
}
}
_ => return err!(TypeNotPrimitive(ty)),
};
Ok(kind)
pub fn ty_to_primitive(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, layout::Primitive> {
match self.layout_of(ty)?.abi {
layout::Abi::Scalar(ref scalar) => Ok(scalar.value),
_ => err!(TypeNotPrimitive(ty)),
}
}
fn ensure_valid_value(&self, val: Scalar, ty: Ty<'tcx>) -> EvalResult<'tcx> {
......
......@@ -68,8 +68,8 @@ pub fn binary_op(
) -> EvalResult<'tcx, (Scalar, bool)> {
use rustc::mir::BinOp::*;
let left_kind = self.ty_to_scalar_kind(left_ty)?;
let right_kind = self.ty_to_scalar_kind(right_ty)?;
let left_kind = self.ty_to_primitive(left_ty)?;
let right_kind = self.ty_to_primitive(right_ty)?;
trace!("Running binary op {:?}: {:?} ({:?}), {:?} ({:?})", bin_op, left, left_kind, right, right_kind);
// I: Handle operations that support pointers
......
......@@ -33,8 +33,8 @@ fn float_reg<'a, Ty, C>(cx: C, ret: &ArgType<'a, Ty>, i: usize) -> Option<Reg>
{
match ret.layout.field(cx, i).abi {
abi::Abi::Scalar(ref scalar) => match scalar.value {
abi::F32 => Some(Reg::f32()),
abi::F64 => Some(Reg::f64()),
abi::Float(abi::FloatTy::F32) => Some(Reg::f32()),
abi::Float(abi::FloatTy::F64) => Some(Reg::f64()),
_ => None
},
_ => None
......@@ -117,7 +117,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: C, arg: &mut ArgType<'a, Ty>)
// We only care about aligned doubles
if let abi::Abi::Scalar(ref scalar) = field.abi {
if let abi::F64 = scalar.value {
if let abi::Float(abi::FloatTy::F64) = scalar.value {
if offset.is_abi_aligned(dl.f64_align) {
// Insert enough integers to cover [last_offset, offset)
assert!(last_offset.is_abi_aligned(dl.f64_align));
......
......@@ -256,8 +256,7 @@ fn homogeneous_aggregate<C>(&self, cx: C) -> Option<Reg>
let kind = match scalar.value {
abi::Int(..) |
abi::Pointer => RegKind::Integer,
abi::F32 |
abi::F64 => RegKind::Float
abi::Float(_) => RegKind::Float,
};
Some(Reg {
kind,
......
......@@ -29,12 +29,7 @@ fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
match layout.abi {
abi::Abi::Scalar(ref scalar) => {
match scalar.value {
abi::F32 | abi::F64 => true,
_ => false
}
}
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
abi::Abi::Aggregate { .. } => {
if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 {
is_single_fp_element(cx, layout.field(cx, 0))
......
......@@ -23,12 +23,7 @@ fn is_single_fp_element<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>) -> bool
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
{
match layout.abi {
abi::Abi::Scalar(ref scalar) => {
match scalar.value {
abi::F32 | abi::F64 => true,
_ => false
}
}
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
abi::Abi::Aggregate { .. } => {
if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 {
is_single_fp_element(cx, layout.field(cx, 0))
......
......@@ -55,8 +55,7 @@ fn classify<'a, Ty, C>(cx: C, layout: TyLayout<'a, Ty>,
match scalar.value {
abi::Int(..) |
abi::Pointer => Class::Int,
abi::F32 |
abi::F64 => Class::Sse
abi::Float(_) => Class::Sse
}
}
......
......@@ -13,7 +13,7 @@
use spec::Target;
use std::cmp;
use std::{cmp, fmt};
use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
pub mod call;
......@@ -488,6 +488,42 @@ pub fn approximate_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Integer {
}
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy,
PartialOrd, Ord)]
pub enum FloatTy {
F32,
F64,
}
impl fmt::Debug for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.ty_to_string())
}
}
impl FloatTy {
pub fn ty_to_string(&self) -> &'static str {
match *self {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
}
}
pub fn bit_width(&self) -> usize {
match *self {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
}
}
}
/// Fundamental unit of memory access and layout.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Primitive {
......@@ -499,8 +535,7 @@ pub enum Primitive {
/// a negative integer passed by zero-extension will appear positive in
/// the callee, and most operations on it will produce the wrong values.
Int(Integer, bool),
F32,
F64,
Float(FloatTy),
Pointer
}
......@@ -510,8 +545,8 @@ pub fn size<C: HasDataLayout>(self, cx: C) -> Size {
match self {
Int(i, _) => i.size(),
F32 => Size::from_bits(32),
F64 => Size::from_bits(64),
Float(FloatTy::F32) => Size::from_bits(32),
Float(FloatTy::F64) => Size::from_bits(64),
Pointer => dl.pointer_size
}
}
......@@ -521,11 +556,25 @@ pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
match self {
Int(i, _) => i.align(dl),
F32 => dl.f32_align,
F64 => dl.f64_align,
Float(FloatTy::F32) => dl.f32_align,
Float(FloatTy::F64) => dl.f64_align,
Pointer => dl.pointer_align
}
}
pub fn is_float(self) -> bool {
match self {
Float(_) => true,
_ => false
}
}
pub fn is_int(self) -> bool {
match self {
Int(..) => true,
_ => false,
}
}
}
/// Information about one scalar component of a Rust type.
......
......@@ -33,6 +33,8 @@
use rustc_data_structures::sync::Lrc;
use std::u32;
pub use rustc_target::abi::FloatTy;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct Label {
pub ident: Ident,
......@@ -1519,41 +1521,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy,
PartialOrd, Ord)]
pub enum FloatTy {
F32,
F64,
}
impl fmt::Debug for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.ty_to_string())
}
}
impl FloatTy {
pub fn ty_to_string(&self) -> &'static str {
match *self {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
}
}
pub fn bit_width(&self) -> usize {
match *self {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
}
}
}
// Bind a type to an associated type: `A=Foo`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TypeBinding {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册