1/* Copyright (c) 2002 Michael Stumpf <mistumpf@de.pepperl-fuchs.com> 2 Copyright (c) 2006,2008 Dmitry Xmelkov 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are met: 7 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in 12 the documentation and/or other materials provided with the 13 distribution. 14 * Neither the name of the copyright holders nor the names of 15 contributors may be used to endorse or promote products derived 16 from this software without specific prior written permission. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 POSSIBILITY OF SUCH DAMAGE. */ 29 30/* $Id: fp_cmp.S 2191 2010-11-05 13:45:57Z arcanum $ */ 31 32#if !defined(__AVR_TINY__) 33 34#include "fp32def.h" 35#include "asmdef.h" 36 37/* GCC expects all these functions to return -1/0/1 as for __cmpsf2 - 38 compare with gcc/config/fp-bit.c (the only difference is with NaNs 39 where we should always return nonzero for EQ/NE, -1 for GT/GE, 40 1 for LT/LE). -MM 2000-11-18 */ 41 42#define ret_lo r24 /* return value (signed byte) */ 43.ifnc ret_lo, rA2 ; This is used in __fp_cmp() function. 44 .err 45.endif 46 47/* The base compare function. 48 Return: 49 if (A < B) 50 rA2 = -1, C = 0 51 elif (A == B) 52 rA2 = 0, C = 0 53 elif (A > B) 54 rA2 = 1, C = 0 55 else // isnan(A) || isnan(B) 56 C = 1 57 */ 58ENTRY __fp_cmp 59 lsl rA3 60 sbc r0, r0 ; r0 = (A < 0) ? -1 : 0 61 lsl rB3 62 sbc rBE, rBE ; rBE = (B < 0) ? -1 : 0 63 ; isnan(A) ? 64 ldi ZL, 0x80 ; NaN: 0x{f/7}f800001..0x{f/7}fffffff 65 ldi ZH, 0xfe 66 cp r1, rA0 67 cpc r1, rA1 68 cpc ZL, rA2 69 cpc ZH, rA3 70 brlo 9f ; branch, if C == 1 71 ; isnan(B) ? 72 cp r1, rB0 73 cpc r1, rB1 74 cpc ZL, rB2 75 cpc ZH, rB3 76 brlo 9f ; branch, if C == 1 77 ; compare 78 sub rA0, rB0 79 sbc rA1, rB1 80 sbc rA2, rB2 81 sbc rA3, rB3 ; C is set, if A < B 82 brne 1f 83 ; absolute values are equal, check signs 84 eor r0, rBE 85 breq 9f ; if branch, rA2 = 0, C = 0 86 ; force -0.0 == +0.0 87 or rB0, rB1 88 or rB0, rB2 89 or rB0, rB3 90 brne 2f ; evaluate sign(B) 91 ret 92 ; view argument signes 931: eor r0, rBE ; C is not changed 94 brne 2f ; signs are different 95 sbci rBE, 1 ; rBE[0] = (A < B && A > 0) ? 0 : 1 962: lsr rBE ; C = above result OR sign(B) 97 ; build return value, C is set, if A > B 98 ldi rA2, -1 99 adc rA2, r1 100 adc rA2, r1 ; C = 0 at any case 1019: ret 102ENDFUNC 103 104#endif /* !defined(__AVR_TINY__) */ 105