Implement some binops for TyRawPtr
This commit is contained in:
parent
fdc625e18a
commit
f52727b8e6
3 changed files with 112 additions and 31 deletions
26
example.rs
26
example.rs
|
@ -6,7 +6,11 @@
|
||||||
trait Sized {}
|
trait Sized {}
|
||||||
|
|
||||||
#[lang="copy"]
|
#[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"]
|
#[lang="freeze"]
|
||||||
trait 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"]
|
#[lang="panic"]
|
||||||
fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
|
fn panic(_expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
|
@ -89,3 +109,7 @@ fn promoted_val() -> &'static u8 {
|
||||||
fn cast_ref_to_raw_ptr(abc: &u8) -> *const u8 {
|
fn cast_ref_to_raw_ptr(abc: &u8) -> *const u8 {
|
||||||
abc as *const u8
|
abc as *const u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmp_raw_ptr(a: *const u8, b: *const u8) -> bool {
|
||||||
|
a == b
|
||||||
|
}
|
||||||
|
|
115
src/base.rs
115
src/base.rs
|
@ -327,6 +327,9 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
|
||||||
TypeVariants::TyInt(_) => {
|
TypeVariants::TyInt(_) => {
|
||||||
trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, true, false)
|
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),
|
_ => unimplemented!("bin op {:?} for {:?}", bin_op, ty),
|
||||||
};
|
};
|
||||||
lval.write_cvalue(fx, res);
|
lval.write_cvalue(fx, res);
|
||||||
|
@ -467,36 +470,90 @@ fn trans_stmt<'a, 'tcx: 'a>(fx: &mut FunctionCx<'a, 'tcx>, stmt: &Statement<'tcx
|
||||||
Ok(())
|
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> {
|
macro_rules! binop_match {
|
||||||
let res = match (bin_op, signed) {
|
(@single $fx:expr, $bug_fmt:expr, $var:expr, $lhs:expr, $rhs:expr, bug) => {
|
||||||
(BinOp::Add, _) => fx.bcx.ins().iadd(lhs, rhs),
|
bug!("bin op {} on {} lhs: {:?} rhs: {:?}", stringify!($var), $bug_fmt, $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),
|
|
||||||
};
|
};
|
||||||
|
(@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
|
// TODO: return correct value for checked binops
|
||||||
CValue::ByVal(res, fx.layout_of(ty))
|
CValue::ByVal(res, fx.layout_of(ty))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private, macro_at_most_once_rep)]
|
||||||
#![allow(intra_doc_link_resolution_failure)]
|
#![allow(intra_doc_link_resolution_failure)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue