# M

Author:

AN575
where f is the fraction or mantissa, e is the exponent or characteristic, n is the number of bits in f and a(k) is the bit value where, k = 0 ,.., n - 1 number with a(0) = MSb, and s is the sign bit. The fraction was in normalized sign-magnitude representation with implicit MSb equal to one, and e was stored in biased form, where the bias was the magnitude of the most negative possible exponent[1,2], leading to a biased exponent eb in the form

IEEE 754 Compliant Floating Point Routines

Frank J. Testa FJT Consulting

INTRODUCTION
This application note presents an implementation of the following ﬂoating point math routines for the PICmicro™ microcontroller families: • • • • • • ﬂoat to integer conversion integer to ﬂoat conversion normalize add/subtract multiply divide

eb = e + 2

m Ð 1,

where m is the number of bits in the exponent. The fraction f then satisﬁes the inequality

ú 0.5 ≤ f < 1.
Finalization of the IEEE 754 standard[4] deviated from these conventions on several points. First, the radix point was located to the right of the MSb, yielding the representation

Routines for the PIC16/17 families are provided in a modiﬁed IEEE 754 32-bit format together with versions in 24-bit reduced format. A Glossary of terms is located on page 8.

FLOATING POINT ARITHMETIC
Although ﬁxed point arithmetic can usually be employed in many numerical problems through the use of proper scaling techniques, this approach can become complicated and sometimes result in less efﬁcient code than is possible using ﬂoating point methods[1]. Floating point arithmetic is essentially equivalent to arithmetic in scientiﬁc notation relative to a particular base or radix. The base used in an implementation of ﬂoating point arithmetic is distinct from the base associated with a particular computing system. For example, the IBM System/360 is a binary computer with a hexadecimal or base-16 ﬂoating point representation, whereas the VAX together with most contemporary microcomputers are binary machines with base-2 ﬂoating point implementations. Before the establishment of the IEEE 754 ﬂoating point standard, base-2 ﬂoating point numbers were typically represented in the form

A = ( Ð1 ) f

s

⋅ 2e,

nÐ1

f =

k=0

