Skip to content

Commit cb0a9b9

Browse files
committed
Implement _addcarryx_{u32,u64}
1 parent 8cad29a commit cb0a9b9

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/intrinsics/llvm_x86.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,13 +501,30 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
501501
intrinsic_args!(fx, args => (c_in, a, b); intrinsic);
502502
let c_in = c_in.load_scalar(fx);
503503

504-
llvm_add_sub(fx, BinOp::Add, ret, c_in, a, b);
504+
let (cb_out, c) = llvm_add_sub(fx, BinOp::Add, c_in, a, b);
505+
506+
let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, a.layout().ty]));
507+
let val = CValue::by_val_pair(cb_out, c, layout);
508+
ret.write_cvalue(fx, val);
509+
}
510+
"llvm.x86.addcarryx.u32" | "llvm.x86.addcarryx.u64" => {
511+
intrinsic_args!(fx, args => (c_in, a, b, out); intrinsic);
512+
let c_in = c_in.load_scalar(fx);
513+
514+
let (cb_out, c) = llvm_add_sub(fx, BinOp::Add, c_in, a, b);
515+
516+
Pointer::new(out.load_scalar(fx)).store(fx, c, MemFlags::trusted());
517+
ret.write_cvalue(fx, CValue::by_val(cb_out, fx.layout_of(fx.tcx.types.u8)));
505518
}
506519
"llvm.x86.subborrow.32" | "llvm.x86.subborrow.64" => {
507520
intrinsic_args!(fx, args => (b_in, a, b); intrinsic);
508521
let b_in = b_in.load_scalar(fx);
509522

510-
llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
523+
let (cb_out, c) = llvm_add_sub(fx, BinOp::Sub, b_in, a, b);
524+
525+
let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, a.layout().ty]));
526+
let val = CValue::by_val_pair(cb_out, c, layout);
527+
ret.write_cvalue(fx, val);
511528
}
512529
_ => {
513530
fx.tcx
@@ -532,11 +549,10 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
532549
fn llvm_add_sub<'tcx>(
533550
fx: &mut FunctionCx<'_, '_, 'tcx>,
534551
bin_op: BinOp,
535-
ret: CPlace<'tcx>,
536552
cb_in: Value,
537553
a: CValue<'tcx>,
538554
b: CValue<'tcx>,
539-
) {
555+
) -> (Value, Value) {
540556
assert_eq!(a.layout().ty, b.layout().ty);
541557

542558
// c + carry -> c + first intermediate carry or borrow respectively
@@ -554,7 +570,5 @@ fn llvm_add_sub<'tcx>(
554570
// carry0 | carry1 -> carry or borrow respectively
555571
let cb_out = fx.bcx.ins().bor(cb0, cb1);
556572

557-
let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, a.layout().ty]));
558-
let val = CValue::by_val_pair(cb_out, c, layout);
559-
ret.write_cvalue(fx, val);
573+
(cb_out, c)
560574
}

0 commit comments

Comments
 (0)