📄 sc_nbexterns.cpp
字号:
/***************************************************************************** The following code is derived, directly or indirectly, from the SystemC source code Copyright (c) 1996-2006 by all Contributors. All Rights reserved. The contents of this file are subject to the restrictions and limitations set forth in the SystemC Open Source License Version 2.4 (the "License"); You may not use this file except in compliance with such restrictions and limitations. You may obtain instructions on how to receive a copy of the License at http://www.systemc.org/. Software distributed by Contributors under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. *****************************************************************************//***************************************************************************** sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned classes. These functions work on two parameters u and v, and copy the result to the first parameter u. This is also the reason that they are suffixed with _on_help. Original Author: Ali Dasdan, Synopsys, Inc. *****************************************************************************//***************************************************************************** MODIFICATION LOG - modifiers, enter your name, affiliation, date and changes you are making here. Name, Affiliation, Date: Description of Modification: *****************************************************************************/// $Log: sc_nbexterns.cpp,v $// Revision 1.1.1.1 2006/12/15 20:31:36 acg// SystemC 2.2//// Revision 1.3 2006/01/13 18:49:32 acg// Added $Log command so that CVS check in comments are reproduced in the// source.//#include "sysc/datatypes/int/sc_nbexterns.h"#include "sysc/kernel/sc_macros.h"namespace sc_dt{// ----------------------------------------------------------------------------// SECTION: External functions for PLUS operators.// ----------------------------------------------------------------------------// Handles the cases 3 and 4 and returns the result in u.voidadd_on_help(small_type &us, int /* unb */, int und, sc_digit *ud, small_type vs, int /* vnb */, int vnd, const sc_digit *vd){ vnd = vec_skip_leading_zeros(vnd, vd); if (us == vs) { // case 3 if (und >= vnd) vec_add_on(und, ud, vnd, vd); else vec_add_on2(und, ud, vnd, vd); } else { // case 4 // vec_cmp expects that und is the number of non-zero digits in ud. int new_und = vec_skip_leading_zeros(und, ud); int cmp_res = vec_cmp(new_und, ud, vnd, vd); if (cmp_res == 0) { // u == v us = SC_ZERO; vec_zero(und, ud); return; } if (cmp_res > 0) // u > v vec_sub_on(und, ud, vnd, vd); else { // u < v us = -us; vec_sub_on2(und, ud, vnd, vd); } }}// ----------------------------------------------------------------------------/* mul_on_help_signed and mul_on_help_unsigned have the same body exceptthat CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed andunsigned, respectively. This comment also applies to thesigned/unsigned versions of div_on_help and mod_on_help. It ispossible to take COPY_DIGITS out of these functions and create asingle version of each of these helper functions; however, this willimpose an onverhead on performance. In the versions below, any changein the signed version of a helper function must be carried to acorresponding change in the unsigned verion of the same function orvice versa.*/// ----------------------------------------------------------------------------// SECTION: External functions of MULTIPLICATION operators.// ----------------------------------------------------------------------------voidmul_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd){#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM#define COPY_DIGITS copy_digits_signed { // Body of mul_on_help int old_und = und; und = vec_skip_leading_zeros(und, ud); vnd = vec_skip_leading_zeros(vnd, vd); sc_digit ud0 = (*ud); sc_digit vd0 = (*vd); if ((vnd == 1) && (vd0 == 1)) { us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); return; } if ((und == 1) && (ud0 == 1)) { COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); return; } if ((und == 1) && (vnd == 1) && (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { sc_digit d = ud0 * vd0; COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); return; } int nd = und + vnd; #ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[nd];#endif vec_zero(nd, d); if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) vec_mul_small(vnd, vd, ud0, d); else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) vec_mul_small(und, ud, vd0, d); else if (vnd < und) vec_mul(und, ud, vnd, vd, d); else vec_mul(vnd, vd, und, ud, d); COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); #ifndef SC_MAX_NBITS delete [] d;#endif }#undef COPY_DIGITS#undef CONVERT_SM_to_2C_to_SM}voidmul_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd){#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM#define COPY_DIGITS copy_digits_unsigned { // Body of mul_on_help int old_und = und; und = vec_skip_leading_zeros(und, ud); vnd = vec_skip_leading_zeros(vnd, vd); sc_digit ud0 = (*ud); sc_digit vd0 = (*vd); if ((vnd == 1) && (vd0 == 1)) { us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); return; } if ((und == 1) && (ud0 == 1)) { COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd); return; } if ((und == 1) && (vnd == 1) && (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) { sc_digit d = ud0 * vd0; COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d); return; } int nd = und + vnd; #ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[nd];#endif vec_zero(nd, d); if ((und == 1) && (ud0 < HALF_DIGIT_RADIX)) vec_mul_small(vnd, vd, ud0, d); else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) vec_mul_small(und, ud, vd0, d); else if (vnd < und) vec_mul(und, ud, vnd, vd, d); else vec_mul(vnd, vd, und, ud, d); COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d); #ifndef SC_MAX_NBITS delete [] d;#endif }#undef COPY_DIGITS#undef CONVERT_SM_to_2C_to_SM}// ----------------------------------------------------------------------------// SECTION: External functions for DIVISION operators.// ----------------------------------------------------------------------------voiddiv_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd){#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM#define COPY_DIGITS copy_digits_signed { // Body of div_on_help int old_und = und; und = vec_skip_leading_zeros(und, ud); vnd = vec_skip_leading_zeros(vnd, vd); int cmp_res = vec_cmp(und, ud, vnd, vd); if (cmp_res < 0) { // u < v => u / v = 0 - case 4 us = SC_ZERO; vec_zero(old_und, ud); return; } sc_digit vd0 = (*vd); if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); return; } // One extra digit for d is allocated to simplify vec_div_*(). int nd = sc_max(und, vnd) + 1; #ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS + 1];#else sc_digit *d = new sc_digit[nd];#endif vec_zero(nd, d); // u = v => u / v = 1 - case 3 if (cmp_res == 0) d[0] = 1; else if ((vnd == 1) && (und == 1)) d[0] = (*ud) / vd0; else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) vec_div_small(und, ud, vd0, d); else vec_div_large(und, ud, vnd, vd, d); COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); #ifndef SC_MAX_NBITS delete [] d;#endif } #undef COPY_DIGITS#undef CONVERT_SM_to_2C_to_SM}voiddiv_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd){#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM#define COPY_DIGITS copy_digits_unsigned { // Body of div_on_help int old_und = und; und = vec_skip_leading_zeros(und, ud); vnd = vec_skip_leading_zeros(vnd, vd); int cmp_res = vec_cmp(und, ud, vnd, vd); if (cmp_res < 0) { // u < v => u / v = 0 - case 4 us = SC_ZERO; vec_zero(old_und, ud); return; } sc_digit vd0 = (*vd); if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) { us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud); return; } // One extra digit for d is allocated to simplify vec_div_*(). int nd = sc_max(und, vnd) + 1; #ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS + 1];#else sc_digit *d = new sc_digit[nd];#endif vec_zero(nd, d); // u = v => u / v = 1 - case 3 if (cmp_res == 0) d[0] = 1; else if ((vnd == 1) && (und == 1)) d[0] = (*ud) / vd0; else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX)) vec_div_small(und, ud, vd0, d); else vec_div_large(und, ud, vnd, vd, d); COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d); #ifndef SC_MAX_NBITS delete [] d;#endif } #undef COPY_DIGITS#undef CONVERT_SM_to_2C_to_SM}// ----------------------------------------------------------------------------// SECTION: External functions for MOD operators.// ----------------------------------------------------------------------------voidmod_on_help_signed(small_type &us, int unb, int und, sc_digit *ud, int /* vnb */, int vnd, const sc_digit *vd){#define COPY_DIGITS copy_digits_signed { // Body of mod_on_help int old_und = und; und = vec_skip_leading_zeros(und, ud); vnd = vec_skip_leading_zeros(vnd, vd); int cmp_res = vec_cmp(und, ud, vnd, vd); // u < v => u % v = u - case 4 if (cmp_res < 0) return; // u = v => u % v = 0 - case 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -