简体   繁体   English

在 MIPS 中将两个 IEEE 754 浮点数相乘

[英]Multiplying two IEEE 754 floating point numbers in MIPS

I am trying to multiply two IEEE 754 numbers in MIPS assembly without using floating point operations.我试图在不使用浮点运算的情况下将 MIPS 程序集中的两个 IEEE 754 数字相乘。

I have two floating point numbers stored in $a0 and $a1我有两个浮点数存储在 $a0 和 $a1

multiply_fp:    #$s0 = final sign bit, $s1 = final exponent, $s2 = final mantissa

    #check the sign bit
    srl $t1, $a0, 31    # leave just sign bit
    srl $t2, $a1, 31    # leave just sign bit

    bnez $t1, negative  # check if sign bit is 1
    bnez $t2, negative  # check if sign bit is 1
positive:   
    addi $s0, $zero, 0  # set sign bit to 0
    j exponent
negative:
    addi $s0, $zero, 10000000000000000000000000000000   #set sign bit to 1
exponent:
    andi $t1, $a0, 01111111100000000000000000000000     #get exponent bits from fp1
    andi $t2, $a1, 01111111100000000000000000000000     #get exponent bits from fp2
    srl $t1, $t1, 23                    #move them all the way to the right
    srl $t2, $t2, 23
    add $s1, $t1, $t2                   #add them together
    addi $s1, $s1, -127                 #subtract 127 from the sum
    sll $s1, $s1, 23                    #move them back to the right position

mantissa:
    andi $t1, $a0, 00000000011111111111111111111111     #get the mantissa bits from fp1
    andi $t2, $a1, 00000000011111111111111111111111     #get the mantissa bits from fp2
    ori $t1, $t1, 00000000100000000000000000000000      #add a 1 at the msb
    ori $t2, $t2, 00000000100000000000000000000000
    mul $s2, $t1, $t2                   #multiply the mantissas
    andi $s2, 00000000011111111111111111111111      #cut the 1 back off

combine:
    or $v0, $s0, $s1
    or $v0, $v0, $s2

    jr $ra

I am having trouble with the mantissa section I think.我认为尾数部分有问题。 According to my logic I am to multiply the fraction portion and then get rid of leading 1. For example 1.011 * 1.010 = 1.10111 and I would cut off the leading 1 to result in 10111 as my new mantissa.根据我的逻辑,我将乘以小数部分,然后去掉前导 1。例如 1.011 * 1.010 = 1.10111,我会切断前导 1 以得到 10111 作为我的新尾数。 I do this similarly by just removing the decimal points so: 1011 * 1010 = 110111 and cut off the leading 1 to result in 10111.我通过删除小数点来类似地执行此操作:1011 * 1010 = 110111 并切断前导 1 以产生 10111。

However the mul function is giving very odd results, and I'm not sure why.然而 mul 函数给出了非常奇怪的结果,我不知道为什么。 Can anyone see errors with my logic?谁能看到我的逻辑错误?

Unfortunately I'm not that good with IEEE 754 to fix your mul without some studying, but the function prologue got me interested...不幸的是,我不太擅长使用 IEEE 754 来修复您的 mul,而无需进行一些学习,但是函数序言让我感兴趣......

If you enter it with two negative numbers, it will jump to negative: , while the answer should be positive.如果你输入两个负数,它会跳到negative: ,而答案应该是正数。

You can calculate target sign for example like this:您可以像这样计算目标符号:

multiply_fp:
    xor     $s0, $a0, $a1   # multiply sign bits
    andi    $s0, 0x80000000 # extract sign bit to s0

And I'm not sure what assembler you use, I have only MARS here, and that one compiles those binary numbers wrongly.而且我不确定你使用的是什么汇编程序,我这里只有 MARS,而且那个二进制数编译错误。 I was also unable to find any help for its syntax (the included help is very vague about numeric constants and possible formatting).我也找不到任何关于它的语法的帮助(包含的帮助对于数字常量和可能的格式非常模糊)。

So instead of:所以而不是:

andi $t1, $a0, 01111111100000000000000000000000     #get exponent bits from fp1
andi $t2, $a1, 01111111100000000000000000000000     #get exponent bits from fp2

I would stick to good old hexa:我会坚持老六:

andi $t1, $a0, 0x7F800000     #get exponent bits from fp1
andi $t2, $a1, 0x7F800000     #get exponent bits from fp2

When I tried in MARS to call your code with ~0 in both a0, a1 , after andi the result is 0x9D800000 , which is plain wrong.当我在 MARS 中尝试在a0, a1使用~0调用您的代码时,在andi之后结果是0x9D800000 ,这是完全错误的。 The same goes for the mantissa andi , completely borked in MARS.尾数andi ,在 MARS 中完全无聊。

Maybe your assembler does understand those, but I suggest to verify.也许您的汇编程序确实理解这些,但我建议您进行验证。

And you should probably handle exponent under/overflow, like this?你可能应该像这样处理指数下/溢出?

    # calculate exponent - extract exponents to t1, t2
    srl     $t1, $a0, 23
    srl     $t2, $a1, 23
    andi    $t1, $t1, 0xFF
    andi    $t2, $t2, 0xFF
    addu    $s1, $t1, $t2     # add exponents together
    bltu    $s1, 127, exp_too_small # if exp is less than 127 => too small
    addiu   $s1, $s1, -127    # subtract 127 from the sum
    sll     $s1, $s1, 23      #move exp back to the right position
    bltz    $s1, exp_too_big  # if sign bit is set, exponent is too big
srl     $t1, $a0, 23 //This take the exponent part 
andi    $t1, $t1, 0xFF 

in that part $t1 is the exponent part of this number, if anyone wants to find exponent part of it they can use it.在那个部分$t1是这个数字的指数部分,如果有人想找到它的指数部分,他们可以使用它。

I have wrote this because in my lab assignment i have to find the exponent part,thanks to this i can figure out my problem.我写这个是因为在我的实验室作业中我必须找到指数部分,因此我可以找出我的问题。

If anyone has problem like that they can use the code which is above.如果有人有这样的问题,他们可以使用上面的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM