12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300 |
- /**********************************************************************
- Each of the companies; Lucent, Motorola, Nokia, and Qualcomm (hereinafter
- referred to individually as "Source" or collectively as "Sources") do
- hereby state:
- To the extent to which the Source(s) may legally and freely do so, the
- Source(s), upon submission of a Contribution, grant(s) a free,
- irrevocable, non-exclusive, license to the Third Generation Partnership
- Project 2 (3GPP2) and its Organizational Partners: ARIB, CCSA, TIA, TTA,
- and TTC, under the Source's copyright or copyright license rights in the
- Contribution, to, in whole or in part, copy, make derivative works,
- perform, display and distribute the Contribution and derivative works
- thereof consistent with 3GPP2's and each Organizational Partner's
- policies and procedures, with the right to (i) sublicense the foregoing
- rights consistent with 3GPP2's and each Organizational Partner's policies
- and procedures and (ii) copyright and sell, if applicable) in 3GPP2's name
- or each Organizational Partner's name any 3GPP2 or transposed Publication
- even though this Publication may contain the Contribution or a derivative
- work thereof. The Contribution shall disclose any known limitations on
- the Source's rights to license as herein provided.
- When a Contribution is submitted by the Source(s) to assist the
- formulating groups of 3GPP2 or any of its Organizational Partners, it
- is proposed to the Committee as a basis for discussion and is not to
- be construed as a binding proposal on the Source(s). The Source(s)
- specifically reserve(s) the right to amend or modify the material
- contained in the Contribution. Nothing contained in the Contribution
- shall, except as herein expressly provided, be construed as conferring
- by implication, estoppel or otherwise, any license or right under (i)
- any existing or later issuing patent, whether or not the use of
- information in the document necessarily employs an invention of any
- existing or later issued patent, (ii) any copyright, (iii) any
- trademark, or (iv) any other intellectual property right.
- With respect to the Software necessary for the practice of any or
- all Normative portions of the Enhanced Variable Rate Codec (EVRC) as
- it exists on the date of submittal of this form, should the EVRC be
- approved as a Specification or Report by 3GPP2, or as a transposed
- Standard by any of the 3GPP2's Organizational Partners, the Source(s)
- state(s) that a worldwide license to reproduce, use and distribute the
- Software, the license rights to which are held by the Source(s), will
- be made available to applicants under terms and conditions that are
- reasonable and non-discriminatory, which may include monetary compensation,
- and only to the extent necessary for the practice of any or all of the
- Normative portions of the EVRC or the field of use of practice of the
- EVRC Specification, Report, or Standard. The statement contained above
- is irrevocable and shall be binding upon the Source(s). In the event
- the rights of the Source(s) in and to copyright or copyright license
- rights subject to such commitment are assigned or transferred, the
- Source(s) shall notify the assignee or transferee of the existence of
- such commitments.
- *******************************************************************/
-
- /*======================================================================*/
- /* Enhanced Variable Rate Codec - Bit-Exact C Specification */
- /* Copyright (C) 1997-1998 Telecommunications Industry Association. */
- /* All rights reserved. */
- /*----------------------------------------------------------------------*/
- /* Note: Reproduction and use of this software for the design and */
- /* development of North American Wideband CDMA Digital */
- /* Cellular Telephony Standards is authorized by the TIA. */
- /* The TIA does not authorize the use of this software for any */
- /* other purpose. */
- /* */
- /* The availability of this software does not provide any license */
- /* by implication, estoppel, or otherwise under any patent rights */
- /* of TIA member companies or others covering any use of the */
- /* contents herein. */
- /* */
- /* Any copies of this software or derivative works must include */
- /* this and all other proprietary notices. */
- /*======================================================================*/
- /***************************************************************************
- *
- * File Name: mathevrc.c
- *
- * Purpose: Contains functions which implement the primitive
- * arithmetic operations.
- *
- * The functions in this file are listed below. Some of them are
- * defined in terms of other basic operations. One of the
- * routines, saturate() is static. This is not a basic
- * operation, and is not referenced outside the scope of this
- * file.
- *
- *
- * abs_s()
- * add()
- * clearOverflow()
- * divide_s()
- * extract_h()
- * extract_l()
- * isOverflow()
- * L_abs()
- * L_add()
- * L_deposit_h()
- * L_deposit_l()
- * L_mac()
- * L_msu()
- * L_mult()
- * L_negate()
- * L_shift_r()
- * L_shl()
- * L_shr()
- * L_sub()
- * mac_r()
- * msu_r()
- * mult()
- * mult_r()
- * negate()
- * norm_l()
- * norm_s()
- * popOverflow()
- * round32()
- * saturate()
- * setOverflow()
- * shift_r()
- * shl()
- * shr()
- * sub()
- *
- **************************************************************************/
- /*_________________________________________________________________________
- | |
- | Include Files |
- |_________________________________________________________________________|
- */
- #include "typedefs.h"
- #include "mathevrc.h"
- //#include <math.h>
- /***************************************************************************
- *
- * FUNCTION NAME: saturate
- *
- * PURPOSE:
- *
- * Limit the 32 bit input to the range of a 16 bit word.
- *
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * KEYWORDS: saturation, limiting, limit, saturate, 16 bits
- *
- *************************************************************************/
- static Shortword saturate(Longword L_var1)
- {
- Shortword swOut;
- if (L_var1 > SW_MAX)
- {
- swOut = SW_MAX;
- giOverflow = 1;
- }
- else if (L_var1 < SW_MIN)
- {
- swOut = SW_MIN;
- giOverflow = 1;
- }
- else
- swOut = (Shortword) L_var1; /* automatic type conversion */
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_saturate
- *
- * PURPOSE:
- *
- * Limit the input double (possibly exceeding 32 bit dynamic
- * range) having to the 32 output wordsize.
- *
- * INPUTS:
- *
- * dVar1
- * A double whose range is
- * 0x8 0000 0000 <= L_var1 <= 0x7 ffff ffff.
- * i.e. a 33 bit number. Not modified.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long integer (Longword) where the DSP's
- * rules of saturation are followed:
- * for: 0x8000 0000 <= dVal1 <= 0x7fff ffff
- * input == output, no saturation
- * for: 0x8000 0000 > dVal1 output 0x8000 0000
- * for: dVal1 > 0x7fff ffff output 0x7fff ffff
- *
- * KEYWORDS: saturation, limiting, limit, saturate, 32 bits
- *
- *************************************************************************/
- Longword L_saturate(double dVar1)
- {
- OP_COUNT(4); /* Complexity Count -- LT 6/96 */
- if (dVar1 > (double) LW_MAX)
- {
- dVar1 = (double) LW_MAX;
- giOverflow = 1;
- }
- else if (dVar1 < (double) LW_MIN)
- {
- dVar1 = (double) LW_MIN;
- giOverflow = 1;
- }
- return ((Longword) dVar1);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: abs_s
- *
- * PURPOSE:
- *
- * Take the absolute value of the 16 bit input. An input of
- * -0x8000 results in a return value of 0x7fff.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0x0000 0000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Take the absolute value of the 16 bit input. An input of
- * -0x8000 results in a return value of 0x7fff.
- *
- * KEYWORDS: absolute value, abs
- *
- *************************************************************************/
- Shortword abs_s(Shortword var1)
- {
- Shortword swOut;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- if (var1 == SW_MIN)
- {
- swOut = SW_MAX;
- giOverflow = 1;
- }
- else
- {
- if (var1 < 0)
- swOut = -var1;
- else
- swOut = var1;
- }
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: add
- *
- * PURPOSE:
- *
- * Perform the addition of the two 16 bit input variable with
- * saturation.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Perform the addition of the two 16 bit input variable with
- * saturation.
- *
- * swOut = var1 + var2
- *
- * swOut is set to 0x7fff if the operation results in an
- * overflow. swOut is set to 0x8000 if the operation results
- * in an underflow.
- *
- * KEYWORDS: add, addition
- *
- *************************************************************************/
- Shortword add(Shortword var1, Shortword var2)
- {
- Longword L_sum;
- Shortword swOut;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_sum = (Longword) var1 + var2;
- swOut = saturate(L_sum);
- return (swOut);
- }
- /****************************************************************************
- *
- * FUNCTION NAME: clearOverflow
- *
- * PURPOSE:
- *
- * Clear the overflow flag
- *
- * INPUTS:
- *
- * none
- *
- *
- * OUTPUTS: global overflow flag is cleared
- * previous value stored in giOldOverflow
- *
- * RETURN VALUE: previous value of overflow
- *
- *
- * KEYWORDS: saturation, limit, overflow
- *
- ***************************************************************************/
- int clearOverflow(void)
- {
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- giOldOverflow = giOverflow;
- giOverflow = 0;
- return (giOldOverflow);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: divide_s
- *
- * PURPOSE:
- *
- * Divide var1 by var2. Note that both must be positive, and
- * var1 >= var2. The output is set to 0 if invalid input is
- * provided.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * In the case where var1==var2 the function returns 0x7fff. The output
- * is undefined for invalid inputs. This implementation returns zero
- * and issues a warning via stdio if invalid input is presented.
- *
- * KEYWORDS: divide
- *
- *************************************************************************/
- Shortword divide_s(Shortword var1, Shortword var2)
- {
- Longword L_div;
- Shortword swOut;
- OP_COUNT(18); /* Complexity Count -- LT 6/96 */
- if (var1 < 0 || var2 < 0 || var1 > var2)
- {
- /* undefined output for invalid input into divide_s */
- return (0);
- }
- if (var1 == var2)
- {
- giOverflow = 1;
- return (0x7fff);
- }
- L_div = ((0x00008000L * (Longword) var1) / (Longword) var2);
- swOut = saturate(L_div);
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: extract_h
- *
- * PURPOSE:
- *
- * Extract the 16 MS bits of a 32 bit Longword. Return the 16 bit
- * number as a Shortword. This is used as a "truncation" of a fractional
- * number.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * KEYWORDS: assign, truncate
- *
- *************************************************************************/
- Shortword extract_h(Longword L_var1)
- {
- Shortword var2;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- var2 = (Shortword) (0x0000ffffL & (L_var1 >> 16));
- return (var2);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: extract_l
- *
- * PURPOSE:
- *
- * Extract the 16 LS bits of a 32 bit Longword. Return the 16 bit
- * number as a Shortword. The upper portion of the input Longword
- * has no impact whatsoever on the output.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- *
- * KEYWORDS: extract, assign
- *
- *************************************************************************/
- Shortword extract_l(Longword L_var1)
- {
- Shortword var2;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- var2 = (Shortword) (0x0000ffffL & L_var1);
- return (var2);
- }
- /****************************************************************************
- *
- * FUNCTION NAME: isOverflow
- *
- * PURPOSE:
- *
- * Check to see whether an overflow/saturation/limiting has occurred
- *
- * INPUTS:
- *
- * none
- *
- *
- * OUTPUTS: none
- *
- * RETURN VALUE: 1 if overflow has been flagged
- * 0 otherwise
- *
- * KEYWORDS: saturation, limit, overflow
- *
- ***************************************************************************/
- int isOverflow(void)
- {
- return (giOverflow);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_abs
- *
- * PURPOSE:
- *
- * Take the absolute value of the 32 bit input. An input of
- * -0x8000 0000 results in a return value of 0x7fff ffff.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- *
- *
- * KEYWORDS: absolute value, abs
- *
- *************************************************************************/
- Longword L_abs(Longword L_var1)
- {
- Longword L_Out;
- OP_COUNT(3); /* Complexity Count -- LT 6/96 */
- if (L_var1 == LW_MIN)
- {
- L_Out = LW_MAX;
- giOverflow = 1;
- }
- else
- {
- if (L_var1 < 0)
- L_Out = -L_var1;
- else
- L_Out = L_var1;
- }
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_add
- *
- * PURPOSE:
- *
- * Perform the addition of the two 32 bit input variables with
- * saturation.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * L_var2
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * IMPLEMENTATION:
- *
- * Perform the addition of the two 32 bit input variables with
- * saturation.
- *
- * L_Out = L_var1 + L_var2
- *
- * L_Out is set to 0x7fff ffff if the operation results in an
- * overflow. L_Out is set to 0x8000 0000 if the operation
- * results in an underflow.
- *
- * KEYWORDS: add, addition
- *
- *************************************************************************/
- Longword L_add(Longword L_var1, Longword L_var2)
- {
- Longword L_Sum;
- double dSum;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- dSum = (double) L_var1 + (double) L_var2;
- L_Sum = L_var1 + L_var2;
- if (dSum != (double) L_Sum)
- {
- /* overflow occurred */
- L_Sum = L_saturate(dSum); OP_COUNT(-4);
- }
- return (L_Sum);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_deposit_h
- *
- * PURPOSE:
- *
- * Put the 16 bit input into the 16 MSB's of the output Longword. The
- * LS 16 bits are zeroed.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff 0000.
- *
- *
- * KEYWORDS: deposit, assign, fractional assign
- *
- *************************************************************************/
- Longword L_deposit_h(Shortword var1)
- {
- Longword L_var2;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_var2 = (Longword) var1 << 16;
- return (L_var2);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_deposit_l
- *
- * PURPOSE:
- *
- * Put the 16 bit input into the 16 LSB's of the output Longword with
- * sign extension i.e. the top 16 bits are set to either 0 or 0xffff.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0xffff 8000 <= L_var1 <= 0x0000 7fff.
- *
- * KEYWORDS: deposit, assign
- *
- *************************************************************************/
- Longword L_deposit_l(Shortword var1)
- {
- Longword L_Out;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_Out = var1;
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_mac
- *
- * PURPOSE:
- *
- * Multiply accumulate. Fractionally multiply two 16 bit
- * numbers together with saturation. Add that result to the
- * 32 bit input with saturation. Return the 32 bit result.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var3
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * IMPLEMENTATION:
- *
- * Fractionally multiply two 16 bit numbers together with
- * saturation. The only numbers which will cause saturation on
- * the multiply are 0x8000 * 0x8000.
- *
- * Add that result to the 32 bit input with saturation.
- * Return the 32 bit result.
- *
- * Please note that this is not a true multiply accumulate as
- * most processors would implement it. The 0x8000*0x8000
- * causes and overflow for this instruction. On most
- * processors this would cause an overflow only if the 32 bit
- * input added to it were positive or zero.
- *
- * KEYWORDS: mac, multiply accumulate
- *
- *************************************************************************/
- Longword L_mac(Longword L_var3, Shortword var1, Shortword var2)
- {
- Longword L_product;
- double dlwA, dlwB;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_product = (Longword) var1 *var2; /* integer multiply */
- if (L_product == (Longword) 0x40000000)
- {
- /* the event 0x8000 * 0x8000, the only possible saturation
- * in the multiply */
- L_product = L_saturate(2147483648.0 + (double) L_var3); OP_COUNT(-4);
- }
- else
- {
- /* no overflow possible in mult */
- L_product = L_product << 1;
- L_product = L_add(L_var3, L_product); OP_COUNT(-2);
- }
- return (L_product);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_msu
- *
- * PURPOSE:
- *
- * Multiply and subtract. Fractionally multiply two 16 bit
- * numbers together with saturation. Subtract that result from
- * the 32 bit input with saturation. Return the 32 bit result.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var3
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * IMPLEMENTATION:
- *
- * Fractionally multiply two 16 bit numbers together with
- * saturation. The only numbers which will cause saturation on
- * the multiply are 0x8000 * 0x8000.
- *
- * Subtract that result from the 32 bit input with saturation.
- * Return the 32 bit result.
- *
- * Please note that this is not a true multiply accumulate as
- * most processors would implement it. The 0x8000*0x8000
- * causes and overflow for this instruction. On most
- * processors this would cause an overflow only if the 32 bit
- * input added to it were negative or zero.
- *
- * KEYWORDS: mac, multiply accumulate, msu
- *
- *************************************************************************/
- Longword L_msu(Longword L_var3, Shortword var1, Shortword var2)
- {
- Longword L_product;
- double dlwA, dlwB;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_product = (Longword) var1 *var2; /* integer multiply */
- if (L_product == (Longword) 0x40000000)
- {
- /* the event 0x8000 * 0x8000, the only possible saturation
- * in the multiply */
- L_product = L_saturate((double) L_var3 - 2147483648.0); OP_COUNT(-4);
- }
- else
- {
- /* no overflow possible in mult */
- L_product <<= 1;
- L_product = L_sub(L_var3, L_product); OP_COUNT(-2); /* LT 6/96 */
- }
- return (L_product);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_mult
- *
- * PURPOSE:
- *
- * Perform a fractional multipy of the two 16 bit input numbers
- * with saturation. Output a 32 bit number.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * IMPLEMENTATION:
- *
- * Multiply the two the two 16 bit input numbers. If the
- * result is within this range, left shift the result by one
- * and output the 32 bit number. The only possible overflow
- * occurs when var1==var2==-0x8000. In this case output
- * 0x7fff ffff.
- *
- * KEYWORDS: multiply, mult, mpy
- *
- *************************************************************************/
- Longword L_mult(Shortword var1, Shortword var2)
- {
- Longword L_product;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- if (var1 == SW_MIN && var2 == SW_MIN)
- {
- L_product = LW_MAX; /* overflow */
- giOverflow = 1;
- }
- else
- {
- L_product = (Longword) var1 *var2; /* integer multiply */
- L_product = L_product << 1;
- }
- return (L_product);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_negate
- *
- * PURPOSE:
- *
- * Negate the 32 bit input. 0x8000 0000's negated value is
- * 0x7fff ffff.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0001 <= L_var1 <= 0x7fff ffff.
- *
- * KEYWORDS: negate, negative
- *
- *************************************************************************/
- Longword L_negate(Longword L_var1)
- {
- Longword L_Out;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- if (L_var1 == LW_MIN)
- {
- L_Out = LW_MAX;
- giOverflow = 1;
- }
- else
- L_Out = -L_var1;
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_shift_r
- *
- * PURPOSE:
- *
- * Shift and round. Perform a shift right. After shifting, use
- * the last bit shifted out of the LSB to round the result up
- * or down.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- *
- * IMPLEMENTATION:
- *
- * Shift and round. Perform a shift right. After shifting, use
- * the last bit shifted out of the LSB to round the result up
- * or down. This is just like shift_r above except that the
- * input/output is 32 bits as opposed to 16.
- *
- * if var2 is positve perform a arithmetic left shift
- * with saturation (see L_shl() above).
- *
- * If var2 is zero simply return L_var1.
- *
- * If var2 is negative perform a arithmetic right shift (L_shr)
- * of L_var1 by (-var2)+1. Add the LS bit of the result to
- * L_var1 shifted right (L_shr) by -var2.
- *
- * Note that there is no constraint on var2, so if var2 is
- * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff.
- * This is the reason the L_shl function is used.
- *
- *
- * KEYWORDS:
- *
- *************************************************************************/
- Longword L_shift_r(Longword L_var1, Shortword var2)
- {
- Longword L_Out, L_rnd;
- OP_COUNT(3); /* Complexity Count -- LT 6/96 */
- if (var2 < -31)
- {
- L_Out = 0;
- }
- else if (var2 < 0)
- {
- /* right shift */
- L_rnd = L_shl(L_var1, var2 + 1) & 0x1; OP_COUNT(-2); /* LT 6/96 */
- L_Out = L_add(L_shl(L_var1, var2), L_rnd); OP_COUNT(-2); /* LT 6/96 */
- }
- else
- {
- L_Out = L_shl(L_var1, var2); OP_COUNT(-2); /* LT 6/96 */
- }
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_shl
- *
- * PURPOSE:
- *
- * Arithmetic shift left (or right).
- * Arithmetically shift the input left by var2. If var2 is
- * negative then an arithmetic shift right (L_shr) of L_var1 by
- * -var2 is performed.
- *
- * INPUTS:
- *
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- *
- * IMPLEMENTATION:
- *
- * Arithmetically shift the 32 bit input left by var2. This
- * operation maintains the sign of the input number. If var2 is
- * negative then an arithmetic shift right (L_shr) of L_var1 by
- * -var2 is performed. See description of L_shr for details.
- *
- * Equivalent to the Full-Rate GSM ">> n" operation. Note that
- * ANSI-C does not guarantee operation of the C ">>" or "<<"
- * operator for negative numbers.
- *
- * KEYWORDS: shift, arithmetic shift left,
- *
- *************************************************************************/
- Longword L_shl(Longword L_var1, Shortword var2)
- {
- Longword L_Mask, L_Out;
- int i, iOverflow = 0;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- if (var2 == 0 || L_var1 == 0)
- {
- L_Out = L_var1;
- }
- else if (var2 < 0)
- {
- if (var2 <= -31)
- {
- if (L_var1 > 0)
- L_Out = 0;
- else
- L_Out = 0xffffffffL;
- }
- else
- {
- L_Out = L_shr(L_var1, -var2);
- OP_COUNT(-2); /* Complexity Count -- LT 6/96 */
- }
- }
- else
- {
- if (var2 >= 31)
- iOverflow = 1;
- else
- {
- if (L_var1 < 0)
- L_Mask = LW_SIGN; /* sign bit mask */
- else
- L_Mask = 0x0;
- L_Out = L_var1;
- for (i = 0; i < var2 && !iOverflow; i++)
- {
- /* check the sign bit */
- L_Out = (L_Out & 0x7fffffffL) << 1;
- if ((L_Mask ^ L_Out) & LW_SIGN)
- iOverflow = 1;
- }
- }
- if (iOverflow)
- {
- /* saturate */
- if (L_var1 > 0)
- L_Out = LW_MAX;
- else
- L_Out = LW_MIN;
- giOverflow = 1;
- }
- }
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_shr
- *
- * PURPOSE:
- *
- * Arithmetic shift right (or left).
- * Arithmetically shift the input right by var2. If var2 is
- * negative then an arithmetic shift left (shl) of var1 by
- * -var2 is performed.
- *
- * INPUTS:
- *
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- *
- * IMPLEMENTATION:
- *
- * Arithmetically shift the input right by var2. This
- * operation maintains the sign of the input number. If var2 is
- * negative then an arithmetic shift left (shl) of L_var1 by
- * -var2 is performed. See description of L_shl for details.
- *
- * The input is a 32 bit number, as is the output.
- *
- * Equivalent to the Full-Rate GSM ">> n" operation. Note that
- * ANSI-C does not guarantee operation of the C ">>" or "<<"
- * operator for negative numbers.
- *
- * KEYWORDS: shift, arithmetic shift right,
- *
- *************************************************************************/
- Longword L_shr(Longword L_var1, Shortword var2)
- {
- Longword L_Mask, L_Out;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- if (var2 == 0 || L_var1 == 0)
- {
- L_Out = L_var1;
- }
- else if (var2 < 0)
- {
- /* perform a left shift */
- /*----------------------*/
- if (var2 <= -31)
- {
- /* saturate */
- if (L_var1 > 0)
- {
- L_Out = LW_MAX;
- giOverflow = 1;
- }
- else
- {
- L_Out = LW_MIN;
- giOverflow = 1;
- }
- }
- else
- {
- L_Out = L_shl(L_var1, -var2);
- OP_COUNT(-2); /* Complexity Count -- LT 6/96 */
- }
- }
- else
- {
- if (var2 >= 31)
- {
- if (L_var1 > 0)
- L_Out = 0;
- else
- L_Out = 0xffffffffL;
- }
- else
- {
- L_Mask = 0;
- if (L_var1 < 0)
- {
- L_Mask = ~L_Mask << (32 - var2);
- }
- L_var1 >>= var2;
- L_Out = L_Mask | L_var1;
- }
- }
- return (L_Out);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: L_sub
- *
- * PURPOSE:
- *
- * Perform the subtraction of the two 32 bit input variables with
- * saturation.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * L_var2
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * L_Out
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * IMPLEMENTATION:
- *
- * Perform the subtraction of the two 32 bit input variables with
- * saturation.
- *
- * L_Out = L_var1 - L_var2
- *
- * L_Out is set to 0x7fff ffff if the operation results in an
- * overflow. L_Out is set to 0x8000 0000 if the operation
- * results in an underflow.
- *
- * KEYWORDS: sub, subtraction
- *
- *************************************************************************/
- Longword L_sub(Longword L_var1, Longword L_var2)
- {
- Longword L_Sum;
- double dSum;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- dSum = (double) L_var1 - (double) L_var2;
- L_Sum = L_var1 - L_var2;
- if (dSum != L_Sum)
- {
- /* overflow occurred */
- L_Sum = L_saturate(dSum);
- OP_COUNT(-4); /* Complexity Count -- LT 6/96 */
- }
- return (L_Sum);
- }
- /***************************************************************************
- *
- * FUNCTION NAME:mac_r
- *
- * PURPOSE:
- *
- * Multiply accumulate and round. Fractionally multiply two 16
- * bit numbers together with saturation. Add that result to
- * the 32 bit input with saturation. Finally round the result
- * into a 16 bit number.
- *
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var3
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Fractionally multiply two 16 bit numbers together with
- * saturation. The only numbers which will cause saturation on
- * the multiply are 0x8000 * 0x8000.
- *
- * Add that result to the 32 bit input with saturation.
- * Round the 32 bit result by adding 0x0000 8000 to the input.
- * The result may overflow due to the add. If so, the result
- * is saturated. The 32 bit rounded number is then shifted
- * down 16 bits and returned as a Shortword.
- *
- * Please note that this is not a true multiply accumulate as
- * most processors would implement it. The 0x8000*0x8000
- * causes and overflow for this instruction. On most
- * processors this would cause an overflow only if the 32 bit
- * input added to it were positive or zero.
- *
- * KEYWORDS: mac, multiply accumulate, macr
- *
- *************************************************************************/
- Shortword mac_r(Longword L_var3, Shortword var1, Shortword var2)
- {
- return (round32(L_mac(L_var3, var1, var2)));
- }
- /***************************************************************************
- *
- * FUNCTION NAME: msu_r
- *
- * PURPOSE:
- *
- * Multiply subtract and round. Fractionally multiply two 16
- * bit numbers together with saturation. Subtract that result from
- * the 32 bit input with saturation. Finally round the result
- * into a 16 bit number.
- *
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- * L_var3
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var2 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Fractionally multiply two 16 bit numbers together with
- * saturation. The only numbers which will cause saturation on
- * the multiply are 0x8000 * 0x8000.
- *
- * Subtract that result from the 32 bit input with saturation.
- * Round the 32 bit result by adding 0x0000 8000 to the input.
- * The result may overflow due to the add. If so, the result
- * is saturated. The 32 bit rounded number is then shifted
- * down 16 bits and returned as a Shortword.
- *
- * Please note that this is not a true multiply accumulate as
- * most processors would implement it. The 0x8000*0x8000
- * causes and overflow for this instruction. On most
- * processors this would cause an overflow only if the 32 bit
- * input added to it were positive or zero.
- *
- * KEYWORDS: mac, multiply accumulate, macr
- *
- *************************************************************************/
- Shortword msu_r(Longword L_var3, Shortword var1, Shortword var2)
- {
- return (round32(L_msu(L_var3, var1, var2)));
- }
- /***************************************************************************
- *
- * FUNCTION NAME: mult
- *
- * PURPOSE:
- *
- * Perform a fractional multipy of the two 16 bit input numbers
- * with saturation and truncation.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Perform a fractional multipy of the two 16 bit input
- * numbers. If var1 == var2 == -0x8000, output 0x7fff.
- * Otherwise output var1*var2 >> 15. The output is a
- * 16 bit number.
- *
- * KEYWORDS: mult, mulitply, mpy
- *
- *************************************************************************/
- Shortword mult(Shortword var1, Shortword var2)
- {
- Longword L_product;
- Shortword swOut;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- L_product = L_mult(var1, var2); OP_COUNT(-1);
- swOut = extract_h(L_product); OP_COUNT(-1);
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: mult_r
- *
- * PURPOSE:
- *
- * Perform a fractional multipy and round of the two 16 bit
- * input numbers with saturation.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * This routine is defined as the concatenation of the multiply
- * operation and the round operation.
- *
- * The fractional multiply (L_mult) produces a saturated 32 bit
- * output. This is followed by a an add of 0x0000 8000 to the
- * 32 bit result. The result may overflow due to the add. If
- * so, the result is saturated. The 32 bit rounded number is
- * then shifted down 16 bits and returned as a Shortword.
- *
- *
- * KEYWORDS: multiply and round, round, mult_r, mpyr
- *
- *************************************************************************/
- Shortword mult_r(Shortword var1, Shortword var2)
- {
- Shortword swOut;
- OP_COUNT(2); /* Complexity Count -- LT 6/96 */
- swOut = round32(L_mult(var1, var2));
- OP_COUNT(-2); /* Complexity Count -- LT 6/96 */
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: negate
- *
- * PURPOSE:
- *
- * Negate the 16 bit input. 0x8000's negated value is 0x7fff.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8001 <= swOut <= 0x0000 7fff.
- *
- * KEYWORDS: negate, negative, invert
- *
- *************************************************************************/
- Shortword negate(Shortword var1)
- {
- Shortword swOut;
- OP_COUNT(1); /* Complexity Count -- LT 6/96 */
- if (var1 == SW_MIN)
- {
- swOut = SW_MAX;
- giOverflow = 1;
- }
- else
- swOut = -var1;
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: norm_l
- *
- * PURPOSE:
- *
- * Get normalize shift count:
- *
- * A 32 bit number is input (possiblly unnormalized). Output
- * the positive (or zero) shift count required to normalize the
- * input.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0 <= swOut <= 31
- *
- *
- *
- * IMPLEMENTATION:
- *
- * Get normalize shift count:
- *
- * A 32 bit number is input (possiblly unnormalized). Output
- * the positive (or zero) shift count required to normalize the
- * input.
- *
- * If zero in input, return 0 as the shift count.
- *
- * For non-zero numbers, count the number of left shift
- * required to get the number to fall into the range:
- *
- * 0x4000 0000 >= normlzd number >= 0x7fff ffff (positive number)
- * or
- * 0x8000 0000 <= normlzd number < 0xc000 0000 (negative number)
- *
- * Return the number of shifts.
- *
- * This instruction corresponds exactly to the Full-Rate "norm"
- * instruction.
- *
- * KEYWORDS: norm, normalization
- *
- *************************************************************************/
- Shortword norm_l(Longword L_var1)
- {
- Shortword swShiftCnt;
- // wprintf("sizeof(Longword) = %u sizeof(Shortword) = %u\n",sizeof(Longword),sizeof(Shortword));
- // wprintf("LW_MIN=%d(%x)\n",LW_MIN,LW_MIN);
- // wprintf("0xc0000000 = %d\n",0xc0000000);
- // wprintf("L_var1=%d(%x)\n",L_var1,L_var1);
- // wprintf("L_var1 < (Longword) 0xc0000000L = %s\n",( L_var1 < (Longword) 0xc0000000L ? "true" : "false"));
- // wprintf("L_var1 >= LW_MIN = %s\n",( L_var1 >= LW_MIN ? "true" : "false"));
- OP_COUNT(30); /* Complexity Count -- LT 6/96 */
- if (L_var1 != 0)
- {
- if (!(L_var1 & LW_SIGN))
- {
- /* positive input */
- for (swShiftCnt = 0; !(L_var1 <= LW_MAX && L_var1 >= 0x40000000);
- swShiftCnt++)
- {
- L_var1 = L_var1 << 1;
- }
- }
- else
- {
- /* negative input */
- for (swShiftCnt = 0;
- !(L_var1 >= LW_MIN && L_var1 < (Longword) 0xc0000000);
- swShiftCnt++)
- {
- L_var1 = L_var1 << 1;
- }
- }
- }
- else
- {
- swShiftCnt = 0;
- }
- // wprintf("norm_l end\n");
- return (swShiftCnt);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: norm_s
- *
- * PURPOSE:
- *
- * Get normalize shift count:
- *
- * A 16 bit number is input (possiblly unnormalized). Output
- * the positive (or zero) shift count required to normalize the
- * input.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0 <= swOut <= 15
- *
- *
- *
- * IMPLEMENTATION:
- *
- * Get normalize shift count:
- *
- * A 16 bit number is input (possiblly unnormalized). Output
- * the positive (or zero) shift count required to normalize the
- * input.
- *
- * If zero in input, return 0 as the shift count.
- *
- * For non-zero numbers, count the number of left shift
- * required to get the number to fall into the range:
- *
- * 0x4000 >= normlzd number >= 0x7fff (positive number)
- * or
- * 0x8000 <= normlzd number < 0xc000 (negative number)
- *
- * Return the number of shifts.
- *
- * This instruction corresponds exactly to the Full-Rate "norm"
- * instruction.
- *
- * KEYWORDS: norm, normalization
- *
- *************************************************************************/
- Shortword norm_s(Shortword var1)
- {
- short swShiftCnt;
- Longword L_var1;
- OP_COUNT(15); /* Complexity Count -- LT 6/96 */
- L_var1 = L_deposit_h(var1); OP_COUNT(-1);
- swShiftCnt = norm_l(L_var1); OP_COUNT(-30);
- return (swShiftCnt);
- }
- /****************************************************************************
- *
- * FUNCTION NAME: popOverflow
- *
- * PURPOSE:
- *
- * Pull the old overflow state from the "stack". Replace the current
- * overflow status with its predecessor.
- *
- * INPUTS:
- *
- * none
- *
- *
- * OUTPUTS: none
- *
- * RETURN VALUE: value of datum about the be lost (usually the
- * temporary saturation state)
- *
- * KEYWORDS: saturation, limit, overflow
- *
- ***************************************************************************/
- int popOverflow(void)
- {
- int i;
- i = giOverflow;
- giOverflow = giOldOverflow;
- return (i);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: round
- *
- * PURPOSE:
- *
- * Round the 32 bit Longword into a 16 bit shortword with saturation.
- *
- * INPUTS:
- *
- * L_var1
- * 32 bit long signed integer (Longword) whose value
- * falls in the range
- * 0x8000 0000 <= L_var1 <= 0x7fff ffff.
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Perform a two's complement round on the input Longword with
- * saturation.
- *
- * This is equivalent to adding 0x0000 8000 to the input. The
- * result may overflow due to the add. If so, the result is
- * saturated. The 32 bit rounded number is then shifted down
- * 16 bits and returned as a Shortword.
- *
- *
- * KEYWORDS: round
- *
- *************************************************************************/
- Shortword round32(Longword L_var1)
- {
- Longword L_Prod;
- OP_COUNT(1);
- L_Prod = L_add(L_var1, 0x00008000L); /* round MSP */
- OP_COUNT(-3);
- return (extract_h(L_Prod));
- }
- /****************************************************************************
- *
- * FUNCTION NAME: set overflow
- *
- * PURPOSE:
- *
- * Clear the overflow flag
- *
- * INPUTS:
- *
- * none
- *
- *
- * OUTPUTS: global overflow flag is cleared
- * previous value stored in giOldOverflow
- *
- * RETURN VALUE: previous value of overflow
- *
- *
- * KEYWORDS: saturation, limit, overflow
- *
- ***************************************************************************/
- int setOverflow(void)
- {
- giOldOverflow = giOverflow;
- giOverflow = 1;
- return (giOldOverflow);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: shift_r
- *
- * PURPOSE:
- *
- * Shift and round. Perform a shift right. After shifting, use
- * the last bit shifted out of the LSB to round the result up
- * or down.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- *
- * IMPLEMENTATION:
- *
- * Shift and round. Perform a shift right. After shifting, use
- * the last bit shifted out of the LSB to round the result up
- * or down.
- *
- * If var2 is positive perform a arithmetic left shift
- * with saturation (see shl() above).
- *
- * If var2 is zero simply return var1.
- *
- * If var2 is negative perform a arithmetic right shift (shr)
- * of var1 by (-var2)+1. Add the LS bit of the result to var1
- * shifted right (shr) by -var2.
- *
- * Note that there is no constraint on var2, so if var2 is
- * -0xffff 8000 then -var2 is 0x0000 8000, not 0x0000 7fff.
- * This is the reason the shl function is used.
- *
- *
- * KEYWORDS:
- *
- *************************************************************************/
- Shortword shift_r(Shortword var1, Shortword var2)
- {
- Shortword swOut, swRnd;
- OP_COUNT(2);
- if (var2 >= 0)
- {
- swOut = shl(var1, var2); OP_COUNT(-1);
- }
- else
- {
- /* right shift */
- if (var2 < -15)
- {
- swOut = 0;
- }
- else
- {
- swRnd = shl(var1, var2 + 1) & 0x1; OP_COUNT(-1);
- swOut = add(shl(var1, var2), swRnd); OP_COUNT(-2);
- }
- }
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: shl
- *
- * PURPOSE:
- *
- * Arithmetically shift the input left by var2.
- *
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * If Arithmetically shift the input left by var2. If var2 is
- * negative then an arithmetic shift right (shr) of var1 by
- * -var2 is performed. See description of shr for details.
- * When an arithmetic shift left is performed the var2 LS bits
- * are zero filled.
- *
- * The only exception is if the left shift causes an overflow
- * or underflow. In this case the LS bits are not modified.
- * The number returned is 0x8000 in the case of an underflow or
- * 0x7fff in the case of an overflow.
- *
- * The shl is equivalent to the Full-Rate GSM "<< n" operation.
- * Note that ANSI-C does not guarantee operation of the C ">>"
- * or "<<" operator for negative numbers - it is not specified
- * whether this shift is an arithmetic or logical shift.
- *
- * KEYWORDS: asl, arithmetic shift left, shift
- *
- *************************************************************************/
- Shortword shl(Shortword var1, Shortword var2)
- {
- Shortword swOut;
- Longword L_Out;
- OP_COUNT(1);
- if (var2 == 0 || var1 == 0)
- {
- swOut = var1;
- }
- else if (var2 < 0)
- {
- /* perform a right shift */
- /*-----------------------*/
- if (var2 <= -15)
- {
- if (var1 < 0)
- swOut = (Shortword) 0xffff;
- else
- swOut = 0x0;
- }
- else
- {
- swOut = shr(var1, -var2); OP_COUNT(-1);
- }
- }
- else
- {
- /* var2 > 0 */
- if (var2 >= 15)
- {
- /* saturate */
- if (var1 > 0)
- swOut = SW_MAX;
- else
- swOut = SW_MIN;
- giOverflow = 1;
- }
- else
- {
- L_Out = (Longword) var1 *(1 << var2);
- swOut = (Shortword) L_Out; /* copy low portion to swOut, overflow
- * could have hpnd */
- if (swOut != L_Out)
- {
- /* overflow */
- if (var1 > 0)
- swOut = SW_MAX; /* saturate */
- else
- swOut = SW_MIN; /* saturate */
- giOverflow = 1;
- }
- }
- }
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: shr
- *
- * PURPOSE:
- *
- * Arithmetic shift right (or left).
- * Arithmetically shift the input right by var2. If var2 is
- * negative then an arithmetic shift left (shl) of var1 by
- * -var2 is performed.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Arithmetically shift the input right by var2. This
- * operation maintains the sign of the input number. If var2 is
- * negative then an arithmetic shift left (shl) of var1 by
- * -var2 is performed. See description of shl for details.
- *
- * Equivalent to the Full-Rate GSM ">> n" operation. Note that
- * ANSI-C does not guarantee operation of the C ">>" or "<<"
- * operator for negative numbers.
- *
- * KEYWORDS: shift, arithmetic shift right,
- *
- *************************************************************************/
- Shortword shr(Shortword var1, Shortword var2)
- {
- Shortword swMask, swOut;
- OP_COUNT(1);
- if (var2 == 0 || var1 == 0)
- swOut = var1;
- else if (var2 < 0)
- {
- /* perform an arithmetic left shift */
- /*----------------------------------*/
- if (var2 <= -15)
- {
- /* saturate */
- if (var1 > 0)
- swOut = SW_MAX;
- else
- swOut = SW_MIN;
- giOverflow = 1;
- }
- else
- {
- swOut = shl(var1, -var2); OP_COUNT(-1);
- }
- }
- else
- {
- /* positive shift count */
- /*----------------------*/
- if (var2 >= 15)
- {
- if (var1 < 0)
- swOut = (Shortword) 0xffff;
- else
- swOut = 0x0;
- }
- else
- {
- /* take care of sign extension */
- /*-----------------------------*/
- swMask = 0;
- if (var1 < 0)
- {
- swMask = ~swMask << (16 - var2);
- }
- var1 >>= var2;
- swOut = swMask | var1;
- }
- }
- return (swOut);
- }
- /***************************************************************************
- *
- * FUNCTION NAME: sub
- *
- * PURPOSE:
- *
- * Perform the subtraction of the two 16 bit input variable with
- * saturation.
- *
- * INPUTS:
- *
- * var1
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
- * var2
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
- *
- * OUTPUTS:
- *
- * none
- *
- * RETURN VALUE:
- *
- * swOut
- * 16 bit short signed integer (Shortword) whose value
- * falls in the range
- * 0xffff 8000 <= swOut <= 0x0000 7fff.
- *
- * IMPLEMENTATION:
- *
- * Perform the subtraction of the two 16 bit input variable with
- * saturation.
- *
- * swOut = var1 - var2
- *
- * swOut is set to 0x7fff if the operation results in an
- * overflow. swOut is set to 0x8000 if the operation results
- * in an underflow.
- *
- * KEYWORDS: sub, subtraction
- *
- *************************************************************************/
- Shortword sub(Shortword var1, Shortword var2)
- {
- Longword L_diff;
- Shortword swOut;
- OP_COUNT(1);
- L_diff = (Longword) var1 - var2;
- swOut = saturate(L_diff);
- return (swOut);
- }
|