add more atomic intrinsics

This commit is contained in:
Oliver Schneider 2016-11-15 15:19:38 +01:00
parent f77a0ab10b
commit e2091ff934
No known key found for this signature in database
GPG Key ID: 56D6EEA0FC67AC46
2 changed files with 82 additions and 0 deletions

View File

@ -57,6 +57,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}
"atomic_load" |
"atomic_load_acq" |
"volatile_load" => {
let ty = substs.type_at(0);
let ptr = arg_vals[0].read_ptr(&self.memory)?;
@ -74,6 +75,53 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
// we are inherently singlethreaded and singlecored, this is a nop
}
"atomic_xchg" => {
let ty = substs.type_at(0);
let ptr = arg_vals[0].read_ptr(&self.memory)?;
let change = self.value_to_primval(arg_vals[1], ty)?;
let old = self.read_value(ptr, ty)?;
let old = match old {
Value::ByVal(val) => val,
Value::ByRef(_) => bug!("just read the value, can't be byref"),
Value::ByValPair(..) => bug!("atomic_xchg doesn't work with nonprimitives"),
};
self.write_primval(dest, old)?;
self.write_primval(Lvalue::from_ptr(ptr), change)?;
}
"atomic_cxchg" => {
let ty = substs.type_at(0);
let ptr = arg_vals[0].read_ptr(&self.memory)?;
let expect_old = self.value_to_primval(arg_vals[1], ty)?;
let change = self.value_to_primval(arg_vals[2], ty)?;
let old = self.read_value(ptr, ty)?;
let old = match old {
Value::ByVal(val) => val,
Value::ByRef(_) => bug!("just read the value, can't be byref"),
Value::ByValPair(..) => bug!("atomic_cxchg doesn't work with nonprimitives"),
};
let (val, _) = primval::binary_op(mir::BinOp::Eq, old, expect_old)?;
let dest = self.force_allocation(dest)?.to_ptr();
self.write_pair_to_ptr(old, val, dest, dest_ty)?;
self.write_primval(Lvalue::from_ptr(ptr), change)?;
}
"atomic_xadd_relaxed" => {
let ty = substs.type_at(0);
let ptr = arg_vals[0].read_ptr(&self.memory)?;
let change = self.value_to_primval(arg_vals[1], ty)?;
let old = self.read_value(ptr, ty)?;
let old = match old {
Value::ByVal(val) => val,
Value::ByRef(_) => bug!("just read the value, can't be byref"),
Value::ByValPair(..) => bug!("atomic_xadd_relaxed doesn't work with nonprimitives"),
};
self.write_primval(dest, old)?;
// FIXME: what do atomics do on overflow?
let (val, _) = primval::binary_op(mir::BinOp::Add, old, change)?;
self.write_primval(Lvalue::from_ptr(ptr), val)?;
},
"atomic_xsub_rel" => {
let ty = substs.type_at(0);
let ptr = arg_vals[0].read_ptr(&self.memory)?;

View File

@ -0,0 +1,34 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that a class with only sendable fields can be sent
// pretty-expanded FIXME #23616
use std::sync::mpsc::channel;
#[allow(dead_code)]
struct Foo {
i: isize,
j: char,
}
fn foo(i:isize, j: char) -> Foo {
Foo {
i: i,
j: j
}
}
pub fn main() {
let (tx, rx) = channel();
let _ = tx.send(foo(42, 'c'));
let _ = rx;
}