1/* Copyright (c) 2002 Michael Stumpf <mistumpf@de.pepperl-fuchs.com> 2 Copyright (c) 2006 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_split3.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/* <non_standart> __fp_split3 (float A, float B); 38 It splits two float numbers. 39 40 Return: 41 rA3, rA2.rA1.rA0 - exponent and mantissa of A (see __fp_splitA) 42 rB3, rB2.rB1.rB0 - exponent and mantissa of B (see __fp_splitA) 43 Flags: 44 C = 0 - both numbers are finite 45 C = 1 - A and/or B is Inf/NaN 46 T = sign(A) ^ sign(B) 47 48 Notes: 49 * Flag is different sense vs __fp_splitA() 50 * All other registers are not changed. 51 */ 52ENTRY __fp_split3 53 ; rA3[7] := sign(A) ^ sign(B) 54 sbrc rB3, 7 55 subi rA3, 0x80 56 ; split B 57 lsl rB2 58 rol rB3 ; exponent 59 breq 4f 60 cpi rB3, 0xff ; C = 1, if rB3 != 0xff 61 breq 5f 621: ror rB2 ; restore rB2 and (possible) hidden bit 63 64/* <non_standart> __fp_splitA (float A); 65 It splits an A float number. 66 67 Return: 68 rA3 - exponent: 69 0 for +0.0/-0.0 70 1..254 for finite number 71 255 for Inf/NaN 72 rA2.rA1.rA0 - mantissa: 73 0 for +0.0/-0.0 74 0x000001..0x7fffff for subnormal (and rA3 = 1) 75 0x800000..0xffffff for normal (rA3 = 1..254) 76 0x000000 for Inf 77 0x000001..0x7fffff for NaN 78 Flags: 79 C = 0 for finite number 80 C = 1, Z = 1 for Inf 81 C = 1, Z = 0 for NaN 82 T = sign 83 84 Notes: 85 * Other registers are not scratched. 86 */ 87ENTRY __fp_splitA 88 lsl rA2 892: bst rA3, 7 90 rol rA3 91 breq 6f 92 cpi rA3, 0xff 93 breq 7f 943: ror rA2 95 ret 96 97 ; B is zero or subnormal 984: cp r1, rB0 99 cpc r1, rB1 100 cpc r1, rB2 ; C = 1, if B is not a zero 101 rol rB3 ; C = 0 102 rjmp 1b 103 ; B is not a finite 1045: lsr rB2 105 rcall __fp_splitA 106 rjmp 8f 107 108 ; A is zero or subnormal 1096: cp r1, rA0 110 cpc r1, rA1 111 cpc r1, rA2 112 rol rA3 113 rjmp 3b 114 ; A is not a finite 1157: lsr rA2 ; C = 0 116 cpc rA1, r1 117 cpc rA0, r1 1188: sec 119 ret 120ENDFUNC 121 122#endif /* !defined(__AVR_TINY__) */ 123