I needed to translate the follwing C code to MIPS64:
#include <stdio.h>
int main() {
int x;
for (x=0;x<10;x++) {
}
return 0;
}
I used codebench to crosscompile this code to MIPS64. The following code was created:
.file 1 "loop.c"
.section .mdebug.abi32
.previous
.gnu_attribute 4, 1
.abicalls
.option pic0
.text
.align 2
.globl main
.set nomips16
.set nomicromips
.ent main
.type main, @function
main:
.frame $fp,24,$31 # vars= 8, regs= 1/0, args= 0, gp= 8
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-24
sw $fp,20($sp)
move $fp,$sp
sw $0,8($fp)
j $L2
nop
$L3:
lw $2,8($fp)
addiu $2,$2,1
sw $2,8($fp)
$L2:
lw $2,8($fp)
slt $2,$2,10
bne $2,$0,$L3
nop
move $2,$0
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
j $31
nop
.set macro
.set reorder
.end main
.size main, .-main
.ident "GCC: (Sourcery CodeBench 2012.03-81) 4.6.3"
To check if the code works as expected, I usually use the WINMIPS64 simulator. For one or other reason this simulator does not want to accept this code. It appears that every line of code is wrong. I have been looking at this issue for over a day. I hope someone can help me out with this. What is wrong with this assembly code for the mips64 architecture?
From page 7 of the WINMIPS64 documentation:
The following assembler directives are supported
.data - start of data segment
.text - start of code segment
.code - start of code segment (same as .text)
.org <n> - start address
.space <n> - leave n empty bytes
.asciiz <s> - enters zero terminated ascii string
.ascii <s> - enter ascii string
.align <n> - align to n-byte boundary
.word <n1>,<n2>.. - enters word(s) of data (64-bits)
.byte <n1>,<n2>.. - enter bytes
.word32 <n1>,<n2>.. - enters 32 bit number(s)
.word16 <n1>,<n2>.. - enters 16 bit number(s)
.double <n1>,<n2>.. - enters floating-point number(s)
Get rid of everything that's not in the above list, as it won't run in the simulator.
You'll need to move the .align
to before .text
WINMIPS64 expects daddi
/daddui
instead of addi
/addiu
, again as per the documentation.
As per the documentation, move $a, $b
is not a supported mnemonic. Replace them with daddui $a, $b, 0
instead.
slt
needs to be slti
.
Finally, the simulator expects an absolute address for j
, but you've given it a register. Use jr
instead.
At this point I get an infinite loop. This is because the stack pointer doesn't get initialized. The simulator only gives you 0x400 bytes of memory, so go ahead and initialize the stack to 0x400:
.text
daddui $sp,$0,0x400
Now it runs. Since you're running the code by itself, nothing will be in the return register and the final jr $31
will just bring it back to the beginning.
Here's my version:
.align 2
.text
daddui $sp,$0,0x400
main:
daddui $sp,$sp,-24
sw $fp,20($sp)
daddui $fp,$sp,0
sw $0,8($fp)
j $L2
nop
$L3:
lw $2,8($fp)
daddui $2,$2,1
sw $2,8($fp)
$L2:
lw $2,8($fp)
slti $2,$2,10
bne $2,$0,$L3
nop
daddui $2,$0,0
daddui $sp,$fp,0
lw $fp,20($sp)
daddui $sp,$sp,24
jr $31
nop
Consider getting either another compiler or another simulator, because these two clearly hate each other.