Implement some binops for TyRawPtr

This commit is contained in:
bjorn3 2018-07-18 15:17:22 +02:00
parent fdc625e18a
commit f52727b8e6
3 changed files with 112 additions and 31 deletions

View file

@ -6,7 +6,11 @@
trait Sized {}
#[lang="copy"]
trait Copy {}
unsafe trait Copy {}
unsafe impl Copy for u8 {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
#[lang="freeze"]
trait Freeze {}
@ -27,6 +31,22 @@ impl Mul for u8 {
}
}
#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool;
}
impl PartialEq for u8 {
fn eq(&self, other: &u8) -> bool { (*self) == (*other) }
fn ne(&self, other: &u8) -> bool { (*self) != (*other) }
}
impl<T: ?Sized> PartialEq for *const T {
fn eq(&self, other: &*const T) -> bool { *self == *other }
fn ne(&self, other: &*const T) -> bool { *self != *other }
}
#[lang="panic"]
fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
loop {}
@ -89,3 +109,7 @@ fn promoted_val() -> &'static u8 {
fn cast_ref_to_raw_ptr(abc: &u8) -> *const u8 {
abc as *const u8
}
fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
a == b
}

View file

@ -327,6 +327,9 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
TypeVariants::TyInt(_) => {
trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, true, false)
}
TypeVariants::TyRawPtr(..) => {
trans_ptr_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, false)
}
_ => unimplemented!("bin op {:?} for {:?}", bin_op, ty),
};
lval.write_cvalue(fx, res);
@ -467,36 +470,90 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
Ok(())
}
fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: Value, rhs: Value, ty: Ty<'tcx>, signed: bool, _checked: bool) -> CValue<'tcx> {
let res = match (bin_op, signed) {
(BinOp::Add, _) => fx.bcx.ins().iadd(lhs, rhs),
(BinOp::Sub, _) => fx.bcx.ins().isub(lhs, rhs),
(BinOp::Mul, _) => fx.bcx.ins().imul(lhs, rhs),
(BinOp::Div, false) => fx.bcx.ins().udiv(lhs, rhs),
(BinOp::Div, true) => fx.bcx.ins().sdiv(lhs, rhs),
(BinOp::Rem, false) => fx.bcx.ins().urem(lhs, rhs),
(BinOp::Rem, true) => fx.bcx.ins().srem(lhs, rhs),
(BinOp::BitXor, _) => fx.bcx.ins().bxor(lhs, rhs),
(BinOp::BitAnd, _) => fx.bcx.ins().band(lhs, rhs),
(BinOp::BitOr, _) => fx.bcx.ins().bor(lhs, rhs),
(BinOp::Shl, _) => fx.bcx.ins().ishl(lhs, rhs),
(BinOp::Shr, false) => fx.bcx.ins().ushr(lhs, rhs),
(BinOp::Shr, true) => fx.bcx.ins().sshr(lhs, rhs),
// TODO: cast b1 to u8
(BinOp::Eq, _) => fx.bcx.ins().icmp(IntCC::Equal , lhs, rhs),
(BinOp::Lt, false) => fx.bcx.ins().icmp(IntCC::UnsignedLessThan , lhs, rhs),
(BinOp::Lt, true) => fx.bcx.ins().icmp(IntCC::SignedLessThan , lhs, rhs),
(BinOp::Le, false) => fx.bcx.ins().icmp(IntCC::UnsignedLessThanOrEqual , lhs, rhs),
(BinOp::Le, true) => fx.bcx.ins().icmp(IntCC::SignedLessThanOrEqual , lhs, rhs),
(BinOp::Ne, _) => fx.bcx.ins().icmp(IntCC::NotEqual , lhs, rhs),
(BinOp::Ge, false) => fx.bcx.ins().icmp(IntCC::UnsignedGreaterThanOrEqual , lhs, rhs),
(BinOp::Ge, true) => fx.bcx.ins().icmp(IntCC::SignedGreaterThanOrEqual , lhs, rhs),
(BinOp::Gt, false) => fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan , lhs, rhs),
(BinOp::Gt, true) => fx.bcx.ins().icmp(IntCC::SignedGreaterThan , lhs, rhs),
(BinOp::Offset, _) => bug!("bin op Offset on non ptr lhs: {:?} rhs: {:?}", lhs, rhs),
macro_rules! binop_match {
(@single $fx:expr, $bug_fmt:expr, $var:expr, $lhs:expr, $rhs:expr, bug) => {
bug!("bin op {} on {} lhs: {:?} rhs: {:?}", stringify!($var), $bug_fmt, $lhs, $rhs)
};
(@single $fx:expr, $bug_fmt:expr, $var:expr, $lhs:expr, $rhs:expr, icmp($cc:ident)) => {{
let b = $fx.bcx.ins().icmp(IntCC::$cc, $lhs, $rhs);
$fx.bcx.ins().bint(types::I8, b)
}};
(@single $fx:expr, $bug_fmt:expr, $var:expr, $lhs:expr, $rhs:expr, $name:ident) => {
$fx.bcx.ins().$name($lhs, $rhs)
};
(
$fx:expr, $bin_op:expr, $signed:expr, $lhs:expr, $rhs:expr, $bug_fmt:expr;
$(
$var:ident ($sign:pat) $name:tt $( ( $next:tt ) )? ;
)*
) => {
match ($bin_op, $signed) {
$(
(BinOp::$var, $sign) => binop_match!(@single $fx, $bug_fmt, $var, $lhs, $rhs, $name $( ( $next ) )?),
)*
}
}
}
fn trans_int_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: Value, rhs: Value, ty: Ty<'tcx>, signed: bool, _checked: bool) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, signed, lhs, rhs, "non ptr";
Add (_) iadd;
Sub (_) isub;
Mul (_) imul;
Div (false) udiv;
Div (true) sdiv;
Rem (false) urem;
Rem (true) srem;
BitXor (_) bxor;
BitAnd (_) band;
BitOr (_) bor;
Shl (_) ishl;
Shr (false) ushr;
Shr (true) sshr;
Eq (_) icmp(Equal);
Lt (false) icmp(UnsignedLessThan);
Lt (true) icmp(SignedLessThan);
Le (false) icmp(UnsignedLessThanOrEqual);
Le (true) icmp(SignedLessThanOrEqual);
Ne (_) icmp(NotEqual);
Ge (false) icmp(UnsignedGreaterThanOrEqual);
Ge (true) icmp(SignedGreaterThanOrEqual);
Gt (false) icmp(UnsignedGreaterThan);
Gt (true) icmp(SignedGreaterThan);
Offset (_) bug;
};
// TODO: return correct value for checked binops
CValue::ByVal(res, fx.layout_of(ty))
}
fn trans_ptr_binop<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, bin_op: BinOp, lhs: Value, rhs: Value, ty: Ty<'tcx>, _checked: bool) -> CValue<'tcx> {
let res = binop_match! {
fx, bin_op, false, lhs, rhs, "ptr";
Add (_) bug;
Sub (_) bug;
Mul (_) bug;
Div (_) bug;
Rem (_) bug;
BitXor (_) bug;
BitAnd (_) bug;
BitOr (_) bug;
Shl (_) bug;
Shr (_) bug;
Eq (_) icmp(Equal);
Lt (_) icmp(UnsignedLessThan);
Le (_) icmp(UnsignedLessThanOrEqual);
Ne (_) icmp(NotEqual);
Ge (_) icmp(UnsignedGreaterThanOrEqual);
Gt (_) icmp(UnsignedGreaterThan);
Offset (_) iadd;
};
// TODO: return correct value for checked binops
CValue::ByVal(res, fx.layout_of(ty))
}

View file

@ -1,4 +1,4 @@
#![feature(rustc_private)]
#![feature(rustc_private, macro_at_most_once_rep)]
#![allow(intra_doc_link_resolution_failure)]
extern crate syntax;