[Top] [All Lists]

Re: Immediate branch offset

To: "Maciej W. Rozycki" <>
Subject: Re: Immediate branch offset
From: Alexis BRENON <>
Date: Mon, 10 Jun 2013 09:18:00 +0200
In-reply-to: <>
List-archive: <>
List-help: <>
List-id: linux-mips <>
List-owner: <>
List-post: <>
List-software: Ecartis version 1.0.0
List-subscribe: <>
List-unsubscribe: <>
Original-recipient: rfc822;
References: <> <>
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130510 Thunderbird/17.0.6
Le 09/06/2013 16:43, Maciej W. Rozycki a écrit :
On Fri, 7 Jun 2013, Alexis BRENON wrote:

To create the JIT, I have to load some MIPS instruction directly in memory
without passing through a .asm file or else. So, I cannot set some labels. So
to make some branches, I try to load the equivalent instruction of :
     bne $t0, $t1, -8
to go back, just before the bne instruction, if $t0 and $t1 are equals. But
when it run, I've got an illegal instruction error.
  Please note that BNE means Branch-if-Not-Equal, your quoted instruction
will jump backwards if $t0 and $t1 are *not* equal.

Yes, sorry, it's just a typing mistake, since I tried with all branch instructions.

To debug, I write a small program in the MARS MIPS simulator with this
instruction. But when compiling, assembler says me that -8 is an operand of
incorrect type.
  The instruction you quoted assembles for me successfully, what version of
binutils do you use and what exact error message do you get?

I didn't try to assemble it, but only to run it in the MARS simulator. If I assemble it with GNU AS, it assembles successfully.

  Please note however that this instruction is not what I understand you
need -- it is treated as a branch to the absolute address -8 (0xfffffff8
in the o32 ABI), rather than 8 bytes back (there's an off-by-four bug in
GAS here too making it jump to -4 instead, and some other issues; I'll see
if I can get them fixed sometime -- see the discussion around if interested in
the gory details).

  If you want to jump to the instruction immediately preceding the branch
and avoid a label (assuming the standard MIPS ISA), use:

        bne     $t0, $t1, . - 4

-- "." is a special "the address of this instruction" designator (see the
GAS manual for further information), so this produces the machine
instruction you require (the jump is calculated as relative to the next
instruction -- that is (. + 4) -- so the ultimate effective (i.e. shifted
rather than as encoded in the instruction's 16-bit immediate operand
field) offset is -8).

$ cat foo.s
        bne     $t0, $t1, . - 4
$ mips-linux-as -o foo.o foo.s
$ mips-linux-objdump -dr foo.o

foo.o:     file format elf32-tradbigmips

Disassembly of section .text:

00000000 <.text>:
    0:  1509fffe        bne     t0,t1,0xfffffffc
    4:  00000000        nop
$ mips-linux-as --version
GNU assembler (GNU Binutils) 2.23.2

Likewise with the current binutils trunk.

  I hope this helps.


I downloaded MIPS32 Architecture For Programmers Volume II: The MIPS32 Instruction Set. If you read the BNE-BEQ-B... description it says :

To compare GPRs then do a PC-relative conditional branch

        Description: if rs = rt then branch
An 18-bit signed offset (the 16-bit offset field shifted left 2 bits) is added 
to the address of the instruction
following the branch (not the branch itself), in the branch delay slot, to form 
a PC-relative effective target

It says that it's a PC-relative jump, the offset is added to the PC value, and not a absolute jump as the J instruction. Nevertheless, I try to type this :

        addiu $v0, $v0, 1
        bne $v0, $t1, .-4

or this :

        addiu $v0, $v0, 1
        bne $v0, $t1, -8

In both cases, the objdump command says me :

   8:   24420001        addiu   v0,v0,1
   c:   1449fffe        bne     v0,t1,8 <loop>
  10:   00000000        nop

It seems to be equivalent.

Thanks for your answer.

<Prev in Thread] Current Thread [Next in Thread>