在没有FPU的情况下,在MIPS组件中将双精度除以单精度

时间:2013-01-15 00:39:14

标签: assembly mips division ieee-754 fpu

我必须在MIPS程序集中创建一个程序,它将双精度浮点数除以单精度数(使用标准IEEE 754)而不使用浮点指针单元。我唯一无法理解的是如何处理两个数字的尾数来计算除法,这里是代码,除法的部分是在标签divis中:(在$ t2和$ t3我有两个部分的双精度数尾数,$ t6单精度的尾数)......

.data
res: .asciiz "result is="
neg_res: .asciiz "result is= - "
choice: .asciiz "\nMake your choice:\n1)execute\n2)exit\n"
wrong: .asciiz "Inserted value not correct!!"
first: .asciiz "insert the first number"
n: .asciiz "\n"
second: .asciiz "insert the second number"
divz: .asciiz "can't divide for 0"
.text

main:
la $a0, choice
li $v0, 4
syscall         #Print first part

li $v0, 5
syscall         #input choice

move $t7, $v0       
beq $t7,2, end      #Control=2
blt $t7,1, err      #control<1
bgt $t7,2, err      #control>2

getdoub:

la $a0, first
li $v0, 4
syscall         #Message for input numerator

li $v0, 7
syscall
mov.d $f4, $f0      #input double numerator

getfloat:

la $a0, second
li $v0, 4
syscall         

li $v0, 6
syscall
mov.s $f6, $f0      #input float denominator

li $t1,1
mtc1 $t1,$f8
cvt.s.w $f8,$f8
c.eq.s $f6,$f8      #Control if the denominator is =1
bc1t print_dou      #print double

li $t0,0
mtc1 $t0,$f8
cvt.s.w $f8,$f8
c.eq.s $f6,$f8      #Control if denominator è =0
bc1t errz       #print error

# fin qua tutto bene

sign_d:

cvt.d.s $f8,$f8     #convert from single to double to avoid errors in compare
c.lt.d $f4, $f8     #control sign of double
bc1t  minus_d       #if c1 is true (that means $f4<$f8) jump to minus_d
b plus_d        #otherwise plus_d

minus_d:

li $t0, 1       #negative sign

plus_d:

li $t0, 0       #positive sign

extr_double:

mfc1.d  $t2,$f4         #in $t2 I've sign, exponent and 20 bit of mantissa    in t3, 32 bit of mantissa
li $t6, 2146435072      #Mask for 11 bit of exponent
and $t1,$t2,$t6         #in $t1 Exponent
li $t6, 1048575         #mask for 20 bit of mantissa
and $t2, $t2,$t6
add $t2,$t2, 2097152        #in t2 I've mantissa 1 and in t3 ho la mantissa 2 automatically

# fin qui logicamente ci siamo... I've taken sign, exponent, mantissa 1 and 2

sign_s:

cvt.s.d $f8, $f8        #convert $f8 from double to single
c.lt.s $f6, $f8         #same control made for numerator
bc1t minus_s
b plus_s

minus_s:

li $t4, 1
b extr_sing

plus_s:

li $t4,0
            # t4 sign
extr_sing:

mfc1 $t6,$f6
li $t7, 2139095040  # 8 bit of exponent a 1 
and  $t5,$t6,$t7    # in $t5 I've exponent

li $t7, 8388607     #mask for 23 bit
and $t6, $t6,$t7
add $t6, $t6, 16777216  # in $t6 I've mantissa

sign:

xor $t0,$t0,$t4     #Sign of result
beqz $t0, print_res
b p_neg_res

exp:

sub $t5,$t5, 1023   #taking real exponent
sub $t1,$t1, 127    #taking real exponent
sub $t1,$t1,$t5     #in $t1 I've the exponent of the final number
add $t1,$t1, 1023   #adding bias (the final number will be a double)
sll $t1,$t1,20      #shifting so when I add $t2 (the first part of mantissa) I    have the number in the right position

divis:

div $t3,$t3,$t6     #first part of division (32 bit of mantissa) 
div $t2,$t2,$t6     #second part of division (20 bit of mantissa)
            #HUGE QUESTION MARK
add $t2, $t1,$t2    #Adding exponent and mantissa, in this way in $t2 I have all the information
mtc1.d $t2,$f4      #$t2 & $t3 are moved in $f4 & $f5 so I have a double number   in $f4...I Hope
b print_dou
print_res:          #Print positive result
la $a0, res
li $v0, 4
syscall

b divis

p_neg_res:          #print negative result
la $a0, neg_res
li $v0, 4
syscall
b divis

err:                #Error in the choice
la $a0, wrong
li $v0, 4
syscall
b main
end:                #End program
li $v0,10
syscall
errz:               #Error dividing by 0
la $a0, divz
li $v0, 4
syscall
b main
print_dou:          #Print the number!!

mov.d $f12,$f4
li $v0,3
syscall
b main

0 个答案:

没有答案