112854Sgabeblack@google.com/***************************************************************************** 212854Sgabeblack@google.com 312854Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412854Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512854Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612854Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712854Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812854Sgabeblack@google.com License. You may obtain a copy of the License at 912854Sgabeblack@google.com 1012854Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112854Sgabeblack@google.com 1212854Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312854Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412854Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512854Sgabeblack@google.com implied. See the License for the specific language governing 1612854Sgabeblack@google.com permissions and limitations under the License. 1712854Sgabeblack@google.com 1812854Sgabeblack@google.com *****************************************************************************/ 1912854Sgabeblack@google.com 2012854Sgabeblack@google.com/***************************************************************************** 2112854Sgabeblack@google.com 2212854Sgabeblack@google.com sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned 2312854Sgabeblack@google.com classes. These functions work on two parameters u and 2412854Sgabeblack@google.com v, and copy the result to the first parameter u. This 2512854Sgabeblack@google.com is also the reason that they are suffixed with _on_help. 2612854Sgabeblack@google.com 2712854Sgabeblack@google.com Original Author: Ali Dasdan, Synopsys, Inc. 2812854Sgabeblack@google.com 2912854Sgabeblack@google.com *****************************************************************************/ 3012854Sgabeblack@google.com 3112854Sgabeblack@google.com/***************************************************************************** 3212854Sgabeblack@google.com 3312854Sgabeblack@google.com MODIFICATION LOG - modifiers, enter your name, affiliation, date and 3412854Sgabeblack@google.com changes you are making here. 3512854Sgabeblack@google.com 3612854Sgabeblack@google.com Name, Affiliation, Date: 3712854Sgabeblack@google.com Description of Modification: 3812854Sgabeblack@google.com 3912854Sgabeblack@google.com *****************************************************************************/ 4012854Sgabeblack@google.com 4112854Sgabeblack@google.com 4212854Sgabeblack@google.com// $Log: sc_nbexterns.cpp,v $ 4312854Sgabeblack@google.com// Revision 1.2 2011/02/18 20:19:15 acg 4412854Sgabeblack@google.com// Andy Goodrich: updating Copyright notice. 4512854Sgabeblack@google.com// 4612854Sgabeblack@google.com// Revision 1.1.1.1 2006/12/15 20:20:05 acg 4712854Sgabeblack@google.com// SystemC 2.3 4812854Sgabeblack@google.com// 4912854Sgabeblack@google.com// Revision 1.3 2006/01/13 18:49:32 acg 5012854Sgabeblack@google.com// Added $Log command so that CVS check in comments are reproduced in the 5112854Sgabeblack@google.com// source. 5212854Sgabeblack@google.com// 5312854Sgabeblack@google.com 5412854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_nbexterns.hh" 5512854Sgabeblack@google.com#include "systemc/ext/utils/functions.hh" 5612854Sgabeblack@google.com 5712854Sgabeblack@google.comnamespace sc_dt 5812854Sgabeblack@google.com{ 5912854Sgabeblack@google.com 6012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 6112854Sgabeblack@google.com// SECTION: External functions for PLUS operators. 6212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 6312854Sgabeblack@google.com 6412854Sgabeblack@google.com// Handles the cases 3 and 4 and returns the result in u. 6512854Sgabeblack@google.comvoid 6612854Sgabeblack@google.comadd_on_help(small_type &us, int /* unb */, int und, sc_digit *ud, 6712854Sgabeblack@google.com small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 6812854Sgabeblack@google.com{ 6912854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 7012854Sgabeblack@google.com 7112854Sgabeblack@google.com if (us == vs) { // case 3 7212854Sgabeblack@google.com if (und >= vnd) 7312854Sgabeblack@google.com vec_add_on(und, ud, vnd, vd); 7412854Sgabeblack@google.com else 7512854Sgabeblack@google.com vec_add_on2(und, ud, vnd, vd); 7612854Sgabeblack@google.com 7712854Sgabeblack@google.com } else { // case 4 7812854Sgabeblack@google.com // vec_cmp expects that und is the number of non-zero digits in ud. 7912854Sgabeblack@google.com int new_und = vec_skip_leading_zeros(und, ud); 8012854Sgabeblack@google.com int cmp_res = vec_cmp(new_und, ud, vnd, vd); 8112854Sgabeblack@google.com 8212854Sgabeblack@google.com if (cmp_res == 0) { // u == v 8312854Sgabeblack@google.com us = SC_ZERO; 8412854Sgabeblack@google.com vec_zero(und, ud); 8512854Sgabeblack@google.com return; 8612854Sgabeblack@google.com } 8712854Sgabeblack@google.com 8812854Sgabeblack@google.com if (cmp_res > 0) { // u > v 8912854Sgabeblack@google.com vec_sub_on(und, ud, vnd, vd); 9012854Sgabeblack@google.com } else { // u < v 9112854Sgabeblack@google.com us = -us; 9212854Sgabeblack@google.com vec_sub_on2(und, ud, vnd, vd); 9312854Sgabeblack@google.com } 9412854Sgabeblack@google.com } 9512854Sgabeblack@google.com} 9612854Sgabeblack@google.com 9712854Sgabeblack@google.com 9812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 9912854Sgabeblack@google.com 10012854Sgabeblack@google.com/* 10112854Sgabeblack@google.com 10212854Sgabeblack@google.commul_on_help_signed and mul_on_help_unsigned have the same body except 10312854Sgabeblack@google.comthat CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and 10412854Sgabeblack@google.comunsigned, respectively. This comment also applies to the 10512854Sgabeblack@google.comsigned/unsigned versions of div_on_help and mod_on_help. It is 10612854Sgabeblack@google.compossible to take COPY_DIGITS out of these functions and create a 10712854Sgabeblack@google.comsingle version of each of these helper functions; however, this will 10812854Sgabeblack@google.comimpose an onverhead on performance. In the versions below, any change 10912854Sgabeblack@google.comin the signed version of a helper function must be carried to a 11012854Sgabeblack@google.comcorresponding change in the unsigned verion of the same function or 11112854Sgabeblack@google.comvice versa. 11212854Sgabeblack@google.com 11312854Sgabeblack@google.com*/ 11412854Sgabeblack@google.com 11512854Sgabeblack@google.com 11612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 11712854Sgabeblack@google.com// SECTION: External functions of MULTIPLICATION operators. 11812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 11912854Sgabeblack@google.com 12012854Sgabeblack@google.comvoid 12112854Sgabeblack@google.commul_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 12212854Sgabeblack@google.com int vnb, int vnd, const sc_digit *vd) 12312854Sgabeblack@google.com{ 12412854Sgabeblack@google.com#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 12512854Sgabeblack@google.com#define COPY_DIGITS copy_digits_signed 12612854Sgabeblack@google.com { // Body of mul_on_help 12712854Sgabeblack@google.com int old_und = und; 12812854Sgabeblack@google.com 12912854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 13012854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 13112854Sgabeblack@google.com 13212854Sgabeblack@google.com sc_digit ud0 = (*ud); 13312854Sgabeblack@google.com sc_digit vd0 = (*vd); 13412854Sgabeblack@google.com 13512854Sgabeblack@google.com if ((vnd == 1) && (vd0 == 1)) { 13612854Sgabeblack@google.com us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 13712854Sgabeblack@google.com return; 13812854Sgabeblack@google.com } 13912854Sgabeblack@google.com 14012854Sgabeblack@google.com if ((und == 1) && (ud0 == 1)) { 14112854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 14212854Sgabeblack@google.com return; 14312854Sgabeblack@google.com } 14412854Sgabeblack@google.com 14512854Sgabeblack@google.com if ((und == 1) && (vnd == 1) && 14612854Sgabeblack@google.com (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 14712854Sgabeblack@google.com 14812854Sgabeblack@google.com sc_digit d = ud0 * vd0; 14912854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 15012854Sgabeblack@google.com return; 15112854Sgabeblack@google.com } 15212854Sgabeblack@google.com 15312854Sgabeblack@google.com int nd = und + vnd; 15412854Sgabeblack@google.com 15512854Sgabeblack@google.com#ifdef SC_MAX_NBITS 15612854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 15712854Sgabeblack@google.com#else 15812854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 15912854Sgabeblack@google.com#endif 16012854Sgabeblack@google.com 16112854Sgabeblack@google.com vec_zero(nd, d); 16212854Sgabeblack@google.com 16312854Sgabeblack@google.com if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 16412854Sgabeblack@google.com vec_mul_small(vnd, vd, ud0, d); 16512854Sgabeblack@google.com else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 16612854Sgabeblack@google.com vec_mul_small(und, ud, vd0, d); 16712854Sgabeblack@google.com else if (vnd < und) 16812854Sgabeblack@google.com vec_mul(und, ud, vnd, vd, d); 16912854Sgabeblack@google.com else 17012854Sgabeblack@google.com vec_mul(vnd, vd, und, ud, d); 17112854Sgabeblack@google.com 17212854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 17312854Sgabeblack@google.com 17412854Sgabeblack@google.com#ifndef SC_MAX_NBITS 17512854Sgabeblack@google.com delete [] d; 17612854Sgabeblack@google.com#endif 17712854Sgabeblack@google.com } 17812854Sgabeblack@google.com#undef COPY_DIGITS 17912854Sgabeblack@google.com#undef CONVERT_SM_to_2C_to_SM 18012854Sgabeblack@google.com} 18112854Sgabeblack@google.com 18212854Sgabeblack@google.com 18312854Sgabeblack@google.comvoid 18412854Sgabeblack@google.commul_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 18512854Sgabeblack@google.com int vnb, int vnd, const sc_digit *vd) 18612854Sgabeblack@google.com{ 18712854Sgabeblack@google.com#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 18812854Sgabeblack@google.com#define COPY_DIGITS copy_digits_unsigned 18912854Sgabeblack@google.com { // Body of mul_on_help 19012854Sgabeblack@google.com int old_und = und; 19112854Sgabeblack@google.com 19212854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 19312854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 19412854Sgabeblack@google.com 19512854Sgabeblack@google.com sc_digit ud0 = (*ud); 19612854Sgabeblack@google.com sc_digit vd0 = (*vd); 19712854Sgabeblack@google.com 19812854Sgabeblack@google.com if ((vnd == 1) && (vd0 == 1)) { 19912854Sgabeblack@google.com us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 20012854Sgabeblack@google.com return; 20112854Sgabeblack@google.com } 20212854Sgabeblack@google.com 20312854Sgabeblack@google.com if ((und == 1) && (ud0 == 1)) { 20412854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); 20512854Sgabeblack@google.com return; 20612854Sgabeblack@google.com } 20712854Sgabeblack@google.com 20812854Sgabeblack@google.com if ((und == 1) && (vnd == 1) && 20912854Sgabeblack@google.com (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { 21012854Sgabeblack@google.com 21112854Sgabeblack@google.com sc_digit d = ud0 * vd0; 21212854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); 21312854Sgabeblack@google.com return; 21412854Sgabeblack@google.com } 21512854Sgabeblack@google.com 21612854Sgabeblack@google.com int nd = und + vnd; 21712854Sgabeblack@google.com 21812854Sgabeblack@google.com#ifdef SC_MAX_NBITS 21912854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 22012854Sgabeblack@google.com#else 22112854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 22212854Sgabeblack@google.com#endif 22312854Sgabeblack@google.com 22412854Sgabeblack@google.com vec_zero(nd, d); 22512854Sgabeblack@google.com 22612854Sgabeblack@google.com if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) 22712854Sgabeblack@google.com vec_mul_small(vnd, vd, ud0, d); 22812854Sgabeblack@google.com else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 22912854Sgabeblack@google.com vec_mul_small(und, ud, vd0, d); 23012854Sgabeblack@google.com else if (vnd < und) 23112854Sgabeblack@google.com vec_mul(und, ud, vnd, vd, d); 23212854Sgabeblack@google.com else 23312854Sgabeblack@google.com vec_mul(vnd, vd, und, ud, d); 23412854Sgabeblack@google.com 23512854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); 23612854Sgabeblack@google.com 23712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 23812854Sgabeblack@google.com delete [] d; 23912854Sgabeblack@google.com#endif 24012854Sgabeblack@google.com } 24112854Sgabeblack@google.com#undef COPY_DIGITS 24212854Sgabeblack@google.com#undef CONVERT_SM_to_2C_to_SM 24312854Sgabeblack@google.com} 24412854Sgabeblack@google.com 24512854Sgabeblack@google.com 24612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 24712854Sgabeblack@google.com// SECTION: External functions for DIVISION operators. 24812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 24912854Sgabeblack@google.com 25012854Sgabeblack@google.comvoid 25112854Sgabeblack@google.comdiv_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 25212854Sgabeblack@google.com int vnb, int vnd, const sc_digit *vd) 25312854Sgabeblack@google.com{ 25412854Sgabeblack@google.com#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM 25512854Sgabeblack@google.com#define COPY_DIGITS copy_digits_signed 25612854Sgabeblack@google.com { // Body of div_on_help 25712854Sgabeblack@google.com int old_und = und; 25812854Sgabeblack@google.com 25912854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 26012854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 26112854Sgabeblack@google.com 26212854Sgabeblack@google.com int cmp_res = vec_cmp(und, ud, vnd, vd); 26312854Sgabeblack@google.com 26412854Sgabeblack@google.com if (cmp_res < 0) { // u < v => u / v = 0 - case 4 26512854Sgabeblack@google.com us = SC_ZERO; 26612854Sgabeblack@google.com vec_zero(old_und, ud); 26712854Sgabeblack@google.com return; 26812854Sgabeblack@google.com } 26912854Sgabeblack@google.com 27012854Sgabeblack@google.com sc_digit vd0 = (*vd); 27112854Sgabeblack@google.com 27212854Sgabeblack@google.com if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 27312854Sgabeblack@google.com us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 27412854Sgabeblack@google.com return; 27512854Sgabeblack@google.com } 27612854Sgabeblack@google.com 27712854Sgabeblack@google.com // One extra digit for d is allocated to simplify vec_div_*(). 27812854Sgabeblack@google.com int nd = sc_max(und, vnd) + 1; 27912854Sgabeblack@google.com 28012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 28112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS + 1]; 28212854Sgabeblack@google.com#else 28312854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 28412854Sgabeblack@google.com#endif 28512854Sgabeblack@google.com 28612854Sgabeblack@google.com vec_zero(nd, d); 28712854Sgabeblack@google.com 28812854Sgabeblack@google.com // u = v => u / v = 1 - case 3 28912854Sgabeblack@google.com if (cmp_res == 0) 29012854Sgabeblack@google.com d[0] = 1; 29112854Sgabeblack@google.com else if ((vnd == 1) && (und == 1)) 29212854Sgabeblack@google.com d[0] = (*ud) / vd0; 29312854Sgabeblack@google.com else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 29412854Sgabeblack@google.com vec_div_small(und, ud, vd0, d); 29512854Sgabeblack@google.com else 29612854Sgabeblack@google.com vec_div_large(und, ud, vnd, vd, d); 29712854Sgabeblack@google.com 29812854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 29912854Sgabeblack@google.com 30012854Sgabeblack@google.com#ifndef SC_MAX_NBITS 30112854Sgabeblack@google.com delete [] d; 30212854Sgabeblack@google.com#endif 30312854Sgabeblack@google.com } 30412854Sgabeblack@google.com#undef COPY_DIGITS 30512854Sgabeblack@google.com#undef CONVERT_SM_to_2C_to_SM 30612854Sgabeblack@google.com} 30712854Sgabeblack@google.com 30812854Sgabeblack@google.com 30912854Sgabeblack@google.comvoid 31012854Sgabeblack@google.comdiv_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 31112854Sgabeblack@google.com int vnb, int vnd, const sc_digit *vd) 31212854Sgabeblack@google.com{ 31312854Sgabeblack@google.com#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM 31412854Sgabeblack@google.com#define COPY_DIGITS copy_digits_unsigned 31512854Sgabeblack@google.com { // Body of div_on_help 31612854Sgabeblack@google.com int old_und = und; 31712854Sgabeblack@google.com 31812854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 31912854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 32012854Sgabeblack@google.com 32112854Sgabeblack@google.com int cmp_res = vec_cmp(und, ud, vnd, vd); 32212854Sgabeblack@google.com 32312854Sgabeblack@google.com if (cmp_res < 0) { // u < v => u / v = 0 - case 4 32412854Sgabeblack@google.com us = SC_ZERO; 32512854Sgabeblack@google.com vec_zero(old_und, ud); 32612854Sgabeblack@google.com return; 32712854Sgabeblack@google.com } 32812854Sgabeblack@google.com 32912854Sgabeblack@google.com sc_digit vd0 = (*vd); 33012854Sgabeblack@google.com 33112854Sgabeblack@google.com if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { 33212854Sgabeblack@google.com us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); 33312854Sgabeblack@google.com return; 33412854Sgabeblack@google.com } 33512854Sgabeblack@google.com 33612854Sgabeblack@google.com // One extra digit for d is allocated to simplify vec_div_*(). 33712854Sgabeblack@google.com int nd = sc_max(und, vnd) + 1; 33812854Sgabeblack@google.com 33912854Sgabeblack@google.com#ifdef SC_MAX_NBITS 34012854Sgabeblack@google.com sc_digit d[MAX_NDIGITS + 1]; 34112854Sgabeblack@google.com#else 34212854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 34312854Sgabeblack@google.com#endif 34412854Sgabeblack@google.com 34512854Sgabeblack@google.com vec_zero(nd, d); 34612854Sgabeblack@google.com 34712854Sgabeblack@google.com // u = v => u / v = 1 - case 3 34812854Sgabeblack@google.com if (cmp_res == 0) 34912854Sgabeblack@google.com d[0] = 1; 35012854Sgabeblack@google.com else if ((vnd == 1) && (und == 1)) 35112854Sgabeblack@google.com d[0] = (*ud) / vd0; 35212854Sgabeblack@google.com else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 35312854Sgabeblack@google.com vec_div_small(und, ud, vd0, d); 35412854Sgabeblack@google.com else 35512854Sgabeblack@google.com vec_div_large(und, ud, vnd, vd, d); 35612854Sgabeblack@google.com 35712854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); 35812854Sgabeblack@google.com 35912854Sgabeblack@google.com#ifndef SC_MAX_NBITS 36012854Sgabeblack@google.com delete [] d; 36112854Sgabeblack@google.com#endif 36212854Sgabeblack@google.com } 36312854Sgabeblack@google.com#undef COPY_DIGITS 36412854Sgabeblack@google.com#undef CONVERT_SM_to_2C_to_SM 36512854Sgabeblack@google.com} 36612854Sgabeblack@google.com 36712854Sgabeblack@google.com 36812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 36912854Sgabeblack@google.com// SECTION: External functions for MOD operators. 37012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 37112854Sgabeblack@google.com 37212854Sgabeblack@google.comvoid 37312854Sgabeblack@google.commod_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, 37412854Sgabeblack@google.com int /* vnb */, int vnd, const sc_digit *vd) 37512854Sgabeblack@google.com{ 37612854Sgabeblack@google.com#define COPY_DIGITS copy_digits_signed 37712854Sgabeblack@google.com { // Body of mod_on_help 37812854Sgabeblack@google.com int old_und = und; 37912854Sgabeblack@google.com 38012854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 38112854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 38212854Sgabeblack@google.com 38312854Sgabeblack@google.com int cmp_res = vec_cmp(und, ud, vnd, vd); 38412854Sgabeblack@google.com 38512854Sgabeblack@google.com // u < v => u % v = u - case 4 38612854Sgabeblack@google.com if (cmp_res < 0) 38712854Sgabeblack@google.com return; 38812854Sgabeblack@google.com 38912854Sgabeblack@google.com // u = v => u % v = 0 - case 3 39012854Sgabeblack@google.com if (cmp_res == 0) { 39112854Sgabeblack@google.com us = SC_ZERO; 39212854Sgabeblack@google.com vec_zero(old_und, ud); 39312854Sgabeblack@google.com return; 39412854Sgabeblack@google.com } 39512854Sgabeblack@google.com // else if u > v - case 5 39612854Sgabeblack@google.com 39712854Sgabeblack@google.com sc_digit vd0 = (*vd); 39812854Sgabeblack@google.com 39912854Sgabeblack@google.com if ((vnd == 1) && (vd0 == 1)) { 40012854Sgabeblack@google.com us = SC_ZERO; 40112854Sgabeblack@google.com vec_zero(old_und, ud); 40212854Sgabeblack@google.com return; 40312854Sgabeblack@google.com } 40412854Sgabeblack@google.com 40512854Sgabeblack@google.com // One extra digit for d is allocated to simplify vec_div_*(). 40612854Sgabeblack@google.com int nd = sc_max(und, vnd) + 1; 40712854Sgabeblack@google.com 40812854Sgabeblack@google.com#ifdef SC_MAX_NBITS 40912854Sgabeblack@google.com sc_digit d[MAX_NDIGITS + 1]; 41012854Sgabeblack@google.com#else 41112854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 41212854Sgabeblack@google.com#endif 41312854Sgabeblack@google.com 41412854Sgabeblack@google.com vec_zero(nd, d); 41512854Sgabeblack@google.com 41612854Sgabeblack@google.com if ((vnd == 1) && (und == 1)) 41712854Sgabeblack@google.com d[0] = (*ud) % vd0; 41812854Sgabeblack@google.com if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 41912854Sgabeblack@google.com d[0] = vec_rem_small(und, ud, vd0); 42012854Sgabeblack@google.com else 42112854Sgabeblack@google.com vec_rem_large(und, ud, vnd, vd, d); 42212854Sgabeblack@google.com 42312854Sgabeblack@google.com us = check_for_zero(us, nd - 1, d); 42412854Sgabeblack@google.com 42512854Sgabeblack@google.com if (us == SC_ZERO) 42612854Sgabeblack@google.com vec_zero(old_und, ud); 42712854Sgabeblack@google.com else 42812854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 42912854Sgabeblack@google.com 43012854Sgabeblack@google.com#ifndef SC_MAX_NBITS 43112854Sgabeblack@google.com delete [] d; 43212854Sgabeblack@google.com#endif 43312854Sgabeblack@google.com } 43412854Sgabeblack@google.com#undef COPY_DIGITS 43512854Sgabeblack@google.com} 43612854Sgabeblack@google.com 43712854Sgabeblack@google.com 43812854Sgabeblack@google.comvoid 43912854Sgabeblack@google.commod_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, 44012854Sgabeblack@google.com int /* vnb */, int vnd, const sc_digit *vd) 44112854Sgabeblack@google.com{ 44212854Sgabeblack@google.com#define COPY_DIGITS copy_digits_unsigned 44312854Sgabeblack@google.com { // Body of mod_on_help 44412854Sgabeblack@google.com int old_und = und; 44512854Sgabeblack@google.com 44612854Sgabeblack@google.com und = vec_skip_leading_zeros(und, ud); 44712854Sgabeblack@google.com vnd = vec_skip_leading_zeros(vnd, vd); 44812854Sgabeblack@google.com 44912854Sgabeblack@google.com int cmp_res = vec_cmp(und, ud, vnd, vd); 45012854Sgabeblack@google.com 45112854Sgabeblack@google.com // u < v => u % v = u - case 4 45212854Sgabeblack@google.com if (cmp_res < 0) 45312854Sgabeblack@google.com return; 45412854Sgabeblack@google.com 45512854Sgabeblack@google.com // u = v => u % v = 0 - case 3 45612854Sgabeblack@google.com if (cmp_res == 0) { 45712854Sgabeblack@google.com us = SC_ZERO; 45812854Sgabeblack@google.com vec_zero(old_und, ud); 45912854Sgabeblack@google.com return; 46012854Sgabeblack@google.com } 46112854Sgabeblack@google.com 46212854Sgabeblack@google.com // else if u > v - case 5 46312854Sgabeblack@google.com 46412854Sgabeblack@google.com sc_digit vd0 = (*vd); 46512854Sgabeblack@google.com 46612854Sgabeblack@google.com if ((vnd == 1) && (vd0 == 1)) { 46712854Sgabeblack@google.com us = SC_ZERO; 46812854Sgabeblack@google.com vec_zero(old_und, ud); 46912854Sgabeblack@google.com return; 47012854Sgabeblack@google.com } 47112854Sgabeblack@google.com 47212854Sgabeblack@google.com // One extra digit for d is allocated to simplify vec_div_*(). 47312854Sgabeblack@google.com int nd = sc_max(und, vnd) + 1; 47412854Sgabeblack@google.com 47512854Sgabeblack@google.com#ifdef SC_MAX_NBITS 47612854Sgabeblack@google.com sc_digit d[MAX_NDIGITS + 1]; 47712854Sgabeblack@google.com#else 47812854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 47912854Sgabeblack@google.com#endif 48012854Sgabeblack@google.com 48112854Sgabeblack@google.com vec_zero(nd, d); 48212854Sgabeblack@google.com 48312854Sgabeblack@google.com if ((vnd == 1) && (und == 1)) 48412854Sgabeblack@google.com d[0] = (*ud) % vd0; 48512854Sgabeblack@google.com if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) 48612854Sgabeblack@google.com d[0] = vec_rem_small(und, ud, vd0); 48712854Sgabeblack@google.com else 48812854Sgabeblack@google.com vec_rem_large(und, ud, vnd, vd, d); 48912854Sgabeblack@google.com 49012854Sgabeblack@google.com us = check_for_zero(us, nd - 1, d); 49112854Sgabeblack@google.com 49212854Sgabeblack@google.com if (us == SC_ZERO) 49312854Sgabeblack@google.com vec_zero(old_und, ud); 49412854Sgabeblack@google.com else 49512854Sgabeblack@google.com COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d); 49612854Sgabeblack@google.com 49712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 49812854Sgabeblack@google.com delete [] d; 49912854Sgabeblack@google.com#endif 50012854Sgabeblack@google.com } 50112854Sgabeblack@google.com#undef COPY_DIGITS 50212854Sgabeblack@google.com} 50312854Sgabeblack@google.com 50412854Sgabeblack@google.com 50512854Sgabeblack@google.com// ---------------------------------------------------------------------------- 50612854Sgabeblack@google.com// SECTION: External functions for AND operators. 50712854Sgabeblack@google.com// ---------------------------------------------------------------------------- 50812854Sgabeblack@google.com 50912854Sgabeblack@google.com// Handles the cases 2-5 and returns the result in u. 51012854Sgabeblack@google.comvoid 51112854Sgabeblack@google.comand_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 51212854Sgabeblack@google.com small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 51312854Sgabeblack@google.com{ 51412854Sgabeblack@google.com sc_digit *x = ud; 51512854Sgabeblack@google.com const sc_digit *y = vd; 51612854Sgabeblack@google.com int xnd = und; 51712854Sgabeblack@google.com int ynd = vnd; 51812854Sgabeblack@google.com 51912854Sgabeblack@google.com // Truncate y. 52012854Sgabeblack@google.com if (xnd < ynd) 52112854Sgabeblack@google.com ynd = xnd; 52212854Sgabeblack@google.com 52312854Sgabeblack@google.com const sc_digit *xend = (x + xnd); 52412854Sgabeblack@google.com const sc_digit *yend = (y + ynd); 52512854Sgabeblack@google.com 52612854Sgabeblack@google.com // x is longer than y. 52712854Sgabeblack@google.com small_type s = mul_signs(us, vs); 52812854Sgabeblack@google.com 52912854Sgabeblack@google.com if (s > 0) { 53012854Sgabeblack@google.com if (us > 0) { // case 2 53112854Sgabeblack@google.com while (y < yend) 53212854Sgabeblack@google.com (*x++) &= (*y++); 53312854Sgabeblack@google.com while (x < xend) 53412854Sgabeblack@google.com (*x++) = 0; 53512854Sgabeblack@google.com } else { // case 3 53612854Sgabeblack@google.com sc_digit xcarry = 1; 53712854Sgabeblack@google.com sc_digit ycarry = 1; 53812854Sgabeblack@google.com while (y < yend) { 53912854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 54012854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 54112854Sgabeblack@google.com (*x++) = (xcarry & ycarry) & DIGIT_MASK; 54212854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 54312854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 54412854Sgabeblack@google.com } 54512854Sgabeblack@google.com while (x < xend) { 54612854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 54712854Sgabeblack@google.com ycarry += DIGIT_MASK; 54812854Sgabeblack@google.com (*x++) = (xcarry & ycarry) & DIGIT_MASK; 54912854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 55012854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 55112854Sgabeblack@google.com } 55212854Sgabeblack@google.com 55312854Sgabeblack@google.com } 55412854Sgabeblack@google.com } else { 55512854Sgabeblack@google.com if (us > 0) { // case 4 55612854Sgabeblack@google.com sc_digit ycarry = 1; 55712854Sgabeblack@google.com while (y < yend) { 55812854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 55912854Sgabeblack@google.com (*x++) &= ycarry & DIGIT_MASK; 56012854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 56112854Sgabeblack@google.com } 56212854Sgabeblack@google.com while (x < xend) { 56312854Sgabeblack@google.com ycarry += DIGIT_MASK; 56412854Sgabeblack@google.com (*x++) &= ycarry & DIGIT_MASK; 56512854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 56612854Sgabeblack@google.com } 56712854Sgabeblack@google.com } else { // case 5 56812854Sgabeblack@google.com sc_digit xcarry = 1; 56912854Sgabeblack@google.com while (y < yend) { 57012854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 57112854Sgabeblack@google.com (*x++) = (xcarry & (*y++)) & DIGIT_MASK; 57212854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 57312854Sgabeblack@google.com } 57412854Sgabeblack@google.com while (x < xend) 57512854Sgabeblack@google.com (*x++) = 0; 57612854Sgabeblack@google.com } 57712854Sgabeblack@google.com } 57812854Sgabeblack@google.com} 57912854Sgabeblack@google.com 58012854Sgabeblack@google.com 58112854Sgabeblack@google.com// ---------------------------------------------------------------------------- 58212854Sgabeblack@google.com// SECTION: External functions for OR operators. 58312854Sgabeblack@google.com// ---------------------------------------------------------------------------- 58412854Sgabeblack@google.com 58512854Sgabeblack@google.com// Handles the cases 3-5 and returns the result in u. 58612854Sgabeblack@google.comvoid 58712854Sgabeblack@google.comor_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 58812854Sgabeblack@google.com small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 58912854Sgabeblack@google.com{ 59012854Sgabeblack@google.com sc_digit *x = ud; 59112854Sgabeblack@google.com const sc_digit *y = vd; 59212854Sgabeblack@google.com int xnd = und; 59312854Sgabeblack@google.com int ynd = vnd; 59412854Sgabeblack@google.com 59512854Sgabeblack@google.com if (xnd < ynd) 59612854Sgabeblack@google.com ynd = xnd; 59712854Sgabeblack@google.com 59812854Sgabeblack@google.com const sc_digit *xend = (x + xnd); 59912854Sgabeblack@google.com const sc_digit *yend = (y + ynd); 60012854Sgabeblack@google.com 60112854Sgabeblack@google.com // x is longer than y. 60212854Sgabeblack@google.com small_type s = mul_signs(us, vs); 60312854Sgabeblack@google.com 60412854Sgabeblack@google.com if (s > 0) { 60512854Sgabeblack@google.com if (us > 0) { // case 3 60612854Sgabeblack@google.com while (y < yend) 60712854Sgabeblack@google.com (*x++) |= (*y++); 60812854Sgabeblack@google.com // No change for the rest of x. 60912854Sgabeblack@google.com } else { // case 4 61012854Sgabeblack@google.com sc_digit xcarry = 1; 61112854Sgabeblack@google.com sc_digit ycarry = 1; 61212854Sgabeblack@google.com while (y < yend) { 61312854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 61412854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 61512854Sgabeblack@google.com (*x++) = (xcarry | ycarry) & DIGIT_MASK; 61612854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 61712854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 61812854Sgabeblack@google.com } 61912854Sgabeblack@google.com while (x < xend) { 62012854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 62112854Sgabeblack@google.com ycarry += DIGIT_MASK; 62212854Sgabeblack@google.com (*x++) = (xcarry | ycarry) & DIGIT_MASK; 62312854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 62412854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 62512854Sgabeblack@google.com } 62612854Sgabeblack@google.com } 62712854Sgabeblack@google.com } else { 62812854Sgabeblack@google.com if (us > 0) { // case 5 62912854Sgabeblack@google.com sc_digit ycarry = 1; 63012854Sgabeblack@google.com while (y < yend) { 63112854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 63212854Sgabeblack@google.com (*x) = ((*x) | ycarry) & DIGIT_MASK; 63312854Sgabeblack@google.com x++; 63412854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 63512854Sgabeblack@google.com } 63612854Sgabeblack@google.com while (x < xend) { 63712854Sgabeblack@google.com ycarry += DIGIT_MASK; 63812854Sgabeblack@google.com (*x) = ((*x) | ycarry) & DIGIT_MASK; 63912854Sgabeblack@google.com x++; 64012854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 64112854Sgabeblack@google.com } 64212854Sgabeblack@google.com } else { // case 6 64312854Sgabeblack@google.com sc_digit xcarry = 1; 64412854Sgabeblack@google.com while (y < yend) { 64512854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 64612854Sgabeblack@google.com (*x++) = (xcarry | (*y++)) & DIGIT_MASK; 64712854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 64812854Sgabeblack@google.com } 64912854Sgabeblack@google.com while (x < xend) { 65012854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 65112854Sgabeblack@google.com (*x++) = xcarry & DIGIT_MASK; 65212854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 65312854Sgabeblack@google.com } 65412854Sgabeblack@google.com } 65512854Sgabeblack@google.com } 65612854Sgabeblack@google.com} 65712854Sgabeblack@google.com 65812854Sgabeblack@google.com 65912854Sgabeblack@google.com// ---------------------------------------------------------------------------- 66012854Sgabeblack@google.com// SECTION: External functions for XOR operators. 66112854Sgabeblack@google.com// ---------------------------------------------------------------------------- 66212854Sgabeblack@google.com 66312854Sgabeblack@google.com// Handles the cases 3-5 and returns the result in u. 66412854Sgabeblack@google.comvoid 66512854Sgabeblack@google.comxor_on_help(small_type us, int /* unb */, int und, sc_digit *ud, 66612854Sgabeblack@google.com small_type vs, int /* vnb */, int vnd, const sc_digit *vd) 66712854Sgabeblack@google.com{ 66812854Sgabeblack@google.com sc_digit *x = ud; 66912854Sgabeblack@google.com const sc_digit *y = vd; 67012854Sgabeblack@google.com int xnd = und; 67112854Sgabeblack@google.com int ynd = vnd; 67212854Sgabeblack@google.com 67312854Sgabeblack@google.com if (xnd < ynd) 67412854Sgabeblack@google.com ynd = xnd; 67512854Sgabeblack@google.com 67612854Sgabeblack@google.com const sc_digit *xend = (x + xnd); 67712854Sgabeblack@google.com const sc_digit *yend = (y + ynd); 67812854Sgabeblack@google.com 67912854Sgabeblack@google.com // x is longer than y. 68012854Sgabeblack@google.com small_type s = mul_signs(us, vs); 68112854Sgabeblack@google.com 68212854Sgabeblack@google.com if (s > 0) { 68312854Sgabeblack@google.com if (us > 0) { // case 3 68412854Sgabeblack@google.com while (y < yend) { 68512854Sgabeblack@google.com (*x) = ((*x) ^ (*y)) & DIGIT_MASK; 68612854Sgabeblack@google.com x++; 68712854Sgabeblack@google.com y++; 68812854Sgabeblack@google.com } 68912854Sgabeblack@google.com // No change for the rest of x. 69012854Sgabeblack@google.com } else { // case 4 69112854Sgabeblack@google.com sc_digit xcarry = 1; 69212854Sgabeblack@google.com sc_digit ycarry = 1; 69312854Sgabeblack@google.com while (y < yend) { 69412854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 69512854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 69612854Sgabeblack@google.com (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 69712854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 69812854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 69912854Sgabeblack@google.com } 70012854Sgabeblack@google.com while (x < xend) { 70112854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 70212854Sgabeblack@google.com ycarry += DIGIT_MASK; 70312854Sgabeblack@google.com (*x++) = (xcarry ^ ycarry) & DIGIT_MASK; 70412854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 70512854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 70612854Sgabeblack@google.com } 70712854Sgabeblack@google.com } 70812854Sgabeblack@google.com } else { 70912854Sgabeblack@google.com if (us > 0) { // case 5 71012854Sgabeblack@google.com sc_digit ycarry = 1; 71112854Sgabeblack@google.com while (y < yend) { 71212854Sgabeblack@google.com ycarry += (~(*y++) & DIGIT_MASK); 71312854Sgabeblack@google.com (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 71412854Sgabeblack@google.com x++; 71512854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 71612854Sgabeblack@google.com } 71712854Sgabeblack@google.com while (x < xend) { 71812854Sgabeblack@google.com ycarry += DIGIT_MASK; 71912854Sgabeblack@google.com (*x) = ((*x) ^ ycarry) & DIGIT_MASK; 72012854Sgabeblack@google.com x++; 72112854Sgabeblack@google.com ycarry >>= BITS_PER_DIGIT; 72212854Sgabeblack@google.com } 72312854Sgabeblack@google.com } else { // case 6 72412854Sgabeblack@google.com sc_digit xcarry = 1; 72512854Sgabeblack@google.com while (y < yend) { 72612854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 72712854Sgabeblack@google.com (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK; 72812854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 72912854Sgabeblack@google.com } 73012854Sgabeblack@google.com while (x < xend) { 73112854Sgabeblack@google.com xcarry += (~(*x) & DIGIT_MASK); 73212854Sgabeblack@google.com (*x++) = xcarry & DIGIT_MASK; 73312854Sgabeblack@google.com xcarry >>= BITS_PER_DIGIT; 73412854Sgabeblack@google.com } 73512854Sgabeblack@google.com } 73612854Sgabeblack@google.com } 73712854Sgabeblack@google.com} 73812854Sgabeblack@google.com 73912854Sgabeblack@google.com} // namespace sc_dt 740