         ttl       ieee format equivalent back-end routines (iefback)
iefback  idnt   1,1  ieee format equivalent back-end routines
******************************************
*  (c)  copyright 1981 by motorola inc.  *
******************************************
 
         section   9
 
****************************************************************
*              iefrtnan (internal routine)                     *
*  ieee format equivalent fast floating point return nan       *
*                                                              *
*  input: sp -> +0  original callers d3-d7 registers           *
*              +20  original callers return address            *
*                                                              *
*  output: d7 - a newly created nan (not-a-number)             *
*          ccr - the "v" bit is forced on                      *
*                                                              *
*          and direct return to the original caller            *
*                                                              *
*  purpose:  called whenever the result of an operation        *
*          is illegal or undefined and a nan result must       *
*          be generated as the final result.                   *
*                                                              *
*   the ieee format defined nan is determined by an exponent   *
*   of all one's and a non-zero significand.  the sign bit     *
*   is a don't care.  the ieee standard leaves up to each      *
*   implementation what is placed in the significand.  here    *
*   we will generate the low order 23 bits of the original     *
*   caller's return address.  however, this may not be         *
*   sufficient - if all 23 bits happen to be zero or the       *
*   address is larger than 23 bits this would lead to an       *
*   incorrect result.  therfore, if this happens only the low  *
*   order significand bit is set on with the rest zeroes.      *
*   this represents an odd address (illegal with current m68000*
*   instruction alignment restrictions) and any interested     *
*   party can tell if such a substitution has taken place.     *
*   also, if this was illegally assumed to be an address and   *
*   used, an address exception trap would ensue thus not       *
*   allowing its use as a valid address.                       *
*                                                              *
****************************************************************
 
signmsk  equ       $80000000 ieee format sign isolation mask
expmsk   equ       $7f800000 ieee format exponent mask
vbit     equ       $0002     condition code "v" bit mask
zbit     equ       $0004     condition code "z" bit mask
 
         xdef      iefrtnan  return nan result routine
 
iefrtnan movem.l   (sp)+,d3-d7         restore callers registers
         move.l    (sp),d7             load up return address
         and.l     #signmsk+expmsk,d7  verify not larger than 23 bits
         bne.s     iefnone             it is, cannot use it - return a one
         move.l    (sp),d7             load up return address
         and.l     #$007fffff,d7       isolate address bits required
         bne.s     iefnzro             branch if not zero
iefnone  move.l    #1,d7               set only low bit on
iefnzro  or.l      #expmsk,d7          force exponent all ones
         or.b      #vbit,ccr           return with "v" bit set [vlh]
         rts                           return to original caller
         page
**********************************************************
*           ieftieee (internal subroutine)               *
*  ieee format compatible convert ffp to ieee format     *
*                                                        *
*  input: d7 - result of fast floating point operation   *
*         ccr - set for above result                     *
*         sp -> +0  original callers saved d3-d7         *
*              +20  original callers return address      *
*                                                        *
*  output: d7 - ieee format equivalent of the result     *
*                                                        *
*  condition code:                                       *
*                                                        *
*              n - set if the result is negative         *
*              z - set if the result is zero             *
*              v - cleared (not nan)                     *
*              c - cleared                               *
*              x - undefined                             *
*                                                        *
*    all fast floating point numbers have an exact       *
*    ieee format representation.  since the fast         *
*    floating point routines always set the "v" bit      *
*    for overflows and returns the proper sign, we       *
*    can easily change the result to an ieee infinity    *
*    and unflag the "v" bit.                             *
*                                                        *
**********************************************************
 
         xdef      ieftieee  return ieee result to original caller
 
ieftieee bvs.s     iefvset   branch if overflow ffp result
         add.l     d7,d7     delete mantissa high bit
         beq.s     ieftrtn   branch zero as finished
         eor.b     #$80,d7   to twos complement exponent
         asr.b     #1,d7     form 8-bit exponent
         sub.b     #$82,d7   adjust 64 to 127 and excessize
         swap.w    d7        swap for high byte placement
         rol.l     #7,d7     set sign+exp in high byte
ieftrtn  tst.l     d7        test "z" and "n", clear "v" and "c" in ccr
         movem.l   (sp)+,d3-d6 restore d3 thru d6 callers registers
         add.l     #4,sp     skip original d7
         rts                 return to original caller with result
 
* overflow - set to proper ieee format infinity
iefvset  add.b     d7,d7     save sign bit in "x"
         move.l    #expmsk<<1,d7 set exponent of ones shifted left
         roxr.l    #1,d7     insert proper sign
         bra       ieftrtn   and return to original caller
         page
*******************************************************************
*  general purpose return routines                                *
*                                                                 *
*  the following routines return a specific final result          *
*  to the original caller with the proper condition codes         *
*  set as follows:                                                *
*                                                                 *
*              n - the result is negative                         *
*              z - the result is a zero                           *
*              v - cleared (not a nan)                            *
*              c - undefined                                      *
*              x - undefined                                      *
*                                                                 *
*  the routines are as follows:                                   *
*                                                                 *
*   iefrtd7  - return the current contents of d7                  *
*   iefrtod7 - return the original contents of d7                 *
*   iefrtsz  - return a signed zero (sign is bit 31 of d7)        *
*   iefrtie  - return infinity with sign exclusive or of          *
*              original argument signs                            *
*   iefrtsze - return signed zero with sign exclusiv or           *
*              of original argument signs                         *
*                                                                 *
*******************************************************************
 
         xdef      iefrtd7,iefrtsz,iefrtod7,iefrtie,iefrtsze
 
**********************
* return original d7 *
* (cant be neg zero) *
**********************
iefrtod7 move.l    16(sp),d7  load original d7 into d7
 
*********************
* return current d7 *
* (cant be neg zero)*
*********************
iefrtd7  movem.l   (sp)+,d3-d6         load all but d7 registers back up
         add.l     #4,sp     skip original d7 on stack
         add.l     d7,d7     check for signed zero
         beq.s     iefwasz   branch if was a zero
         roxr.l    #1,d7     value back into position set ccr ("v" clear)
         rts                 return to caller with ccr and result
 
**************************************
* return signed zero with sign being *
* eor of the original operands       *
**************************************
iefrtsze movem.l   12(sp),d6-d7 load original arguments
         eor.l     d6,d7     produce proper sign
 
**********************
* return signed zero *
* d7 bit31 has sign  *
**********************
iefrtsz  movem.l   (sp)+,d3-d6 load all but d7 back up
         add.l     #4,sp     skip original d7 on stack
         add.l     d7,d7     set sign bit into carry
         move.l    #0,d7     zero d7
iefwasz  roxr.l    #1,d7     set sign bit back in ("v" cleared)
         or.b      #zbit,ccr  force zero bit on in ccr [vlh]
         rts
 
*********************************
* return infinity with eor sign *
* of original arguments         *
*********************************
iefrtie  movem.l   (sp)+,d3-d7 restore original arguments
         eor.l     d6,d7   produce proper sign
         add.l     d7,d7     shift sign out
         move.l    #expmsk<<1,d7 setup infinity (exponent all ones)
         roxr.l    #1,d7     set sign back in ("v" cleared)
         rts                 return with result and ccr set
 
         end
