I am trying to write MIPS code that computes number's power recursively. Everything seems to be correct, but in one test case I got 5^-2 = 0.04000000000000001
. I assume that it is due to my computer's architecture. Am I right or is there something wrong in my code?
For better understanding there is an array of doubles and an array of integer powers in data segment.
Here's code:
.data
double_array: .double 5.0 2.0 -3.0 -3.0 -4.2 5.0 -2.0 0.0 0.0
power_array: .word -2 -4 2 1 0 -2 -3 0 10
N_OF_CASES: .word 9
str_case: .asciiz "case_"
str_colon: .asciiz ": "
str_equal: .asciiz " = "
str_power: .asciiz "^"
str_newLine: .asciiz "\n"
one: .double 1.0
zero: .double 0.0
main:
lw $t1, N_OF_CASES
la $t2, double_array
la $t3, power_array
li $t4, 0
loop:
lw $a1, ($t3)
lw $t0, ($t3)
l.d $f14, ($t2)
l.d $f16, ($t2)
jal power
li $v0, 3
mov.d $f12, $f16
syscall
li $v0, 4
la $a0, str_power
syscall
li $v0, 1
move $a0, $t0
syscall
li $v0, 4
la $a0, str_equal
syscall
li $v0, 3
mov.d $f12, $f0
syscall
la $v0, 4
la $a0, str_newLine
syscall
addi $t2, $t2, 8
addi $t3, $t3, 4
addi $t4, $t4, 1
subi $t1, $t1, 1
bnez $t1, loop
li $v0 10
syscall
power:
andi $sp 0xfffffff8
addi $sp $sp -16
s.d $f20 ($sp)
sw $ra 8($sp)
li $t7, 0
beq $a1, $t7, base_case
bgez $a1, not_negative
l.d $f2, one
div.d $f14, $f2, $f14
li $t6, -1
mul $a1, $a1, $t6
j power
not_negative:
mov.d $f2, $f14
subi $a1, $a1, 1
jal power
mul.d $f0, $f0, $f2
power_done:
l.d $f20, ($sp)
lw $ra, 8($sp)
addi $sp, $sp, 16
jr $ra
base_case:
l.d, $f0, one
j power_done
Your question is answered by the floating point reference I provided in comment.
However, about the posted code, the j power
is highly suspicious. It jumps to the beginning of the function, runs the prologue and creates another stack frame, though without having been called. If this is trying to do Tail Call Optimization, you should skip over the prologue to re-enter the function just after prologue. Otherwise, jal power
is more appropriate though you'll have to add j powerDone
after.
Your register usages are non-standard.