11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// Helper functions that operate on {Digits} vectors of digits.
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#ifndef V8_BIGINT_VECTOR_ARITHMETIC_H_
81cb0ef41Sopenharmony_ci#define V8_BIGINT_VECTOR_ARITHMETIC_H_
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "src/bigint/bigint.h"
111cb0ef41Sopenharmony_ci#include "src/bigint/digit-arithmetic.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace bigint {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci// Z += X. Returns carry on overflow.
171cb0ef41Sopenharmony_cidigit_t AddAndReturnOverflow(RWDigits Z, Digits X);
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci// Z -= X. Returns borrow on overflow.
201cb0ef41Sopenharmony_cidigit_t SubAndReturnBorrow(RWDigits Z, Digits X);
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci// X += y.
231cb0ef41Sopenharmony_ciinline void Add(RWDigits X, digit_t y) {
241cb0ef41Sopenharmony_ci  digit_t carry = y;
251cb0ef41Sopenharmony_ci  int i = 0;
261cb0ef41Sopenharmony_ci  do {
271cb0ef41Sopenharmony_ci    X[i] = digit_add2(X[i], carry, &carry);
281cb0ef41Sopenharmony_ci    i++;
291cb0ef41Sopenharmony_ci  } while (carry != 0);
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci// X -= y.
331cb0ef41Sopenharmony_ciinline void Subtract(RWDigits X, digit_t y) {
341cb0ef41Sopenharmony_ci  digit_t borrow = y;
351cb0ef41Sopenharmony_ci  int i = 0;
361cb0ef41Sopenharmony_ci  do {
371cb0ef41Sopenharmony_ci    X[i] = digit_sub(X[i], borrow, &borrow);
381cb0ef41Sopenharmony_ci    i++;
391cb0ef41Sopenharmony_ci  } while (borrow != 0);
401cb0ef41Sopenharmony_ci}
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci// These add exactly Y's digits to the matching digits in X, storing the
431cb0ef41Sopenharmony_ci// result in (part of) Z, and return the carry/borrow.
441cb0ef41Sopenharmony_cidigit_t AddAndReturnCarry(RWDigits Z, Digits X, Digits Y);
451cb0ef41Sopenharmony_cidigit_t SubtractAndReturnBorrow(RWDigits Z, Digits X, Digits Y);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ciinline bool IsDigitNormalized(Digits X) { return X.len() == 0 || X.msd() != 0; }
481cb0ef41Sopenharmony_ciinline bool IsBitNormalized(Digits X) {
491cb0ef41Sopenharmony_ci  return (X.msd() >> (kDigitBits - 1)) == 1;
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ciinline bool GreaterThanOrEqual(Digits A, Digits B) {
531cb0ef41Sopenharmony_ci  return Compare(A, B) >= 0;
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciinline int BitLength(Digits X) {
571cb0ef41Sopenharmony_ci  return X.len() * kDigitBits - CountLeadingZeros(X.msd());
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci}  // namespace bigint
611cb0ef41Sopenharmony_ci}  // namespace v8
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci#endif  // V8_BIGINT_VECTOR_ARITHMETIC_H_
64