Pregunta

Code to transfer the integer 9 to the coprocessor, get the ceiling of its square root, then transfer this value back, and print it:

addi $t1, $zero, 9
mtc1 $t1, $f0
sqrt.s $f0, $f0      # (*)
ceil.w.s $f0, $f0   # (*)
mfc1 $t0, $f0
addi $v0, $zero, 1
addi $a0, $t0, 0
syscall

Note on lines with (*): (1) I also tried with .d instead of .s; (2) I also tried making the source and destination registers different ($f0 to $f2, and back). 

My result is 1 (if I take the floor instead, 0). However, if I comment the *-ed lines out, 9 is transferred to and fro fine: 9 is printed. 

I added a syscall "print_double" (=3) after transfer (and before transfer back to CPU) to print the number transferred, and a very small positive number is printed. 

My questions: 

(a) What is going on?

(b) mtc1: is the integer transferred from the CPU received as a double, or a single? Before sending it back with mfc1, does it need to be a single or double, or does it not matter? (I experimented using cvt.d.s, etc., to no avail)

Remark: I'm doing this for fun using "Computer Organization and Design" (Patterson, Hennessy). The 4th edition has the syntax for mtc1 wrong in appendix B.10 - order of rd and rs should be as above.

¿Fue útil?

Solución

Adding a cvt.s.w to convert the loaded integer to single-precision floating point fixes the problem:

addi $t1, $zero, 36
mtc1 $t1, $f0
cvt.s.w $f0,$f0    # convert the integer in $f0 to floating point
sqrt.s $f0, $f0      
ceil.w.s $f0, $f0  # ceil and convert from floating point to integer 
mfc1 $t0, $f0
addi $v0, $zero, 1
addi $a0, $t0, 0
syscall
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top