implement atomic_nand

This commit is contained in:
Ralf Jung 2019-02-06 11:38:40 +01:00
parent 9e0e219917
commit 661ed7b82d

View File

@ -108,6 +108,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
"atomic_and_rel" |
"atomic_and_acqrel" |
"atomic_and_relaxed" |
"atomic_nand" |
"atomic_nand_acq" |
"atomic_nand_rel" |
"atomic_nand_acqrel" |
"atomic_nand_relaxed" |
"atomic_xadd" |
"atomic_xadd_acq" |
"atomic_xadd_rel" |
@ -125,16 +130,23 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
let rhs = this.read_immediate(args[1])?;
let old = this.read_immediate(ptr.into())?;
this.write_immediate(*old, dest)?; // old value is returned
let op = match intrinsic_name.split('_').nth(1).unwrap() {
"or" => mir::BinOp::BitOr,
"xor" => mir::BinOp::BitXor,
"and" => mir::BinOp::BitAnd,
"xadd" => mir::BinOp::Add,
"xsub" => mir::BinOp::Sub,
let (op, neg) = match intrinsic_name.split('_').nth(1).unwrap() {
"or" => (mir::BinOp::BitOr, false),
"xor" => (mir::BinOp::BitXor, false),
"and" => (mir::BinOp::BitAnd, false),
"xadd" => (mir::BinOp::Add, false),
"xsub" => (mir::BinOp::Sub, false),
"nand" => (mir::BinOp::BitAnd, true),
_ => bug!(),
};
// Atomics wrap around on overflow.
this.binop_ignore_overflow(op, old, rhs, ptr.into())?;
let (val, _overflowed) = this.binary_op_imm(op, old, rhs)?;
let val = if neg {
this.unary_op(mir::UnOp::Not, val, old.layout)?
} else {
val
};
this.write_scalar(val, ptr.into())?;
}
"breakpoint" => unimplemented!(), // halt miri