lfpfunc.c revision 290000
137446Srnordier#include "config.h"
237446Srnordier
337446Srnordier#include "ntp_stdlib.h"
437446Srnordier#include "ntp_fp.h"
537446Srnordier
637446Srnordier#include "unity.h"
737446Srnordier
837446Srnordier#include <float.h>
937446Srnordier#include <math.h>
1037446Srnordier
1137446Srnordier
1237446Srnordier/* replaced TEST_ASSERT_EQUAL_MEMORY(&a, &b, sizeof(a)) with TEST_ASSERT_EQUAL_l_fp(a, b).
1337446Srnordier   It's safer this way, because structs can be compared even if they aren't initiated
1437446Srnordier   with memset (due to padding bytes).
1537446Srnordier*/
1637446Srnordier#define TEST_ASSERT_EQUAL_l_fp(a, b) { \
1737446Srnordier    TEST_ASSERT_EQUAL_MESSAGE(a.l_i, b.l_i, "Field l_i"); \
1837446Srnordier    TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf");	\
1937446Srnordier}
2037446Srnordier
2137446Srnordier
2237446Srnordier
2337446Srnordiertypedef int bool; // typedef enum { FALSE, TRUE } boolean; -> can't use this because TRUE and FALSE are already defined
2437446Srnordier
2537446Srnordier
2637446Srnordiertypedef struct  {
2737446Srnordier	uint32_t h, l;
2837446Srnordier} lfp_hl;
2937446Srnordier
3050476Speter
3137446Srnordierint l_fp_scmp(const l_fp first, const l_fp second);
3237446Srnordierint l_fp_ucmp(const l_fp first, l_fp second );
3337446Srnordierl_fp l_fp_init(int32 i, u_int32 f);
34106372Sscottll_fp l_fp_add(const l_fp first, const l_fp second);
35106372Sscottll_fp l_fp_subtract(const l_fp first, const l_fp second);
3637446Srnordierl_fp l_fp_negate(const l_fp first);
3737446Srnordierl_fp l_fp_abs(const l_fp first);
3866907Swollmanint l_fp_signum(const l_fp first);
3966907Swollmandouble l_fp_convert_to_double(const l_fp first);
4037446Srnordierl_fp l_fp_init_from_double( double rhs);
4137446Srnordiervoid l_fp_swap(l_fp * first, l_fp *second);
4237446Srnordierbool l_isgt(const l_fp first, const l_fp second);
4337446Srnordierbool l_isgtu(const l_fp first, const l_fp second);
4437446Srnordierbool l_ishis(const l_fp first, const l_fp second);
45185594Smlaierbool l_isgeq(const l_fp first, const l_fp second);
4637446Srnordierbool l_isequ(const l_fp first, const l_fp second);
4737446Srnordierdouble eps(double d);
4837446Srnordier
4937446Srnordier
5066907Swollmanvoid test_AdditionLR(void);
5137446Srnordiervoid test_AdditionRL(void);
5237446Srnordiervoid test_SubtractionLR(void);
5337446Srnordiervoid test_SubtractionRL(void);
5437446Srnordiervoid test_Negation(void);
5537446Srnordiervoid test_Absolute(void);
5637446Srnordiervoid test_FDF_RoundTrip(void);
5737446Srnordiervoid test_SignedRelOps(void);
58170166Strhodesvoid test_UnsignedRelOps(void);
5937446Srnordier
6037446Srnordier
6137446Srnordier
6237446Srnordierstatic int cmp_work(u_int32 a[3], u_int32 b[3]);
6337446Srnordier
6437446Srnordier//----------------------------------------------------------------------
65203868Skib// reference comparision
66203868Skib// This is implementad as a full signed MP-subtract in 3 limbs, where
67203868Skib// the operands are zero or sign extended before the subtraction is
68203868Skib// executed.
69203868Skib//----------------------------------------------------------------------
70203868Skib
7137446Srnordierint
7237446Srnordierl_fp_scmp(const l_fp first, const l_fp second)
7337446Srnordier{
7437446Srnordier	u_int32 a[3], b[3];
7537446Srnordier
7637446Srnordier	const l_fp op1 = first;
7737446Srnordier	const l_fp op2 = second;
7837446Srnordier
7937446Srnordier	a[0] = op1.l_uf; a[1] = op1.l_ui; a[2] = 0;
8037446Srnordier	b[0] = op2.l_uf; b[1] = op2.l_ui; b[2] = 0;
8137446Srnordier
8237446Srnordier	a[2] -= (op1.l_i < 0);
8337446Srnordier	b[2] -= (op2.l_i < 0);
8437446Srnordier
8537446Srnordier	return cmp_work(a,b);
8637446Srnordier}
8737446Srnordier
8837446Srnordierint
8937446Srnordierl_fp_ucmp(const l_fp first, l_fp second )
9037446Srnordier{
9137446Srnordier	u_int32 a[3], b[3];
9237446Srnordier	const l_fp op1 = first;
9337446Srnordier	const l_fp op2 = second;
9437446Srnordier
9537446Srnordier	a[0] = op1.l_uf; a[1] = op1.l_ui; a[2] = 0;
9637446Srnordier	b[0] = op2.l_uf; b[1] = op2.l_ui; b[2] = 0;
9737446Srnordier
9837446Srnordier	return cmp_work(a,b);
99203869Skib}
100203869Skib
10137446Srnordier// maybe rename it to lf_cmp_work
10237446Srnordierint
10337446Srnordiercmp_work(u_int32 a[3], u_int32 b[3])
104203869Skib{
105203869Skib	u_int32 cy, idx, tmp;
106203869Skib	for (cy = idx = 0; idx < 3; ++idx) {
107203869Skib		tmp = a[idx]; cy  = (a[idx] -=   cy  ) > tmp;
108203869Skib		tmp = a[idx]; cy |= (a[idx] -= b[idx]) > tmp;
109203869Skib	}
110203869Skib	if (a[2])
111203869Skib		return -1;
112203869Skib	return a[0] || a[1];
113203869Skib}
114203869Skib
115203869Skib
11637446Srnordier//----------------------------------------------------------------------
11737446Srnordier// imlementation of the LFP stuff
11837446Srnordier// This should be easy enough...
119203869Skib//----------------------------------------------------------------------
120203869Skib
121203869Skibl_fp
122203869Skibl_fp_init(int32 i, u_int32 f)
123203869Skib{
124203869Skib	l_fp temp;
125203869Skib	temp.l_i  = i;
12637446Srnordier	temp.l_uf = f;
12737446Srnordier
12837446Srnordier	return temp;
129203869Skib}
130203869Skib
131203869Skibl_fp
132203869Skibl_fp_add(const l_fp first, const l_fp second)
133203869Skib{
134203869Skib	l_fp temp = first;
13537446Srnordier	L_ADD(&temp, &second);
13637446Srnordier
13737446Srnordier	return temp;
138203869Skib}
139203869Skib
14037446Srnordierl_fp
141203869Skibl_fp_subtract(const l_fp first, const l_fp second)
142203869Skib{
143203869Skib	l_fp temp = first;
144203869Skib	L_SUB(&temp, &second);
14537446Srnordier
14637446Srnordier	return temp;
14737446Srnordier}
148203869Skib
149203869Skibl_fp
150203869Skibl_fp_negate(const l_fp first)
151203869Skib{
152203869Skib	l_fp temp = first;
153203869Skib	L_NEG(&temp);
154203869Skib
155203869Skib	return temp;
156203869Skib}
157203869Skib
158203869Skibl_fp
159203869Skibl_fp_abs(const l_fp first)
160203869Skib{
161203869Skib	l_fp temp = first;
162203869Skib	if (L_ISNEG(&temp))
163203869Skib		L_NEG(&temp);
16437446Srnordier	return temp;
16537446Srnordier}
166140384Sdelphij
167140384Sdelphijint
168203868Skibl_fp_signum(const l_fp first)
169203869Skib{
170203869Skib	if (first.l_ui & 0x80000000u)
17137446Srnordier		return -1;
17237446Srnordier	return (first.l_ui || first.l_uf);
17337446Srnordier}
174190927Sed
175203868Skibdouble
176203868Skibl_fp_convert_to_double(const l_fp first)
177203868Skib{
178203868Skib	double res;
179203868Skib	LFPTOD(&first, res);
180203868Skib	return res;
181203868Skib}
182203868Skib
183203868Skibl_fp
184203868Skibl_fp_init_from_double( double rhs)
18537446Srnordier{
18637446Srnordier	l_fp temp;
187190927Sed	DTOLFP(rhs, &temp);
18837446Srnordier	return temp;
18937446Srnordier}
19037446Srnordier
19137446Srnordiervoid
19237446Srnordierl_fp_swap(l_fp * first, l_fp *second){
19337446Srnordier	l_fp temp = *second;
19437446Srnordier
19537446Srnordier	*second = *first;
19637446Srnordier	*first = temp;
19737446Srnordier}
19837446Srnordier
19937446Srnordier//----------------------------------------------------------------------
20037446Srnordier// testing the relational macros works better with proper predicate
20137446Srnordier// formatting functions; it slows down the tests a bit, but makes for
20237446Srnordier// readable failure messages.
20337446Srnordier//----------------------------------------------------------------------
20437446Srnordier
20537446Srnordier
20637446Srnordierbool
20737446Srnordierl_isgt (const l_fp first, const l_fp second) {
20837446Srnordier	return L_ISGT(&first, &second);
20937446Srnordier}
21037446Srnordier
21137446Srnordierbool
21237446Srnordierl_isgtu(const l_fp first, const l_fp second) {
21337446Srnordier	return L_ISGTU(&first, &second);
21437446Srnordier}
21537446Srnordier
21637446Srnordierbool
21737446Srnordierl_ishis(const l_fp first, const l_fp second) {
21837446Srnordier	return L_ISHIS(&first, &second);
21937446Srnordier}
22037446Srnordier
22137446Srnordierbool
22237446Srnordierl_isgeq(const l_fp first, const l_fp second) {
22337446Srnordier	return L_ISGEQ(&first, &second);
22437446Srnordier}
22537446Srnordier
226185587Sluigibool
22737446Srnordierl_isequ(const l_fp first, const l_fp second) {
22837446Srnordier	return L_ISEQU(&first, &second);
22937446Srnordier}
23037446Srnordier
23137446Srnordier
23237446Srnordier//----------------------------------------------------------------------
233102231Strhodes// test data table for add/sub and compare
23437446Srnordier//----------------------------------------------------------------------
23537446Srnordier
23637446Srnordier
23737446Srnordierstatic const lfp_hl addsub_tab[][3] = {
238190927Sed	// trivial idendity:
239190927Sed	{{0 ,0         }, { 0,0         }, { 0,0}},
240190927Sed	// with carry from fraction and sign change:
241190927Sed	{{-1,0x80000000}, { 0,0x80000000}, { 0,0}},
242190927Sed	// without carry from fraction
243190927Sed	{{ 1,0x40000000}, { 1,0x40000000}, { 2,0x80000000}},
244190927Sed	// with carry from fraction:
24537446Srnordier	{{ 1,0xC0000000}, { 1,0xC0000000}, { 3,0x80000000}},
24637446Srnordier	// with carry from fraction and sign change:
24737446Srnordier	{{0x7FFFFFFF, 0x7FFFFFFF}, {0x7FFFFFFF,0x7FFFFFFF}, {0xFFFFFFFE,0xFFFFFFFE}},
24837446Srnordier	// two tests w/o carry (used for l_fp<-->double):
24937446Srnordier	{{0x55555555,0xAAAAAAAA}, {0x11111111,0x11111111}, {0x66666666,0xBBBBBBBB}},
25037446Srnordier	{{0x55555555,0x55555555}, {0x11111111,0x11111111}, {0x66666666,0x66666666}},
25137446Srnordier	// wide-range test, triggers compare trouble
25237446Srnordier	{{0x80000000,0x00000001}, {0xFFFFFFFF,0xFFFFFFFE}, {0x7FFFFFFF,0xFFFFFFFF}}
25337446Srnordier};
25437446Srnordierstatic const size_t addsub_cnt = (sizeof(addsub_tab)/sizeof(addsub_tab[0]));
25537446Srnordierstatic const size_t addsub_tot = (sizeof(addsub_tab)/sizeof(addsub_tab[0][0]));
25637446Srnordier
25737446Srnordier
25840487Sbde
25937446Srnordier//----------------------------------------------------------------------
26037446Srnordier// epsilon estimation for the precision of a conversion double --> l_fp
261190927Sed//
26237446Srnordier// The error estimation limit is as follows:
26337446Srnordier//  * The 'l_fp' fixed point fraction has 32 bits precision, so we allow
26437446Srnordier//    for the LSB to toggle by clamping the epsilon to be at least 2^(-31)
265185587Sluigi//
266185587Sluigi//  * The double mantissa has a precsion 54 bits, so the other minimum is
267185587Sluigi//    dval * (2^(-53))
26837446Srnordier//
26937446Srnordier//  The maximum of those two boundaries is used for the check.
27037446Srnordier//
27137446Srnordier// Note: once there are more than 54 bits between the highest and lowest
27237446Srnordier// '1'-bit of the l_fp value, the roundtrip *will* create truncation
27337446Srnordier// errors. This is an inherent property caused by the 54-bit mantissa of
274185587Sluigi// the 'double' type.
275185587Sluigidouble
276185587Sluigieps(double d)
27737446Srnordier{
27837446Srnordier	return fmax(ldexp(1.0, -31), ldexp(fabs(d), -53));
27937446Srnordier}
28037446Srnordier
28137446Srnordier//----------------------------------------------------------------------
28237446Srnordier// test addition
28337446Srnordier//----------------------------------------------------------------------
28437446Srnordiervoid
28537446Srnordiertest_AdditionLR(void) {
28637446Srnordier
28737446Srnordier	size_t idx = 0;
28837446Srnordier	for (idx = 0; idx < addsub_cnt; ++idx) {
28937446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
29037446Srnordier		l_fp op2 = l_fp_init(addsub_tab[idx][1].h, addsub_tab[idx][1].l);
29137446Srnordier		l_fp exp = l_fp_init(addsub_tab[idx][2].h, addsub_tab[idx][2].l);
29237446Srnordier		l_fp res = l_fp_add(op1, op2);
29337446Srnordier
29437446Srnordier		TEST_ASSERT_EQUAL_l_fp(exp, res);
29537446Srnordier	}
29637446Srnordier}
29737446Srnordier
29837446Srnordiervoid
29937446Srnordiertest_AdditionRL(void) {
30037446Srnordier	size_t idx = 0;
30137446Srnordier	for (idx = 0; idx < addsub_cnt; ++idx) {
30237446Srnordier		l_fp op2 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
30337446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][1].h, addsub_tab[idx][1].l);
30437446Srnordier		l_fp exp = l_fp_init(addsub_tab[idx][2].h, addsub_tab[idx][2].l);
30537446Srnordier		l_fp res = l_fp_add(op1, op2);
30637446Srnordier
30737446Srnordier		TEST_ASSERT_EQUAL_l_fp(exp, res);
30837446Srnordier	}
30937446Srnordier}
31037446Srnordier
31137446Srnordier
31237446Srnordier
31337446Srnordier//----------------------------------------------------------------------
31437446Srnordier// test subtraction
31537446Srnordier//----------------------------------------------------------------------
31637446Srnordiervoid
31737446Srnordiertest_SubtractionLR(void) {
31837446Srnordier	size_t idx = 0;
31937446Srnordier	for (idx = 0; idx < addsub_cnt; ++idx) {
32037446Srnordier		l_fp op2 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
32137446Srnordier		l_fp exp = l_fp_init(addsub_tab[idx][1].h, addsub_tab[idx][1].l);
32237446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][2].h, addsub_tab[idx][2].l);
32337446Srnordier		l_fp res = l_fp_subtract(op1, op2);
32437446Srnordier
32537446Srnordier		TEST_ASSERT_EQUAL_l_fp(exp, res);
32637446Srnordier	}
32737446Srnordier}
32837446Srnordier
32937446Srnordiervoid
33037446Srnordiertest_SubtractionRL(void) {
33137446Srnordier	size_t idx = 0;
33237446Srnordier	for (idx = 0; idx < addsub_cnt; ++idx) {
33337446Srnordier		l_fp exp = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
33437446Srnordier		l_fp op2 = l_fp_init(addsub_tab[idx][1].h, addsub_tab[idx][1].l);
33537446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][2].h, addsub_tab[idx][2].l);
33637446Srnordier		l_fp res = l_fp_subtract(op1, op2);
33737446Srnordier
33837446Srnordier		TEST_ASSERT_EQUAL_l_fp(exp, res);
33937446Srnordier	}
34037446Srnordier}
34137446Srnordier
342102231Strhodes//----------------------------------------------------------------------
34337446Srnordier// test negation
34437446Srnordier//----------------------------------------------------------------------
34537446Srnordier
34637446Srnordiervoid
34737446Srnordiertest_Negation(void) {
34837446Srnordier
34937446Srnordier	size_t idx = 0;
35037446Srnordier	for (idx = 0; idx < addsub_cnt; ++idx) {
35137446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
35237446Srnordier		l_fp op2 = l_fp_negate(op1);
35337446Srnordier		l_fp sum = l_fp_add(op1, op2);
35437446Srnordier
355190932Sed		l_fp zero = l_fp_init(0, 0);
35663892Sasmodai
35737446Srnordier		TEST_ASSERT_EQUAL_l_fp(zero, sum);
35837446Srnordier	}
35937446Srnordier}
36037446Srnordier
361185587Sluigi
362185587Sluigi
363185587Sluigi//----------------------------------------------------------------------
364185587Sluigi// test absolute value
365185587Sluigi//----------------------------------------------------------------------
366185587Sluigivoid
367190929Sedtest_Absolute(void) {
368185594Smlaier	size_t idx = 0;
369190930Sed	for (idx = 0; idx < addsub_cnt; ++idx) {
37037446Srnordier		l_fp op1 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
371190930Sed		l_fp op2 = l_fp_abs(op1);
372190930Sed
373190931Sed		TEST_ASSERT_TRUE(l_fp_signum(op2) >= 0);
374190931Sed
375190931Sed		if (l_fp_signum(op1) >= 0)
376190931Sed			op1 = l_fp_subtract(op1, op2);
377190931Sed		else
378190931Sed			op1 = l_fp_add(op1, op2);
379190931Sed
38037446Srnordier		l_fp zero = l_fp_init(0, 0);
38137446Srnordier
382185587Sluigi		TEST_ASSERT_EQUAL_l_fp(zero, op1);
383185594Smlaier	}
38437446Srnordier
38537446Srnordier	// There is one special case we have to check: the minimum
38637446Srnordier	// value cannot be negated, or, to be more precise, the
387203869Skib	// negation reproduces the original pattern.
388203869Skib	l_fp minVal = l_fp_init(0x80000000, 0x00000000);
389203869Skib	l_fp minAbs = l_fp_abs(minVal);
390203869Skib	TEST_ASSERT_EQUAL(-1, l_fp_signum(minVal));
39137446Srnordier
39237446Srnordier	TEST_ASSERT_EQUAL_l_fp(minVal, minAbs);
393203869Skib}
39437446Srnordier
395203869Skib
39637446Srnordier//----------------------------------------------------------------------
397203869Skib// fp -> double -> fp rountrip test
39837446Srnordier//----------------------------------------------------------------------
399203869Skibvoid
40037446Srnordiertest_FDF_RoundTrip(void) {
401203869Skib	// since a l_fp has 64 bits in it's mantissa and a double has
402185587Sluigi	// only 54 bits available (including the hidden '1') we have to
403185587Sluigi	// make a few concessions on the roundtrip precision. The 'eps()'
40437446Srnordier	// function makes an educated guess about the avilable precision
405203869Skib	// and checks the difference in the two 'l_fp' values against
406203869Skib	// that limit.
407185587Sluigi	size_t idx = 0;
408185587Sluigi	for (idx = 0; idx < addsub_cnt; ++idx) {
409203869Skib		l_fp op1 = l_fp_init(addsub_tab[idx][0].h, addsub_tab[idx][0].l);
410203869Skib		double op2 = l_fp_convert_to_double(op1);
411185587Sluigi		l_fp op3 = l_fp_init_from_double(op2);
412203869Skib
413203869Skib		l_fp temp = l_fp_subtract(op1, op3);
414203869Skib		double d = l_fp_convert_to_double(temp);
415203869Skib 		TEST_ASSERT_DOUBLE_WITHIN(eps(op2), 0.0, fabs(d));
416203869Skib	}
417203869Skib}
418203869Skib
419203869Skib
420203869Skib//----------------------------------------------------------------------
421185587Sluigi// test the compare stuff
422203869Skib//
423185587Sluigi// This uses the local compare and checks if the operations using the
424185587Sluigi// macros in 'ntp_fp.h' produce mathing results.
425203869Skib// ----------------------------------------------------------------------
426203869Skibvoid
427203869Skibtest_SignedRelOps(void) {
42837446Srnordier	const lfp_hl * tv = (&addsub_tab[0][0]);
429203869Skib	size_t lc ;
43048954Sbillf	for (lc = addsub_tot - 1; lc; --lc, ++tv) {
43137446Srnordier		l_fp op1 = l_fp_init(tv[0].h, tv[0].l);
43237446Srnordier		l_fp op2 = l_fp_init(tv[1].h, tv[1].l);
43337446Srnordier		int cmp = l_fp_scmp(op1, op2);
43437446Srnordier
43548954Sbillf		switch (cmp) {
43637446Srnordier		case -1:
43737446Srnordier			//printf("op1:%d %d, op2:%d %d\n",op1.l_uf,op1.l_ui,op2.l_uf,op2.l_ui);
43837446Srnordier			l_fp_swap(&op1, &op2);
43937446Srnordier			//printf("op1:%d %d, op2:%d %d\n",op1.l_uf,op1.l_ui,op2.l_uf,op2.l_ui);
44037446Srnordier		case 1:
441203869Skib			TEST_ASSERT_TRUE (l_isgt(op1, op2));
44237446Srnordier			TEST_ASSERT_FALSE(l_isgt(op2, op1));
44337446Srnordier
44437446Srnordier			TEST_ASSERT_TRUE (l_isgeq(op1, op2));
445203869Skib			TEST_ASSERT_FALSE(l_isgeq(op2, op1));
44637446Srnordier
447203869Skib			TEST_ASSERT_FALSE(l_isequ(op1, op2));
448203869Skib			TEST_ASSERT_FALSE(l_isequ(op2, op1));
44937446Srnordier			break;
450203869Skib		case 0:
451203869Skib			TEST_ASSERT_FALSE(l_isgt(op1, op2));
45237446Srnordier			TEST_ASSERT_FALSE(l_isgt(op2, op1));
45337446Srnordier
45437446Srnordier			TEST_ASSERT_TRUE (l_isgeq(op1, op2));
45537446Srnordier			TEST_ASSERT_TRUE (l_isgeq(op2, op1));
456203869Skib
45737446Srnordier			TEST_ASSERT_TRUE (l_isequ(op1, op2));
45837446Srnordier			TEST_ASSERT_TRUE (l_isequ(op2, op1));
459203869Skib			break;
46037446Srnordier		default:
46137446Srnordier			TEST_FAIL_MESSAGE("unexpected UCMP result: " );
46237446Srnordier		}
46337446Srnordier	}
464203869Skib}
46537446Srnordier
46637446Srnordiervoid
467203869Skibtest_UnsignedRelOps(void) {
46837446Srnordier	const lfp_hl * tv =(&addsub_tab[0][0]);
46937446Srnordier	size_t lc;
47041586Srnordier	for (lc = addsub_tot - 1; lc; --lc, ++tv) {
471203869Skib		l_fp op1 = l_fp_init(tv[0].h, tv[0].l);
47237446Srnordier		l_fp op2 = l_fp_init(tv[1].h, tv[1].l);
47337446Srnordier		int cmp = l_fp_ucmp(op1, op2);
474203869Skib
47537446Srnordier		switch (cmp) {
476203869Skib		case -1:
47737446Srnordier			//printf("op1:%d %d, op2:%d %d\n",op1.l_uf,op1.l_ui,op2.l_uf,op2.l_ui);
478203869Skib			l_fp_swap(&op1, &op2);
47937446Srnordier			//printf("op1:%d %d, op2:%d %d\n",op1.l_uf,op1.l_ui,op2.l_uf,op2.l_ui);
48037446Srnordier		case 1:
48137446Srnordier			TEST_ASSERT_TRUE (l_isgtu(op1, op2));
48237446Srnordier			TEST_ASSERT_FALSE(l_isgtu(op2, op1));
48337446Srnordier
48437446Srnordier			TEST_ASSERT_TRUE (l_ishis(op1, op2));
48542261Sjkh			TEST_ASSERT_FALSE(l_ishis(op2, op1));
48637446Srnordier			break;
48737446Srnordier		case 0:
48837446Srnordier			TEST_ASSERT_FALSE(l_isgtu(op1, op2));
48937446Srnordier			TEST_ASSERT_FALSE(l_isgtu(op2, op1));
49037446Srnordier
491203869Skib			TEST_ASSERT_TRUE (l_ishis(op1, op2));
492203869Skib			TEST_ASSERT_TRUE (l_ishis(op2, op1));
49337446Srnordier			break;
494203869Skib		default:
49537446Srnordier			TEST_FAIL_MESSAGE("unexpected UCMP result: " );
496203869Skib		}
497203869Skib	}
49848954Sbillf}
499203869Skib/*
500203869Skib*/
501203869Skib
502203869Skib//----------------------------------------------------------------------
503203869Skib// that's all folks... but feel free to add things!
504203869Skib//----------------------------------------------------------------------
505203869Skib