// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2014, STMicroelectronics International N.V. */ #include "mpa.h" /************************************************************* * * GLOBAL CONSTANTS * *************************************************************/ const mpa_num_base const_largest_deci_base = { 1, 1, {LARGEST_DECIMAL_BASE_IN_WORD} }; const mpa_num_base Const_1_LShift_Base = { 2, 2, {0, 1} }; const mpa_num_base const_one = { 1, 1, {1} }; /************************************************************* * * HELPERS * *************************************************************/ /* -------------------------------------------------------------------- * Function: __mpa_set_unused_digits_to_zero * * */ void __mpa_set_unused_digits_to_zero(mpanum n) { int i; /* * Pointer arithmetics on *mpa_word_t will put the * pointer at the right place. */ i = __mpanum_size(n); mpa_memset((n->d) + i, 0, (n->alloc - i) * BYTES_PER_WORD); } /************************************************************* * * LIB FUNCTIONS * *************************************************************/ /*------------------------------------------------------------ * * mpa_wipe * * fills the digits with zero and set size = 0; * */ void mpa_wipe(mpanum var) { mpa_memset(var->d, 0, var->alloc * BYTES_PER_WORD); var->size = 0; } /*------------------------------------------------------------ * * mpa_copy * * Copies src to dest. * * Doesn't check if src fits into dest * */ void mpa_copy(mpanum dest, const mpanum src) { if (dest == src) return; mpa_memcpy(dest->d, src->d, __mpanum_size(src) * BYTES_PER_WORD); dest->size = src->size; } /* -------------------------------------------------------------------- * Function: mpa_abs * Computes the absolut value of src and puts it in dest * dest and src can be the same mpanum */ void mpa_abs(mpanum dest, const mpanum src) { mpa_copy(dest, src); __mpanum_set_sign(dest, MPA_POS_SIGN); } /* -------------------------------------------------------------------- * Function: mpa_highest_bit_index * Returns the index of the highest 1 in |src|. * The index starts at 0 for the least significant bit. * If src == zero, it will return -1 * */ int mpa_highest_bit_index(const mpanum src) { mpa_word_t w; mpa_word_t b; if (__mpanum_is_zero(src)) return -1; w = __mpanum_msw(src); for (b = 0; b < WORD_SIZE; b++) { w >>= 1; if (w == 0) break; } return (int)(__mpanum_size(src) - 1) * WORD_SIZE + b; } /*------------------------------------------------------------ * * mpa_get_bit * * Returns the value of the idx:th bit in src. * if idx is larger than the number of bits in src, * it returns zero. * */ uint32_t mpa_get_bit(const mpanum src, uint32_t idx) { mpa_word_t w; /* word of bitIndex */ unsigned long b; /* bit number in that word */ w = idx >> LOG_OF_WORD_SIZE; b = idx & (WORD_SIZE - 1); if (w > __mpanum_size(src)) return 0; b = (1ul << b); return ((src->d[w] & b) != 0); } /*------------------------------------------------------------ * * mpa_CanHold * * returns 1 if dest can hold src without overflowing, 0 otherwise */ int mpa_can_hold(mpanum dest, const mpanum src) { return (__mpanum_alloced(dest) >= __mpanum_size(src) ? 1 : 0); } /*------------------------------------------------------------ * * mpa_parity * */ int mpa_parity(const mpanum src) { return (((__mpanum_lsw(src) & 0x01) == 0) ? MPA_EVEN_PARITY : MPA_ODD_PARITY); } /*------------------------------------------------------------ * * mpa_constant_one * */ mpanum mpa_constant_one(void) { return (mpanum)&const_one; }