qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [Bug] MIPS code fails at branch instruction


From: Stefan Weil
Subject: [Qemu-devel] [Bug] MIPS code fails at branch instruction
Date: Sat, 17 Mar 2007 00:12:28 +0100
User-agent: IceDove 1.5.0.10 (X11/20070307)

Hi,

QEMU MIPS emulation fails with code using "illegal" commands
in the delay slot of a branch.

I had an endless loop with QEMU running the firmware of a
MIPS based router.

MIPS says: branches, jumps, ... instructions should not be
placed in the delay slot of a branch or jump.

Nevertheless, some routers use this kind of code.

I wrote a test program to examine the difference between emulation
and a real MIPS CPU (see appendices).

Results are given below for real hardware, normal emulation and
emulation using single stepping.

Stefan


Compile branch test like this:
mipsel-linux-gcc -Os -g btest.c btest2.S

AR7 (MIPS 4KEc) router:
# ./a.out
0
1100
1000

qemu-system-mipsel (unmodified):
# ./a.out
0
# (program hangs)

qemu-system-mipsel (single stepping / MIPS_SINGLE_STEP in translate.c):
# ./a.out
0
1221
1221

/*

Compile branch test like this:
mipsel-linux-gcc -Os -g btest.c btest2.S

Original code failing with emulation:
218:       8d090000        lw      t1,0(t0)
21c:       31290001        andi    t1,t1,0x1
220:       1120fffd        beqz    t1,0x218
224:       03e00008        jr      ra
228:       3c088000        lui     t0,0x8000
22c:       3c093c1a        lui     t1,0x3c1a

AR7 router:
# ./a.out
0
1100
1000

qemu-system-mipsel (unmodified):
# ./a.out
0
# (program hangs)

qemu-system-mipsel (unmodified):
# ./a.out
0
1221
1221

*/

#include <stdio.h>

extern int test1(int i);
extern int test2(int i);

int main(void)
{
  int i = 0;
  printf("%d\n", i);
  i = test1(0);
  printf("%d\n", i);
  i = test2(0);
  printf("%d\n", i);
  return 0;
}
#if 0
218:       8d090000        lw      t1,0(t0)
21c:       31290001        andi    t1,t1,0x1
220:       1120fffd        beqz    t1,0x218
224:       03e00008        jr      ra
228:       3c088000        lui     t0,0x8000
22c:       3c093c1a        lui     t1,0x3c1a
230:       35299400        ori     t1,t1,0x9400
234:       ad090000        sw      t1,0(t0)
238:       3c09275a        lui     t1,0x275a
23c:       ad090004        sw      t1,4(t0)
#endif

#include <asm/asm.h>
#include <asm/regdef.h>

        .text
        .set noreorder
        .set mips32r2

        LEAF(test1)
        move    v0,a0
        addiu   v0,v0,1000
        bnez    a0,$L1
        jr      ra
        addiu   v0,v0,100
$L1:
        beqz    a0,$L2
        jr      ra
        addiu   v0,v0,10
$L2:
        addiu   v0,v0,1
        jr      ra
        nop
        END(test1)

        LEAF(test2)
        move    v0,a0
        addiu   v0,v0,1000
        beqz    a0,$L3
        jr      ra
        addiu   v0,v0,100
$L3:
        bnez    a0,$L4
        jr      ra
        addiu   v0,v0,10
$L4:
        addiu   v0,v0,1
        jr      ra
        nop
        END(test2)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]