foss-for-synopsys-dwc-arc-processors/qemu

Throw Instruction Error if last instruction of ZOL is a branch

shahab-vahedi opened this issue · 0 comments

QEMU must throw an exception when

  1. The CPU is of type archs
  2. the last instruction of the loop body is a branch
$ cat lp.s
  .text
  .global __start

  __start:
    mov     r0, 0
    mov     r1, 1
    mov     r2, 2
    mov     lp_count, r2
    nop_s
    lp      @1f
    add     r0, r0, 1
    breq  r1, r2, @bad
  1:
    brne    r0, r2, @bad
    mov     r0, 0x1337
    st      1, [0xF0000008]
    flag    1
  bad:
    mov     r0, 0xbad
    st      1, [0xF0000008]
    flag    1
  end:

$ arc-elf32-gcc -Wl,-T,tarc.ld test.s ivt.S -g3 -nostartfiles -o test -mcpu=arcem

$ nsimdrv -p nsim_isa_family=av2hs            \
          -p nsim_isa_div_rem_option=2        \
          -p nsim_isa_number_of_interrupts=32 \
          -p nsim_isa_core=4                  \
          -p nsim_isa_mpy_option=2            \
          -prop=nsim_debug=4                  \
          -prop=nsim_trace-output=run.log     \
          -on=trace                           \
          test

$ cat run.log
[0x00000100] 0x204a0000  K       mov            r0,0x0 : (w0) r0 <= 0x00000000 *
[0x00000104] 0x214a0040  K       mov            r1,0x1 : (w0) r1 <= 0x00000001 *
[0x00000108] 0x224a0080  K       mov            r2,0x2 : (w0) r2 <= 0x00000002 *
[0x0000010c] 0x240a7080  K       mov            r60,r2 : (w0) r60 <= 0x00000002 *
[0x00000110] 0x78e0      K       nop_s           *
[0x00000112] 0x20a801c0  K       lp             0xe : LP_START <= 0x00000116, LP_END <= 0x0000011e, LP_COUNT = 2 *
[0x00000116] 0x20400040  K       add            r0,r0,0x1 : (w0) r0 <= 0x00000001 *
[0x0000011a] 0x091f0080  K       breq           r1,r2,0x1e
 EXCEPTION RAISED: 
	ECR      <= 0x00020100 - VECTOR:InstructionError
	ERET     <= 0x0000011a
	ERSTATUS <= 0x00000000
	BTA      <= 0x00000000
	EFA      <= 0x0000011a
	PC       <= 0x0000014c
	STATUS32 <= 0x00001020

Also, when

  1. The CPU is of type arc{em,hs}
  2. The delay slot of a branch instruction is straddled over the end of the loop body

Notice the the breq.d and the "nsim_isa_family=av2em" below.

$ cat lp.s
  .text
  .global __start

  __start:
    mov     r0, 0
    mov     r1, 1
    mov     r2, 2
    mov     lp_count, r2
    nop_s
    lp      @1f
    add     r0, r0, 1
    breq.d  r1, r2, @bad
  1:
    nop
    brne    r0, r2, @bad
    mov     r0, 0x1337
    st      1, [0xF0000008]
    flag    1
  bad:
    mov     r0, 0xbad
    st      1, [0xF0000008]
    flag    1
  end:

$ arc-elf32-gcc -Wl,-T,tarc.ld test.s ivt.S -g3 -nostartfiles -o test -mcpu=arcem

$ nsimdrv -p nsim_isa_family=av2em            \
          -p nsim_isa_div_rem_option=2        \
          -p nsim_isa_number_of_interrupts=32 \
          -p nsim_isa_core=4                  \
          -p nsim_isa_mpy_option=2            \
          -prop=nsim_debug=4                  \
          -prop=nsim_trace-output=run.log     \
          -on=trace                           \
          test

$ cat run.log
[0x00000100] 0x204a0000  K       mov            r0,0x0 : (w0) r0 <= 0x00000000 *
[0x00000104] 0x214a0040  K       mov            r1,0x1 : (w0) r1 <= 0x00000001 *
[0x00000108] 0x224a0080  K       mov            r2,0x2 : (w0) r2 <= 0x00000002 *
[0x0000010c] 0x240a7080  K       mov            r60,r2 : (w0) r60 <= 0x00000002 *
[0x00000110] 0x78e0      K       nop_s           *
[0x00000112] 0x20a801c0  K       lp             0xe : LP_START <= 0x00000116, LP_END <= 0x0000011e, LP_COUNT = 2 *
[0x00000116] 0x20400040  K       add            r0,r0,0x1 : (w0) r0 <= 0x00000001 *
[0x0000011a] 0x092300a0  K       breq.d         r1,r2,0x22
 EXCEPTION RAISED: 
	ECR      <= 0x00020100 - VECTOR:InstructionError
	ERET     <= 0x0000011a
	ERSTATUS <= 0x00000000
	BTA      <= 0x00000000
	EFA      <= 0x0000011a
	PC       <= 0x00000150
	STATUS32 <= 0x00001020