Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ed83f1a

Browse files
committed
Move out addition logic
1 parent 9afd752 commit ed83f1a

File tree

1 file changed

+29
-39
lines changed
  • src/tools/miri/src/shims/x86

1 file changed

+29
-39
lines changed

src/tools/miri/src/shims/x86/mod.rs

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,17 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4545
return Ok(EmulateItemResult::NotSupported);
4646
}
4747

48+
let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
49+
4850
let op = if unprefixed_name.starts_with("add") {
4951
mir::BinOp::AddWithOverflow
5052
} else {
5153
mir::BinOp::SubWithOverflow
5254
};
5355

54-
let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
55-
let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0;
56-
let a = this.read_immediate(a)?;
57-
let b = this.read_immediate(b)?;
58-
59-
let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this);
60-
let (sum, overflow2) =
61-
this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this);
62-
let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?;
63-
64-
let d1 = this.project_field(dest, 0)?;
65-
let d2 = this.project_field(dest, 1)?;
66-
write_twice(this, &d1, Scalar::from_u8(cb_out.into()), &d2, sum)?;
56+
let (sum, cb_out) = carrying_add(this, cb_in, a, b, op)?;
57+
this.write_scalar(cb_out, &this.project_field(dest, 0)?)?;
58+
this.write_immediate(*sum, &this.project_field(dest, 1)?)?;
6759
}
6860

6961
// Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions,
@@ -77,23 +69,10 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
7769
}
7870

7971
let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
80-
let c_in = this.read_scalar(c_in)?.to_u8()? != 0;
81-
let a = this.read_immediate(a)?;
82-
let b = this.read_immediate(b)?;
83-
84-
let (sum, overflow1) =
85-
this.binary_op(mir::BinOp::AddWithOverflow, &a, &b)?.to_pair(this);
86-
let (sum, overflow2) = this
87-
.binary_op(
88-
mir::BinOp::AddWithOverflow,
89-
&sum,
90-
&ImmTy::from_uint(c_in, a.layout),
91-
)?
92-
.to_pair(this);
93-
let c_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?;
9472

95-
let out = this.deref_pointer_as(out, sum.layout)?;
96-
write_twice(this, dest, Scalar::from_u8(c_out.into()), &out, sum)?;
73+
let (sum, c_out) = carrying_add(this, c_in, a, b, mir::BinOp::AddWithOverflow)?;
74+
this.write_scalar(c_out, dest)?;
75+
this.write_immediate(*sum, &this.deref_pointer_as(out, sum.layout)?)?;
9776
}
9877

9978
// Used to implement the `_mm_pause` function.
@@ -1369,15 +1348,26 @@ fn psign<'tcx>(
13691348
Ok(())
13701349
}
13711350

1372-
/// Write two values `v1` and `v2` to the places `d1` and `d2`.
1373-
fn write_twice<'tcx>(
1351+
/// Calcultates either `a + b + cb_in` or `a - b - cb_in` depending on the value
1352+
/// of `op` and returns both the sum and the overflow bit. `op` is expected to be
1353+
/// either one of `mir::BinOp::AddWithOverflow` and `mir::BinOp::SubWithOverflow`.
1354+
fn carrying_add<'tcx>(
13741355
this: &mut crate::MiriInterpCx<'tcx>,
1375-
d1: &MPlaceTy<'tcx>,
1376-
v1: Scalar,
1377-
d2: &MPlaceTy<'tcx>,
1378-
v2: ImmTy<'tcx>,
1379-
) -> InterpResult<'tcx, ()> {
1380-
this.write_scalar(v1, d1)?;
1381-
this.write_immediate(*v2, d2)?;
1382-
Ok(())
1356+
cb_in: &OpTy<'tcx>,
1357+
a: &OpTy<'tcx>,
1358+
b: &OpTy<'tcx>,
1359+
op: mir::BinOp,
1360+
) -> InterpResult<'tcx, (ImmTy<'tcx>, Scalar)> {
1361+
assert!(op == mir::BinOp::AddWithOverflow || op == mir::BinOp::SubWithOverflow);
1362+
1363+
let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0;
1364+
let a = this.read_immediate(a)?;
1365+
let b = this.read_immediate(b)?;
1366+
1367+
let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this);
1368+
let (sum, overflow2) =
1369+
this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this);
1370+
let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?;
1371+
1372+
Ok((sum, Scalar::from_u8(cb_out.into())))
13831373
}

0 commit comments

Comments
 (0)