A.U.TH. Computer Architecture and Design Lab quiz5 assignement. A floating point multiplication implementation for MIPS. In this project there are no corner cases(like, NaN, Inf, Zero etc...) as requested.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
6.4 KiB

  1. .text
  2. .globl main
  3. main:
  4. # intro - stack-frame
  5. addi $sp, $sp, -8 # main
  6. sw $ra, 4($sp)
  7. sw $fp, 0($sp)
  8. addi $fp, $sp, 0 # stack arguments (no)
  9. li $a0, 0xbf800000 # <-- test case goes here
  10. li $a1, 0x3f800000
  11. jal multFloat
  12. # epilogue - stack-frame
  13. lw $fp, 0($sp)
  14. lw $ra, 4($sp)
  15. addi $sp, $sp, 8
  16. jr $ra
  17. #
  18. # encodeFloat (sign, exp, mant)
  19. # Arguments
  20. # $a0: The sign
  21. # $a1: The exponent without the bias
  22. # $a2: The normalized mantissa 24bit, with the implied bit
  23. # Retuen
  24. # $v0: The floating point word
  25. encodeFloat:
  26. # intro - stack-frame
  27. addi $sp, $sp, -8 # encodeFloat
  28. sw $ra, 4($sp)
  29. sw $fp, 0($sp)
  30. addi $fp, $sp, 0 # stack arguments (no)
  31. sll $v0, $a0, 31 # v0 = sign << 31
  32. addi $a1, $a1, 127 # v0 |= (exp + offset) << 23
  33. sll $a1, $a1, 23
  34. or $v0, $v0, $a1
  35. li $t0, 0x7FFFFF # v0 |= (mant & 0x7FFFFF);
  36. and $a2, $a2, $t0
  37. or $v0, $v0, $a2
  38. # epilogue - stack-frame
  39. lw $fp, 0($sp)
  40. lw $ra, 4($sp)
  41. addi $sp, $sp, 8
  42. jr $ra
  43. #
  44. # decodeFloat(number)
  45. # arguments
  46. # $a0 : 32bit floating point
  47. # return
  48. # $v0 : sign unsigned int 0 or 1
  49. # $v1 : exponent the value of bits(30:24) - 127, signed integer
  50. # $a1 : mantissa with bits 1 followed by bits (22:0)
  51. decodeFloat:
  52. # intro - stack-frame
  53. addi $sp, $sp, -8 # decodeFloat
  54. sw $ra, 4($sp)
  55. sw $fp, 0($sp)
  56. addi $fp, $sp, 0 # stack arguments (no)
  57. srl $v0, $a0, 31 # sign[v0] = a0 >> 31;
  58. srl $t0, $a0, 23 # exp[v1] = ((a0 >> 23) & 0xFF) - 127;
  59. and $t0, $t0, 0xFF
  60. addi $v1, $t0, -127
  61. li $t0, 0x7FFFFF # Mantissa[a1] = (a0 & 0x7FFFFF) | 0x800000;
  62. and $a1, $a0, $t0
  63. li $t0, 0x800000
  64. or $a1, $a1, $t0
  65. # epilogue - stack-frame
  66. lw $fp, 0($sp)
  67. lw $ra, 4($sp)
  68. addi $sp, $sp, 8
  69. jr $ra # return
  70. #
  71. # multFloat(f1, f2)
  72. # arguments
  73. # $a0 : 32bit floating point 1
  74. # $a1 : 32bit floating point 2
  75. # return
  76. # $v0 : 32bit floating point multiplication result
  77. multFloat:
  78. # s0: sign and argument 2
  79. # s1: exp
  80. # s2: mantissa
  81. # intro - stack-frame
  82. addi $sp, $sp, -20 # multFloat
  83. sw $ra, 16($sp)
  84. sw $fp, 12($sp)
  85. sw $s2, 8($sp)
  86. sw $s1, 4($sp)
  87. sw $s0, 0($sp)
  88. addi $fp, $sp, 0 # stack arguments (no)
  89. move $s0, $a1 # save 2nd argument
  90. jal decodeFloat # decodeFloat(arg1) : [v0, v1, a1] <- [s, e, m]
  91. move $t0, $s0 # $s0 change variable to $t0
  92. move $s0, $v0 # load return values to variable regs
  93. move $s1, $v1
  94. move $s2, $a1
  95. move $a0, $t0 # load back argument 2
  96. jal decodeFloat # decodeFloat(arg2) : [v0, v1, a1] <- [s, e, m]
  97. xor $s0, $s0, $v0 # sign = s1 ^ s2
  98. add $s1, $s1, $v1 # exp = e1 + e2
  99. multu $s2, $a1 # mantissa = m1 * m2
  100. mfhi $t4 # t4: mantissa-hi
  101. mflo $t3 # t3: mantissa-low
  102. addi $s2, $zero, 0
  103. li $t9, 0x8000 # if (HI & (1<<15))
  104. and $t8, $t9, $t4
  105. beq $t8, $zero, _multf_l0
  106. # (true)not zero, 48-bits result, normalize
  107. sll $s2, $t4, 8 # mant = HI << 8
  108. srl $t9, $t3, 24 # mant |= LOW >> (32-8)
  109. or $s2, $s2, $t9
  110. addi $s1, $s1, 1 # ++exp, normalize
  111. li $t9, 0x800000 # if (ml & (1<<23)), rounding check
  112. and $t8, $t9, $t3
  113. beq $t8, $zero, _multf_l0_end
  114. addi $s2, $s2, 1 # ++mant, round-up
  115. j _multf_l0_end
  116. _multf_l0:
  117. # (false)zero, 47-bits result
  118. sll $s2, $t4, 9 # mant = HI << 9
  119. srl $t9, $t3, 23 # mant |= LOW >> (32-9)
  120. or $s2, $s2, $t9
  121. li $t9, 0x400000 # if (ml & (1<<22)), rounding check
  122. and $t8, $t9, $t3
  123. beq $t8, $zero, _multf_l0_end
  124. addi $s2, $s2, 1 # ++mant, round-up
  125. _multf_l0_end:
  126. move $a0, $s0
  127. move $a1, $s1
  128. move $a2, $s2
  129. jal encodeFloat # encodeFloat(s, e, m) : float(v0)
  130. # epilogue - stack-frame
  131. lw $s0, 0($sp)
  132. lw $s1, 4($sp)
  133. lw $s2, 8($sp)
  134. lw $fp, 12($sp)
  135. lw $ra, 16($sp)
  136. addi $sp, $sp, 20
  137. jr $ra # return
  138. #
  139. # fprod(vector, size)
  140. # Calculates the product x[0] * x[1] * x[2] * ... * x[n-1] as
  141. # Left fold of product operator on a vector of numbers - foldl(*, x)
  142. #
  143. # Arguments
  144. # $a0: Pointer to array x[] in RAM
  145. # $a1: Number of elements
  146. # Return
  147. # $v0: The product
  148. fprod:
  149. # intro - stack-frame
  150. addi $sp, $sp, -20 # fprod
  151. sw $ra, 16($sp)
  152. sw $fp, 12($sp)
  153. sw $s2, 8($sp)
  154. sw $s1, 4($sp)
  155. sw $s0, 0($sp)
  156. addi $fp, $sp, 0 # stack arguments (no)
  157. # keep input arguments
  158. move $s0, $a0 # x[]
  159. move $s1, $a1 # n
  160. lw $v0, 0($s0) # Acc = *x
  161. addi $s2, $zero, 1 # i=1
  162. _fprod_loop: # for ( ; i<n ; ) {
  163. bge $s2, $s1, _fprod_loop_end
  164. addi $s0, $s0, 4 # a0 <- *++x
  165. lw $a0, 0($s0)
  166. move $a1, $v0 # a1 <- use prev result
  167. jal multFloat
  168. addi $s2, $s2, 1 # ++i
  169. j _fprod_loop # }
  170. _fprod_loop_end:
  171. # epilogue - stack-frame
  172. lw $s0, 0($sp)
  173. lw $s1, 4($sp)
  174. lw $s2, 8($sp)
  175. lw $fp, 12($sp)
  176. lw $ra, 16($sp)
  177. addi $sp, $sp, 20
  178. jr $ra # return