1/*- 2 * Copyright (c) 1985 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Computer Consoles Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)Kaddd.s 7.1 (Berkeley) 12/06/90 11 */ 12 13#include "../math/fp.h" 14#include "../tahoe/SYS.h" 15 16/* 17 * _Kaddd(acc_most,acc_least,op_most,op_least,hfs) 18 */ 19 20ENTRY(Kaddd, R10|R9|R8|R7|R6|R5|R4|R3|R2) 21/* 22 * see which operand has a greater exponent 23 * The greater one will be fetched into r0,r1,r2,r3. 24 * r0,r1 - 'pure' fraction, r2 - exponent, r3 - sign). 25 * The smaller operand will be fetched into r4,r5,r6,r7. 26 */ 27 tstl 4(fp) # handle (a+b) where a and/or b = 0.0 28 jneq next 29 movl 16(fp),r1 30 movl 12(fp),r0 31 ret 32next: 33 tstl 12(fp) 34 jneq doit 35 movl 8(fp),r1 36 movl 4(fp),r0 37 ret 38doit: 39 andl3 $EXPMASK,4(fp),r0 40 andl3 $EXPMASK,12(fp),r1 41 cmpl r0,r1 42 jgtr first_greater 43 44 movl 12(fp),r0 # bigger operand to r0,r1 45 movl 16(fp),r1 46 47 movl 4(fp),r4 # smaller operand to r4,r5 48 movl 8(fp),r5 49 jmp expo 50 51first_greater: 52 movl 4(fp),r0 # bigger operand to r0,r1 53 movl 8(fp),r1 54 55 movl 12(fp),r4 # smaller operand to r4,r5 56 movl 16(fp),r5 57 58 59/* 60 * Compute exponents: 61 */ 62expo: 63 andl3 $EXPMASK,r0,r2 # r2 will hold the exponent. 64 shrl $EXPSHIFT,r2,r2 65 andl3 $EXPMASK,r4,r6 # r6 will hold the exponent. 66 shrl $EXPSHIFT,r6,r6 67/* 68 * Compare the exponents: 69 */ 70 subl3 r6,r2,r8 71 jeql signs 72 cmpl r8,$MAX_EXP_DIF 73 jleq signs 74 ret # return the bigger number. 75 76/* 77 * Remember the signs: 78 */ 79signs: 80 clrl r3 81 bbc $31,r0,sign2 # if negative remember it. 82 incl r3 83sign2: 84 clrl r7 85 bbc $31,r4,frac # if negative remember it. 86 incl r7 87/* 88 * Compute 'pure' fraction: 89 */ 90frac: 91 # clear the non fraction parts. 92 andl2 $(0!(EXPMASK | SIGNBIT)),r0 93 # add the hidden bit. 94 orl2 $(0!CLEARHID),r0 95 # clear the non fraction parts. 96 andl2 $(0!(EXPMASK | SIGNBIT)),r4 97 # add the hidden bit. 98 orl2 $(0!CLEARHID),r4 99 100/* 101 * Shift the smaller operand: 102 */ 103 shrq r8,r4,r4 104eql_exps: 105 cmpl r3,r7 106 jeql add 107 bbc $0,r3,negr4r5 108/* 109 * Negate the pair r0,r1: 110 */ 111 clrl r3 112 mcoml r1,r1 113 clrl r9 # r9 - carry flag. 114 incl r1 115 bcc comr0 116 incl r9 # remember the carry. 117comr0: mcoml r0,r0 118 bbc $0,r9,add 119 incl r0 120 121/* 122 * Add the fractions: 123 */ 124add: 125 clrl r10 # to remember the sign of the result. 126 addl2 r5,r1 127 adwc r4,r0 128 jgeq norm # if positive go to normelize. 129 incl r10 # else remember it and negate the result. 130/* 131 * Negate the pair r0,r1: 132 */ 133 clrl r3 134 mcoml r1,r1 135 clrl r9 # r9 - carry flag. 136 incl r1 137 bcc comr00 138 incl r9 # remember the carry. 139comr00: mcoml r0,r0 140 bbc $0,r9,norm 141 incl r0 142norm: pushl 20(fp) # addr of returnen exception. 143 callf $8,_Kfnorm 144 145/* 146 * Add the sign bit 147 */ 148 bbs $0,r10,negative 149 bbs $0,r3,negative 150 ret 151negative: 152 orl2 $SIGNBIT,r0 153 ret 154 155 156/* 157 * Negate the pair r4,r5: 158 */ 159negr4r5: 160 clrl r7 161 mcoml r5,r5 162 clrl r9 # r9 - carry flag. 163 incl r5 164 bcc comr4 165 incl r9 # remember the carry. 166comr4: mcoml r4,r4 167 bbc $0,r9,add 168 incl r4 169 jmp add 170 171 movl r4,r0 # return the smaller operand. 172 movl r5,r1 173 ret 174