a k) (

⋅ 2Ð k,

. with f satisfying the bounds given by 1 ≤ f < 2 . In order to accommodate a slot in the biased exponent format for representations of inﬁnity to implement exact inﬁnity arithmetic, the bias was reduced by one, yielding the biased exponent eb given by

eb = e + 2 m Ð 1 Ð 1 .
In the case of single precision with m = 8, this results in a bias of 127. The use of biased exponents permits comparison of exponents through a simple unsigned comparator, and further results in a unique representation of zero given by f = eb = 0. Since our ﬂoating point implementation will not include exact inﬁnity arithmetic

A = ( Ð1 ) f
nÐ1

s

⋅ 2e, ⋅ 2 Ð( k + 1 ) ,

f=

k=0

a k) (

DS00575B-page 1

AN575
at this time, we use the IEEE 754 bias but allow the representation of the exponent to extend into this ﬁnal slot, resulting in the range of exponents

ROUNDING METHODS
Truncation of a binary representation to n-bits is severely biased since it always leads to a number whose absolute value is less than or equal to that of the exact value, thereby possibly causing signiﬁcant error buildup during a long sequence of calculations. Simple adder-based rounding by adding the MSb to the LSb is unbiased except when the value to be rounded is equidistant from the two nearest n-bit values[1]. This small but still undesirable bias can be removed by stipulating that in the equidistant case, the n-bit value with LSb = 0 is selected, commonly referred to as the rounding to the nearest method, the default mode in the IEEE 754 standard[4,5]. The number of guard bits or extra bits of precision, is related to the sensitivity of the rounding method. Since the introduction of the hardware multiply on the PIC17[6], improvements in the ﬂoating point multiply and divide routines have provided an extra byte for guard bits, thereby offering a more sensitive rounding to the nearest method given by: n bit value guard bits A A A < 0x80 = 0x80 > 0x80 result round to A if A,LSb = 0, round to A if A,LSb = 1, round to A+1 round to A+1

Ð 126 ≤ e ≤ 128.
Algorithms for radix conversion are discussed in Appendix A, and can be used to produce the binary ﬂoating point representation of a given decimal number. Examples of sign-magnitude ﬂoating point representations of some decimal numbers are as follows: Decimal 1.0 0.15625 0.1 1.23x10**3

e
0 -3 -4 10

f
1.0000000 1.0100000 1.10011001100.... 1.0011001110

It is important to note that the only numbers that can be represented exactly in binary arithmetic are those which are sums of powers of two, resulting in nonterminating binary representations of some simple decimal numbers such as 0.1 as shown above, and leading to truncation errors regardless of the value of n. Floating point calculations, even involving numbers admitting an exact binary representation, usually lose information after truncation to an n-bit result, and therefore require some rounding scheme to minimize such roundoff errors[1].

In the equidistant case, this procedure always selects the machine number with even parity, namely, LSb = 0. However, the PIC16 implementation still uses the less sensitive single guard bit method, following the nearest neighbor rounding procedure: n bit value A A A+1 guard bit 0 1 0 result round to A if A,LSb = 0, round to A if A,LSb = 1, round to A+1 round to A+1

Currently, as a compromise between performance and rounding accuracy, a sticky bit is not used in this implementation. The lack of information regarding bits shifted out beyond the guard bits is more noticeable in the PIC16CXXX case where only one guard bit is saved. Another interesting rounding method, is von Neumann rounding or jamming, where the exact number is truncated to n-bits and then set LSb = 1. Although the errors can be twice as large as in round to the nearest, it is unbiased and requires little more effort than truncation[1].

DS00575B-page 2

AN575
FLOATING POINT FORMATS
In what follows, we use the following ﬂoating point formats:

eb
IEEE754 32-bit MIcrochip 32-bit Microchip 24-bit

f0 y ⋅ xxx xxxx s ⋅ xxx xxxx s ⋅ xxx xxxx

f1
xxxx xxxx xxxx xxxx xxxx xxxx

f2
xxxx xxxx xxxx xxxx

sxxx xxxx
xxxx xxxx xxxx xxxx

Legend: s is the Sign bit, y = LSb of eb register, ⋅ = radix point where eb is the biased 8-bit exponent, with bias = 127, s is the sign bit, and bytes f0, f1 and f2 constitute the fraction with f0 the most signiﬁcant byte with implicit MSb = 1. It is important to note that the IEEE 754 standard format[4] places the sign bit as the MSb of eb with the LSb of the exponent as the MSb of f0. Because of the inherent byte structure of the PIC16/17 families of microcontrollers, more efﬁcient code was possible by adopting the above formats rather than strictly adhering to the IEEE standard. The difference between the formats consists of a rotation of the top nine bits of the representation, with a left rotate for IEEE to PIC16/17 and a right rotate for PIC16/17 to IEEE. This can be realized through the following PIC16/17 code. IEEE_to_PIC16/17 RLCF RLCF RRCF AARGB0,F AEXP,F AARGB0,F PIC16/17_to_IEEE RLCF RRCF RRCF AARGB0,F AEXP,F AARGB0,F

Conversion to the 24-bit format is obtained by the rounding to the nearest from the IEEE 754 representation. The limiting absolute values of the above ﬂoating point formats are given as follows: |A|

eb
MAX MIN 0xFF 0x01

e
128 -126

f
7FFFFF 000000

decimal 6.80564693E+38 1.17549435E-38

where the MSb is implicitly equal to one, and its bit location is occupied by the sign bit. The bounds for the 24-bit format are obtained by simply truncating f to 16-bits and recomputing their decimal equivalents.

DS00575B-page 3

AN575
EXAMPLE 1: MICROCHIP FLOAT FORMAT TO DECIMAL
To illustrate the interpretation of the previous ﬂoating point representation, consider the following simple example consisting of a 32-bit value rounded to the nearest representation of the number

A = 16π = 50.2654824574 ≈ A = 0x84490FDB ,
implying a biased exponent eb = 0x84, and the fraction or mantissa f = 0x490FDB. To obtain the base 2 exponent e, we subtract the bias 0x7F, yielding

e = eb Ð bias = 0x84 Ð 0x7F = 0x05.
The fraction, with its MSb made explicit, has the binary representation

C

9

0

F

D

B

f = 1.100 1001 0000 1111 1101 1011
The decimal equivalent of f can then be computed by adding the respective powers of two corresponding to nonzero bits,

f = 20 + 2-1 + 2-4 + 2-7 + 2-12 + 2-13 + 2-14 + 2-15 + 2-16 + 2-17 + 2-19 + 2-20 + 2-22 + 2-23 = 1.5707963705,
evaluated in full precision on an HP48 calculator. The decimal equivalent of the representation of A can now be obtained by multiplying by the power of two deﬁned by the exponent e.

A = 2e ⋅ f = 32 ⋅ 1.5707963705 = 50.265483856 .
24-bit Format It is important to note that the difference between this evaluation of A and the number A is a result of the truncation error induced by obtaining only the nearest machine representable number and not an exact representation. Alternatively, if we use the 24-bit reduced format, the result rounded to the nearest representation of A is given by

A = 16π = 50.2654824574 ≈ A = 0x844910 ,

f = 20 + 2-1 + 2-4 + 2-7 + 2-11 = 1.57080078125
and the decimal equivalent of A

A = 2e ⋅ f = 32 ⋅ 1.57080078125 = 50.265625
with a correspondingly larger truncation error as expected. It is coincidence that both of these representations overestimate A in that an increment of the LSb occurs during nearest neighbor rounding in each case. To produce the correct representation of a particular decimal number, a debugger could be used to display the internal binary representation on a host computer and make the appropriate conversion to the above format. If this approach is not feasible, algorithms for producing this representation are provided in Appendix A.

DS00575B-page 4

AN575
EXAMPLE 2: DECIMAL TO MICROCHIP FLOAT FORMAT
Decimal to Binary Example:

A = 0.15625 (Decimal Number)
(see algorithm A.3)

Find Exponent:

z 2 = 0.15625 ln ( 0.15625 ) z = ----------------------------- = Ð 2.6780719 ln ( 2 ) e = int ( z ) = Ð 3

Find fractional part:

0.15625 x = ------------------ = 1.25 Ð3 2

(x will always be > 1 )

k = 0 k = 1 k = 2

1.25 ≥ 2 0.25 ≥ 2 0.25 ≥ 2

0 Ð1 Ð2

?, yes ?, no ?, yes

a(0) = 1 a(1) = 0 a(2) = 1

; ; ;

x = 1.25 Ð 1 = 0.25 x = 0.25 x = 0

Therefore, f = 1.25 decimal = 1.010 0000 0000 s e A = ( Ð1 ) f ⋅ 2 ; where f = x, 0000 0000 0000 binary 0.15625 = 1.25 ⋅ 2 Ð3

s = 0 (sign bit)

Now, convert 0.15625 to Microchip Float Format eb = Biased Exponent eb = e + 7Fh eb = -3 + 7Fh eb = 7Ch Microchip Float Format: Exp 0.15625 = 7C f0 20 f1 00 f2 00

Remember the MSb, a(0) = 1 is implied in the ﬂoat number above.

DS00575B-page 5

AN575
FLOATING POINT EXCEPTIONS
Although the dynamic range of mathematical calculations is increased through ﬂoating point arithmetic, overﬂow and underﬂow are both possible when the limiting values of the representation are exceeded, such as in multiplication requiring the addition of exponents, or in division with the difference of exponents[2]. In these operations, fraction calculations followed by appropriate normalizing and exponent modiﬁcation can also lead to overﬂow or underﬂow in special cases. Similarly, addition and subtraction after fraction alignment, followed by normalization can also lead to such exceptions.

USAGE
For the unary operations, input argument and result are in AARG. The binary operations require input arguments in AARG and BARG, and produces the result in AARG, thereby simplifying sequencing of operations.

EXCEPTION HANDLING
All routines return WREG = 0x00 upon successful completion and WREG = 0xFF, together with the appropriate FPFLAGS ﬂag bit is set to 1 upon exception. If SAT = 0, saturation is disabled and spurious results are obtained in AARG upon an exception. If SAT = 1, saturation is enabled, and all overﬂow or underﬂow exceptions produce saturated results in AARG.

DATA RAM REQUIREMENTS
The following contiguous data RAM locations are used by the library:
AARGB7 AARGB6 AARGB5 AARGB4 AARGB3 AARGB2 AARGB1 AARGB0 AEXP SIGN FPFLAGS = = = = = = = = = ACCB7 ACCB6 ACCB5 ACCB4 ACCB3 ACCB2 ACCB1 ACCB0 EXP = = = = REMB3 REMB2 REMB1 REMB0 LSB to MSB

ROUNDING
With RND = 0, rounding is disabled, and simple truncation is used, resulting in some speed enhancement. If RND = 1, rounding is enabled, and rounding to the nearest LSb results.

remainder

INTEGER TO FLOAT CONVERSION
= ACC AARG and ACC fract AARG and ACC expon sign in MSb exception flags, option bits LSB to MSB

The routine FLOxxyy converts the two's complement xx-bit integer in AARG to the above yy-bit ﬂoating point representation, producing the result in AEXP, AARG. The routine initializes the exponent to move the radix point to the right of the MSb and then calls the normalize routine. An example is given by FLO1624(12106) = FLO1624(0x2F4A) = 0x8C3D28 = 12106.0

BARGB3 BARGB2 BARGB1 BARGB0 BEXP TEMPB3 TEMPB2 TEMPB1 TEMPB0 = TEMP

BARG fraction BARG exponent

NORMALIZE
The routine NRMxxyy takes an unnormalized xx-bit ﬂoating point number in AEXP, AARG and left shifts the fraction and adjusts the exponent until the result has an implicit MSb = 1, producing a yy-bit result in AEXP, AARG. This routine is called by FLOxxyy, FPAyy and FPSyy, and is usually not needed explicitly by the user since all operations producing a ﬂoating point result are implicitly normalized.

temporary storage

The exception ﬂags and option bits in FPFLAGS are deﬁned as follows:
PFFLAGS SAT RND DOM NAN FDZ FUN FOV IOV 7 SAT RND DOM NAN FDZ FUN FOV IOV 6 5 4 3 2 1 0

FLOAT TO INTEGER CONVERSION
The routine INTxxyy converts the normalized xx-bit ﬂoating point number in AEXP, AARG, to a two's complement yy-bit integer in AARG. After removing the bias from AEXP and precluding a result of zero or integer overﬂow, the fraction in AARG is left shifted by AEXP and converted to two's complement representation. As an example, consider: INT2416(123.45) = INT2416(0x8576E6) = 0x7B = 123

SATurate enable bit RouNDing enable bit DOMain error exception flag Not-A-Number exception flag Floating point Divide by Zero Floating point Underflow Flag Floating point Overflow Flag Integer Overflow Flag

DS00575B-page 6

AN575
The ﬂoating point add routine FPAxx, takes the arguments in AEXP, AARG and BEXP, BARG and returns the sum in AEXP, AARG. If necessary, the arguments are swapped to ensure that AEXP >= BEXP, and then BARG is then aligned by right shifting by AEXP - BEXP. The fractions are then added and the result is normalized by calling NRMxx. The subtract routine FPSxx simply toggles the sign bit in BARG and calls FPAxx. Several examples are as follows: FPA24(-0.32212E+5, 0.1120E+4) = FPA24(0x8DFBA8, 0x890C00) = 0x8DF2E8 = -0.31092E+5 FPS24(0.89010E+4, -0.71208E5) = FPS24(0x8C0B14, 0x8F8B14) = 0x8F1C76 = 0.80109E+5

DIVISION
The ﬂoating point divide routine FPDxx, takes the numerator in AEXP, AARG and denominator in BEXP, BARG and returns the quotient in AEXP, AARG. The PIC17 implementation uses the hardware multiply in an iterative method known as multiplicative division[6], achieving performance not possible by standard restoring or non-restoring algorithms. After a divide by zero test, an initial seed for the iteration is obtained by a table lookup, followed by a sequence of multiplicative factors for both numberator and denominator such that the denominators approach one. By a careful choice of the seed method, the quadratic convergence of the algorithm guarantees the 0.5ulp (unit in the last position) accuracy requirement in one iteration[6]. For the PIC16 family, after testing for a zero denominator, the sign and exponent of the result are computed together with testing for dividend alignment. If the argument fractions satisfy the inequality AARG >= BARG, the dividend AARG is right shifted by one bit and the exponent is adjusted, thereby resulting in AARG < BARG and the dividend is aligned. Alignment permits a valid division sequence and eliminates the need for postnormalization. After testing for overﬂow or underﬂow as appropriate, the fractions are then divided using a standard shift-subtract restoring method. A simple example is given by: FPD24(-0.16106E+5, 0.24715E+5) = FPD24(0x8CFBA8, 0x8D4116) = 0x7EA6D3 = -0.65167E+0

MULTIPLICATION
The ﬂoating point multiply routine FPMxx, takes the arguments in AEXP, AARG and BEXP, BARG and returns the product in AEXP, AARG. After testing for a zero argument, the sign and exponent of the result are computed together with testing for overﬂow. On the PIC17, the fractions are multiplied using the hardware multiply[6], while a standard add-shift method is used on the PIC16, in each case followed by postnormalization if necessary. For example, consider: FPM32(-8.246268E+6, 6.327233E+6) = FPM32(0x95FBA7F8, 95411782) = 0xACBDD0BD = -5.217606E+13

DS00575B-page 7

AN575
GLOSSARY
BIASED EXPONENTS - nonnegative representation of exponents produced by adding a bias to a two's complement exponent, permitting unsigned exponent comparison together with a unique representation of zero. FLOATING POINT UNDERFLOW - occurs when the real number to be represented is smaller in absolute value than the smallest ﬂoating point number. FLOATING POINT OVERFLOW - occurs when the real number to be represented is larger in absolute value than the largest ﬂoating point number. GUARD BITS - additional bits of precision carried in a calculation for improved rounding sensitivity. LSb - least signiﬁcant bit MSb - most signiﬁcant bit NEAREST NEIGHBOR ROUNDING - an unbiased rounding method where a number to be rounded is rounded to its nearest neighbor in the representation, with the stipulation that if equidistant from its nearest neighbors, the neighbor with LSb equal to zero is selected. NORMALIZATION - the process of left shifting the fraction of an unnormalized ﬂoating point number until the MSb equals one, while decreasing the exponent by the number of left shifts. NSb - next signiﬁcant bit just to the right of the LSb. ONE'S COMPLEMENT - a special case of the diminished radix complement for radix two systems where the value of each bit is reversed. Although sometimes used in representing positive and negative numbers, it produces two representations of the number zero. RADIX - the base of a given number system. RADIX POINT - separates the integer and fractional parts of a number. SATURATION - mode of operation where ﬂoating point numbers are ﬁxed at there limiting values when an underﬂow or overﬂow is detected. SIGN MAGNITUDE - representation of positive and negative binary numbers where the absolute value is expressed together with the appropriate value of the sign bit. STICKY BIT - a bit set only if information is lost through shifting beyond the guard bits. TRUNCATION - discarding any bits to the right of a given bit location. TWO'S COMPLEMENT - a special case of radix complement for radix two systems where the value of each bit is reversed and the result is incremented by one. Producing a unique representation of zero, and covernÐ1 nÐ1 ing the range Ð 2 to 2 Ð 1 , this is more easily applied in addition and subtraction operations and is therefore the most commonly used method of representing positive and negative numbers.

REFERENCES
1. 2. 3. 4. Cavanagh, J.J.F., "Digital Computer Arithmetic," McGraw-Hill,1984. Hwang, K., "Computer Arithmetic," John Wiley & Sons, 1979. Scott, N.R., "Computer Number Systems & Arithmetic," Prentice Hall, 1985. IEEE Standards Board, "IEEE Standard for Floating-Point Arithmetic," ANSI/IEEE Std 754-1985, IEEE, 1985. Knuth, D.E., "The Art of Computer Programming, Volume 2," Addison-Wesley, 1981. Testa, F. J., "AN575: Applications of the 17CXX Hardware Multiply in Math Library Routines,: Embedded Control Handbook, Microchip Technology, 1996.

5. 6.

DS00575B-page 8

AN575
APPENDIX A: ALGORITHMS FOR DECIMAL TO BINARY CONVERSION
Several algorithms for decimal to binary conversion are given below. The integer and fractional conversion algorithms are useful in both native assembly as well as high level languages. Algorithm A.3 is a more brute force method easily implemented on a calculator or in a high level language on a host computer and is portable across platforms. An ANSI C implementation of algorithm A.3 is given.

A.1

Integer conversion algorithm[3]:

Given an integer I, where d(k) are the bit values of its n-bit binary representation with d(0) = LSb,
nÐ1

I =

k=0 k=0 I(k) = I while I(k) =! 0 d(k) = remainder of I(k)/2 I(k+1) = [ I(k)/2 ] k = k + 1 endw

∑ d(k) ⋅ 2

k

where [ ] denotes the greatest integer function.

A.2

Fractional conversion algorithm[3]:

Given a fraction F, where d(k) are the bit values of its n-bit binary representation with d(1) = MSb,

F=
k=0 F(k) = F while k <= n d(k) = [ F(k)*2 ] F(k+1) = fractional part of F(k)*2 k = k + 1 endw

k = 1

∑ d(k) ⋅ 2

n

Ðk

A.3

Decimal to binary conversion algorithm:

Given a decimal number A, and the number of fraction bits n, the bits in the fraction of the above binary representation of A, a(k), k = 0,2,...,n-1, where a(0) = MSb, are given by the following algorithm:
z = ln A / ln 2 e = int ( z ) if e > z e = e - 1 endif x = A / (2**e) k = 0 while k <= n-1 if x >= 2**(-k) a(k) = 1 else a(k) = 0 endif x = x - a(k) * 2**(-k) k = k + 1 endw

DS00575B-page 9

AN575
Formally, the number A then has the ﬂoating point representation
nÐ1

A=

( Ð1 ) s f

⋅2

e

f =

k=0

∑ a(k) ⋅ 2

Ðk

A simple C implementation of algorithm A.3 is given as follows:
#include <stdio.h> #include <math.h> main() { int a[32],e,k,j; double A,x,z; printf("Enter A: "); while(scanf("%lf",&A) == 1) { z = log(A)/log(2.); e = (int)z; if((double)e > z)e = e-1; x = A/pow(2.,(double)e); for(k=0; k<32; k++) { if(x >= pow(2.,(double)(-k))) a[k]=1; else a[k]=0; x = x - (double)a[k] * pow(2., (double)(-k)); } printf("e = %4i\n",e); printf("f = %1i.",a[0]); for(j=1; j<4; j++) printf("%1i",a[j]); printf(" "); for(k=1; k<8; k++) { for(j=0; j<4; j++) printf("%1i",a[k*4+j]); printf(" "); } printf("\n"); printf("Enter A: "); } }

DS00575B-page 10

AN575
FIGURE A-1: INTEGER TO FLOAT CONVERSION
FLO24 Yes AHI MSb = 0? Initialize EXP add bias clear SIGN No EXP ≤ EXPDEC? Yes A < 0? No A = -A set SIGN MSb EXP = EXP - EXPDEC Set FUN Flag No Yes Left Shift A by 1-bit EXPDEC = EXPDEC + 1

SETFUN24

No AXSIGN24 NRM24 Yes Restore SIGN MSb to A MSb RETURN and indicate Error SAT = 0?

EXPDEC = 0

Yes AHI = 0?

No

RETURN and indicate No Error Saturate to smallest number module sign bit

AHI = ALO, ALO = 0, EXPDEC = 8 No ALO = 0? Yes No AHI nibble = 0? RES024 Yes A=0 Shift A by nibble EXPDEC = EXPDEC + 4 RES024

RETURN and indicate Error

RETURN and indicate No Error

DS00575B-page 11

AN575
FIGURE A-2: FLOAT TO INTEGER CONVERSION
INT24 RND = 0? Save SIGN Make MSb explicit EXP = EXP - BIAS Yes No Yes EXP < 0? No RES024 Yes EXP > 16? SETIOV24 Yes A = -A EXP ≤ 8? No Right Shift by byte EXP = EXP - 8 RETURN and indicate No Error Set IOV Flag No Yes Sign bit = 0? No SETIOV24 No Add Next Signiﬁcant bit for Rounding

MSb = 1? Yes

Yes

SAT = 0? No

EXP = 0? Yes

No

EXP ≥ 4? No

Yes

Saturate to Largest Two’s Complement Integer

Right Shift by nibble EXP = EXP - 4

RETURN and indicate Error

No EXP = 0? Yes Right Shift by 1-bit EXP = EXP - 1 No EXP = 0? Yes

DS00575B-page 12

AN575
FIGURE A-3: FLOATING POINT MULTIPLY
FPM24

Yes

No A = 0 or B = 0? No RND = 0? Yes No Compute Sign EXP = AEXP - BIAS + BEXP

Add Next Signiﬁcant bit for Rounding

RES024 Carry = 1? Yes

Yes

Carry = 1? No

Right Shift by 1-bit EXP = EXP + 1

SETFOV24 No Carry = 1? Make MSb’s Explicit Overwrite Explicit MSb with Sign bit Add - Shift Multiply RETURN and indicate No Error Yes Carry = 1? No No Normalize by 1-bit EXP = EXP - 1 Yes SAT = 0? Yes

SETFOV24

Set FOV Flag

Saturate to Largest Number Modulo Sign bit

RETURN and indicate Error

DS00575B-page 13

AN575
FIGURE A-4: FLOATING POINT DIVIDE
FPD24

Yes

No B = 0? No RND = 0? Yes No

Compute Next Signiﬁcant bit and add for Rounding

Set FDZ Flag Carry = 1? RETURN and indicate Error Compute Sign Make MSbs Explicit Shift-Restore Division No Carry = 1? No Yes Align Dividend Overwrite Explicit MSb with Sign bit Yes

Right Shift by 1-bit EXP = EXP + 1

Yes

A ≥ B Mantissa?

SETFOV24

Compute EXP

RETURN and indicate No Error Yes Overﬂow? Yes SETFOV24 No

AEXP ≥ BEXP? No

Underﬂow? Yes

No

SETFUN24

DS00575B-page 14

AN575
FIGURE A-5:
FPS24

FLOATING POINT SUBTRACT

Toggle B Sign bit

No RND = 0? Yes No

Add Next Signiﬁcant bit for Rounding

FPA24

Carry = 1? Yes

Save XOR of Signs in TEMP Right Shift by 1-bit EXP = EXP + 1 Swap A and B No Carry = 1? Save Sign of A in SIGN Make MSbs Explicit Yes

Yes AEXP < BEXP? No

ALIGNED24

SETFOV24

Compute Shift Count in BEXP

BEXP ≥ 8? Yes Right Shift B by Byte BEXP = BEXP - 8

No

BEXP ≥ 4? Yes Right Shift B by Nibble BEXP = BEXP - 4

No

No BEXP = 0? Yes

No BEXP ≥ 8? Yes Restore Sign in A Yes BEXP = 0? No Right Shift B by 1-bit BEXP = BEXP - 1

RETURN and indicate No Error

DS00575B-page 15

AN575
FIGURE A-6: NORMALIZATION

ALIGNED24

No TEMP MSb = 0? Yes B = -B

A=A+B

Yes TEMP MSb = 0? No Carry = 1? No

Yes

Right Shift by 1-bit EXP = EXP + 1

Yes Carry = 1? No NRM24

No EXP = 0? Yes

A = -A Toggle Sign bit

Overwrite Explicit No MSb with Sign bit

SETFOV24

NRM24

RETURN and indicate No Error

DS00575B-page 16

AN575
TABLE A-1:
Routine FLO1624 FLO2424 INT2416 INT2424 FPA24 FPS24 FPM24 FPD24 Routine FLO2432 FLO3232 INT3224 INT3232 FPA32 FPS32 FPM32 FPD32

PIC17CXXX FLOATING POINT PERFORMANCE DATA
Max Cycles 49 64 41 48 63 120 61 172 Max Cycles 60 74 47 47 66 100 101 317 Min Cycles 34 39 41 44 52 0 56 168 Min Cycles 35 40 43 43 55 83 95 312 Program Memory 72 130 101 156 212 213 224 377 1465 Program Memory 120 189 155 219 329 330 382 661 2385 Data Memory 6 7 6 7 10 10 10 11 11 Data Memory 7 8 7 8 12 12 13 14 14 Total Memory Total Memory

TABLE A-2:
Routine FLO1624 FLO2424 INT2416 INT2424 FPA24 FPS24 FPM24 FPD24 Routine FLO2432 FLO3232 INT3224 INT3232 FPA32 FPS32 FPM32 FPD32

PIC16C5X/PIC16CXXX FLOATING POINT PERFORMANCE DATA
Max Cycles 81 108 47 46 74 196 298 469 Max Cycles 83 129 90 126 248 250 574 929 Min Cycles 35 28 41 44 74 46 11 348 Min Cycles 35 28 15 15 50 52 12 704 Program Memory 37 65 64 64 102 104 80 117 652 Program Memory 52 83 83 103 136 138 94 152 841 Data Memory 6 7 6 6 11 11 11 11 11 Data Memory 7 8 6 7 14 14 14 14 14 Total Memory Total Memory

DS00575B-page 17

AN575
NOTES:

DS00575B-page 18

AN575
Please check the Microchip BBS for the latest version of the source code. For BBS access information, see Section 6, Microchip Bulletin Board Service information, page 6-3.

APPENDIX B:
B.1
; ;

Device Family Include File
RCS Header \$Id: dev_fam.inc 1.2 1997/03/24 23:25:07 F.J.Testa Exp \$ \$Revision: 1.2 \$

; DEV_FAM.INC Device Family Type File, Version 1.00 Microchip Technology, Inc. ; ; This file takes the defined device from the LIST directive, and specifies a ; device family type and the Reset Vector Address (in RESET_V). ; ;******* ;******* Device Family Type, Returns one of these three Symbols (flags) set ;******* (other two are cleared) depending on processor selected in LIST Directive: ;******* P16C5X, P16CXX, or P17CXX ;******* Also sets the Reset Vector Address in symbol RESET_V ;******* ;******* File Name: DEV_FAM.INC ;******* Revision: 1.00.00 08/24/95 MP ;******* 1.00.01 03/21/97 AL ;******* ; TRUE EQU 1 FALSE EQU 0 ; P16C5X SET FALSE ; If P16C5X, use INHX8M file format. P16CXX SET FALSE ; If P16CXX, use INHX8M file format. P17CXX SET FALSE ; If P17CXX, the INHX32 file format is required ; ; in the LIST directive RESET_V SET 0x0000 ; Default Reset Vector address of 0h ; (16Cxx and 17Cxx devices) P16_MAP1 SET FALSE ; FOR 16C60/61/70/71/710/711/715/84 Memory Map P16_MAP2 SET FALSE ; For all other 16Cxx Memory Maps ; ;****** 16CXX *********** ; IFDEF __14000 P16CXX SET TRUE ; If P14000, use INHX8M file format. P16_MAP2 SET TRUE ENDIF ; IFDEF __16C554 P16CXX SET TRUE ; If P16C554, use INHX8M file format. P16_MAP2 SET TRUE ENDIF ; IFDEF __16C556 P16CXX SET TRUE ; If P16C556, use INHX8M file format. P16_MAP2 SET TRUE ENDIF ; IFDEF __16C558 P16CXX SET TRUE ; If P16C558, use INHX8M file format. P16_MAP2 SET TRUE ENDIF ; IFDEF __16C61 P16CXX SET TRUE ; If P16C61, use INHX8M file format. P16_MAP1 SET TRUE ENDIF ;

DS00575B-page 19

AN575
IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF __16C62 SET TRUE SET TRUE ; If P16C62, use INHX8M file format.

__16C62A SET TRUE SET TRUE

; If P16C62A, use INHX8M file format.

__16C63 SET TRUE SET TRUE

; If P16C63, use INHX8M file format.

__16C64 SET TRUE SET TRUE

; If P16C64, use INHX8M file format.

__16C64A SET TRUE SET TRUE

; If P16C64A, use INHX8M file format.

__16C65 SET TRUE SET TRUE

; If P16C65, use INHX8M file format.

__16C65A SET TRUE SET TRUE

; If P16C65A, use INHX8M file format.

__16C620 SET TRUE SET TRUE

; If P16C620, use INHX8M file format.

__16C621 SET TRUE SET TRUE

; If P16C621, use INHX8M file format.

__16C622 SET TRUE SET TRUE

; If P16C622, use INHX8M file format.

__16C642 SET TRUE SET TRUE

; If P16C642, use INHX8M file format.

__16C662 SET TRUE SET TRUE

; If P16C662, use INHX8M file format.

__16C710 SET TRUE SET TRUE

; If P16C710, use INHX8M file format.

__16C71

DS00575B-page 20

AN575
P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP1 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; IFDEF P16CXX SET SET TRUE TRUE ; If P16C71, use INHX8M file format.

__16C711 SET TRUE SET TRUE

; If P16C711, use INHX8M file format.

__16C72 SET TRUE SET TRUE

; If P16C72, use INHX8M file format.

__16C73 SET TRUE SET TRUE

; If P16C73, use INHX8M file format. ;

__16C73A SET TRUE SET TRUE

; If P16C73A, use INHX8M file format. ;

__16C74 SET TRUE SET TRUE

; If P16C74, use INHX8M file format. ;

__16C74A SET TRUE SET TRUE

; If P16C74A, use INHX8M file format. ;

__16C84 SET TRUE SET TRUE

; If P16C84, use INHX8M file format.

__16F84 SET TRUE SET TRUE

; If P16F84, use INHX8M file format.

__16F83 SET TRUE SET TRUE

; If P16F83, use INHX8M file format.

__16CR83 SET TRUE SET TRUE

; If P16CR83, use INHX8M file format.

__16CR84 SET TRUE SET TRUE

; If P16CR84, use INHX8M file format.

__16C923 SET TRUE SET TRUE

; If P16C923, use INHX8M file format.

__16C924 SET TRUE

; If P16C924, use INHX8M file format.

DS00575B-page 21

AN575
P16_MAP2 ENDIF ; IFDEF P16CXX P16_MAP2 ENDIF ; ; ; ;****** ; ; IFDEF P17CXX ; ENDIF ; IFDEF P17CXX ; ENDIF ; IFDEF P17CXX ; ENDIF ; IFDEF P17CXX ; ENDIF ; ;****** ; ; IFDEF P16C5X RESET_V ENDIF ; IFDEF P16C5X RESET_V ENDIF ; IFDEF P16C5X RESET_V ENDIF ; IFDEF P16C5X RESET_V ENDIF ; IFDEF P16C5X RESET_V ENDIF ; IFDEF P16C5X RESET_V ENDIF ; SET TRUE

__16CXX SET TRUE SET TRUE

; Generic Processor Type ; If P16CXX, use INHX8M file format. ;

17CXX

***********

__17C42 SET TRUE

; If P17C42, the INHX32 file format is required ; in the LIST directive

__17C43 SET TRUE

; If P17C43, the INHX32 file format is required ; in the LIST directive

__17C44 SET TRUE

; If P17C44, the INHX32 file format is required ; in the LIST directive

__17CXX SET TRUE

; Generic Processor Type ; If P17CXX, the INHX32 file format is required ; in the LIST directive

16C5X

***********

__16C54 SET TRUE SET 0x01FF

; If P16C54, use INHX8M file format. ; Reset Vector at end of 512 words

__16C54A SET TRUE SET 0x01FF

; If P16C54A, use INHX8M file format. ; Reset Vector at end of 512 words

__16C55 SET TRUE SET 0x01FF

; If P16C55, use INHX8M file format. ; Reset Vector at end of 512 words

__16C56 SET TRUE SET 0x03FF

; If P16C56, use INHX8M file format. ; Reset Vector at end of 1K words

__16C57 SET TRUE SET 0x07FF

; If P16C57, use INHX8M file format. ; Reset Vector at end of 2K words

__16C58A SET TRUE SET 0x07FF

; If P16C58A, use INHX8M file format. ; Reset Vector at end of 2K words

DS00575B-page 22

AN575
IFDEF __16C5X ; Generic Processor Type P16C5X SET TRUE ; If P16C5X, use INHX8M file format. RESET_V SET 0x07FF ; Reset Vector at end of 2K words ENDIF ; ; if ( P16C5X + P16CXX + P17CXX != 1 ) MESSG “WARNING - USER DEFINED: One and only one device family can be selected” MESSG “ May be NEW processor not defined in this file” endif ;

DS00575B-page 23

AN575
B.2
; ; ; ; ; ; ; ;

Math16 Include File
RCS Header \$Id: math16.inc 2.4 1997/02/11 16:58:49 F.J.Testa Exp \$ \$Revision: 2.4 \$ MATH16 INCLUDE FILE IMPORTANT NOTE: The math library routines can be used in a dedicated application on an individual basis and memory allocation may be modified with the stipulation that on the PIC17, P type registers must remain so since P type specific instructions were used to realize some performance improvements.

;********************************************************************************************* ; ; GENERAL MATH LIBRARY DEFINITIONS ; ; general literal constants ; B0 B1 B2 B3 B4 B5 B6 B7 MSB LSB define assembler constants equ equ equ equ equ equ equ equ equ equ 0 1 2 3 4 5 6 7 7 0

; ;

define commonly used bits STATUS bit definitions _C _Z STATUS,0 STATUS,2

#define #define ; ; ;

general register variables IF ( P16_MAP1 )

ACCB7 ACCB6 ACCB5 ACCB4 ACCB3 ACCB2 ACCB1 ACCB0 ACC ; SIGN ; TEMPB3 TEMPB2 TEMPB1 TEMPB0 TEMP ;

equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ

0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x13 0x15 0x1C 0x1D 0x1E 0x1F 0x1F

; most significant byte of contiguous 8 byte accumulator ; save location for sign in MSB

; temporary storage

DS00575B-page 24

AN575
; binary operation arguments ; AARGB7 equ 0x0C AARGB6 equ 0x0D AARGB5 equ 0x0E AARGB4 equ 0x0F AARGB3 equ 0x10 AARGB2 equ 0x11 AARGB1 equ 0x12 AARGB0 equ 0x13 AARG equ 0x13 ; most significant byte of argument A ; BARGB3 equ 0x17 BARGB2 equ 0x18 BARGB1 equ 0x19 BARGB0 equ 0x1A BARG equ 0x1A ; most significant byte of argument B ; ; Note that AARG and ACC reference the same storage location ; ;********************************************************************************************* ; ; FIXED POINT SPECIFIC DEFINITIONS ; ; remainder storage ; REMB3 equ 0x0C REMB2 equ 0x0D REMB1 equ 0x0E REMB0 equ 0x0F ; most significant byte of remainder LOOPCOUNT equ 0x20 ; loop counter ; ;********************************************************************************************* ; ; FLOATING POINT SPECIFIC DEFINITIONS ; ; literal constants ; EXPBIAS equ D’127’ ; ; biased exponents ; EXP equ 0x14 ; 8 bit biased exponent AEXP equ 0x14 ; 8 bit biased exponent for argument A BEXP equ 0x1B ; 8 bit biased exponent for argument B ; ; floating point library exception flags ; FPFLAGS equ 0x16 ; floating point library exception flags IOV equ 0 ; bit0 = integer overflow flag FOV equ 1 ; bit1 = floating point overflow flag FUN equ 2 ; bit2 = floating point underflow flag FDZ equ 3 ; bit3 = floating point divide by zero flag NAN equ 4 ; bit4 = not-a-number exception flag DOM equ 5 ; bit5 = domain error exception flag RND equ 6 ; bit6 = floating point rounding flag, 0 = truncation ; 1 = unbiased rounding to nearest LSB SAT equ 7 ; bit7 = floating point saturate flag, 0 = terminate on ; exception without saturation, 1 = terminate on ; exception with saturation to appropriate value ENDIF ; ; IF ( P16_MAP2 )

DS00575B-page 25

AN575
ACCB7 equ 0x20 ACCB6 equ 0x21 ACCB5 equ 0x22 ACCB4 equ 0x23 ACCB3 equ 0x24 ACCB2 equ 0x25 ACCB1 equ 0x26 ACCB0 equ 0x27 ACC equ 0x27 ; most significant byte of contiguous 8 byte accumulator ; SIGN equ 0x29 ; save location for sign in MSB ; TEMPB3 equ 0x30 TEMPB2 equ 0x31 TEMPB1 equ 0x32 TEMPB0 equ 0x33 TEMP equ 0x33 ; temporary storage ; ; binary operation arguments ; AARGB7 equ 0x20 AARGB6 equ 0x21 AARGB5 equ 0x22 AARGB4 equ 0x23 AARGB3 equ 0x24 AARGB2 equ 0x25 AARGB1 equ 0x26 AARGB0 equ 0x27 AARG equ 0x27 ; most significant byte of argument A ; BARGB3 equ 0x2B BARGB2 equ 0x2C BARGB1 equ 0x2D BARGB0 equ 0x2E BARG equ 0x2E ; most significant byte of argument B ; ; Note that AARG and ACC reference the same storage location ; ;********************************************************************************************* ; ; FIXED POINT SPECIFIC DEFINITIONS ; ; remainder storage ; REMB3 equ 0x20 REMB2 equ 0x21 REMB1 equ 0x22 REMB0 equ 0x23 ; most significant byte of remainder LOOPCOUNT equ 0x34 ; loop counter ; ;********************************************************************************************* ; ; FLOATING POINT SPECIFIC DEFINITIONS ; ; literal constants ; EXPBIAS equ D’127’ ; ; biased exponents ; EXP equ 0x28 ; 8 bit biased exponent AEXP equ 0x28 ; 8 bit biased exponent for argument A BEXP equ 0x2F ; 8 bit biased exponent for argument B ;

DS00575B-page 26

AN575
; floating point library exception flags ; FPFLAGS equ 0x2A ; floating point library exception flags IOV equ 0 ; bit0 = integer overflow flag FOV equ 1 ; bit1 = floating point overflow flag FUN equ 2 ; bit2 = floating point underflow flag FDZ equ 3 ; bit3 = floating point divide by zero flag NAN equ 4 ; bit4 = not-a-number exception flag DOM equ 5 ; bit5 = domain error exception flag RND equ 6 ; bit6 = floating point rounding flag, 0 = truncation ; 1 = unbiased rounding to nearest LSb SAT equ 7 ; bit7 = floating point saturate flag, 0 = terminate on ; exception without saturation, 1 = terminate on ; exception with saturation to appropriate value ;********************************************************************************************** ; CEXP CARGB0 CARGB1 CARGB2 CARGB3 DEXP DARGB0 DARGB1 DARGB2 DARGB3 EEXP EARGB0 EARGB1 EARGB2 EARGB3 ZARGB0 ZARGB1 ZARGB2 ZARGB3 RANDB0 RANDB1 RANDB2 RANDB3 ELEMENTARY FUNCTION MEMORY equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ 0x35 0x36 0x37 0x38 0x39 0x3A 0x3B 0x3C 0x3D 0x3E 0x3F 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4A 0x4B

;********************************************************************************************** ; ; 24-BIT FLOATING POINT CONSTANTS Machine precision equ equ equ 0x6F 0x00 0x00 ; 1.52587890625e-5 = 2**-16

MACHEP24EXP MACHEP24B0 MACHEP24B1 ;

Maximum argument to EXP24 equ equ equ 0x85 0x31 0x72 ; 88.7228391117 = log(2**128)

MAXLOG24EXP MAXLOG24B0 MAXLOG24B1 ;

Minimum argument to EXP24

DS00575B-page 27

AN575
MINLOG24EXP MINLOG24B0 MINLOG24B1 ; equ equ equ 0x85 0xAE 0xAC ; -87.3365447506 = log(2**-126)

Maximum argument to EXP1024 equ equ equ 0x84 0x1A 0x21 ; 38.531839445 = log10(2**128)

MAXLOG1024EXP MAXLOG1024B0 MAXLOG1024B1 ;

Minimum argument to EXP1024 equ equ equ 0x84 0x97 0xB8 ; -37.9297794537 = log10(2**-126)

MINLOG1024EXP MINLOG1024B0 MINLOG1024B1 ;

Maximum representable number before overflow equ equ equ 0xFF 0x7F 0xFF ; 6.80554349248E38 = (2**128) * (2 - 2**-15)

MAXNUM24EXP MAXNUM24B0 MAXNUM24B1 ;

Minimum representable number before underflow equ equ equ 0x01 0x00 0x00 ; 1.17549435082E-38 = (2**-126) * 1

MINNUM24EXP MINNUM24B0 MINNUM24B1 ;

Loss threshold for argument to SIN24 and COS24 equ equ equ 0x8B 0x00 0x00 ; 4096 = sqrt(2**24)

LOSSTHR24EXP LOSSTHR24B0 LOSSTHR24B1

;********************************************************************************************** ; ; 32-BIT FLOATING POINT CONSTANTS Machine precision equ equ equ equ 0x67 0x00 0x00 0x00 ; 5.96046447754E-8 = 2**-24

MACHEP32EXP MACHEP32B0 MACHEP32B1 MACHEP32B2 ;

Maximum argument to EXP32 equ equ equ equ 0x85 0x31 0x72 0x18 ; 88.7228391117 = log(2**128)

MAXLOG32EXP MAXLOG32B0 MAXLOG32B1 MAXLOG32B2 ;

Minimum argument to EXP32 equ equ equ equ 0x85 0xAE 0xAC 0x50 ; -87.3365447506 = log(2**-126)

MINLOG32EXP MINLOG32B0 MINLOG32B1 MINLOG32B2 ;

Maximum argument to EXP1032 equ equ equ equ 0x84 0x1A 0x20 0x9B ; 38.531839445 = log10(2**128)

MAXLOG1032EXP MAXLOG1032B0 MAXLOG1032B1 MAXLOG1032B2 ;

Minimum argument to EXP1032

DS00575B-page 28

AN575
MINLOG1032EXP MINLOG1032B0 MINLOG1032B1 MINLOG1032B2 ; equ equ equ equ 0x84 0x97 0xB8 0x18 ; -37.9297794537 = log10(2**-126)

Maximum representable number before overflow equ equ equ equ 0xFF 0x7F 0xFF 0xFF ; 6.80564774407E38 = (2**128) * (2 - 2**-23)

MAXNUM32EXP MAXNUM32B0 MAXNUM32B1 MAXNUM32B2 ;

Minimum representable number before underflow equ equ equ equ 0x01 0x00 0x00 0x00 ; 1.17549435082E-38 = (2**-126) * 1

MINNUM32EXP MINNUM32B0 MINNUM32B1 MINNUM32B2 ;

Loss threshold for argument to SIN32 and COS32 equ equ equ equ 0x8B 0x00 0x00 0x00 ; 4096 = sqrt(2**24)

LOSSTHR32EXP LOSSTHR32B0 LOSSTHR32B1 LOSSTHR32B2

ENDIF

DS00575B-page 29

AN575
B.3
; ; ; ; ; ; ; ;

Math17 Include File
RCS Header \$Id: math17.inc 2.9 1997/01/31 02:23:41 F.J.Testa Exp \$ \$Revision: 2.9 \$ MATH17 INCLUDE FILE IMPORTANT NOTE: The math library routines can be used in a dedicated application on an individual basis and memory allocation may be modified with the stipulation that P type registers must remain so since P type specific instructions were used to realize some performance improvements. This applies only to the PIC17.

;********************************************************************************************* ; GENERAL MATH LIBRARY DEFINITIONS

; ; B0 B1 B2 B3 B4 B5 B6 B7 MSB LSB

general literal constants define assembler constants equ equ equ equ equ equ equ equ equ equ 0 1 2 3 4 5 6 7 7 0

; ;

define commonly used bits STATUS bit definitions _C _DC _Z _OV ALUSTA,0 ALUSTA,1 ALUSTA,2 ALUSTA,3

#define #define #define #define ; ACCB7 ACCB6 ACCB5 ACCB4 ACCB3 ACCB2 ACCB1 ACCB0 ACC SIGN TEMPB3 TEMPB2 TEMPB1 TEMPB0 TEMP

general register variables equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x1F 0x21 0x28 0x29 0x2A 0x2B 0x2B

; most significant byte of contiguous 8 byte accumulator ; save location for sign in MSB

; temporary storage

DS00575B-page 30

AN575
; AARGB7 AARGB6 AARGB5 AARGB4 AARGB3 AARGB2 AARGB1 AARGB0 AARG BARGB3 BARGB2 BARGB1 BARGB0 BARG binary operation arguments equ equ equ equ equ equ equ equ equ equ equ equ equ equ 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x1F 0x23 0x24 0x25 0x26 0x26

; most significant byte of argument A

; most significant byte of argument B

;

Note that AARG and ACC reference the same storage location

;********************************************************************************************* ; ; REMB3 REMB2 REMB1 REMB0 FIXED POINT SPECIFIC DEFINITIONS remainder storage equ equ equ equ 0x18 0x19 0x1A 0x1B

; most significant byte of remainder

;********************************************************************************************* ; ; EXPBIAS ; EXP AEXP BEXP ; FPFLAGS IOV FOV FUN FDZ NAN DOM RND SAT FLOATING POINT SPECIFIC DEFINITIONS literal constants equ biased exponents equ equ equ 0x20 0x20 0x27 ; 8 bit biased exponent ; 8 bit biased exponent for argument A ; 8 bit biased exponent for argument B D’127’

floating point library exception flags equ equ equ equ equ equ equ equ equ 0x22 0 1 2 3 4 5 6 7 ; ; ; ; ; ; ; ; ; ; ; ; floating point library exception flags bit0 = integer overflow flag bit1 = floating point overflow flag bit2 = floating point underflow flag bit3 = floating point divide by zero flag bit4 = not-a-number exception flag bit5 = domain error flag bit6 = floating point rounding flag, 0 = truncation 1 = unbiased rounding to nearest LSB bit7 = floating point saturate flag, 0 = terminate on exception without saturation, 1 = terminate on exception with saturation to appropriate value

;**********************************************************************************************

DS00575B-page 31

AN575
; CEXP CARGB0 CARGB1 CARGB2 CARGB3 DEXP DARGB0 DARGB1 DARGB2 DARGB3 EEXP EARGB0 EARGB1 EARGB2 EARGB3 FEXP FARGB0 FARGB1 FARGB2 FARGB3 GEXP GARGB0 GARGB1 GARGB2 GARGB3 ZARGB0 ZARGB1 ZARGB2 ZARGB3 RANDB0 RANDB1 RANDB2 RANDB3 ELEMENTARY FUNCTION MEMORY equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ equ 0x34 0x33 0x32 0x31 0x30 0x39 0x38 0x37 0x36 0x35 0x3E 0x3D 0x3C 0x3B 0x3A 0x43 0x42 0x41 0x40 0x3F 0x48 0x47 0x46 0x45 0x44 0x2F 0x2E 0x2D 0x2C 0x4C 0x4B 0x4A 0x49

;********************************************************************************************** ; ; 24-BIT FLOATING POINT CONSTANTS Machine precision equ equ equ 0x6F 0x00 0x00 ; 1.52587890625e-5 = 2**-16

MACHEP24EXP MACHEP24B0 MACHEP24B1 ;

Maximum argument to EXP24 equ equ equ 0x85 0x31 0x72 ; 88.7228391117 = log(2**128)

MAXLOG24EXP MAXLOG24B0 MAXLOG24B1 ;

Minimum argument to EXP24 equ equ equ 0x85 0xAE 0xAC ; -87.3365447506 = log(2**-126)

MINLOG24EXP MINLOG24B0 MINLOG24B1

DS00575B-page 32

AN575
; Maximum argument to EXP1024 qu equ equ 0x84 0x1A 0x21 ; 38.531839445 = log10(2**128) MAXLOG1024EXPe MAXLOG1024B0 MAXLOG1024B1 ;

Minimum argument to EXP1024 equ equ equ 0x84 0x97 0xB8 ; -37.9297794537 = log10(2**-126)

MINLOG1024EXP MINLOG1024B0 MINLOG1024B1 ;

Maximum representable number before overflow equ equ equ 0xFF 0x7F 0xFF ; 6.80554349248E38 = (2**128) * (2 - 2**-15)

MAXNUM24EXP MAXNUM24B0 MAXNUM24B1 ;

Minimum representable number before underflow equ equ equ 0x01 0x00 0x00 ; 1.17549435082E-38 = (2**-126) * 1

MINNUM24EXP MINNUM24B0 MINNUM24B1 ;

Loss threshold for argument to SIN24 and COS24 equ equ equ 0x8A 0x49 0x10 ; LOSSTHR = sqrt(2**24)*PI/4

LOSSTHR24EXP LOSSTHR24B0 LOSSTHR24B1

;********************************************************************************************** ; ; 32-BIT FLOATING POINT CONSTANTS Machine precision equ equ equ equ 0x67 0x00 0x00 0x00 ; 5.96046447754E-8 = 2**-24

MACHEP32EXP MACHEP32B0 MACHEP32B1 MACHEP32B2 ;

Maximum argument to EXP32 equ equ equ equ 0x85 0x31 0x72 0x18 ; 88.7228391117 = log(2**128)

MAXLOG32EXP MAXLOG32B0 MAXLOG32B1 MAXLOG32B2 ;

Minimum argument to EXP32 equ equ equ equ 0x85 0xAE 0xAC 0x50 ; -87.3365447506 = log(2**-126)

MINLOG32EXP MINLOG32B0 MINLOG32B1 MINLOG32B2 ;

Maximum argument to EXP1032 equ equ equ equ 0x84 0x1A 0x20 0x9B ; 38.531839445 = log10(2**128)

MAXLOG1032EXP MAXLOG1032B0 MAXLOG1032B1 MAXLOG1032B2

DS00575B-page 33

AN575
; Minimum argument to EXP1032 equ equ equ equ 0x84 0x97 0xB8 0x18 ; -37.9297794537 = log10(2**-126) MINLOG1032EXP MINLOG1032B0 MINLOG1032B1 MINLOG1032B2 ;

Maximum representable number before overflow equ equ equ equ 0xFF 0x7F 0xFF 0xFF ; 6.80564774407E38 = (2**128) * (2 - 2**-23)

MAXNUM32EXP MAXNUM32B0 MAXNUM32B1 MAXNUM32B2 ;

Minimum representable number before underflow equ equ equ equ 0x01 0x00 0x00 0x00 ; 1.17549435082E-38 = (2**-126) * 1

MINNUM32EXP MINNUM32B0 MINNUM32B1 MINNUM32B2 ;

Loss threshold for argument to SIN32 and COS32 equ equ equ equ 0x8A 0x49 0x0F 0xDB ; LOSSTHR = sqrt(2**24)*PI/4

LOSSTHR32EXP LOSSTHR32B0 LOSSTHR32B1 LOSSTHR32B2

DS00575B-page 34

AN575
Please check the Microchip BBS for the latest version of the source code. For BBS access information, see Section 6, Microchip Bulletin Board Service information, page 6-3.

APPENDIX C: PIC16CXXX 24-BIT FLOATING POINT LIBRARY
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; RCS Header \$Id: fp24.a16 2.7 1996/10/07 13:50:29 F.J.Testa Exp \$ \$Revision: 2.7 \$ PIC16 24-BIT FLOATING POINT LIBRARY Unary operations: both input and output are in AEXP,AARG Binary operations: input in AEXP,AARG and BEXP,BARG with output in AEXP,AARG All routines return WREG = 0x00 for successful completion, and WREG = 0xFF for an error condition specified in FPFLAGS. All timings are worst case cycle counts Routine Function

FLO1624 16 bit integer to 24 bit floating point conversion FLO24 Timing: 0 0 SAT 1 NRM2424 NRM24 Timing: 0 0 SAT 1 INT2416 INT24 Timing: 0 0 SAT 1 FLO2424 Timing: 0 0 SAT 1 108 123 108 83 92 83 77 77 72 88 88 83 RND 1 83

24 bit normalization of unnormalized 24 bit floating point numbers

RND 1 72

24 bit floating point to 16 bit integer conversion

RND 1 89

24 bit integer to 24 bit floating point conversion RND 1 117

DS00575B-page 35

AN575
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; NRM3224 Timing: 0 0 SAT 1 INT2424 Timing: 0 0 SAT 1 FPA24 Timing: 0 0 SAT 1 FPS24 Timing: 0 0 SAT 1 FPM24 Timing: 0 0 SAT 1 FPD24 Timing: 0 0 SAT 1 472 498 472 298 313 298 199 215 199 197 213 197 105 115 105 94 109 94 32 bit normalization of unnormalized 24 bit floating point numbers RND 1 103

24 bit floating point to 24 bit integer conversion RND 1 113

24 bit floating point add RND 1 208

24 bit floating point subtract RND 1 240

24 bit floating point multiply RND 1 309

24 bit floating point divide RND 1 494

;********************************************************************************************** ;********************************************************************************************** ; ; 24-bit floating point representation ; ; EXPONENT 8 bit biased exponent ; It is important to note that the use of biased exponents produces ; a unique representation of a floating point 0, given by ; EXP = HIGHBYTE = LOWBYTE = 0x00, with 0 being the only ; number with EXP = 0.

DS00575B-page 36

AN575
; ; ; ; ; ; ; ; ; ; ; ; ; ; HIGHBYTE 8 bit most significant byte of fraction in sign-magnitude representation, with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB 8 bit least significant byte of sign-magnitude fraction HIGHBYTE S.xxxxxxx | RADIX POINT LOWBYTE xxxxxxxx

LOWBYTE EXPONENT xxxxxxxx

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 16 bit 2’s complement integer right justified in AARGB0, AARGB1 CALL FLO1624 or CALL FLO24

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-FLOAT( AARG ) SAT = 0 SAT = 1 AARG = 0

11+72 = 83 clks 11+77 = 88 clks 7+14 = 21 clks 7+18 = 25 clks

Min Timing:

PM: 11+26 = 37

DM: 6

;---------------------------------------------------------------------------------------------FLO1624 FLO24 MOVLW MOVWF MOVF MOVWF BTFSS GOTO COMF COMF INCF BTFSC INCF D’15’+EXPBIAS EXP AARGB0,W SIGN AARGB0,MSB NRM2424 AARGB1,F AARGB0,F AARGB1,F _Z AARGB0,F ; initialize exponent and add bias

; test sign ; if < 0, negate and set MSB in SIGN

;********************************************************************************************** ; ; ; ; ; ; Normalization routine Input: 24 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, with sign in SIGN, MSB and other bits zero. CALL NRM2424 or CALL NRM24

Use:

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1 Result: AARG <-NORMALIZE( AARG )

DS00575B-page 37

AN575
; ; ; ; ; Max Timing: 10+6+7*7+7 = 72 clks 10+6+7*7+1+11 = 77 clks 14 clks 5+9+4 = 18 clks SAT = 0 SAT = 1 AARG = 0

Min Timing:

PM: 26

DM: 6

;---------------------------------------------------------------------------------------------NRM2424 NRM24 CLRF MOVF BTFSS GOTO MOVF MOVWF BTFSC GOTO CLRF BSF NORM2424 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM2424A BTFSC GOTO RLF RLF DECFSZ GOTO GOTO FIXSIGN24 BTFSS BCF RETLW CLRF CLRF CLRF CLRF RETLW TEMP AARGB0,W _Z NORM2424 AARGB1,W AARGB0 _Z RES024 AARGB1 TEMP,3 TEMP,W EXP,F _Z _C SETFUN24 _C AARGB0,MSB FIXSIGN24 AARGB1,F AARGB0,F EXP,F NORM2424A SETFUN24 SIGN,MSB AARGB0,MSB 0 AARGB0 AARGB1 AARGB2 EXP 0 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; decrement EXP ; clear exponent decrement ; test if highbyte=0

; if so, shift 8 bits by move ; if highbyte=0, result=0

; underflow if EXP=0

; clear explicit MSB if positive

RES024

; result equals zero ; clear extended byte

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 CALL FLO2424

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-FLOAT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

14+94 = 108 clks 14+103 = 117 clks 14+109 = 123 clks

DS00575B-page 38

AN575
; ; ; Min Timing: 6+28 = 34 clks 6+22 = 28 clks AARG = 0

PM: 14+51 = 65

DM: 7

;---------------------------------------------------------------------------------------------FLO2424 MOVLW MOVWF CLRF BTFSS GOTO COMF COMF COMF INCF BTFSC INCF BTFSC INCF BSF D’23’+EXPBIAS EXP SIGN AARGB0,MSB NRM3224 AARGB2,F AARGB1,F AARGB0,F AARGB2,F _Z AARGB1,F _Z AARGB0,F SIGN,MSB ; initialize exponent and add bias

; test sign ; if < 0, negate and set MSB in SIGN

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 32 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2, with sign in SIGN,MSB CALL NRM3224

Use:

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-NORMALIZE( AARG )

21+6+7*8+7+4 = 94 clks RND = 0 21+6+7*8+20+4 = 103 clks RND = 1, SAT = 0 21+6+7*8+19+11 = 109 clks RND = 1, SAT = 1 22+6 = 28 clks 5+9+4+4 = 22 clks AARG = 0

Min Timing:

PM: 51

DM: 7

;---------------------------------------------------------------------------------------------NRM3224 CLRF MOVF BTFSS GOTO MOVF MOVWF MOVF MOVWF CLRF BSF MOVF BTFSS GOTO MOVF MOVWF CLRF BCF BSF TEMP AARGB0,W _Z NORM3224 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 AARGB0,W _Z NORM3224 AARGB1,W AARGB0 AARGB1 TEMP,3 TEMP,4 ; clear exponent decrement ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8

DS00575B-page 39

AN575
MOVF BTFSC GOTO NORM3224 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM3224A BTFSC GOTO RLF RLF RLF DECFSZ GOTO GOTO BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSS GOTO RRF RRF INCF BTFSC GOTO GOTO AARGB0,W _Z RES024 TEMP,W EXP,F _Z _C SETFUN24 _C AARGB0,MSB NRMRND3224 AARGB2,F AARGB1,F AARGB0,F EXP,F NORM3224A SETFUN24 FPFLAGS,RND AARGB1,LSB FIXSIGN24 AARGB2,MSB FIXSIGN24 AARGB1,F _Z AARGB0,F _Z FIXSIGN24 AARGB0,F AARGB1,F EXP,F _Z SETFOV24 FIXSIGN24 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; decrement EXP ; if highbyte=0, result=0

; underflow if EXP=0

NRMRND3224

; round if next bit is set

; has rounding caused carryout? ; if so, right shift

; check for overflow

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 24 bit floating point number in AEXP, AARGB0, AARGB1 CALL INT2416 or CALL INT24

Output: 16 bit 2’s complement integer right justified in AARGB0, AARGB1 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

29+6*6+5+13 = 83 clks 29+6*6+5+19 = 89 clks 29+6*6+5+22 = 92 clks 18+5+7 = 30 clks

Min Timing: PM: 63

DM: 6

;---------------------------------------------------------------------------------------------INT2416 INT24 MOVF EXP,W ; test for zero argument

DS00575B-page 40

AN575
BTFSC RETLW MOVF MOVWF BSF MOVLW SUBWF BTFSS GOTO COMF INCF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF CLRF MOVF BTFSS BCF GOTO TSHIFT2416 MOVF BTFSC GOTO BCF RRF RRF DECFSZ GOTO BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC GOTO INT2416OK BTFSS RETLW COMF COMF INCF BTFSC INCF RETLW _Z 0x00 AARGB0,W SIGN AARGB0,MSB EXPBIAS+D’15’ EXP,F EXP,MSB SETIOV16 EXP,F EXP,F 8 EXP,W _C TSHIFT2416 EXP AARGB1,F AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT2416 EXP AARGB1,F AARGB1 EXP,W _Z _C SHIFT2416OK EXP,W _Z SHIFT2416OK _C AARGB0,F AARGB1,F EXP,F SHIFT2416 FPFLAGS,RND AARGB1,LSB INT2416OK _C INT2416OK AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV16 SIGN,MSB 0 AARGB1,F AARGB0,F AARGB1,F _Z AARGB0,F 0 ; save sign in SIGN ; make MSB explicit ; remove bias from EXP

; do byte shift if EXP >= 8

; rotate next bit for rounding

; do byte shift if EXP >= 8

; rotate next bit for rounding

; shift completed if EXP = 0

SHIFT2416

; right shift by EXP

SHIFT2416OK

; round if next bit is set

; test for overflow

; if sign bit set, negate

DS00575B-page 41

AN575
SETIOV16 BSF BTFSS RETLW CLRF BTFSS MOVLW MOVWF MOVWF RLF RRF RETLW FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 SIGN,F AARGB0,F 0xFF ; set integer overflow flag ; test for saturation ; return error code in WREG ; saturate to largest two’s ; complement 16 bit integer ; SIGN = 0, 0x 7F FF ; SIGN = 1, 0x 80 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 24 bit floating point number in AEXP, AARGB0, AARGB1 CALL INT2424

Output: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

41+6*7+6+16 = 105 clks 41+6*7+6+24 = 113 clks 41+6*7+6+26 = 115 clks 5 clks

Min Timing: PM: 82

DM: 6

;---------------------------------------------------------------------------------------------INT2424 CLRF MOVF BTFSC RETLW MOVF MOVWF BSF MOVLW SUBWF BTFSS GOTO COMF INCF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF MOVF MOVWF AARGB2 EXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB EXPBIAS+D’23’ EXP,F EXP,MSB SETIOV24 EXP,F EXP,F 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB1,W AARGB2 AARGB0,W AARGB1 ; test for zero argument

; save sign in SIGN ; make MSB explicit ; remove bias from EXP

; do byte shift if EXP >= 8

; rotate next bit for rounding

DS00575B-page 42

AN575
CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF CLRF MOVF BTFSS BCF GOTO TSHIFT2424 MOVF BTFSC GOTO BCF RRF RRF RRF DECFSZ GOTO BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSC GOTO BTFSS RETLW COMF COMF COMF INCF BTFSC INCF BTFSC INCF RETLW CLRF CLRF CLRF RETLW BSF AARGB0 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB1,W AARGB2 AARGB1 8 EXP,W _C TSHIFT2424 EXP AARGB2,F AARGB2 EXP,W _Z _C SHIFT2424OK EXP,W _Z SHIFT2424OK _C AARGB0,F AARGB1,F AARGB2,F EXP,F SHIFT2424 FPFLAGS,RND AARGB2,LSB INT2424OK _C INT2424OK AARGB2,F _Z AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV24 SIGN,MSB 0 AARGB0,F AARGB1,F AARGB2,F AARGB2,F _Z AARGB1,F _Z AARGB0,F 0 AARGB0 AARGB1 AARGB2 0 FPFLAGS,IOV ; do another byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; shift completed if EXP = 0

SHIFT2424

; right shift by EXP

SHIFT2424OK

; test for overflow

INT2424OK

; if sign bit set, negate

IRES024

; integer result equals zero

SETIOV24

; set integer overflow flag

DS00575B-page 43

AN575
BTFSS RETLW CLRF BTFSS MOVLW MOVWF MOVWF MOVWF RLF RRF RETLW FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF ; test for saturation ; return error code in WREG ; saturate to largest two’s ; complement 24 bit integer ; SIGN = 0, 0x 7F FF FF ; SIGN = 1, 0x 80 00 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Floating Point Multiply Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 CALL FPM24

Use:

Output: 24 bit floating point product in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG * BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0

25+15*16+15+18 = 298 clks 25+15*16+15+29 = 309 clks 25+15*16+15+33 = 313 clks 6+5 = 11 clks 24+15*11+14+15 = 218 clks

Min Timing:

PM: 80

DM: 11

;---------------------------------------------------------------------------------------------FPM24 MOVF BTFSS MOVF BTFSC GOTO MOVF XORWF MOVWF MOVF ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO GOTO MTUN24 SUBWF BTFSS GOTO MOVF AEXP,W _Z BEXP,W _Z RES024 AARGB0,W BARGB0,W SIGN BEXP,W EXP,F EXPBIAS-1 _C MTUN24 EXP,F _C SETFOV24 MOK24 EXP,F _C SETFUN24 AARGB0,W ; test for zero arguments

M24BNE0

; set multiply overflow flag

MOK24

DS00575B-page 44

AN575
MOVF MOVWF MOVF MOVWF BSF BSF BCF CLRF CLRF MOVLW MOVWF MLOOP24 BTFSS GOTO MOVF ADDWF MOVF BTFSC INCFSZ ADDWF RRF RRF RRF RRF BCF DECFSZ GOTO BTFSC GOTO RLF RLF RLF DECF MROUND24 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSS GOTO RRF RRF INCF BTFSC GOTO MUL24OK BTFSS BCF RETLW BSF BTFSS RETLW MOVLW MOVWF MOVWF MOVWF AARGB0,W AARGB2 AARGB1,W AARGB3 AARGB2,MSB BARGB0,MSB _C AARGB0 AARGB1 D’16’ TEMP AARGB3,LSB MNOADD24 BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB0,F AARGB1,F AARGB2,F AARGB3,F _C TEMP,F MLOOP24 AARGB0,MSB MROUND24 AARGB2,F AARGB1,F AARGB0,F EXP,F FPFLAGS,RND AARGB1,LSB MUL24OK AARGB2,MSB MUL24OK AARGB1,F _Z AARGB0,F _Z MUL24OK AARGB0,F AARGB1,F EXP,F _Z SETFOV24 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FOV FPFLAGS,SAT 0xFF 0xFF AEXP AARGB0 AARGB1 ; check for postnormalization ; move result to AARG

; make argument MSB’s explicit

; clear initial partial product

; initialize counter ; test next bit

; round if next bit is set

; has rounding caused carryout? ; if so, right shift

; check for overflow

; clear explicit MSB if positive

SETFOV24

; set floating point underflag ; test for saturation ; return error code in WREG

; saturate to largest floating ; point number = 0x FF 7F FF ; modulo the appropriate sign bit

DS00575B-page 45

AN575
RLF RRF RETLW SIGN,F AARGB0,F 0xFF ; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Divide Input: 24 bit floating point dividend in AEXP, AARGB0, AARGB1 24 bit floating point divisor in BEXP, BARGB0, BARGB1 CALL FPD24

Use:

Output: 24 bit floating point quotient in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG / BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

32+13+15*26+25+12 = 472 clks 32+13+15*26+25+34 = 494 clks 32+13+15*26+25+38 = 498 clks 7+5 = 12 clks

Min Timing: PM: 120

DM: 11

;---------------------------------------------------------------------------------------------FPD24 MOVF BTFSC GOTO MOVF BTFSC GOTO D24BNE0 MOVF XORWF MOVWF BSF BSF CLRF MOVF MOVWF MOVF MOVWF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF CLRF CLRF BTFSS GOTO BCF RRF RRF RRF MOVLW BEXP,W _Z SETFDZ24 AEXP,W _Z RES024 AARGB0,W BARGB0,W SIGN AARGB0,MSB BARGB0,MSB TEMP AARGB0,W AARGB2 AARGB1,W AARGB3 BARGB1,W AARGB3, f BARGB0,W _C BARGB0,W AARGB2, f AARGB2 AARGB3 _C DALIGN24OK _C AARGB0,F AARGB1,F AARGB2,F 0x01 ; align if necessary ; test for divide by zero

TALIGN24

; clear align increment ; test for alignment

DS00575B-page 46

AN575
MOVWF DALIGN24OK MOVF SUBWF BTFSS GOTO MOVLW ADDWF ADDWF BTFSC GOTO GOTO MOVLW ADDWF ADDWF BTFSS GOTO MOVLW MOVWF RLF RLF RLF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF RLF IORWF BTFSS GOTO BSF GOTO DREST24 MOVF ADDWF MOVF BTFSC INCF ADDWF BCF DECFSZ GOTO BTFSC BTFSS GOTO BCF RLF RLF RLF MOVF SUBWF TEMP BEXP,W EXP,F _C ALTB24 EXPBIAS-1 TEMP,W EXP,F _C SETFOV24 DARGOK24 EXPBIAS-1 TEMP,W EXP,F _C SETFUN24 D’16’ TEMPB1 AARGB3,F AARGB2,F AARGB1,F AARGB0,F TEMP,F BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,F TEMP,LSB DREST24 AARGB3,LSB DOK24 BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB3,LSB TEMPB1,F DLOOP24 FPFLAGS,RND AARGB3,LSB DIV24OK _C AARGB1,F AARGB0,F TEMP,F BARGB1,W AARGB1,F ; restore if necessary ; test for restore ; save align increment ; compare AEXP and BEXP

AGEB24

; set overflow flag

ALTB24

; set underflow flag ; initialize counter

DARGOK24

DLOOP24

; left shift

; subtract

DOK24

DROUND24

; compute next significant bit ; for rounding

; subtract

DS00575B-page 47

AN575
MOVF BTFSS INCFSZ SUBWF RLF IORWF ANDLW ADDWF BTFSC INCF BTFSS GOTO RRF RRF INCF BTFSC GOTO DIV24OK BTFSS BCF MOVF MOVWF MOVF MOVWF RETLW SETFUN24 BSF BTFSS RETLW MOVLW MOVWF CLRF CLRF RLF RRF RETLW SETFDZ24 BSF RETLW BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,W 0x01 AARGB3,F _C AARGB2,F _Z DIV24OK AARGB2,F AARGB3,F EXP,F _Z SETFOV24 SIGN,MSB AARGB2,MSB AARGB2,W AARGB0 AARGB3,W AARGB1 0 FPFLAGS,FUN FPFLAGS,SAT 0xFF 0x01 AEXP AARGB0 AARGB1 SIGN,F AARGB0,F 0xFF FPFLAGS,FDZ 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to smallest floating ; point number = 0x 01 00 00 ; modulo the appropriate sign bit ; test if rounding caused carryout

; test for overflow

; clear explicit MSB if positive

; move result to AARG

; return error code in WREG ; set divide by zero flag

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Floating Point Subtract Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 CALL FPS24

Use:

Output: 24 bit floating point sum in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

2+197 = 199 clks 2+208 = 210 clks 2+213 = 215 clks 2+12 = 14 clks

Min Timing:

DS00575B-page 48

AN575
; PM: 2+112 = 114 DM: 11 ;---------------------------------------------------------------------------------------------FPS24 MOVLW XORWF 0x80 BARGB0,F

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Add Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 CALL FPA24

Use:

Output: 24 bit floating point sum in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

25+28+6*6+5+31+72 = 197 clks 25+28+6*6+5+42+72 = 208 clks 25+28+6*6+5+42+77 = 213 clks 8+4 = 12 clks

Min Timing: PM: 112

DM: 11

;---------------------------------------------------------------------------------------------FPA24 MOVF XORWF MOVWF CLRF CLRF MOVF SUBWF BTFSS GOTO MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF USEA24 MOVF BTFSC RETLW AARGB0,W BARGB0,W TEMP AARGB2 BARGB2 AEXP,W BEXP,W _C USEA24 BEXP,W AARGB4 AEXP,W BEXP AARGB4,W AEXP BARGB0,W AARGB4 AARGB0,W BARGB0 AARGB4,W AARGB0 BARGB1,W AARGB4 AARGB1,W BARGB1 AARGB4,W AARGB1 BEXP,W _Z 0x00 ; return AARG if BARG = 0 ; exclusive or of signs in TEMP

; clear extended byte

; use AARG if AEXP >= BEXP

; use BARG if AEXP < BEXP ; therefore, swap AARG and BARG

DS00575B-page 49

AN575
MOVF MOVWF BSF BSF MOVF SUBWF MOVWF BTFSC GOTO MOVLW SUBWF BTFSS GOTO MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVF MOVWF RETLW ALIGNB24 MOVF BTFSC GOTO BCF RRF RRF RRF DECFSZ GOTO BTFSS GOTO COMF COMF COMF INCF BTFSC INCF BTFSC INCF AARGB0,W SIGN AARGB0,MSB BARGB0,MSB BEXP,W AEXP,W BEXP _Z ALIGNED24 8 BEXP,W _C ALIGNB24 BEXP BARGB1,W BARGB2 BARGB0,W BARGB1 BARGB0 8 BEXP,W _C ALIGNB24 SIGN,W AARGB0 0x00 BEXP,W _Z ALIGNED24 _C BARGB0,F BARGB1,F BARGB2,F BEXP,F ALOOPB24 TEMP,MSB AOK24 BARGB2,F BARGB1,F BARGB0,F BARGB2,F _Z BARGB1,F _Z BARGB0,F ; save sign in SIGN ; make MSB’s explicit

; compute shift count in BEXP

; if BEXP >= 8, do byte shift

; keep for postnormalization

; if BEXP >= 8, BARG = 0 relative to AARG

; already aligned if BEXP = 0

ALOOPB24

; right shift by BEXP

ALIGNED24

; negate if signs opposite

AOK24 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF BTFSC BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F TEMP,MSB

DS00575B-page 50

AN575
GOTO BTFSS GOTO RRF RRF RRF INCFSZ GOTO GOTO ACOMP24 BTFSC GOTO COMF COMF COMF INCF BTFSC INCF BTFSC INCF MOVLW XORWF GOTO ACOMP24 _C NRMRND3224 AARGB0,F AARGB1,F AARGB2,F AEXP,F NRMRND3224 SETFOV24 _C NRM3224 AARGB2,F AARGB1,F AARGB0,F AARGB2,F _Z AARGB1,F _Z AARGB0,F 0x80 SIGN,F NRM24 ; shift right and increment EXP

; normalize and fix sign

; negate, toggle sign bit and ; then normalize

DS00575B-page 51

AN575
NOTES:

DS00575B-page 52

AN575
Please check the Microchip BBS for the latest version of the source code. For BBS access information, see Section 6, Microchip Bulletin Board Service information, page 6-3.

APPENDIX D: PIC17CXXX 24-BIT FLOATING POINT LIBRARY
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; RCS Header \$Id: fp24.a17 2.8 1996/12/21 20:59:37 F.J.Testa Exp \$ \$Revision: 2.8 \$ PIC17 24-BIT FLOATING POINT LIBRARY Unary operations: both input and output are in AEXP,AARG Binary operations: input in AEXP,AARG and BEXP,BARG with output in AEXP,AARG All routines return WREG = 0x00 for successful completion, and WREG = 0xFF for an error condition specified in FPFLAGS. Max timings are worst case cycle counts, while Min timings are non-exception best case cycle counts. Routine FLO1624 FLO24 Max Timing: 0 0 SAT 1 NRM2424 NRM24 55 55 48 Function 16 bit integer to 24 bit floating point conversion

RND 1 48

24 bit normalization of unnormalized 24 bit floating point numbers

Max Timing: 0 0 SAT 1 46 39

RND 1 39 46

INT2416 INT24 Max Timing:

24 bit floating point to 16 bit integer conversion

RND 0 0 SAT 1 58 70 58 1 66

FLO2424 Max Timing:

24 bit integer to 24 bit floating point conversion RND 0 0 SAT 1 64 83 64 1 77

DS00575B-page 53

AN575
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; NRM3224 24 bit normalization of unnormalized 32 bit floating point numbers Max Timing: 0 0 SAT 1 52 71 52 RND 1 65

INT2424 Max Timing:

24 bit floating point to 24 bit integer conversion RND 0 0 SAT 1 71 82 71 1 79

FPA24 Max Timing:

24 bit floating point add RND 0 0 SAT 1 133 152 133 1 146

FPS24 Max Timing:

24 bit floating point subtract RND 0 0 SAT 1 134 153 134 1 147

FPM24 Max Timing:

24 bit floating point multiply RND 0 0 SAT 1 60 79 60 1 72

FPD24 Max Timing:

24 bit floating point divide RND 0 0 SAT 1 176 192 176 1 185

DS00575B-page 54

AN575
;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; ; ; HIGHBYTE 24 bit floating point representation EXPONENT 8 bit biased exponent It is important to note that the use of biased exponents produces a unique representation of a floating point 0, given by EXP = HIGHBYTE = LOWBYTE = 0x00, with 0 being the only number with EXP = 0. 8 bit most significant byte of fraction in sign-magnitude representation, with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB 8 bit least significant byte of sign-magnitude fraction HIGHBYTE S.xxxxxxx | RADIX POINT LOWBYTE xxxxxxxx

LOWBYTE EXPONENT xxxxxxxx

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 16 bit 2’s complement integer right justified in AARGB0, AARGB1 CALL CALL FLO1624 FLO24

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-FLOAT( AARG ) SAT = 0 SAT = 1 AARG = 0

9+39 = 48 clks 9+45 = 54 clks 6+15 = 21 clks 6+20 = 26 clks

Min Timing:

PM: 9+68 = 77

DM: 6

;---------------------------------------------------------------------------------------------FLO1624 FLO24 MOVLW MOVWF MOVPF BTFSS GOTO COMF COMF INFSNZ INCF D’15’+EXPBIAS EXP AARGB0,SIGN AARGB0,MSB NRM24 AARGB1,F AARGB0,F AARGB1,F AARGB0,F ; initialize exponent and add bias ; save sign in SIGN ; test sign ; if < 0, negate, set MSB in SIGN

DS00575B-page 55

AN575
;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 24 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, with sign in SIGN,MSB. CALL CALL NRM2424 NRM24

Use:

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-NORMALIZE( AARG ) SAT = 0 SAT = 1 AARG = 0

3+12+16+8 = 39 clks 3+12+16+15 = 46 clks 10+5 = 15 clks 3+5+4+8 = 20 clks

Min Timing:

PM: 68

DM: 6

;---------------------------------------------------------------------------------------------NRM2424 NRM24 CLRF CPFSGT GOTO TNIB2424 MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM2424 BCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF TNORMUN2424 MOVFP CPFSGT GOTO SUBWF TEMP,W AARGB0 NRM2424A 0xF0 AARGB0,W WREG NORM2424 AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 TEMP,2 _C AARGB0,MSB TNORMUN2424 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN2424 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN2424 AARGB1,F AARGB0,F TEMP,F TEMP,WREG EXP SETFUN24 EXP,F ; clear exponent decrement ; test if highbyte=0

; test if highnibble=0

; if so, shift 4 bits

; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; ; ; ;

if EXP <= decrement in TEMP, floating point underflow has occured otherwise, compute EXP

DS00575B-page 56

AN575
FIXSIGN24 BTFSS BCF RETLW MOVFP CLRF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF BSF NORM2424A BCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF GOTO RES024 CLRF CLRF CLRF CLRF RETLW SIGN,MSB AARGB0,MSB 0 AARGB1,AARGB0 AARGB1,F TEMP,3 AARGB0 RES024 0xF0 AARGB0,W WREG NORM2424A AARGB0,F TEMP,2 _C AARGB0,MSB TNORMUN2424 AARGB0,F TEMP,F AARGB0,MSB TNORMUN2424 AARGB0,F TEMP,F AARGB0,MSB TNORMUN2424 AARGB0,F TEMP,F TNORMUN2424 AARGB0,F AARGB1,F AARGB2,F EXP,F 0 ; clear explicit MSB if positive

NRM2424A

; if so, shift 8 bits by move ; increase decrement by 8 ; if highbyte=0, result=0

; test if highnibble=0

; if so, shift 4 bits ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; result equals zero ; clear extended byte

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 CALL FLO2424

Output: 24 bit floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-FLOAT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

12+52 = 64 clks 12+65 = 77 clks 12+71 = 83 clks 6+24 = 30 clks 6+24 = 30 clks

Min Timing:

PM: 12+121 = 133

DM: 7

;----------------------------------------------------------------------------------------------

DS00575B-page 57

AN575
FLO2424 MOVLW MOVWF MOVPF BTFSS GOTO CLRF COMF COMF COMF INCF ADDWFC ADDWFC D’23’+EXPBIAS EXP AARGB0,SIGN AARGB0,MSB NRM3224 WREG,F AARGB2,F AARGB1,F AARGB0,F AARGB2,F AARGB1,F AARGB0,F ; initialize exponent and add bias ; save sign in SIGN ; test sign ; if < 0, negate, set MSB in SIGN

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 32 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2 with sign in SIGN,MSB. CALL NRM3224

Use:

Output: 24 bit normalized floating point number in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-NORMALIZE( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

21+19+12 = 52 clks 21+19+25 = 65 clks 21+19+31 = 71 clks 4+7+7+5 = 24 clks 3+5+4+8+4 = 24 clks

Min Timing:

PM: 122

DM: 7

;---------------------------------------------------------------------------------------------NRM3224 CLRF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM3224 BCF BTFSC TEMP,W AARGB0 NRM3224A 0xF0 AARGB0,W WREG NORM3224 AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 AARGB2,W 0x0F AARGB1,F AARGB2,W 0xF0 WREG,AARGB2 TEMP,2 _C AARGB0,MSB ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; clear exponent decrement ; test if highbyte=0

TNIB3224

; test if highnibble=0

; if so, shift 4 bits

DS00575B-page 58

AN575
GOTO RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF INCF TNORMUN3224 MOVFP CPFSGT GOTO SUBWF TNORMUN3224 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB2,F AARGB1,F AARGB0,F TEMP,F TEMP,WREG EXP SETFUN24 EXP,F ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; ; ; ;

if EXP <= decrement in TEMP, floating point underflow has occured otherwise, compute EXP

NRMRND3224 BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC BTFSS GOTO RRCF RRCF INFSNZ GOTO GOTO NRM3224A MOVFP MOVFP CLRF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM3224A BCF FPFLAGS,RND AARGB2,MSB FIXSIGN24 _C 0x80 AARGB2 AARGB1,W WREG,F AARGB1,F AARGB0,F _C FIXSIGN24 AARGB0,F AARGB1,F EXP,F SETFOV24 FIXSIGN24 AARGB1,AARGB0 AARGB2,AARGB1 AARGB2,W TEMP,3 AARGB0 NRM3224B 0xF0 AARGB0,W WREG NORM3224A AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 TEMP,2 _C ; increase decrement by 4 ; clear carry bit ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; has rounding caused carryout? ; if so, right shift ; test for floating point overflow

; shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

TNIB3224A

; test if highnibble=0

; if so, shift 4 bits

DS00575B-page 59

AN575
BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF GOTO NRM3224B MOVFP CLRF BCF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF BSF NORM3224B BCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF GOTO AARGB0,MSB TNORMUN3224 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB1,F AARGB0,F TEMP,F TNORMUN3224 AARGB1,AARGB0 AARGB1,W TEMP,3 TEMP,4 AARGB0 RES024 0xF0 AARGB0,W WREG NORM3224B AARGB0,F TEMP,2 _C AARGB0,MSB TNORMUN3224 AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB0,F TEMP,F AARGB0,MSB TNORMUN3224 AARGB0,F TEMP,F TNORMUN3224 ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; shift 8 bits by move ; increase decrement by 8 ; if highbyte=0, result=0

TNIB3224B

; test if highnibble=0

; if so, shift 4 bits ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 24 bit floating point number in AEXP, AARGB0, AARGB1 CALL CALL INT2416 INT24

Output: 16 bit 2’s complement integer right justified in AARGB0, AARGB1 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

10+36+12 = 58 clks 10+36+20 = 66 clks 10+36+24 = 70 clks

DS00575B-page 60

AN575
; ; Min Timing: PM: 127 4 clks DM: 6

;---------------------------------------------------------------------------------------------INT2416 INT24 CLRF CPFSGT RETLW MOVPF BSF MOVLW SUBWF BTFSS GOTO NEGW MOVLW CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO SNIB2416B MOVLW CPFSGT GOTO SWAPF ANDLW MOVPF GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVFP AARGB2,W EXP 0x00 AARGB0,SIGN AARGB0,MSB EXPBIAS+D’15’ EXP,W WREG,MSB SETIOV2416 EXP,F 7 EXP SNIB2416 EXP,F AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F EXP,F SHIFT2416OK EXP SNIB2416A EXP,F AARGB1,AARGB2 AARGB1,F EXP,F SHIFT2416OK 3 EXP SHIFT2416B AARGB2,W 0x0F WREG,AARGB2 SHIFT2416OK _C AARGB2,F EXP,F SHIFT2416OK _C AARGB2,F EXP,F SHIFT2416OK _C AARGB2,F SHIFT2416OK 3 EXP SHIFT2416A EXP,F AARGB1,W WREG,AARGB2 ; test for zero argument ; save sign in SIGN ; make MSB explicit ; remove bias+15 from EXP

; if >= 15, integer overflow ; will occur

; do byte shift if EXP >= 8

; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0

; EXP = EXP - 7 ; save for rounding ; EXP = EXP - 1 ; shift completed if EXP = 0 ; do nibble shift if EXP >= 4

; shift completed if EXP = 0 ; at most 3 right shifts are required

SHIFT2416B

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB2416A

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

DS00575B-page 61

AN575
ANDLW MOVPF DCFSNZ GOTO SHIFT2416A BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVFP ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF 0x0F WREG,AARGB1 EXP,F SHIFT2416OK _C AARGB1,F AARGB2,F EXP,F SHIFT2416OK _C AARGB1,F AARGB2,F EXP,F SHIFT2416OK _C AARGB1,F AARGB2,F SHIFT2416OK 3 EXP SHIFT2416 EXP,F AARGB1,W WREG,AARGB2 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 EXP,F SHIFT2416OK _C AARGB0,F AARGB1,F AARGB2,F EXP,F SHIFT2416OK _C AARGB0,F AARGB1,F AARGB2,F EXP,F SHIFT2416OK _C AARGB0,F AARGB1,F AARGB2,F ; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB2416

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

SHIFT2416

; shift completed if EXP = 0

; shift completed if EXP = 0

SHIFT2416OK BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC BTFSC FPFLAGS,RND AARGB2,MSB INT2416OK _C 0x80 AARGB2 AARGB1,W WREG,F AARGB1,F AARGB0,F AARGB0,MSB ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

DS00575B-page 62

AN575
GOTO INT2416OK BTFSS RETLW COMF COMF INFSNZ INCF RETLW BSF BTFSS RETLW CLRF BTFSS SETF MOVPF RLCF RRCF RETLW SETIOV2416 SIGN,MSB 0 AARGB1,F AARGB0,F AARGB1,F AARGB0,F 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0,F SIGN,MSB AARGB0,F AARGB0,AARGB1 SIGN,F AARGB0,F 0xFF ; if sign bit set, negate

SETIOV2416

; set integer overflow flag ; test for saturation ; return error code in WREG ; ; ; ; saturate to largest two’s complement 16 bit integer SIGN = 0, 0x 7F FF SIGN = 1, 0x 80 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 24 bit floating point number in AEXP, AARGB0, AARGB1 CALL INT2424

Output: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

11+45+15 = 71 clks 11+45+23 = 79 clks 11+45+26 = 82 clks 4 clks

Min Timing: PM: 185

DM: 7

;---------------------------------------------------------------------------------------------INT2424 CLRF CPFSGT RETLW MOVPF BSF CLRF MOVLW SUBWF BTFSS GOTO NEGW MOVLW CPFSGT GOTO SUBWF MOVFP AARGB2,W EXP 0x00 AARGB0,SIGN AARGB0,MSB AARGB3,F EXPBIAS+D’23’ EXP,W WREG,MSB SETIOV2424 EXP,F 7 EXP SNIB2424 EXP,F AARGB2,AARGB3 ; remove bias+23 from EXP ; test for zero argument ; save sign in SIGN ; make MSB explicit

; if >= 23, integer overflow ; will occur

; do byte shift if EXP >= 8

; EXP = EXP - 7 ; save for rounding

DS00575B-page 63

AN575
MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO SNIB2424C MOVLW CPFSGT GOTO SWAPF ANDLW MOVPF GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F EXP,F SHIFT2424OK EXP SNIB2424A EXP,F AARGB2,AARGB3 AARGB1,AARGB2 AARGB1,F EXP,F SHIFT2424OK EXP SNIB2424B EXP,F AARGB2,AARGB3 AARGB2,F EXP,F SHIFT2424OK 3 EXP SHIFT2424C AARGB3,W 0x0F WREG,AARGB3 SHIFT2424OK _C AARGB3,F EXP,F SHIFT2424OK _C AARGB3,F EXP,F SHIFT2424OK _C AARGB3,F SHIFT2424OK 3 EXP SHIFT2424B EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 EXP,F SHIFT2424OK _C AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB2,F

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding ; EXP = EXP - 1 ; shift completed if EXP = 0 ; do nibble shift if EXP >= 4

; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP ; shift completed if EXP = 0

SHIFT2424C

; shift completed if EXP = 0

SNIB2424B

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

SHIFT2424B

; shift completed if EXP = 0

; shift completed if EXP = 0

DS00575B-page 64

AN575
RRCF GOTO SNIB2424A MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT2424A BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO AARGB3,F SHIFT2424OK 3 EXP SHIFT2424A EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 EXP,F SHIFT2424OK _C AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB1,F AARGB2,F AARGB3,F SHIFT2424OK 3 EXP SHIFT2424 EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 EXP,F SHIFT2424OK ; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB2424

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0

DS00575B-page 65

AN575
SHIFT2424 BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT2424OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SHIFT2424OK BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC ADDWFC BTFSC GOTO INT2424OK BTFSS RETLW COMF COMF COMF INCF CLRF ADDWFC ADDWFC RETLW BSF BTFSS RETLW CLRF BTFSS SETF MOVPF MOVPF RLCF RRCF RETLW FPFLAGS,RND AARGB3,MSB INT2424OK _C 0x80 AARGB3 AARGB2,W WREG,F AARGB2,F AARGB1,F AARGB0,F AARGB0,MSB SETIOV2424 SIGN,MSB 0 AARGB2,F AARGB1,F AARGB0,F AARGB2,F WREG,F AARGB1,F AARGB0,F 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0,F SIGN,MSB AARGB0,F AARGB0,AARGB1 AARGB0,AARGB2 SIGN,F AARGB0,F 0xFF ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; if sign bit set, negate

SETIOV2424

; set integer overflow flag ; test for saturation ; return error code in WREG ; ; ; ; saturate to largest two’s complement 24 bit integer SIGN = 0, 0x 7F FF FF SIGN = 1, 0x 80 00 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; Floating Point Multiply Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1

DS00575B-page 66

AN575
; ; ; ; ; ; ; ; ; Use: CALL FPM24

Output: 24 bit floating point product in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG * BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0

19+33+8 = 60 clks 19+33+20 = 72 clks 19+33+27 = 79 clks 5+5 = 10 clks 13+5+23+11 = 52 clks

Min Timing:

PM: 80

DM: 11

;---------------------------------------------------------------------------------------------FPM24 CLRF CPFSEQ CPFSGT GOTO MOVFP XORWF MOVPF MOVFP ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO GOTO MTUN24 SUBWF BTFSS GOTO BSF BSF MOVPF MOVFP MULWF MOVPF MOVFP MULWF MOVPF MOVPF MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF AARGB2,W BEXP AEXP RES024 AARGB0,WREG BARGB0,W WREG,SIGN BEXP,WREG EXP,F EXPBIAS-1 _C MTUN24 EXP,F _C SETFOV24 MOK24 EXP,F _C SETFUN24 AARGB0,MSB BARGB0,MSB AARGB1,TEMPB1 AARGB1,WREG BARGB1 PRODH,AARGB2 AARGB0,WREG BARGB0 PRODH,AARGB0 PRODL,AARGB1 BARGB1 PRODL,WREG AARGB2,F PRODH,WREG AARGB1,F WREG,F AARGB0,F TEMPB1,WREG BARGB0 ; multiply mantissas ; remove bias and overflow test ; test for zero arguments

M24BNE0

; remove bias and underflow test

MOK24

; make argument MSB’s explicit

DS00575B-page 67

AN575
MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC BTFSC GOTO RLCF RLCF RLCF DECF BTFSC GOTO MROUND24 BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC BTFSS GOTO RRCF RRCF INFSNZ GOTO MUL24OK BTFSS BCF RETLW SETFOV24 BSF BTFSS RETLW SETF SETF SETF RLCF RRCF RETLW FPFLAGS,RND AARGB2,MSB MUL24OK _C 0x80 AARGB2 AARGB1,W WREG,F AARGB1,F AARGB0,F _C MUL24OK AARGB0,F AARGB1,F EXP,F SETFOV24 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FOV FPFLAGS,SAT 0xFF AEXP,F AARGB0,F AARGB1,F SIGN,F AARGB0,F 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to largest floating ; point number = 0x FF 7F FF ; modulo the appropriate sign bit ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry PRODL,WREG AARGB2,F PRODH,WREG AARGB1,F WREG,F AARGB0,F AARGB0,MSB MROUND24 AARGB2,F AARGB1,F AARGB0,F EXP,F _Z SETFUN24 ; check for postnormalization

; has rounding caused carryout? ; if so, right shift ; test for floating point overflow

; clear explicit MSB if positive

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; Floating Point Divide Input: 24 bit floating point dividend in AEXP, AARGB0, AARGB1 24 bit floating point divisor in BEXP, BARGB0, BARGB1 CALL FPD24

Use:

Output: 24 bit floating point quotient in AEXP, AARGB0, AARGB1 Result: AARG <-AARG / BARG

DS00575B-page 68

AN575
; ; ; ; ; ; ; Max Timing: 10+12+30+38+67+19 = 176 clks 10+12+30+38+67+28 = 185 clks 10+12+30+38+67+35 = 192 clks 6+5 = 11 clks RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0 DM: 13

Min Timing:

PM: 201+256 = 457

In addition to those registers defined in MATH17.INC, this routine uses TBLPTRL and TBLPTRH without saving and restoring.

;---------------------------------------------------------------------------------------------FPD24SEED ; ; ; ; Timing: macro 12 clks

PM: 11+257 = 268 generation of F0 using 16 bit zeroth degree minimax approximations to the reciprocal of BARG, with the top 8 explicit bits of BARG as a pointer. MOVLW MOVWF RLCF RLCF ADDLW MOVWF BTFSC INCF TABLRD TLRD TLRD endm HIGH (IBTBL256M) TBLPTRH BARGB1,W BARGB0,W LOW (IBTBL256M) TBLPTRL _C TBLPTRH,F 0,1,TEMPB0 1,TEMPB0 0,TEMPB1 ; access table for F0

;---------------------------------------------------------------------------------------------FPD24SEEDS ; ; ; ; ; Timing: macro 64 clks

PM: 62+17 = 79 generation of F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 4 explicit bits of BARG as a pointer and the remaining 11 explicit bits as the argument to linear interpolation. MOVLW MOVWF RLCF SWAPF ANDLW ADDLW MOVWF BTFSC INCF TABLRD TLRD TABLRD TLRD TLRD MOVFP SUBWF MOVWF HIGH (IBTBL16I) TBLPTRH BARGB0,W WREG,F 0x0F LOW (IBTBL16I) TBLPTRL _C TBLPTRH,F 0,1,TEMPB0 1,TEMPB0 0,0,TEMPB1 1,AARGB4 0,AARGB5 AARGB5,WREG TEMPB1,W AARGB5 ; access table for F0

; calculate difference

DS00575B-page 69

AN575
MOVFP SUBWFB MOVWF MOVPF MOVFP ANDLW MOVPF MOVFP MULWF MOVPF MOVFP MULWF MOVPF MOVPF MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC CLRF RRCF RRCF RRCF CLRF RRCF RRCF RRCF CLRF RRCF RRCF RRCF MOVFP SUBWF MOVPF SUBWFB endm ;---------------------------------------------------------------------------------------------FPD24 CLRF CPFSGT GOTO CPFSGT GOTO D24BNE0 MOVFP XORWF TEMPB3,W BEXP SETFDZ24 AEXP RES024 AARGB0,WREG BARGB0,W ; clear exponent modification ; test for divide by zero AARGB4,WREG TEMPB0,W AARGB4 AARGB5,TBLPTRL BARGB0,WREG 0x07 WREG,TEMPB2 AARGB5,WREG BARGB1 PRODL,TBLPTRH AARGB4,WREG TEMPB2 PRODH,AARGB4 PRODL,AARGB5 BARGB1 PRODL,WREG TBLPTRH,F PRODH,WREG AARGB5,F WREG,F AARGB4,F TBLPTRL,WREG TEMPB2 PRODL,WREG TBLPTRH,F PRODH,WREG AARGB5,F WREG,F AARGB4,F _C AARGB4,F AARGB5,F TBLPTRL,F _C AARGB4,F AARGB5,F TBLPTRL,F _C AARGB4,F AARGB5,F TBLPTRL,F TBLPTRL,WREG TEMPB1,F AARGB5,WREG TEMPB0,F

; F0

DS00575B-page 70

AN575

; generation of F0 ; A0 = F0 * A

DS00575B-page 71

AN575

; A1 = F1 * A

DS00575B-page 72

AN575

; if AEXP > BEXP, test for overflow

ALTB24

; if AEXP < BEXP, test for underflow

DROUND24 BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC BTFSS GOTO RRCF FPFLAGS,RND AARGB2,MSB DIV24OK _C 0x80 AARGB2 AARGB1,W WREG,F AARGB1,F AARGB0,F _C DIV24OK AARGB0,F ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; test if rounding caused carryout

DS00575B-page 73

AN575
RRCF INFSNZ GOTO DIV24OK BTFSS BCF RETLW SETFUN24 BSF BTFSS RETLW MOVLW MOVPF CLRF CLRF RLCF RRCF RETLW SETFDZ24 BSF RETLW AARGB1,F EXP,F SETFOV24 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FUN FPFLAGS,SAT 0xFF 0x01 WREG,AEXP AARGB0,F AARGB1,F SIGN,F AARGB0,F 0xFF FPFLAGS,FDZ 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to smallest floating ; point number = 0x 01 00 00 ; modulo the appropriate sign bit ; test for overflow

; clear explicit MSB if positive

; return error code in WREG ; set floating point divide by zero ; flag and return error code in ; WREG

;---------------------------------------------------------------------------------------------; ; ; IBTBL16I DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA ; ; IBTBL256M DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xFF81 0xFE83 0xFD87 0xFC8D 0xFB95 0xFA9E 0xF9AA 0xF8B7 0xF7C7 0xF6D8 0xF5EB 0xF4FF 0xFFFF 0xF0F1 0xE38E 0xD794 0xCCCD 0xC30C 0xBA2F 0xB216 0xAAAB 0xA3D7 0x9D8A 0x97B4 0x9249 0x8D3E 0x8889 0x8421 0x8001 table of 16 bit approximations to the reciprocal of BARG, with the top 4 explicit bits of BARG as a pointer and the remaining 11 explicit bits as the argument to linear interpolation.

table of 16 bit zeroth degree minimax approximations to the reciprocal of BARG, with the top 8 explicit bits of BARG as a pointer.

DS00575B-page 74

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xF416 0xF32E 0xF248 0xF163 0xF080 0xEF9F 0xEEC0 0xEDE2 0xED06 0xEC2B 0xEB52 0xEA7A 0xE9A4 0xE8D0 0xE7FD 0xE72B 0xE65B 0xE58D 0xE4C0 0xE3F4 0xE32A 0xE261 0xE199 0xE0D3 0xE00E 0xDF4B 0xDE89 0xDDC8 0xDD09 0xDC4A 0xDB8D 0xDAD2 0xDA17 0xD95E 0xD8A6 0xD7EF 0xD73A 0xD686 0xD5D2 0xD520 0xD470 0xD3C0 0xD311 0xD264 0xD1B7 0xD10C 0xD062 0xCFB9 0xCF11 0xCE6A 0xCDC4 0xCD1F 0xCC7B 0xCBD8 0xCB37 0xCA96 0xC9F6 0xC957 0xC8B9 0xC81C 0xC780 0xC6E5 0xC64B 0xC5B2 0xC51A 0xC483

DS00575B-page 75

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xC3EC 0xC357 0xC2C2 0xC22E 0xC19C 0xC10A 0xC078 0xBFE8 0xBF59 0xBECA 0xBE3C 0xBDAF 0xBD23 0xBC98 0xBC0D 0xBB84 0xBAFB 0xBA72 0xB9EB 0xB964 0xB8DF 0xB859 0xB7D5 0xB751 0xB6CE 0xB64C 0xB5CB 0xB54A 0xB4CA 0xB44B 0xB3CC 0xB34E 0xB2D1 0xB254 0xB1D8 0xB15D 0xB0E3 0xB069 0xAFF0 0xAF77 0xAEFF 0xAE88 0xAE11 0xAD9B 0xAD26 0xACB1 0xAC3D 0xABC9 0xAB56 0xAAE4 0xAA72 0xAA01 0xA990 0xA920 0xA8B1 0xA842 0xA7D3 0xA766 0xA6F8 0xA68C 0xA620 0xA5B4 0xA549 0xA4DF 0xA475 0xA40C

DS00575B-page 76

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xA3A3 0xA33A 0xA2D2 0xA26B 0xA204 0xA19E 0xA138 0xA0D3 0xA06E 0xA00A 0x9FA6 0x9F43 0x9EE0 0x9E7E 0x9E1C 0x9DBA 0x9D59 0x9CF9 0x9C99 0x9C39 0x9BDA 0x9B7C 0x9B1D 0x9AC0 0x9A62 0x9A05 0x99A9 0x994D 0x98F1 0x9896 0x983B 0x97E1 0x9787 0x972E 0x96D5 0x967C 0x9624 0x95CC 0x9574 0x951D 0x94C7 0x9470 0x941A 0x93C5 0x9370 0x931B 0x92C7 0x9273 0x921F 0x91CC 0x9179 0x9127 0x90D5 0x9083 0x9031 0x8FE0 0x8F90 0x8F3F 0x8EEF 0x8EA0 0x8E50 0x8E02 0x8DB3 0x8D65 0x8D17 0x8CC9

DS00575B-page 77

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0x8C7C 0x8C2F 0x8BE2 0x8B96 0x8B4A 0x8AFE 0x8AB3 0x8A68 0x8A1E 0x89D3 0x8989 0x893F 0x88F6 0x88AD 0x8864 0x881B 0x87D3 0x878B 0x8744 0x86FC 0x86B5 0x866F 0x8628 0x85E2 0x859C 0x8557 0x8511 0x84CC 0x8487 0x8443 0x83FF 0x83BB 0x8377 0x8334 0x82F1 0x82AE 0x826B 0x8229 0x81E7 0x81A5 0x8164 0x8122 0x80E1 0x80A1 0x8060 0x8020

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Floating Point Subtract Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 CALL FPS24

Use:

Output: 24 bit floating point difference in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

1+133 = 134 clks 1+146 = 147 clks 1+152 = 153 clks 1+10 = 11 clks

Min Timing:

DS00575B-page 78

AN575
; PM: 1+298 = 299 DM: 10

;---------------------------------------------------------------------------------------------FPS24 BTG BARGB0,MSB ; toggle sign bit for subtraction

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Add Input: 24 bit floating point number in AEXP, AARGB0, AARGB1 24 bit floating point number in BEXP, BARGB0, BARGB1 CALL FPA24

Use:

Output: 24 bit floating point sum in AEXP, AARGB0, AARGB1 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

81+52 = 133 clks 81+65 = 146 clks 81+71 = 152 clks 10 clks

Min Timing: PM: 298

DM: 10

;---------------------------------------------------------------------------------------------FPA24 MOVFP XORWF MOVPF CLRF MOVFP CPFSGT GOTO USEB24 MOVFP MOVPF BSF BSF MOVFP MOVPF MOVFP MOVPF CLRF CPFSGT GOTO MOVFP SUBWF BTFSC GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ AARGB0,WREG BARGB0,W WREG,TEMP AARGB2,F AEXP,WREG BEXP USEA24 BARGB0,WREG WREG,SIGN BARGB0,MSB AARGB0,MSB AEXP,WREG WREG,TEMPB1 BEXP,WREG WREG,AEXP WREG,F TEMPB1 BRETURN24 TEMPB1,WREG BEXP,F _Z BLIGNED24 7 BEXP BNIB24 BEXP,F AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F BEXP,F ; exclusive or of signs in TEMP

; clear extended byte ; use AARG if AEXP >= BEXP

; use BARG if AEXP < BEXP ; save sign in SIGN ; make MSB’s explicit

; compute shift count in BEXP

; return BARG if AARG = 0

; do byte shift if BEXP >= 8 ; BEXP = BEXP - 7 ; keep for postnormalization

; BEXP = BEXP - 1

DS00575B-page 79

AN575
GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO BRETURN24 MOVFP MOVFP CLRF RETLW MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BLIGNED24 BEXP BNIB24A BEXP,F AARGB1,AARGB2 AARGB1,F BEXP,F BLIGNED24 BEXP BNIB24B SIGN,AARGB0 BARGB1,AARGB1 AARGB2,F 0x00 3 BEXP BLOOP24B BEXP,F AARGB2,W 0x0F WREG,AARGB2 BEXP,F BLIGNED24 _C AARGB2,F BEXP,F BLIGNED24 _C AARGB2,F BEXP,F BLIGNED24 _C AARGB2,F BLIGNED24 3 BEXP BLOOP24A BEXP,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 BEXP,F BLIGNED24 _C AARGB1,F AARGB2,F BEXP,F BLIGNED24 _C AARGB1,F AARGB2,F BEXP,F BLIGNED24 ; do byte shift if BEXP >= 8 ; BEXP = BEXP - 7 ; keep for postnormalization ; BEXP = BEXP - 1

; if BEXP still >= 8, then ; AARG = 0 relative to BARG ; return BARG

BNIB24B

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP24B

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

BNIB24A

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP24A

; aligned if BEXP = 0

; aligned if BEXP = 0

DS00575B-page 80

AN575
BCF RRCF RRCF GOTO BNIB24 MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF CLRF BTFSS GOTO COMF COMF COMF INCF ADDWFC ADDWFC GOTO TSTFSZ GOTO RETLW CLRF MOVPF BSF BSF MOVFP SUBWF _C AARGB1,F AARGB2,F BLIGNED24 3 BEXP BLOOP24 BEXP,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 BEXP,F BLIGNED24 _C AARGB0,F AARGB1,F AARGB2,F BEXP,F BLIGNED24 _C AARGB0,F AARGB1,F AARGB2,F BEXP,F BLIGNED24 _C AARGB0,F AARGB1,F AARGB2,F BARGB2,W TEMP,MSB AOK24 AARGB2,F AARGB1,F AARGB0,F AARGB2,F AARGB1,F AARGB0,F AOK24 BEXP BNE024 0x00 BARGB2,F AARGB0,SIGN AARGB0,MSB BARGB0,MSB BEXP,WREG AEXP,W ; at most 3 right shifts are ; possible

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP24

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

BLIGNED24

; negate if signs opposite

USEA24

; return AARG if BARG = 0

BNE024

; compute shift count in BEXP

DS00575B-page 81

AN575
MOVPF BTFSC GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVPF MOVFP MOVPF CLRF DCFSNZ GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVPF CLRF DCFSNZ GOTO MOVLW CPFSGT GOTO MOVFP RETLW ANIB24B MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW WREG,BEXP _Z ALIGNED24 7 BEXP ANIB24 BEXP,F BARGB1,WREG WREG,BARGB2 BARGB0,WREG WREG,BARGB1 BARGB0,F BEXP,F ALIGNED24 7 BEXP ANIB24A BEXP,F BARGB1,WREG WREG,BARGB2 BARGB1,F BEXP,F ALIGNED24 7 BEXP ANIB24B SIGN,AARGB0 0x00 3 BEXP ALOOP24B BEXP,F BARGB2,W 0x0F WREG,BARGB2 BEXP,F ALIGNED24 _C BARGB2,F BEXP,F ALIGNED24 _C BARGB2,F BEXP,F ALIGNED24 _C BARGB2,F ALIGNED24 3 BEXP ALOOP24A BEXP,F BARGB2,W 0x0F WREG,BARGB2 BARGB1,W 0xF0

; do byte shift if BEXP >= 8

; BEXP = BEXP - 7 ; keep for postnormalization

; BEXP = BEXP - 1

; if BEXP still >= 8, then ; BARG = 0 relative to AARG ; BEXP = BEXP - 7 ; keep for postnormalization ; BEXP = BEXP - 1

; if BEXP still >= 8, then ; BARG = 0 relative to AARG ; return AARG

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

ALOOP24B

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ANIB24A

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

DS00575B-page 82

AN575
ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO ALOOP24A BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF CLRF BTFSS GOTO COMF COMF BARGB2,F BARGB1,W 0x0F WREG,BARGB1 BEXP,F ALIGNED24 _C BARGB1,F BARGB2,F BEXP,F ALIGNED24 _C BARGB1,F BARGB2,F BEXP,F ALIGNED24 _C BARGB1,F BARGB2,F ALIGNED24 3 BEXP ALOOP24 BEXP,F BARGB2,W 0x0F WREG,BARGB2 BARGB1,W 0xF0 BARGB2,F BARGB1,W 0x0F WREG,BARGB1 BARGB0,W 0xF0 BARGB1,F BARGB0,W 0x0F WREG,BARGB0 BEXP,F ALIGNED24 _C BARGB0,F BARGB1,F BARGB2,F BEXP,F ALIGNED24 _C BARGB0,F BARGB1,F BARGB2,F BEXP,F ALIGNED24 _C BARGB0,F BARGB1,F BARGB2,F AARGB2,W TEMP,MSB AOK24 BARGB2,F BARGB1,F

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ANIB24

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

ALOOP24

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ALIGNED24

; negate if signs opposite

DS00575B-page 83

AN575
COMF INCF ADDWFC ADDWFC AOK24 MOVFP ADDWF MOVFP ADDWFC MOVFP ADDWFC BTFSC GOTO BTFSS GOTO RRCF RRCF RRCF INCFSZ GOTO GOTO ACOMP24 BTFSC GOTO COMF COMF COMF INCF CLRF ADDWFC ADDWFC BTG GOTO BARGB0,F BARGB2,F BARGB1,F BARGB0,F BARGB2,WREG AARGB2,F BARGB1,WREG AARGB1,F BARGB0,WREG AARGB0,F TEMP,MSB ACOMP24 _C NRMRND3224 AARGB0,F AARGB1,F AARGB2,F AEXP,F NRMRND3224 SETFOV24 _C NRM3224 AARGB2,F AARGB1,F AARGB0,F AARGB2,F WREG,F AARGB1,F AARGB0,F SIGN,MSB NRM3224 ; shift right and increment EXP

; set floating point overflow flag

; normalize and fix sign ; negate, toggle sign bit and ; then normalize

DS00575B-page 84

AN575
Please check the Microchip BBS for the latest version of the source code. For BBS access information, see Section 6, Microchip Bulletin Board Service information, page 6-3.

APPENDIX E: PIC16CXXX 32-BIT FLOATING POINT LIBRARY
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; RCS Header \$Id: fp32.a16 2.8 1996/10/07 13:50:59 F.J.Testa Exp \$ \$Revision: 2.8 \$ PIC16 32-BIT FLOATING POINT LIBRARY Unary operations: both input and output are in AEXP,AARG Binary operations: input in AEXP,AARG and BEXP,BARG with output in AEXP,AARG All routines return WREG = 0x00 for successful completion, and WREG = 0xFF for an error condition specified in FPFLAGS. All timings are worst case cycle counts Routine FLO2432 FLO32 Timing: 0 0 SAT 1 NRM3232 NRM32 110 110 104 Function 24 bit integer to 32 bit floating point conversion

RND 1 104

32 bit normalization of unnormalized 32 bit floating point numbers

Timing: 0 0 SAT 1 96 90

RND 1 90 96

INT3224 INT32

32 bit floating point to 24 bit integer conversion

Timing: 0 0 SAT 1 104 104

RND 1 112 114

FLO3232 32 bit integer to 32 bit floating point conversion Timing: 0 0 SAT 1 129 152 129 RND 1 145

DS00575B-page 85

AN575
; NRM4032 32 bit normalization of unnormalized 40 bit floating point numbers ; ; Timing: RND ; 0 1 ; ; 0 112 128 ; SAT ; 1 112 135 ; ; ; INT3232 32 bit floating point to 32 bit integer conversion ; ; ; Timing: RND ; 0 1 ; ; 0 130 137 ; SAT ; 1 130 137 ; ; FPA32 32 bit floating point add ; ; Timing: RND ; 0 1 ; ; 0 251 265 ; SAT ; 1 251 271 ; ; FPS32 32 bit floating point subtract ; ; Timing: RND ; 0 1 ; ; 0 253 267 ; SAT ; 1 253 273 ; ; FPM32 32 bit floating point multiply ; ; Timing: RND ; 0 1 ; ; 0 574 588 ; SAT ; 1 574 591 ; ; FPD32 32 bit floating point divide ; ; Timing: RND ; 0 1 ; ; 0 932 968 ; SAT ; 1 932 971 ; ; ;********************************************************************************************** ;********************************************************************************************** ; ; 32 bit floating point representation ; ; EXPONENT 8 bit biased exponent ; ; It is important to note that the use of biased exponents produces ; a unique representation of a floating point 0, given by

DS00575B-page 86

AN575
; EXP = HIGHBYTE = MIDBYTE = LOWBYTE = 0x00, with 0 being ; the only number with EXP = 0. ; ; HIGHBYTE 8 bit most significant byte of fraction in sign-magnitude representation, ; with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB ; ; MIDBYTE 8 bit middle significant byte of sign-magnitude fraction ; ; LOWBYTE 8 bit least significant byte of sign-magnitude fraction ; ; EXPONENT HIGHBYTE MIDBYTE LOWBYTE ; ; xxxxxxxx S.xxxxxxx xxxxxxxx xxxxxxxx ; ; | ; RADIX ; POINT ; ; ;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 CALL FLO2432 or CALL FLO32

Output: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-FLOAT( AARG ) SAT = 0 SAT = 1 AARG = 0

14+90 = 104 clks 14+96 = 110 clks 6+28 = 34 clks 6+18 = 24 clks

Min Timing:

PM: 14+38 = 52

DM: 7

;---------------------------------------------------------------------------------------------FLO2432 FLO32

MOVLW MOVWF CLRF BTFSS GOTO COMF COMF COMF INCF BTFSC INCF BTFSC INCF BSF

D’23’+EXPBIAS EXP SIGN AARGB0,MSB NRM3232 AARGB2,F AARGB1,F AARGB0,F AARGB2,F _Z AARGB1,F _Z AARGB0,F SIGN,MSB

; initialize exponent and add bias

; test sign ; if < 0, negate and set MSB in SIGN

DS00575B-page 87

AN575
;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 32 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2, with sign in SIGN,MSB CALL NRM3232 or CALL NRM32

Use:

Output: 32 bit normalized floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-NORMALIZE( AARG ) SAT = 0 SAT = 1 AARG = 0

21+6+7*8+7 = 90 clks 21+6+7*8+1+12 = 96 clks 22+6 = 28 clks 5+9+4 = 18 clks

Min Timing:

PM: 38

DM: 7

;---------------------------------------------------------------------------------------------NRM3232 NRM32 CLRF MOVF BTFSS GOTO MOVF MOVWF MOVF MOVWF CLRF BSF MOVF BTFSS GOTO MOVF MOVWF CLRF BCF BSF MOVF BTFSC GOTO NORM3232 MOVF SUBWF BTFSS BTFSS GOTO BCF NORM3232A BTFSC GOTO RLF RLF RLF DECFSZ GOTO GOTO TEMP AARGB0,W _Z NORM3232 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 AARGB0,W _Z NORM3232 AARGB1,W AARGB0 AARGB1 TEMP,3 TEMP,4 AARGB0,W _Z RES032 TEMP,W EXP,F _Z _C SETFUN32 _C AARGB0,MSB FIXSIGN32 AARGB2,F AARGB1,F AARGB0,F EXP,F NORM3232A SETFUN32 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; decrement EXP ; clear exponent decrement ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8

; if highbyte=0, result=0

; underflow if EXP=0

DS00575B-page 88

AN575
FIXSIGN32 BTFSS BCF RETLW CLRF CLRF CLRF CLRF CLRF RETLW SIGN,MSB AARGB0,MSB 0 AARGB0 AARGB1 AARGB2 AARGB3 EXP 0 ; clear explicit MSB if positive

RES032

; result equals zero

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: 32 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2, AARGB3 CALL FLO3232

Use:

Output: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-FLOAT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

17+112 = 129 clks 17+128 = 145 clks 17+135 = 152 clks 6+39 = 45 clks 6+22 = 28 clks

Min Timing:

PM: 17+66 = 83

DM: 8

;---------------------------------------------------------------------------------------------FLO3232 MOVLW MOVWF CLRF BTFSS GOTO COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF BSF D’31’+EXPBIAS EXP SIGN AARGB0,MSB NRM4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F SIGN,MSB ; initialize exponent and add bias

; test sign ; if < 0, negate and set MSB in SIGN

DS00575B-page 89

AN575
;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 40 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2, AARGB3 with sign in SIGN,MSB CALL NRM4032

Use:

Output: 32 bit normalized floating point number in AEXP, AARGB0, AARGB1, AARGB2, AARGB3 Result: AARG Max Timing: <-NORMALIZE( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

38+6*9+12+8 = 112 clks 38+6*9+12+24 = 128 clks 38+6*9+12+31 = 135 clks 33+6 = 39 clks 5+9+8 = 22 clks

Min Timing:

PM: 66

DM: 8

;---------------------------------------------------------------------------------------------NRM4032 CLRF MOVF BTFSS GOTO MOVF MOVWF MOVF MOVWF MOVF MOVWF CLRF BSF MOVF BTFSS GOTO MOVF MOVWF MOVF MOVWF CLRF BCF BSF MOVF BTFSS GOTO MOVF MOVWF CLRF BSF MOVF BTFSC GOTO NORM4032 MOVF SUBWF BTFSS BTFSS GOTO TEMP AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB3,W AARGB2 AARGB3 TEMP,3 AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB2,W AARGB1 AARGB2 TEMP,3 TEMP,4 AARGB0,W _Z NORM4032 AARGB1,W AARGB0 AARGB1 TEMP,3 AARGB0,W _Z RES032 TEMP,W EXP,F _Z _C SETFUN32 ; clear exponent decrement ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8

; test if highbyte=0

; if so, shift 8 bits by move

; increase decrement by 8 ; if highbyte=0, result=0

DS00575B-page 90

AN575
BCF NORM4032A BTFSC GOTO RLF RLF RLF RLF DECFSZ GOTO GOTO NRMRND4032 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSS GOTO RRF RRF RRF INCF BTFSC GOTO GOTO _C AARGB0,MSB NRMRND4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F EXP,F NORM4032A SETFUN32 FPFLAGS,RND AARGB2,LSB FIXSIGN32 AARGB3,MSB FIXSIGN32 AARGB2,F _Z AARGB1,F _Z AARGB0,F _Z FIXSIGN32 AARGB0,F AARGB1,F AARGB2,F EXP,F _Z SETFOV32 FIXSIGN32 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; decrement EXP

; underflow if EXP=0

; round if next bit is set

; has rounding caused carryout? ; if so, right shift

; check for overflow

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 CALL INT3224 or CALL INT32

Output: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

40+6*7+6+16 = 104 clks 40+6*7+6+24 = 112 clks 40+6*7+6+26 = 114 clks 4 clks

Min Timing: PM: 82

DM: 6

;---------------------------------------------------------------------------------------------INT3224 INT32 MOVF BTFSC RETLW MOVF MOVWF EXP,W _Z 0x00 AARGB0,W SIGN ; test for zero argument

DS00575B-page 91

AN575
BSF MOVLW SUBWF BTFSS GOTO COMF INCF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF CLRF MOVF BTFSS BCF GOTO TSHIFT3224 MOVF BTFSC GOTO BCF RRF RRF RRF DECFSZ GOTO BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSC GOTO AARGB0,MSB EXPBIAS+D’23’ EXP,F EXP,MSB SETIOV3224 EXP,F EXP,F 8 EXP,W _C TSHIFT3224 EXP AARGB2,F AARGB1,W AARGB2 AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT3224 EXP AARGB2,F AARGB1,W AARGB2 AARGB1 8 EXP,W _C TSHIFT3224 EXP AARGB2,F AARGB2 EXP,W _Z _C SHIFT3224OK EXP,W _Z SHIFT3224OK _C AARGB0,F AARGB1,F AARGB2,F EXP,F SHIFT3224 FPFLAGS,RND AARGB2,LSB INT3224OK _C INT3224OK AARGB2,F _Z AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV3224 ; make MSB explicit ; remove bias from EXP

; do byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; shift completed if EXP = 0

SHIFT3224

; right shift by EXP

SHIFT3224OK

; test for overflow

DS00575B-page 92

AN575
INT3224OK BTFSS RETLW COMF COMF COMF INCF BTFSC INCF BTFSC INCF RETLW CLRF CLRF CLRF RETLW BSF BTFSS RETLW CLRF BTFSS MOVLW MOVWF MOVWF MOVWF RLF RRF RETLW SIGN,MSB 0 AARGB0,F AARGB1,F AARGB2,F AARGB2,F _Z AARGB1,F _Z AARGB0,F 0 AARGB0 AARGB1 AARGB2 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF ; if sign bit set, negate

IRES03224

; integer result equals zero

SETIOV3224

; set integer overflow flag ; test for saturation ; return error code in WREG ; saturate to largest two’s ; complement 24 bit integer ; SIGN = 0, 0x 7F FF FF ; SIGN = 1, 0x 80 00 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 CALL INT3232

Output: 32 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2, AARGB3 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

54+6*8+7+21 = 130 clks 54+6*8+7+29 = 137 clks 54+6*8+7+29 = 137 clks 5 clks

Min Timing: PM: 102

DM: 7

;---------------------------------------------------------------------------------------------INT3232 CLRF MOVF BTFSC RETLW MOVF MOVWF BSF AARGB3 EXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB ; test for zero argument

DS00575B-page 93

AN575
MOVLW SUBWF BTFSS GOTO COMF INCF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVWF RLF CLRF MOVF BTFSS BCF GOTO TSHIFT3232 MOVF BTFSC GOTO BCF RRF RRF RRF RRF DECFSZ GOTO EXPBIAS+D’31’ EXP,F EXP,MSB SETIOV32 EXP,F EXP,F 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB2,W AARGB3 AARGB1,W AARGB2 AARGB0,W AARGB1 AARGB0 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB2,W AARGB3 AARGB1,W AARGB2 AARGB1 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB2,W AARGB3 AARGB2 8 EXP,W _C TSHIFT3232 EXP AARGB3,F AARGB3 EXP,W _Z _C SHIFT3232OK EXP,W _Z SHIFT3232OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT3232 ; remove bias from EXP

; do byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; do another byte shift if EXP >= 8

; rotate next bit for rounding

; shift completed if EXP = 0

SHIFT3232

; right shift by EXP

DS00575B-page 94

AN575
SHIFT3232OK BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSC INCF BTFSC GOTO BTFSS RETLW COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF RETLW CLRF CLRF CLRF CLRF RETLW BSF BTFSS RETLW CLRF BTFSS MOVLW MOVWF MOVWF MOVWF MOVWF RLF RRF RETLW FPFLAGS,RND AARGB3,LSB INT3232OK _C INT3232OK AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F AARGB0,MSB SETIOV3224 SIGN,MSB 0 AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F 0 AARGB0 AARGB1 AARGB2 AARGB3 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0 SIGN,MSB 0xFF AARGB0 AARGB1 AARGB2 AARGB3 SIGN,F AARGB0,F 0xFF

; test for overflow

INT3232OK

; if sign bit set, negate

IRES032

; integer result equals zero

SETIOV32

; set integer overflow flag ; test for saturation ; return error code in WREG ; saturate to largest two’s ; complement 32 bit integer ; SIGN = 0, 0x 7F FF FF FF ; SIGN = 1, 0x 80 00 00 00

; return error code in WREG

DS00575B-page 95

AN575
;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Floating Point Multiply Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPM32

Use:

Output: 32 bit floating point product in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG * BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0

26+23*22+21+21 = 574 clks 26+23*22+21+35 = 588 clks 26+23*22+21+38 = 591 clks 6+6 = 12 clks 24+23*11+21+17 = 315 clks

Min Timing:

PM: 94

DM: 14

;---------------------------------------------------------------------------------------------FPM32 MOVF BTFSS MOVF BTFSC GOTO MOVF XORWF MOVWF MOVF ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO GOTO MTUN32 SUBWF BTFSS GOTO MOVF MOVWF MOVF MOVWF MOVF MOVWF BSF BSF BCF CLRF CLRF CLRF MOVLW MOVWF BTFSS AEXP,W _Z BEXP,W _Z RES032 AARGB0,W BARGB0,W SIGN BEXP,W EXP,F EXPBIAS-1 _C MTUN32 EXP,F _C SETFOV32 MOK32 EXP,F _C SETFUN32 AARGB0,W AARGB3 AARGB1,W AARGB4 AARGB2,W AARGB5 AARGB3,MSB BARGB0,MSB _C AARGB0 AARGB1 AARGB2 D’24’ TEMP AARGB5,LSB ; test for zero arguments

M32BNE0

; set multiply overflow flag

MOK32

; make argument MSB’s explicit

; clear initial partial product

; initialize counter ; test next bit

MLOOP32

DS00575B-page 96

AN575
GOTO MADD32 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF MNOADD32 RRF RRF RRF RRF RRF RRF BCF DECFSZ GOTO BTFSC GOTO RLF RLF RLF RLF DECF MROUND32 BTFSC BTFSS GOTO BTFSS GOTO INCF BTFSC INCF BTFSC INCF BTFSS GOTO RRF RRF RRF INCF BTFSC GOTO MUL32OK BTFSS BCF RETLW SETFOV32 BSF BTFSS RETLW MOVLW MOVWF MOVWF MOVWF MOVWF MNOADD32 BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB4,F AARGB5,F _C TEMP,F MLOOP32 AARGB0,MSB MROUND32 AARGB3,F AARGB2,F AARGB1,F AARGB0,F EXP,F FPFLAGS,RND AARGB2,LSB MUL32OK AARGB3,MSB MUL32OK AARGB2,F _Z AARGB1,F _Z AARGB0,F _Z MUL32OK AARGB0,F AARGB1,F AARGB2,F EXP,F _Z SETFOV32 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FOV FPFLAGS,SAT 0xFF 0xFF AEXP AARGB0 AARGB1 AARGB2 ; set floating point underflag ; test for saturation ; return error code in WREG ; has rounding caused carryout? ; if so, right shift ; check for postnormalization

; check for overflow

; clear explicit MSB if positive

; saturate to largest floating ; point number = 0x FF 7F FF FF ; modulo the appropriate sign bit

DS00575B-page 97

AN575
RLF RRF RETLW SIGN,F AARGB0,F 0xFF ; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Divide Input: 32 bit floating point dividend in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point divisor in BEXP, BARGB0, BARGB1, BARGB2 CALL FPD32

Use:

Output: 32 bit floating point quotient in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG / BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

43+12+23*36+35+14 = 932 clks 43+12+23*36+35+50 = 968 clks 43+12+23*36+35+53 = 971 clks 7+6 = 13 clks

Min Timing: PM: 155

DM: 14

;---------------------------------------------------------------------------------------------FPD32 MOVF BTFSC GOTO MOVF BTFSC GOTO D32BNE0 MOVF XORWF MOVWF BSF BSF CLRF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF SUBWF MOVF BTFSS INCFSZ TS1ALIGN32 SUBWF MOVF BTFSS INCFSZ SUBWF CLRF CLRF CLRF BEXP,W _Z SETFDZ32 AEXP,W _Z RES032 AARGB0,W BARGB0,W SIGN AARGB0,MSB BARGB0,MSB TEMP AARGB0,W AARGB3 AARGB1,W AARGB4 AARGB2,W AARGB5 BARGB2,W AARGB5,F BARGB1,W _C BARGB1,W AARGB4,F BARGB0,W _C BARGB0,W AARGB3,F AARGB3 AARGB4 AARGB5 ; test for divide by zero

TALIGN32

; clear align increment ; test for alignment

TS2ALIGN32

DS00575B-page 98

AN575
BTFSS GOTO BCF RRF RRF RRF RRF MOVLW MOVWF DALIGN32OK MOVF SUBWF BTFSS GOTO MOVLW ADDWF ADDWF BTFSC GOTO GOTO MOVLW ADDWF ADDWF BTFSS GOTO MOVLW MOVWF RLF RLF RLF RLF RLF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF MOVF BTFSS INCFSZ SUBWF RLF IORWF BTFSS GOTO BSF GOTO DREST32 MOVF ADDWF MOVF BTFSC _C DALIGN32OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F 0x01 TEMP BEXP,W EXP,F _C ALTB32 EXPBIAS-1 TEMP,W EXP,F _C SETFOV32 DARGOK32 EXPBIAS-1 TEMP,W EXP,F _C SETFUN32 D’24’ TEMPB1 AARGB5,F AARGB4,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F TEMP,F BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,F TEMP,LSB DREST32 AARGB5,LSB DOK32 BARGB2,W AARGB2,F BARGB1,W _C ; restore if necessary ; test for restore ; align if necessary

; save align increment ; compare AEXP and BEXP

AGEB32

; set overflow flag

ALTB32

; set underflow flag ; initialize counter

DARGOK32

DLOOP32

; left shift

; subtract

DS132

DS232

DS00575B-page 99

AN575
DAREST32 INCFSZ ADDWF MOVF BTFSC INCF ADDWF BCF DOK32 DECFSZ GOTO BTFSC BTFSS GOTO BCF RLF RLF RLF RLF MOVF SUBWF MOVF BTFSS INCFSZ SUBWF MOVF BTFSS INCFSZ SUBWF RLF IORWF ANDLW ADDWF BTFSC INCF BTFSC INCF BTFSS GOTO RRF RRF RRF INCF BTFSC GOTO BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F AARGB5,LSB TEMPB1,F DLOOP32 FPFLAGS,RND AARGB5,LSB DIV32OK _C AARGB2,F AARGB1,F AARGB0,F TEMP,F BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F BARGB0,W TEMP,W 0x01 AARGB5,F _C AARGB4,F _Z AARGB3,F _Z DIV32OK AARGB3,F AARGB4,F AARGB5,F EXP,F _Z SETFOV32 ; test if rounding caused carryout

DROUND32

; compute next significant bit ; for rounding

; subtract

; test for overflow

DIV32OK

BTFSS BCF MOVF MOVWF MOVF MOVWF MOVF MOVWF RETLW

SIGN,MSB AARGB3,MSB AARGB3,W AARGB0 AARGB4,W AARGB1 AARGB5,W AARGB2 0

; clear explicit MSB if positive

; move result to AARG

DS00575B-page 100

AN575
SETFUN32 BSF BTFSS RETLW MOVLW MOVWF CLRF CLRF CLRF RLF RRF RETLW SETFDZ32 BSF RETLW FPFLAGS,FUN FPFLAGS,SAT 0xFF 0x01 AEXP AARGB0 AARGB1 AARGB2 SIGN,F AARGB0,F 0xFF FPFLAGS,FDZ 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to smallest floating ; point number = 0x 01 00 00 00 ; modulo the appropriate sign bit

; return error code in WREG ; set divide by zero flag

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Subtract Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPS32

Use:

Output: 32 bit floating point sum in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

2+251 = 253 clks 2+265 = 267 clks 2+271 = 273 clks 2+12 = 14 clks

Min Timing: PM: 2+146 = 148

DM: 14

;---------------------------------------------------------------------------------------------FPS32 MOVLW XORWF 0x80 BARGB0,F

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Add Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPA32

Use:

Output: 32 bit floating point sum in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

31+41+6*7+6+41+90 = 251 clks 31+41+6*7+6+55+90 = 265 clks 31+41+6*7+6+55+96 = 271 clks 8+4 = 12 clks

Min Timing: PM: 146

DM: 14

;----------------------------------------------------------------------------------------------

DS00575B-page 101

AN575
FPA32 MOVF XORWF MOVWF CLRF CLRF MOVF SUBWF BTFSS GOTO MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF USEA32 MOVF BTFSC RETLW MOVF MOVWF BSF BSF MOVF SUBWF MOVWF BTFSC GOTO MOVLW SUBWF BTFSS GOTO MOVWF MOVF MOVWF MOVF MOVWF MOVF MOVWF AARGB0,W BARGB0,W TEMP AARGB3 BARGB3 AEXP,W BEXP,W _C USEA32 BEXP,W AARGB5 AEXP,W BEXP AARGB5,W AEXP BARGB0,W AARGB5 AARGB0,W BARGB0 AARGB5,W AARGB0 BARGB1,W AARGB5 AARGB1,W BARGB1 AARGB5,W AARGB1 BARGB2,W AARGB5 AARGB2,W BARGB2 AARGB5,W AARGB2 BEXP,W _Z 0x00 AARGB0,W SIGN AARGB0,MSB BARGB0,MSB BEXP,W AEXP,W BEXP _Z ALIGNED32 8 BEXP,W _C ALIGNB32 BEXP BARGB2,W BARGB3 BARGB1,W BARGB2 BARGB0,W BARGB1 ; return AARG if BARG = 0 ; exclusive or of signs in TEMP

; clear extended byte

; use AARG if AEXP >= BEXP

; use BARG if AEXP < BEXP ; therefore, swap AARG and BARG

; compute shift count in BEXP

; if BEXP >= 8, do byte shift

; keep for postnormalization

DS00575B-page 102

AN575
CLRF MOVLW SUBWF BTFSS GOTO MOVWF MOVF MOVWF MOVF MOVWF CLRF MOVLW SUBWF BTFSS GOTO MOVF MOVWF RETLW ALIGNB32 MOVF BTFSC GOTO BCF RRF RRF RRF RRF DECFSZ GOTO BTFSS GOTO COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF AOK32 MOVF ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF MOVF BTFSC INCFSZ ADDWF BTFSC GOTO BARGB3,W AARGB3,F BARGB2,W _C BARGB2,W AARGB2,F BARGB1,W _C BARGB1,W AARGB1,F BARGB0,W _C BARGB0,W AARGB0,F TEMP,MSB ACOMP32 BARGB0 8 BEXP,W _C ALIGNB32 BEXP BARGB2,W BARGB3 BARGB1,W BARGB2 BARGB1 8 BEXP,W _C ALIGNB32 SIGN,W AARGB0 0x00 BEXP,W _Z ALIGNED32 _C BARGB0,F BARGB1,F BARGB2,F BARGB3,F BEXP,F ALOOPB32 TEMP,MSB AOK32 BARGB3,F BARGB2,F BARGB1,F BARGB0,F BARGB3,F _Z BARGB2,F _Z BARGB1,F _Z BARGB0,F

; if BEXP >= 8, do byte shift

; keep for postnormalization

; if BEXP >= 8, BARG = 0 relative to AARG

; already aligned if BEXP = 0

ALOOPB32

; right shift by BEXP

ALIGNED32

; negate if signs opposite

DS00575B-page 103

AN575
BTFSS GOTO RRF RRF RRF RRF INCFSZ GOTO GOTO ACOMP32 BTFSC GOTO COMF COMF COMF COMF INCF BTFSC INCF BTFSC INCF BTFSC INCF MOVLW XORWF GOTO _C NRMRND4032 AARGB0,F AARGB1,F AARGB2,F AARGB3,F AEXP,F NRMRND4032 SETFOV32 _C NRM4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F _Z AARGB2,F _Z AARGB1,F _Z AARGB0,F 0x80 SIGN,F NRM32 ; shift right and increment EXP

; normalize and fix sign

; negate, toggle sign bit and ; then normalize

DS00575B-page 104

AN575
Please check the Microchip BBS for the latest version of the source code. For BBS access information, see Section 6, Microchip Bulletin Board Service information, page 6-3.

APPENDIX F: PIC17CXXX 32-BIT FLOATING POINT LIBRARY
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; RCS Header \$Id: fp32.a17 2.8 1996/12/21 20:59:37 F.J.Testa Exp \$ \$Revision: 2.8 \$ PIC17 32-BIT FLOATING POINT LIBRARY Unary operations: both input and output are in AEXP,AARG Binary operations: input in AEXP,AARG and BEXP,BARG with output in AEXP,AARG All routines return WREG = 0x00 for successful completion, and WREG = 0xFF for an error condition specified in FPFLAGS. Max timings are worst case cycle counts, while Min timings are non-exception best case cycle counts. Routine FLO2432 FLO32 Function 24 bit integer to 32 bit floating point conversion

Timing: 0 0 SAT 1 NRM3232 NRM32 67 60

RND 1 60 67

32 bit normalization of unnormalized 32 bit floating point numbers

Timing: 0 0 SAT 1 55 48

RND 1 48 55

INT3224 INT32 Timing:

32 bit floating point to 24 bit integer conversion

RND 0 0 70 70 1 79 81

SAT 1

FLO3232

32 bit integer to 32 bit floating point conversion Timing: 0 0 SAT 1 75 97 75 RND 1 91

DS00575B-page 105

AN575
; NRM4032 32 bit normalization of unnormalized 40 bit floating point numbers ; ; Timing: RND ; 0 1 ; ; 0 61 77 ; SAT ; 1 61 83 ; ; ; INT3232 32 bit floating point to 32 bit integer conversion ; ; Timing: RND ; 0 1 ; ; 0 82 91 ; SAT ; 1 82 93 ; ; FPA32 32 bit floating point add ; ; Timing: RND ; 0 1 ; ; 0 160 176 ; SAT ; 1 160 182 ; ; FPS32 32 bit floating point subtract ; ; Timing: RND ; 0 1 ; ; 0 161 177 ; SAT ; 1 161 183 ; ; FPM32 32 bit floating point multiply ; ; Timing: RND ; 0 1 ; ; 0 100 114 ; SAT ; 1 100 122 ; ; FPD32 32 bit floating point divide ; ; Timing: RND ; 0 1 ; ; 0 323 337 ; SAT ; 1 323 345 ; ; ;**********************************************************************************************

DS00575B-page 106

AN575
;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; HIGHBYTE 32 bit floating point representation EXPONENT 8 bit biased exponent It is important to note that the use of biased exponents produces a unique representation of a floating point 0, given by EXP = HIGHBYTE = MIDBYTE = LOWBYTE = 0x00, with 0 being the only number with EXP = 0. 8 bit most significant byte of fraction in sign-magnitude representation, with SIGN = MSB, implicit MSB = 1 and radix point to the right of MSB 8 bit middle significant byte of sign-magnitude fraction 8 bit least significant byte of sign-magnitude fraction HIGHBYTE S.xxxxxxx | RADIX POINT MIDBYTE xxxxxxxx LOWBYTE xxxxxxxx

MIDBYTE LOWBYTE EXPONENT xxxxxxxx

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: Use: 24 bit 2’s complement integer right justified in AARGB0,AARGB1, AARGB2 CALL FLO2432 or CALL FLO32

Output: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-FLOAT( AARG ) SAT = 0 SAT = 1 AARG = 0

12+48 = 60 clks 12+55 = 67 clks 6+24 = 30 clks 6+20 = 26 clks

Min Timing:

PM: 12+115 = 127

DM: 7

;---------------------------------------------------------------------------------------------FLO2432 FLO32 MOVLW MOVWF MOVPF BTFSS GOTO CLRF COMF COMF COMF INCF ADDWFC ADDWFC D’23’+EXPBIAS EXP AARGB0,SIGN AARGB0,MSB NRM3232 WREG,F AARGB2,F AARGB1,F AARGB0,F AARGB2,F AARGB1,F AARGB0,F ; initialize exponent and add bias ; save sign in SIGN ; test sign ; if < 0, negate, set MSB in SIGN

DS00575B-page 107

AN575
;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Normalization routine Input: 32 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2 with sign in SIGN,MSB. CALL NRM3232 or CALL NRM32

Use:

Output: 32 bit normalized floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-NORMALIZE( AARG ) SAT = 0 SAT = 1 AARG = 0

21+19+8 = 48 clks 21+19+15 = 55 clks 4+7+7+6 = 24 clks 3+5+4+8 = 20 clks

Min Timing:

PM: 115

DM: 7

;---------------------------------------------------------------------------------------------NRM3232 NRM32 CLRF CPFSGT GOTO TNIB3232 MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM3232 BCF BTFSC GOTO RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF INCF BTFSC TEMP,W AARGB0 NRM3232A 0xF0 AARGB0,W WREG NORM3232 AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 AARGB2,W 0x0F AARGB1,F AARGB2,W 0xF0 WREG,AARGB2 TEMP,2 _C AARGB0,MSB TNORMUN3232 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3232 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement ; clear exponent decrement ; test if highbyte=0

; test if highnibble=0

; if so, shift 4 bits

; since highnibble != 0, at most

DS00575B-page 108

AN575
GOTO RLCF RLCF RLCF INCF TNORMUN3232 MOVFP CPFSGT GOTO SUBWF BTFSS BCF RETLW MOVFP MOVFP CLRF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM3232A BCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF GOTO NRM3232B MOVFP CLRF BCF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ TNORMUN3232 AARGB2,F AARGB1,F AARGB0,F TEMP,F TEMP,WREG EXP SETFUN32 EXP,F SIGN,MSB AARGB0,MSB 0 AARGB1,AARGB0 AARGB2,AARGB1 AARGB2,W TEMP,3 AARGB0 NRM3232B 0xF0 AARGB0,W WREG NORM3232A AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 TEMP,2 _C AARGB0,MSB TNORMUN3232 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3232 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN3232 AARGB1,F AARGB0,F TEMP,F TNORMUN3232 AARGB1,AARGB0 AARGB1,W TEMP,3 TEMP,4 AARGB0 RES032 0xF0 AARGB0,W WREG ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement ; 3 left shifts are required

; ; ; ;

if EXP <= decrement in TEMP, floating point underflow has occured otherwise, compute EXP

FIXSIGN32

; clear explicit MSB if positive

NRM3232A

; shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

TNIB3232A

; test if highnibble=0

; if so, shift 4 bits

; since highnibble != 0, at most ; 3 left shifts are required

; shift 8 bits by move ; increase decrement by 8 ; if highbyte=0, result=0

TNIB3232B

; test if highnibble=0

DS00575B-page 109

AN575
GOTO SWAPF BSF NORM3232B BCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF GOTO RES032 CLRF CLRF CLRF CLRF CLRF RETLW NORM3232B AARGB0,F TEMP,2 _C AARGB0,MSB TNORMUN3232 AARGB0,F TEMP,F AARGB0,MSB TNORMUN3232 AARGB0,F TEMP,F AARGB0,MSB TNORMUN3232 AARGB0,F TEMP,F TNORMUN3232 AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F 0 ; if so, shift 4 bits ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; result equals zero

; clear extended byte

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; Integer to float conversion Input: 32 bit 2’s complement integer right justified in AARGB0,AARGB1, AARGB2, AARGB3 CALL FLO3232

Use:

Output: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-FLOAT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

14+61 = 75 clks 14+77 = 91 clks 14+83 = 97 clks 6+32 = 38 clks 6+26 = 32 clks

Min Timing:

PM: 14+178 = 192

DM: 8

;---------------------------------------------------------------------------------------------FLO3232 MOVLW MOVWF MOVPF BTFSS GOTO CLRF COMF COMF COMF COMF INCF ADDWFC ADDWFC ADDWFC D’31’+EXPBIAS EXP AARGB0,SIGN AARGB0,MSB NRM4032 WREG,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F ; initialize exponent and add bias ; save sign in SIGN ; test sign ; if < 0, negate, set MSB in SIGN

DS00575B-page 110

AN575
;********************************************************************************************** ; ; ; ; ; ; Normalization routine Input: 40 bit unnormalized floating point number in AEXP, AARGB0, AARGB1, AARGB2, AARGB3 with sign in SIGN,MSB. CALL NRM4032

Use:

Output: 32 bit normalized floating point number in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG <-NORMALIZE( AARG )

; ; ; ; ; ;

Max Timing:

27+22+8+4 = 61 clks 27+22+24+4 = 77 clks 27+22+23+11 = 83 clks 4+8+8+6+6 = 32 clks 3+5+4+8+6 = 26 clks

RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG = 0

Min Timing:

PM: 178

DM: 8

;---------------------------------------------------------------------------------------------NRM4032 CLRF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM4032 BCF BTFSC GOTO RLCF RLCF RLCF TEMP,W AARGB0 NRM4032A 0xF0 AARGB0,W WREG NORM4032 AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 AARGB2,W 0x0F AARGB1,F AARGB2,W 0xF0 WREG,AARGB2 AARGB3,W 0x0F AARGB2,F AARGB3,W 0xF0 WREG,AARGB3 TEMP,2 _C AARGB0,MSB TNORMUN4032 AARGB3,F AARGB2,F AARGB1,F ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement ; clear exponent decrement ; test if highbyte=0

TNIB4032

; test if highnibble=0

; if so, shift 4 bits

DS00575B-page 111

AN575
RLCF INCF BTFSC GOTO RLCF RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF RLCF INCF TNORMUN4032 MOVFP CPFSGT GOTO SUBWF AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB3,F AARGB2,F AARGB1,F AARGB0,F TEMP,F TEMP,WREG EXP SETFUN32 EXP,F

; since highnibble != 0, at most ; 3 left shifts are required

; ; ; ;

if EXP <= decrement in TEMP, floating point underflow has occured otherwise, compute EXP

NRMRND4032 BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC ADDWFC BTFSS GOTO RRCF RRCF RRCF INFSNZ GOTO GOTO NRM4032A MOVFP MOVFP MOVFP CLRF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW FPFLAGS,RND AARGB3,MSB FIXSIGN32 _C 0x80 AARGB3 AARGB2,W WREG,F AARGB2,F AARGB1,F AARGB0,F _C FIXSIGN32 AARGB0,F AARGB1,F AARGB2,F EXP,F SETFOV32 FIXSIGN32 AARGB1,AARGB0 AARGB2,AARGB1 AARGB3,AARGB2 AARGB3,W TEMP,3 AARGB0 NRM4032B 0xF0 AARGB0,W WREG NORM4032A AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 AARGB2,W 0x0F ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; has rounding caused carryout? ; if so, right shift

; test for floating point overflow

; shift 8 bits by move

; increase decrement by 8 ; test if highbyte=0

TNIB4032A

; test if highnibble=0

; if so, shift 4 bits

DS00575B-page 112

AN575
ADDWF SWAPF ANDLW MOVPF BSF NORM4032A BCF BTFSC GOTO RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF INCF BTFSC GOTO RLCF RLCF RLCF INCF GOTO NRM4032B MOVFP MOVFP CLRF BCF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF BSF NORM4032B BCF BTFSC GOTO RLCF RLCF INCF BTFSC GOTO RLCF RLCF INCF AARGB1,F AARGB2,W 0xF0 WREG,AARGB2 TEMP,2 _C AARGB0,MSB TNORMUN4032 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB2,F AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB2,F AARGB1,F AARGB0,F TEMP,F TNORMUN4032 AARGB1,AARGB0 AARGB2,AARGB1 AARGB2,W TEMP,3 TEMP,4 AARGB0 NRM4032C 0xF0 AARGB0,W WREG NORM4032B AARGB0,F AARGB1,W 0x0F AARGB0,F AARGB1,W 0xF0 WREG,AARGB1 TEMP,2 _C AARGB0,MSB TNORMUN4032 AARGB1,F AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB1,F AARGB0,F TEMP,F ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

; shift 8 bits by move

; increase decrement by 8 ; if highbyte=0, result=0

TNIB4032B

; test if highnibble=0

; if so, shift 4 bits

DS00575B-page 113

AN575
BTFSC GOTO RLCF RLCF INCF GOTO NRM4032C MOVFP CLRF BSF CPFSGT GOTO MOVLW ANDWF TSTFSZ GOTO SWAPF BSF NORM4032C BCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF BTFSC GOTO RLCF INCF GOTO AARGB0,MSB TNORMUN4032 AARGB1,F AARGB0,F TEMP,F TNORMUN4032 AARGB1,AARGB0 AARGB1,W TEMP,3 AARGB0 RES032 0xF0 AARGB0,W WREG NORM4032C AARGB0,F TEMP,2 _C AARGB0,MSB TNORMUN4032 AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB0,F TEMP,F AARGB0,MSB TNORMUN4032 AARGB0,F TEMP,F TNORMUN4032 ; since highnibble != 0, at most ; 3 left shifts are required

; shift 8 bits by move ; increase decrement by 8 ; if highbyte=0, result=0

TNIB4032C

; test if highnibble=0

; if so, shift 4 bits ; increase decrement by 4 ; clear carry bit ; if MSB=1, normalization done ; otherwise, shift left and ; increment decrement

; since highnibble != 0, at most ; 3 left shifts are required

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 CALL INT3224 or CALL INT32

Output: 24 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

10+45+15 = 70 clks 10+45+24 = 79 clks 10+45+26 = 81 clks 4 clks

Min Timing: PM: 183

DM: 8

;---------------------------------------------------------------------------------------------INT3224 INT32 CLRF CPFSGT RETLW AARGB3,W EXP 0x00 ; test for zero argument

DS00575B-page 114

AN575
MOVPF BSF MOVLW SUBWF BTFSS GOTO NEGW MOVLW CPFSGT GOTO SUBWF MOVFP MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO SNIB3224C MOVLW CPFSGT GOTO SWAPF ANDLW MOVPF GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF AARGB0,SIGN AARGB0,MSB EXPBIAS+D’23’ EXP,W WREG,MSB SETIOV3224 EXP,F 7 EXP SNIB3224 EXP,F AARGB2,AARGB3 AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F EXP,F SHIFT3224OK EXP SNIB3224A EXP,F AARGB2,AARGB3 AARGB1,AARGB2 AARGB1,F EXP,F SHIFT3224OK EXP SNIB3224B EXP,F AARGB2,AARGB3 AARGB2,F EXP,F SHIFT3224OK 3 EXP SHIFT3224C AARGB3,W 0x0F WREG,AARGB3 SHIFT3224OK _C AARGB3,F EXP,F SHIFT3224OK _C AARGB3,F EXP,F SHIFT3224OK _C AARGB3,F SHIFT3224OK 3 EXP SHIFT3224B EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 ; save sign in SIGN ; make MSB explicit ; remove bias+23 from EXP

; if >= 23, integer overflow ; will occur

; do byte shift if EXP >= 8

; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding ; EXP = EXP - 1 ; shift completed if EXP = 0 ; do nibble shift if EXP >= 4

; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP ; shift completed if EXP = 0

SHIFT3224C

; shift completed if EXP = 0

SNIB3224B

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

DS00575B-page 115

AN575
DCFSNZ GOTO SHIFT3224B BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT3224A BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW EXP,F SHIFT3224OK _C AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB2,F AARGB3,F SHIFT3224OK 3 EXP SHIFT3224A EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 EXP,F SHIFT3224OK _C AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB1,F AARGB2,F AARGB3,F SHIFT3224OK 3 EXP SHIFT3224 EXP,F AARGB2,W WREG,AARGB3 0x0F WREG,AARGB2 AARGB1,W 0xF0 ; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB3224A

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB3224

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

DS00575B-page 116

AN575
ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT3224 BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF AARGB2,F AARGB1,W 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 EXP,F SHIFT3224OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F EXP,F SHIFT3224OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SHIFT3224OK BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC ADDWFC BTFSC GOTO INT3224OK BTFSS RETLW COMF COMF COMF INCF CLRF ADDWFC ADDWFC RETLW BSF BTFSS RETLW FPFLAGS,RND AARGB3,MSB INT3224OK _C 0x80 AARGB3 AARGB2,W WREG,F AARGB2,F AARGB1,F AARGB0,F AARGB0,MSB SETIOV3224 SIGN,MSB 0 AARGB2,F AARGB1,F AARGB0,F AARGB2,F WREG,F AARGB1,F AARGB0,F 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; if sign bit set, negate

SETIOV3224

; set integer overflow flag ; test for saturation ; return error code in WREG

DS00575B-page 117

AN575
CLRF BTFSS SETF MOVPF MOVPF RLCF RRCF RETLW AARGB0,F SIGN,MSB AARGB0,F AARGB0,AARGB1 AARGB0,AARGB2 SIGN,F AARGB0,F 0xFF ; ; ; ; saturate to largest two’s complement 24 bit integer SIGN = 0, 0x 7F FF FF SIGN = 1, 0x 80 00 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Float to integer conversion Input: Use: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 CALL INT3232

Output: 32 bit 2’s complement integer right justified in AARGB0, AARGB1, AARGB2, AARGB3 Result: AARG Max Timing: <-INT( AARG ) RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

11+54+17 = 82 clks 11+54+26 = 91 clks 11+54+28 = 93 clks 4 clks

Min Timing: PM: 249

DM: 9

;---------------------------------------------------------------------------------------------INT3232 CLRF CPFSGT RETLW MOVPF BSF CLRF MOVLW SUBWF BTFSS GOTO NEGW MOVLW CPFSGT GOTO SUBWF MOVFP MOVFP MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP MOVFP AARGB3,W EXP 0x00 AARGB0,SIGN AARGB0,MSB AARGB4,F EXPBIAS+D’31’ EXP,W WREG,MSB SETIOV3232 EXP,F 7 EXP SNIB3232 EXP,F AARGB3,AARGB4 AARGB2,AARGB3 AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F EXP,F SHIFT3232OK EXP SNIB3232A EXP,F AARGB3,AARGB4 AARGB2,AARGB3 ; remove bias from EXP ; test for zero argument ; save sign in SIGN ; make MSB explicit

; if >= 31, integer overflow ; will occur

; do byte shift if EXP >= 8

; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding

DS00575B-page 118

AN575
MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO SNIB3232D MOVLW CPFSGT GOTO SWAPF ANDLW MOVPF GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF AARGB1,AARGB2 AARGB1,F EXP,F SHIFT3232OK EXP SNIB3232B EXP,F AARGB3,AARGB4 AARGB2,AARGB3 AARGB2,F EXP,F SHIFT3232OK EXP SNIB3232C EXP,F AARGB3,AARGB4 AARGB3,F EXP,F SHIFT3232OK 3 EXP SHIFT3232D AARGB4,W 0x0F WREG,AARGB4 SHIFT3232OK _C AARGB4,F EXP,F SHIFT3232OK _C AARGB4,F EXP,F SHIFT3232OK _C AARGB4,F SHIFT3232OK 3 EXP SHIFT3232C EXP,F AARGB3,W WREG,AARGB4 0x0F WREG,AARGB3 EXP,F SHIFT3232OK _C AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB3,F AARGB4,F ; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; do another byte shift if EXP >= 8 ; EXP = EXP - 7 ; save for rounding ; EXP = EXP - 1 ; shift completed if EXP = 0 ; do nibble shift if EXP >= 4

; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP ; shift completed if EXP = 0

SHIFT3232D

; shift completed if EXP = 0

SNIB3232C

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

SHIFT3232C

; shift completed if EXP = 0

; shift completed if EXP = 0

DS00575B-page 119

AN575
GOTO SNIB3232B MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT3232B BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT3232OK 3 EXP SHIFT3232B EXP,F AARGB3,W WREG,AARGB4 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 EXP,F SHIFT3232OK _C AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB2,F AARGB3,F AARGB4,F SHIFT3232OK 3 EXP SHIFT3232A EXP,F AARGB3,W WREG,AARGB4 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 EXP,F SHIFT3232OK ; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB3232A

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0

DS00575B-page 120

AN575
SHIFT3232A BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF MOVPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO SHIFT3232 BCF RRCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF _C AARGB1,F AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB1,F AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB1,F AARGB2,F AARGB3,F AARGB4,F SHIFT3232OK 3 EXP SHIFT3232 EXP,F AARGB3,W WREG,AARGB4 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 EXP,F SHIFT3232OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB0,F ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

; shift completed if EXP = 0

SNIB3232

; do nibble shift if EXP >= 4

; EXP = EXP - 3 ; save for rounding

; EXP = EXP - 1 ; shift completed if EXP = 0 ; at most 3 right shifts are required ; right shift by EXP

; shift completed if EXP = 0

DS00575B-page 121

AN575
RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF RRCF SHIFT3232OK BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC ADDWFC ADDWFC BTFSC GOTO INT3232OK BTFSS RETLW COMF COMF COMF COMF INCF CLRF ADDWFC ADDWFC ADDWFC RETLW BSF BTFSS RETLW CLRF BTFSS SETF MOVPF MOVPF MOVPF RLCF RRCF RETLW FPFLAGS,RND AARGB4,MSB INT3232OK _C 0x80 AARGB4 AARGB3,W WREG,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB0,MSB SETIOV3232 SIGN,MSB 0 AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F WREG,F AARGB2,F AARGB1,F AARGB0,F 0 FPFLAGS,IOV FPFLAGS,SAT 0xFF AARGB0,F SIGN,MSB AARGB0,F AARGB0,AARGB1 AARGB0,AARGB2 AARGB0,AARGB3 SIGN,F AARGB0,F 0xFF ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry AARGB1,F AARGB2,F AARGB3,F AARGB4,F EXP,F SHIFT3232OK _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F AARGB4,F

; shift completed if EXP = 0

; if sign bit set, negate

SETIOV3232

; set integer overflow flag ; test for saturation ; return error code in WREG ; ; ; ; saturate to largest two’s complement 32 bit integer SIGN = 0, 0x 7F FF FF FF SIGN = 1, 0x 80 00 00 00

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; Floating Point Multiply Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPM32

Use:

DS00575B-page 122

AN575
; ; ; ; ; ; ; Output: 32 bit floating point product in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG * BARG RND = 0, SAT = 0 RND = 1, SAT = 0 RND = 1, SAT = 1 AARG * BARG = 0 DM: 15

19+73+8 = 100 clks 19+73+22 = 114 clks 19+73+30 = 122 clks 5+6 = 11 clks

Min Timing: PM: 123

;---------------------------------------------------------------------------------------------FPM32 CLRF CPFSEQ CPFSGT GOTO MOVFP XORWF MOVPF MOVFP ADDWF MOVLW BTFSS GOTO SUBWF BTFSC GOTO GOTO MTUN32 SUBWF BTFSS GOTO BSF BSF MOVPF MOVPF MOVPF MOVFP MULWF MOVPF MOVFP MULWF MOVPF MOVPF MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF MOVPF AARGB3,W BEXP AEXP RES032 AARGB0,WREG BARGB0,W WREG,SIGN BEXP,WREG EXP,F EXPBIAS-1 _C MTUN32 EXP,F _C SETFOV32 MOK32 EXP,F _C SETFUN32 AARGB0,MSB BARGB0,MSB AARGB0,TEMPB0 AARGB1,TEMPB1 AARGB2,TEMPB2 AARGB2,WREG BARGB2 PRODH,AARGB4 AARGB1,WREG BARGB1 PRODH,AARGB2 PRODL,AARGB3 BARGB2 PRODL,WREG AARGB4,F PRODH,WREG AARGB3,F WREG,F AARGB2,F TEMPB2,WREG BARGB1 PRODL,WREG ; remove bias and overflow test ; test for zero arguments

M32BNE0

; remove bias and underflow test

MOK32

; make argument MSB’s explicit

; multiply mantissas

DS00575B-page 123

AN575

DS00575B-page 124

AN575
ADDWFC ADDWFC ADDWFC BTFSS GOTO RRCF RRCF RRCF INFSNZ GOTO MUL32OK BTFSS BCF RETLW SETFOV32 BSF BTFSS RETLW SETF SETF SETF SETF RLCF RRCF RETLW AARGB2,F AARGB1,F AARGB0,F _C MUL32OK AARGB0,F AARGB1,F AARGB2,F EXP,F SETFOV32 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FOV FPFLAGS,SAT 0xFF AEXP,F AARGB0,F AARGB1,F AARGB2,F SIGN,F AARGB0,F 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to largest floating ; point number = 0x FF 7F FF FF ; modulo the appropriate sign bit ; has rounding caused carryout? ; if so, right shift

; test for floating point overflow

; clear explicit MSB if positive

; return error code in WREG

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; ; ; Floating Point Divide Input: 32 bit floating point dividend in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point divisor in BEXP, BARGB0, BARGB1, BARGB2 CALL FPD32

Use:

Output: 32 bit floating point quotient in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG / BARG

10+34+69+80+111+11+8 = 323 clks RND = 0 10+34+69+80+111+11+22 = 337 clks RND = 1, SAT = 0 10+34+69+80+111+11+30 = 345 clks RND = 1, SAT = 1 6+6 = 12 clks AARG = 0 DM: 20

Min Timing:

PM: 350+257 = 607

In addition to those registers defined in MATH17.INC, this routine uses TBLPTRL and TBLPTRH without saving and restoring.

;---------------------------------------------------------------------------------------------FPD32SEED ; ; ; ; ; Timing: macro 34 clks

PM: 32+257 = 289 generation of F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 8 explicit bits of BARG as a pointer and the remaining 7 explicit bits as the argument to linear interpolation.

DS00575B-page 125

AN575
MOVLW MOVWF RLCF RLCF ADDLW MOVWF BTFSC INCF TABLRD TLRD TABLRD TLRD MOVFP SUBWF MOVWF BCF RLCF MULWF MOVPF RLCF MULWF MOVPF ADDWF BTFSC INCF CLRF MOVFP SUBWF MOVPF SUBWFB CLRF SUBWFB endm ;---------------------------------------------------------------------------------------------FPD32SEEDS1 ; ; ; ; ; Timing: macro 51 clks HIGH (IBTBL256I) TBLPTRH BARGB1,W BARGB0,W LOW (IBTBL256I) TBLPTRL _C TBLPTRH,F 0,1,TEMPB0 1,TEMPB0 0,0,TEMPB1 0,AARGB5 AARGB5,WREG TEMPB1,W AARGB5 _C BARGB2,W AARGB5 PRODH,TBLPTRH BARGB1,W AARGB5 PRODL,WREG TBLPTRH,F _C PRODH,F TEMPB2,F TBLPTRH,WREG TEMPB2,F PRODH,WREG TEMPB1,F WREG,F TEMPB0,F ; access table for F0

; calculate difference

; interpolate

; F0

PM: 49+129 = 178 generation of F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 7 explicit bits of BARG as a pointer and the remaining 16 explicit bits as the argument to linear interpolation.

MOVLW MOVWF MOVFP ANDLW ADDLW MOVWF BTFSC INCF TABLRD TLRD TABLRD TLRD TLRD

HIGH (IBTBL128I) TBLPTRH BARGB0,WREG 0x7F LOW (IBTBL128I) TBLPTRL _C TBLPTRH,F 0,1,TEMPB0 1,TEMPB0 0,0,TEMPB1 1,AARGB4 0,AARGB5

; access table for F0

DS00575B-page 126

AN575
MOVFP SUBWF MOVWF MOVFP SUBWFB MOVWF MOVPF MOVFP MULWF MOVPF MOVFP MULWF MOVPF MOVPF MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC CLRF MOVFP SUBWF MOVFP SUBWFB MOVFP SUBWFB endm ;---------------------------------------------------------------------------------------------FPD32SEEDS ; ; ; ; ; Timing: macro 75 clks AARGB5,WREG TEMPB1,W AARGB5 AARGB4,WREG TEMPB0,W AARGB4 AARGB5,TEMPB2 AARGB5,WREG BARGB2 PRODH,TBLPTRH AARGB4,WREG BARGB1 PRODH,AARGB4 PRODL,AARGB5 BARGB2 PRODL,WREG TBLPTRH,F PRODH,WREG AARGB5,F WREG,F AARGB4,F TEMPB2,WREG BARGB1 PRODL,WREG TBLPTRH,F PRODH,WREG AARGB5,F WREG,F AARGB4,F TEMPB2,F TBLPTRH,WREG TEMPB2,F AARGB5,WREG TEMPB1,F AARGB4,WREG TEMPB0,F ; calculate difference

; F0

PM: 73+65 = 138 generation of F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 6 explicit bits of BARG as a pointer and the remaining 17 explicit bits as the argument to linear interpolation.

MOVLW MOVWF RRCF ANDLW ADDLW MOVWF BTFSC

HIGH (IBTBL64I) TBLPTRH BARGB0,W 0x3F LOW (IBTBL64I) TBLPTRL _C

; access table for F0

DS00575B-page 127

AN575

DS00575B-page 128

AN575
MOVFP CLRF MOVFP SUBWF MOVFP SUBWFB MOVFP SUBWFB endm ;---------------------------------------------------------------------------------------------FPD32 CLRF CPFSGT GOTO CPFSGT GOTO D32BNE0 MOVFP XORWF MOVPF BSF BSF FPD32SEED MOVPF MOVPF MOVPF MOVFP MULWF MOVPF MOVFP MULWF MOVPF MOVPF MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF MOVPF ADDWF MOVPF ADDWFC CLRF ADDWFC MOVFP MULWF MOVPF ADDWF MOVPF ADDWFC AARGB0,AARGB5 AARGB1,TBLPTRH AARGB2,TBLPTRL AARGB2,WREG TEMPB2 PRODH,AARGB4 AARGB1,WREG TEMPB1 PRODH,AARGB2 PRODL,AARGB3 TEMPB2 PRODL,WREG AARGB4,F PRODH,WREG AARGB3,F WREG,F AARGB2,F TBLPTRL,WREG TEMPB1 PRODL,WREG AARGB4,F PRODH,WREG AARGB3,F WREG,F AARGB2,F AARGB0,WREG TEMPB2 PRODL,WREG AARGB3,F PRODH,WREG AARGB2,F TEMPB3,W BEXP SETFDZ32 AEXP RES032 AARGB0,WREG BARGB0,W WREG,SIGN AARGB0,MSB BARGB0,MSB ; clear exponent modification ; test for divide by zero TEMPB2,TBLPTRH TEMPB2,F TMR0H,WREG TEMPB2,F TBLPTRH,WREG TEMPB1,F AARGB5,WREG TEMPB0,F

; F0

; generation of F0 ; A0 = F0 * A

DS00575B-page 129

AN575

DS00575B-page 130

AN575

; F1 = 2 - B0

DS00575B-page 131

AN575

DS00575B-page 132

AN575

DS00575B-page 133

AN575
BTFSS GOTO AGEB32 ADDWF ADDWF BTFSC GOTO GOTO ADDWF ADDWF BTFSS GOTO _C ALTB32 TEMPB3,W EXP,F _C SETFOV32 DROUND32 TEMPB3,W EXP,F _C SETFUN32 ; if AEXP > BEXP, test for overflow

ALTB32

; if AEXP < BEXP, test for underflow

DROUND32 BTFSC BTFSS GOTO BSF MOVLW CPFSGT RRCF CLRF ADDWFC ADDWFC ADDWFC BTFSS GOTO RRCF RRCF RRCF INFSNZ GOTO DIV32OK BTFSS BCF RETLW SETFUN32 BSF BTFSS RETLW MOVLW MOVPF CLRF CLRF CLRF RLCF RRCF RETLW SETFDZ32 BSF RETLW FPFLAGS,RND AARGB3,MSB DIV32OK _C 0x80 AARGB3 AARGB2,W WREG,F AARGB2,F AARGB1,F AARGB0,F _C DIV32OK AARGB0,F AARGB1,F AARGB2,F EXP,F SETFOV32 SIGN,MSB AARGB0,MSB 0 FPFLAGS,FUN FPFLAGS,SAT 0xFF 0x01 WREG,AEXP AARGB0,F AARGB1,F AARGB2,F SIGN,F AARGB0,F 0xFF FPFLAGS,FDZ 0xFF ; set floating point underflag ; test for saturation ; return error code in WREG ; saturate to smallest floating ; point number = 0x 01 00 00 00 ; modulo the appropriate sign bit ; is rounding enabled? ; is NSB > 0x80? ; set carry for rounding ; if NSB = 0x80, select even ; using lsb in carry

; test if rounding caused carryout

; test for overflow

; clear explicit MSB if positive

; return error code in WREG ; set floating point divide by zero ; flag and return error code in WREG

;---------------------------------------------------------------------------------------------; ; ; IBTBL64I DATA DATA DATA 0xFFFF 0xFC10 0xF83E table for interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 6 explicit bits of BARG as a pointer and the remaining 17 explicit bits as the argument to linear interpolation.

DS00575B-page 134

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xF48A 0xF0F1 0xED73 0xEA0F 0xE6C3 0xE38E 0xE070 0xDD68 0xDA74 0xD794 0xD4C7 0xD20D 0xCF64 0xCCCD 0xCA46 0xC7CE 0xC566 0xC30C 0xC0C1 0xBE83 0xBC52 0xBA2F 0xB817 0xB60B 0xB40B 0xB216 0xB02C 0xAE4C 0xAC77 0xAAAB 0xA8E8 0xA72F 0xA57F 0xA3D7 0xA238 0xA0A1 0x9F11 0x9D8A 0x9C0A 0x9A91 0x991F 0x97B4 0x9650 0x94F2 0x939B 0x9249 0x90FE 0x8FB8 0x8E78 0x8D3E 0x8C09 0x8AD9 0x89AE 0x8889 0x8768 0x864C 0x8534 0x8421 0x8312 0x8208 0x8102 0x8001

DS00575B-page 135

AN575
;---------------------------------------------------------------------------------------------; ; ; IBTBL128I DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xFFFF 0xFE04 0xFC10 0xFA23 0xF83E 0xF660 0xF48A 0xF2BA 0xF0F1 0xEF2F 0xED73 0xEBBE 0xEA0F 0xE866 0xE6C3 0xE526 0xE38E 0xE1FC 0xE070 0xDEE9 0xDD68 0xDBEB 0xDA74 0xD902 0xD794 0xD62C 0xD4C7 0xD368 0xD20D 0xD0B7 0xCF64 0xCE17 0xCCCD 0xCB87 0xCA46 0xC908 0xC7CE 0xC698 0xC566 0xC437 0xC30C 0xC1E5 0xC0C1 0xBFA0 0xBE83 0xBD69 0xBC52 0xBB3F 0xBA2F 0xB921 0xB817 0xB710 0xB60B 0xB50A 0xB40B 0xB30F 0xB216 0xB120 0xB02C generation of F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 7 explicit bits of BARG as a pointer and the remaining 16 explicit bits as the argument to linear interpolation.

DS00575B-page 136

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xAF3B 0xAE4C 0xAD60 0xAC77 0xAB8F 0xAAAB 0xA9C8 0xA8E8 0xA80B 0xA72F 0xA656 0xA57F 0xA4AA 0xA3D7 0xA306 0xA238 0xA16B 0xA0A1 0x9FD8 0x9F11 0x9E4D 0x9D8A 0x9CC9 0x9C0A 0x9B4C 0x9A91 0x99D7 0x991F 0x9869 0x97B4 0x9701 0x9650 0x95A0 0x94F2 0x9446 0x939B 0x92F1 0x9249 0x91A3 0x90FE 0x905A 0x8FB8 0x8F17 0x8E78 0x8DDA 0x8D3E 0x8CA3 0x8C09 0x8B70 0x8AD9 0x8A43 0x89AE 0x891B 0x8889 0x87F8 0x8768 0x86D9 0x864C 0x85BF 0x8534 0x84AA 0x8421 0x8399 0x8312 0x828D 0x8208

DS00575B-page 137

AN575
DATA DATA DATA DATA 0x8185 0x8102 0x8081 0x8001

;---------------------------------------------------------------------------------------------; ; ; IBTBL256I DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xFFFF 0xFF01 0xFE04 0xFD09 0xFC10 0xFB19 0xFA23 0xF930 0xF83E 0xF74E 0xF660 0xF574 0xF48A 0xF3A1 0xF2BA 0xF1D5 0xF0F1 0xF00F 0xEF2F 0xEE50 0xED73 0xEC98 0xEBBE 0xEAE5 0xEA0F 0xE939 0xE866 0xE793 0xE6C3 0xE5F3 0xE526 0xE459 0xE38E 0xE2C5 0xE1FC 0xE136 0xE070 0xDFAC 0xDEE9 0xDE28 0xDD68 0xDCA9 0xDBEB 0xDB2F 0xDA74 0xD9BA 0xD902 0xD84A 0xD794 0xD6DF 0xD62C 0xD579 0xD4C7 0xD417 table for F0 by interpolating between consecutive 16 bit approximations to the reciprocal of BARG, with the top 8 explicit bits of BARG as a pointer and the remaining 7 explicit bits as the argument to linear interpolation.

DS00575B-page 138

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xD368 0xD2BA 0xD20D 0xD161 0xD0B7 0xD00D 0xCF64 0xCEBD 0xCE17 0xCD71 0xCCCD 0xCC29 0xCB87 0xCAE6 0xCA46 0xC9A6 0xC908 0xC86A 0xC7CE 0xC733 0xC698 0xC5FE 0xC566 0xC4CE 0xC437 0xC3A1 0xC30C 0xC278 0xC1E5 0xC152 0xC0C1 0xC030 0xBFA0 0xBF11 0xBE83 0xBDF6 0xBD69 0xBCDD 0xBC52 0xBBC8 0xBB3F 0xBAB6 0xBA2F 0xB9A8 0xB921 0xB89C 0xB817 0xB793 0xB710 0xB68D 0xB60B 0xB58A 0xB50A 0xB48A 0xB40B 0xB38D 0xB30F 0xB292 0xB216 0xB19B 0xB120 0xB0A6 0xB02C 0xAFB3 0xAF3B 0xAEC3

DS00575B-page 139

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0xAE4C 0xADD6 0xAD60 0xACEB 0xAC77 0xAC03 0xAB8F 0xAB1D 0xAAAB 0xAA39 0xA9C8 0xA958 0xA8E8 0xA879 0xA80B 0xA79C 0xA72F 0xA6C2 0xA656 0xA5EA 0xA57F 0xA514 0xA4AA 0xA440 0xA3D7 0xA36E 0xA306 0xA29F 0xA238 0xA1D1 0xA16B 0xA106 0xA0A1 0xA03C 0x9FD8 0x9F74 0x9F11 0x9EAF 0x9E4D 0x9DEB 0x9D8A 0x9D29 0x9CC9 0x9C69 0x9C0A 0x9BAB 0x9B4C 0x9AEE 0x9A91 0x9A34 0x99D7 0x997B 0x991F 0x98C4 0x9869 0x980E 0x97B4 0x975A 0x9701 0x96A8 0x9650 0x95F8 0x95A0 0x9549 0x94F2 0x949C

DS00575B-page 140

AN575
DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA DATA 0x9446 0x93F0 0x939B 0x9346 0x92F1 0x929D 0x9249 0x91F6 0x91A3 0x9150 0x90FE 0x90AC 0x905A 0x9009 0x8FB8 0x8F68 0x8F17 0x8EC8 0x8E78 0x8E29 0x8DDA 0x8D8C 0x8D3E 0x8CF0 0x8CA3 0x8C56 0x8C09 0x8BBC 0x8B70 0x8B24 0x8AD9 0x8A8E 0x8A43 0x89F8 0x89AE 0x8964 0x891B 0x88D2 0x8889 0x8840 0x87F8 0x87AF 0x8768 0x8720 0x86D9 0x8692 0x864C 0x8605 0x85BF 0x8579 0x8534 0x84EF 0x84AA 0x8465 0x8421 0x83DD 0x8399 0x8356 0x8312 0x82CF 0x828D 0x824A 0x8208 0x81C6 0x8185 0x8143

DS00575B-page 141

AN575
DATA DATA DATA DATA DATA 0x8102 0x80C1 0x8081 0x8040 0x8001

;********************************************************************************************** ;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Subtract Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPS32

Use:

Output: 32 bit floating point difference in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

1+160 = 161 clks 1+176 = 177 clks 1+182 = 183 clks 1+20 = 21 clks

Min Timing: PM: 425

DM: 14

;---------------------------------------------------------------------------------------------FPS32 BTG BARGB0,MSB ; toggle sign bit for subtraction

;********************************************************************************************** ; ; ; ; ; ; ; ; ; ; ; Floating Point Add Input: 32 bit floating point number in AEXP, AARGB0, AARGB1, AARGB2 32 bit floating point number in BEXP, BARGB0, BARGB1, BARGB2 CALL FPA32

Use:

Output: 32 bit floating point sum in AEXP, AARGB0, AARGB1, AARGB2 Result: AARG Max Timing: <-AARG - BARG RND = 0 RND = 1, SAT = 0 RND = 1, SAT = 1

7+70+22+61 = 160 clks 7+70+22+77 = 176 clks 7+70+22+83 = 182 clks 6+14 = 20 clks

Min Timing: PM: 424

DM: 14

;---------------------------------------------------------------------------------------------FPA32 MOVFP XORWF MOVPF CLRF MOVFP CPFSGT GOTO USEB32 MOVFP AARGB0,WREG BARGB0,W WREG,TEMPB0 AARGB3,F AEXP,WREG BEXP USEA32 BARGB0,WREG ; use AARG if AEXP >= BEXP ; exclusive or of signs in TEMPB0

; use BARG if AEXP < BEXP

DS00575B-page 142

AN575
MOVPF BSF BSF MOVFP MOVPF MOVFP MOVPF CLRF CPFSGT GOTO MOVFP SUBWF BTFSC GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO SUBWF MOVFP CLRF DCFSNZ GOTO CPFSGT GOTO BRETURN32 MOVFP MOVFP MOVFP CLRF RETLW MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF WREG,SIGN BARGB0,MSB AARGB0,MSB AEXP,WREG WREG,TEMPB1 BEXP,WREG WREG,AEXP WREG,F TEMPB1 BRETURN32 TEMPB1,WREG BEXP,F _Z BLIGNED32 7 BEXP BNIB32 BEXP,F AARGB2,AARGB3 AARGB1,AARGB2 AARGB0,AARGB1 AARGB0,F BEXP,F BLIGNED32 BEXP BNIB32A BEXP,F AARGB2,AARGB3 AARGB1,AARGB2 AARGB1,F BEXP,F BLIGNED32 BEXP BNIB32B BEXP,F AARGB2,AARGB3 AARGB2,F BEXP,F BLIGNED32 BEXP BNIB32C SIGN,AARGB0 BARGB1,AARGB1 BARGB2,AARGB2 AARGB3,F 0x00 3 BEXP BLOOP32C BEXP,F AARGB3,W 0x0F WREG,AARGB3 BEXP,F BLIGNED32 _C ; save sign in SIGN ; make MSB’s explicit

; compute shift count in BEXP

; return BARG if AARG = 0

; do byte shift if BEXP >= 8

; BEXP = BEXP - 7 ; keep for postnormalization

; BEXP = BEXP - 1

; do another byte shift if BEXP >= 8 ; BEXP = BEXP - 7 ; keep for postnormalization

; BEXP = BEXP - 1

; do another byte shift if BEXP >= 8 ; BEXP = BEXP - 7 ; keep for postnormalization ; BEXP = BEXP - 1

; if BEXP still >= 8, then ; AARG = 0 relative to BARG ; return BARG

BNIB32C

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP32C

DS00575B-page 143

AN575
RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO BNIB32B MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF AARGB3,F BEXP,F BLIGNED32 _C AARGB3,F BEXP,F BLIGNED32 _C AARGB3,F BLIGNED32 3 BEXP BLOOP32B BEXP,F AARGB3,W 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 BEXP,F BLIGNED32 _C AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB2,F AARGB3,F BLIGNED32 3 BEXP BLOOP32A BEXP,F AARGB3,W 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 BEXP,F BLIGNED32 _C AARGB1,F ; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP32B

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

BNIB32A

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP32A

DS00575B-page 144

AN575
RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF GOTO BNIB32 MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF CLRF BTFSS AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB1,F AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB1,F AARGB2,F AARGB3,F BLIGNED32 3 BEXP BLOOP32 BEXP,F AARGB3,W 0x0F WREG,AARGB3 AARGB2,W 0xF0 AARGB3,F AARGB2,W 0x0F WREG,AARGB2 AARGB1,W 0xF0 AARGB2,F AARGB1,W 0x0F WREG,AARGB1 AARGB0,W 0xF0 AARGB1,F AARGB0,W 0x0F WREG,AARGB0 BEXP,F BLIGNED32 _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F BEXP,F BLIGNED32 _C AARGB0,F AARGB1,F AARGB2,F AARGB3,F BARGB3,W TEMPB0,MSB

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

BLOOP32

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

BLIGNED32

; negate if signs opposite

DS00575B-page 145

AN575
GOTO COMF COMF COMF COMF INCF ADDWFC ADDWFC ADDWFC GOTO USEA32 TSTFSZ GOTO RETLW CLRF MOVPF BSF BSF MOVFP SUBWF MOVPF BTFSC GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVPF MOVFP MOVPF MOVFP MOVPF CLRF DCFSNZ GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVPF MOVFP MOVPF CLRF DCFSNZ GOTO MOVLW CPFSGT GOTO SUBWF MOVFP MOVPF CLRF DCFSNZ GOTO MOVLW CPFSGT GOTO AOK32 AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F AOK32 BEXP BNE032 0x00 BARGB3,F AARGB0,SIGN AARGB0,MSB BARGB0,MSB BEXP,WREG AEXP,W WREG,BEXP _Z ALIGNED32 7 BEXP ANIB32 BEXP,F BARGB2,WREG WREG,BARGB3 BARGB1,WREG WREG,BARGB2 BARGB0,WREG WREG,BARGB1 BARGB0,F BEXP,F ALIGNED32 7 BEXP ANIB32A BEXP,F BARGB2,WREG WREG,BARGB3 BARGB1,WREG WREG,BARGB2 BARGB1,F BEXP,F ALIGNED32 7 BEXP ANIB32B BEXP,F BARGB2,WREG WREG,BARGB3 BARGB2,F BEXP,F ALIGNED32 7 BEXP ANIB32C ; return AARG if BARG = 0

BNE032

; compute shift count in BEXP

; do byte shift if BEXP >= 8 ; BEXP = BEXP - 7 ; keep for postnormalization

; BEXP = BEXP - 1

; do another byte shift if BEXP >= 8 ; BEXP = BEXP - 7

; BEXP = BEXP - 1

; do another byte shift if BEXP >= 8 ; BEXP = BEXP - 7

; BEXP = BEXP - 1

; if BEXP still >= 8, then ; BARG = 0 relative to AARG

DS00575B-page 146

AN575
MOVFP RETLW ANIB32C MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF DCFSNZ GOTO BCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SIGN,AARGB0 0x00 3 BEXP ALOOP32C BEXP,F BARGB3,W 0x0F WREG,BARGB3 BEXP,F ALIGNED32 _C BARGB3,F BEXP,F ALIGNED32 _C BARGB3,F BEXP,F ALIGNED32 _C BARGB3,F ALIGNED32 3 BEXP ALOOP32B BEXP,F BARGB3,W 0x0F WREG,BARGB3 BARGB2,W 0xF0 BARGB3,F BARGB2,W 0x0F WREG,BARGB2 BEXP,F ALIGNED32 _C BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C BARGB2,F BARGB3,F ALIGNED32 3 BEXP ALOOP32A BEXP,F BARGB3,W 0x0F WREG,BARGB3 BARGB2,W 0xF0 BARGB3,F ; return AARG

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

ALOOP32C

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ANIB32B

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

ALOOP32B

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ANIB32A

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

DS00575B-page 147

AN575
SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO ALOOP32A BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF GOTO MOVLW CPFSGT GOTO SUBWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF SWAPF ANDLW ADDWF SWAPF ANDLW MOVPF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF BARGB2,W 0x0F WREG,BARGB2 BARGB1,W 0xF0 BARGB2,F BARGB1,W 0x0F WREG,BARGB1 BEXP,F ALIGNED32 _C BARGB1,F BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C BARGB1,F BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C BARGB1,F BARGB2,F BARGB3,F ALIGNED32 3 BEXP ALOOP32 BEXP,F BARGB3,W 0x0F WREG,BARGB3 BARGB2,W 0xF0 BARGB3,F BARGB2,W 0x0F WREG,BARGB2 BARGB1,W 0xF0 BARGB2,F BARGB1,W 0x0F WREG,BARGB1 BARGB0,W 0xF0 BARGB1,F BARGB0,W 0x0F WREG,BARGB0 BEXP,F ALIGNED32 _C BARGB0,F BARGB1,F BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

; aligned if BEXP = 0

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

ANIB32

; do nibbleshift if BEXP >= 4

; BEXP = BEXP -3

; BEXP = BEXP - 1 ; aligned if BEXP = 0 ; right shift by BEXP

ALOOP32

; aligned if BEXP = 0

DS00575B-page 148

AN575
RRCF RRCF RRCF RRCF DCFSNZ GOTO BCF RRCF RRCF RRCF RRCF ALIGNED32 CLRF BTFSS GOTO COMF COMF COMF COMF INCF ADDWFC ADDWFC ADDWFC MOVFP ADDWF MOVFP ADDWFC MOVFP ADDWFC MOVFP ADDWFC BTFSC GOTO BTFSS GOTO RRCF RRCF RRCF RRCF INCFSZ GOTO GOTO ACOMP32 BTFSC GOTO CLRF COMF COMF COMF COMF INCF ADDWFC ADDWFC ADDWFC BTG GOTO BARGB0,F BARGB1,F BARGB2,F BARGB3,F BEXP,F ALIGNED32 _C BARGB0,F BARGB1,F BARGB2,F BARGB3,F AARGB3,W TEMPB0,MSB AOK32 BARGB3,F BARGB2,F BARGB1,F BARGB0,F BARGB3,F BARGB2,F BARGB1,F BARGB0,F BARGB3,WREG AARGB3,F BARGB2,WREG AARGB2,F BARGB1,WREG AARGB1,F BARGB0,WREG AARGB0,F TEMPB0,MSB ACOMP32 _C NRMRND4032 AARGB0,F AARGB1,F AARGB2,F AARGB3,F AEXP,F NRMRND4032 SETFOV32 _C NRM4032 WREG,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F AARGB3,F AARGB2,F AARGB1,F AARGB0,F SIGN,MSB NRM4032 ; shift right and increment EXP

; aligned if BEXP = 0 ; at most 3 right shifts are ; possible

; negate if signs opposite

AOK32

; set floating point overflow flag

; normalize and fix sign ; negate, toggle sign bit and ; then normalize

DS00575B-page 149

Note the following details of the code protection feature on PICmicro® MCUs. • • • The PICmicro family meets the specifications contained in the Microchip Data Sheet. Microchip believes that its family of PICmicro microcontrollers is one of the most secure products of its kind on the market today, when used in the intended manner and under normal conditions. There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our knowledge, require using the PICmicro microcontroller in a manner outside the operating specifications contained in the data sheet. The person doing so may be engaged in theft of intellectual property. Microchip is willing to work with the customer who is concerned about the integrity of their code. Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not mean that we are guaranteeing the product as “unbreakable”. Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our product.

• • •

Information contained in this publication regarding device applications and the like is intended through suggestion only and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. No representation or warranty is given and no liability is assumed by Microchip Technology Incorporated with respect to the accuracy or use of such information, or infringement of patents or other intellectual property rights arising from such use or otherwise. Use of Microchip’s products as critical components in life support systems is not authorized except with express written approval by Microchip. No licenses are conveyed, implicitly or otherwise, under any intellectual property rights.

Trademarks The Microchip name and logo, the Microchip logo, FilterLab, KEELOQ, microID, MPLAB, PIC, PICmicro, PICMASTER, PICSTART, PRO MATE, SEEVAL and The Embedded Control Solutions Company are registered trademarks of Microchip Technology Incorporated in the U.S.A. and other countries. dsPIC, ECONOMONITOR, FanSense, FlexROM, fuzzyLAB, In-Circuit Serial Programming, ICSP, ICEPIC, microPort, Migratable Memory, MPASM, MPLIB, MPLINK, MPSIM, MXDEV, PICC, PICDEM, PICDEM.net, rfPIC, Select Mode and Total Endurance are trademarks of Microchip Technology Incorporated in the U.S.A. Serialized Quick Turn Programming (SQTP) is a service mark of Microchip Technology Incorporated in the U.S.A. All other trademarks mentioned herein are property of their respective companies. © 2002, Microchip Technology Incorporated, Printed in the U.S.A., All Rights Reserved.
Printed on recycled paper.

Microchip received QS-9000 quality system certification for its worldwide headquarters, design and wafer fabrication facilities in Chandler and Tempe, Arizona in July 1999. The Company’s quality system processes and procedures are QS-9000 compliant for its PICmicro® 8-bit MCUs, KEELOQ® code hopping devices, Serial EEPROMs and microperipheral products. In addition, Microchip’s quality system for the design and manufacture of development systems is ISO 9001 certified.

 2002 Microchip Technology Inc.

M
WORLDWIDE SALES AND SERVICE
AMERICAS
Corporate Office
2355 West Chandler Blvd. Chandler, AZ 85224-6199 Tel: 480-792-7200 Fax: 480-792-7277 Technical Support: 480-792-7627 Web Address: http://www.microchip.com

ASIA/PACIFIC
Australia
Microchip Technology Australia Pty Ltd Suite 22, 41 Rawson Street Epping 2121, NSW Australia Tel: 61-2-9868-6733 Fax: 61-2-9868-6755

Japan
Microchip Technology Japan K.K. Benex S-1 6F 3-18-20, Shinyokohama Kohoku-Ku, Yokohama-shi Kanagawa, 222-0033, Japan Tel: 81-45-471- 6166 Fax: 81-45-471-6122

Rocky Mountain
2355 West Chandler Blvd. Chandler, AZ 85224-6199 Tel: 480-792-7966 Fax: 480-792-7456

China - Beijing
Microchip Technology Consulting (Shanghai) Co., Ltd., Beijing Liaison Office Unit 915 Bei Hai Wan Tai Bldg. No. 6 Chaoyangmen Beidajie Beijing, 100027, No. China Tel: 86-10-85282100 Fax: 86-10-85282104

Korea
Microchip Technology Korea 168-1, Youngbo Bldg. 3 Floor Samsung-Dong, Kangnam-Ku Seoul, Korea 135-882 Tel: 82-2-554-7200 Fax: 82-2-558-5934

Atlanta
500 Sugar Mill Road, Suite 200B Atlanta, GA 30350 Tel: 770-640-0034 Fax: 770-640-0307

Singapore
Microchip Technology Singapore Pte Ltd. 200 Middle Road #07-02 Prime Centre Singapore, 188980 Tel: 65-334-8870 Fax: 65-334-8850

Boston
2 Lan Drive, Suite 120 Westford, MA 01886 Tel: 978-692-3848 Fax: 978-692-3821

China - Chengdu
Microchip Technology Consulting (Shanghai) Co., Ltd., Chengdu Liaison Office Rm. 2401, 24th Floor, Ming Xing Financial Tower No. 88 TIDU Street Chengdu 610016, China Tel: 86-28-6766200 Fax: 86-28-6766599

Taiwan
Microchip Technology Taiwan 11F-3, No. 207 Tung Hua North Road Taipei, 105, Taiwan Tel: 886-2-2717-7175 Fax: 886-2-2545-0139

Chicago
333 Pierce Road, Suite 180 Itasca, IL 60143 Tel: 630-285-0071 Fax: 630-285-0075

Dallas
4570 Westgrove Drive, Suite 160 Addison, TX 75001 Tel: 972-818-7423 Fax: 972-818-2924

China - Fuzhou
Microchip Technology Consulting (Shanghai) Co., Ltd., Fuzhou Liaison Office Unit 28F, World Trade Plaza No. 71 Wusi Road Fuzhou 350001, China Tel: 86-591-7503506 Fax: 86-591-7503521

EUROPE
Denmark
Microchip Technology Nordic ApS Regus Business Centre Lautrup hoj 1-3 Ballerup DK-2750 Denmark Tel: 45 4420 9895 Fax: 45 4420 9910

Detroit
Tri-Atria Office Building 32255 Northwestern Highway, Suite 190 Farmington Hills, MI 48334 Tel: 248-538-2250 Fax: 248-538-2260

China - Shanghai
Microchip Technology Consulting (Shanghai) Co., Ltd. Room 701, Bldg. B Far East International Plaza No. 317 Xian Xia Road Shanghai, 200051 Tel: 86-21-6275-5700 Fax: 86-21-6275-5060

Kokomo
2767 S. Albright Road Kokomo, Indiana 46902 Tel: 765-864-8360 Fax: 765-864-8387

France
Microchip Technology SARL Parc d’Activite du Moulin de Massy 43 Rue du Saule Trapu Batiment A - ler Etage 91300 Massy, France Tel: 33-1-69-53-63-20 Fax: 33-1-69-30-90-79

Los Angeles
18201 Von Karman, Suite 1090 Irvine, CA 92612 Tel: 949-263-1888 Fax: 949-263-1338

China - Shenzhen
Microchip Technology Consulting (Shanghai) Co., Ltd., Shenzhen Liaison Office Rm. 1315, 13/F, Shenzhen Kerry Centre, Renminnan Lu Shenzhen 518001, China Tel: 86-755-2350361 Fax: 86-755-2366086

New York
150 Motor Parkway, Suite 202 Hauppauge, NY 11788 Tel: 631-273-5305 Fax: 631-273-5335

Germany
Microchip Technology GmbH Gustav-Heinemann Ring 125 D-81739 Munich, Germany Tel: 49-89-627-144 0 Fax: 49-89-627-144-44

San Jose
Microchip Technology Inc. 2107 North First Street, Suite 590 San Jose, CA 95131 Tel: 408-436-7950 Fax: 408-436-7955

Hong Kong
Microchip Technology Hongkong Ltd. Unit 901-6, Tower 2, Metroplaza 223 Hing Fong Road Kwai Fong, N.T., Hong Kong Tel: 852-2401-1200 Fax: 852-2401-3431

Italy
Microchip Technology SRL Centro Direzionale Colleoni Palazzo Taurus 1 V. Le Colleoni 1 20041 Agrate Brianza Milan, Italy Tel: 39-039-65791-1 Fax: 39-039-6899883

Toronto
6285 Northam Drive, Suite 108 Mississauga, Ontario L4V 1X5, Canada Tel: 905-673-0699 Fax: 905-673-6509

India
Microchip Technology Inc. India Liaison Office Divyasree Chambers 1 Floor, Wing A (A3/A4) No. 11, O’Shaugnessey Road Bangalore, 560 025, India Tel: 91-80-2290061 Fax: 91-80-2290062

United Kingdom
Arizona Microchip Technology Ltd. 505 Eskdale Road Winnersh Triangle Wokingham Berkshire, England RG41 5TU Tel: 44 118 921 5869 Fax: 44-118 921-5820
01/18/02

 2002 Microchip Technology Inc.