[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Lightning] support for mips32r6
From: |
Paulo César Pereira de Andrade |
Subject: |
Re: [Lightning] support for mips32r6 |
Date: |
Fri, 30 Aug 2019 11:47:30 -0400 |
Em sex, 30 de ago de 2019 às 03:48, Bruno Haible <address@hidden> escreveu:
>
> Hi,
Hi,
> A libffcall bug report [1] made me aware of an incompatible change in
> the MIPS ISAs. Namely, for jumping to an address given in a register,
> starting with mips32r6, the existing 'jr' instruction does not work
> any more: it produces an 'illegal instruction'.
>
> There are many documents of the MIPS ISAs, and before 2014 they
> described two instructions JR and JALR:
> JR <rs> jumps to the address in register <rs>
> JALR <rd>,<rs> jumps to the address in register <rs> and puts
> the old PC + 8 into register <rd>
> In particular,
> JR <rs> [SPECIAL, rs, 00000, 00000, hint, 001000]
> is equivalent to
> JALR $0,<rs> [SPECIAL, rs, 00000, 00000, hint, 001001]
> (because writing to $0 is a no-op).
>
> In the documents that consider the MIPS32 R6 architecture, such as [2]
> from 2014 - look at the descriptions of JR and JALR - you see that
> - in order to get the effect of JR, the bit pattern of JALR with destination
> $0 has to be used,
> - in the JALR instruction, the destination $0 is no longer allowed;
> this is merely a hint for the disassembler.
>
> You can see that the GNU assembler has been adjusted. First, see
> the different bit patterns:
>
> $ cat foo.s
> .text
> j $25
> nop
> jal $0,$25
> nop
> # Assemble this using binutils 2.16.1:
> $ mips64-linux-as -32 -o foo.o foo.s
> $ mips64-linux-objdump --disassemble foo.o
>
> foo.o: file format elf32-tradbigmips
>
> Disassembly of section .text:
>
> 00000000 <.text>:
> 0: 03200008 jr t9
> 4: 00000000 nop
> 8: 03200009 jalr zero,t9
> c: 00000000 nop
> ...
>
> # Now, see how a newer GNU assembler (binutils 2.27) and option -mips32r6
> # produce a different result:
> $ mips64-linux-as -32 -mips32r6 -o foo.o foo.s
> $ mips64-linux-objdump --disassemble foo.o [binutils 2.16.1]
>
> foo.o: file format elf32-tradbigmips
>
> Disassembly of section .text:
>
> 00000000 <.text>:
> 0: 03200009 jalr zero,t9
> 4: 00000000 nop
> 8: 03200009 jalr zero,t9
> c: 00000000 nop
> ...
> $ mips64-linux-objdump --disassemble foo.o [binutils 2.27]
>
> foo.o: file format elf32-tradbigmips
>
>
> Disassembly of section .text:
>
> 00000000 <.text>:
> 0: 03200009 jr t9
> 4: 00000000 nop
> 8: 03200009 jr t9
> c: 00000000 nop
> ...
>
>
> Note that the JALR $0,<rs> instruction can be used on all architectures;
> I verified this by looking at old MIPS ISA documentations from 1995,
> and by looking at the source code of QEMU.
>
> Find attached a fix for GNU lightning (untested).
Just tested it, and it works as expected. For example, with this input
for check/lightning:
"""
.data 32
fmt:
.c "%d\n"
.code
prolog
movi %r0 label
movi %r1 10
jmpr %r0
movi %r1 11
label:
prepare
pushargi fmt
ellipsis
pushargr %r1
finishi @printf
ret
epilog
"""
without the patch it was generating:
jmpr v0
0x2aad4020 jr v0
and with the patch:
jmpr v0
0x2aad4020 jalr zero,v0
Verified on an old YeeLoong I bought to test lightning several years ago,
and all tests pass.
> Bruno
>
>
> [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925129
> [2]
> http://hades.mech.northwestern.edu/images/1/16/MIPS32_Architecture_Volume_II-A_Instruction_Set.pdf
Thanks!
Paulo