Hello. While adding support for MIPS release 6 to my software I noticed a bizarre behaviour related to compact branch instructions, in particular conditionals.
Gas adds a useless nop instruction (sll $0,$0,0x0) after most but not all compact branches, unless the instruction following the branch looks like a "plausible" delay-slot instructions (more details in the test case). For example, this: --8<---------------cut here---------------start------------->8--- .set arch=mips32r6 foo: bnezc $3, foo bltzc $3, foo bgtzc $3, foo blezc $3, foo bgezc $3, foo --8<---------------cut here---------------end--------------->8--- disassembles to: --8<---------------cut here---------------start------------->8--- 00000000 <foo>: 0: f87fffff bnezc $3,0 <foo> 4: 00000000 sll $0,$0,0x0 8: 5c63fffd bltzc $3,0 <foo> c: 00000000 sll $0,$0,0x0 10: 5c03fffb bgtzc $3,0 <foo> 14: 00000000 sll $0,$0,0x0 18: 5803fff9 blezc $3,0 <foo> 1c: 00000000 sll $0,$0,0x0 20: 5863fff7 bgezc $3,0 <foo> ... --8<---------------cut here---------------end--------------->8--- This, while not technically assembling incorrect code, does not make sense: the instruction following the compact branch is *not* executed when the branch is taken, which is the entire point of compact branches. This should be independent from what instruction follows the branch, since at least as far as I understand there is no restriction on what instructions are allowed in that position. The balc instruction is not affected. The bc instruction is not affected. The jalrc instruction is not affected. The jic instruction is not affected. Every conditional compact branch I have tried *is* affected. I have not tested the linking versions, but on the other hand every conditional branch seems affected: on zero, on sign, on magnitude. This includes for example beqzc, bltzc, bgtzc, bltc. I am using inline asm from GNU C, from which it is not practical to work around the misbehaviour with .set noreorder , since the last instruction before I switch back to .set reorder will be "completed" with a useless nop, unless the following instruction appears to be suitable to fill the (not actually existing) delay slot. I am attaching a distilled test case along with what the tools show me. Tested with Binutils 2.35.1 (on a cross configuration to big-endian 32-bit MIPS), compiled with crosstool but using stock source tarballs downloaded from ftp.gnu.org, with no patches. Binutils 2.35.1, compiled via crosstool-ng with no patches: m6[luca@moore ~/repos/jitter/_build/cross-mips32r6]$ mips-unknown-linux-gnu-as --version GNU assembler (crosstool-NG 1.23.0.942_5fbcd4b) 2.35.1 Copyright (C) 2020 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or later. This program has absolutely no warranty. This assembler was configured for a target of `mips-unknown-linux-gnu'. m6[luca@moore ~/repos/jitter/_build/cross-mips32r6]$ mips-unknown-linux-gnu-gcc --version mips-unknown-linux-gnu-gcc (crosstool-NG 1.23.0.942_5fbcd4b) 10.2.0 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. m6[luca@moore ~/repos/jitter/_build/cross-mips32r6]$ mips-unknown-linux-gnu-gcc -v -c testcase-beqzc.s Using built-in specs. COLLECT_GCC=mips-unknown-linux-gnu-gcc Target: mips-unknown-linux-gnu Configured with: /home/luca/cross-scratch/mips32r6/.build/mips-unknown-linux-gnu/src/gcc/configure --build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu --target=mips-unknown-linux-gnu --prefix=/home/luca/usr-cross-mips32r6 --with-sysroot=/home/luca/usr-cross-mips32r6/mips-unknown-linux-gnu/sysroot --enable-languages=c,c++ --with-arch=mips32r6 --with-abi=32 --with-float=hard --with-pkgversion='crosstool-NG 1.23.0.942_5fbcd4b' --enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --disable-libquadmath --disable-libquadmath-support --disable-libsanitizer --disable-libmpx --with-gmp=/home/luca/cross-scratch/mips32r6/.build/mips-unknown-linux-gnu/buildtools --with-mpfr=/home/luca/cross-scratch/mips32r6/.build/mips-unknown-linux-gnu/buildtools --with-mpc=/home/luca/cross-scratch/mips32r6/.build/mips-unknown-linux-gnu/buildtools --with-isl=/home/luca/cross-scratch/mips32r6/.build/mips-unknown-linux-gnu/buildtools --disable-lto --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --enable-threads=posix --enable-target-optspace --enable-plugin --disable-nls --disable-multilib --with-local-prefix=/home/luca/usr-cross-mips32r6/mips-unknown-linux-gnu/sysroot --enable-long-long Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.2.0 (crosstool-NG 1.23.0.942_5fbcd4b) COLLECT_GCC_OPTIONS='-v' '-c' '-march=mips32r6' '-mabi=32' '-mhard-float' '-mllsc' '-mips32r6' '-mnan=2008' '-mno-shared' '-EB' /home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/10.2.0/../../../../mips-unknown-linux-gnu/bin/as -v -EB -mips32r6 -O1 -mabi=32 -march=mips32r6 -mnan=2008 -mno-shared -mhard-float -KPIC -o testcase-beqzc.o testcase-beqzc.s GNU assembler version 2.35.1 (mips-unknown-linux-gnu) using BFD version (crosstool-NG 1.23.0.942_5fbcd4b) 2.35.1 COMPILER_PATH=/home/luca/usr-cross-mips32r6/libexec/gcc/mips-unknown-linux-gnu/10.2.0/:/home/luca/usr-cross-mips32r6/libexec/gcc/mips-unknown-linux-gnu/10.2.0/:/home/luca/usr-cross-mips32r6/libexec/gcc/mips-unknown-linux-gnu/:/home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/10.2.0/:/home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/:/home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/10.2.0/../../../../mips-unknown-linux-gnu/bin/ LIBRARY_PATH=/home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/10.2.0/:/home/luca/usr-cross-mips32r6/lib/gcc/mips-unknown-linux-gnu/10.2.0/../../../../mips-unknown-linux-gnu/lib/:/home/luca/usr-cross-mips32r6/mips-unknown-linux-gnu/sysroot/lib/:/home/luca/usr-cross-mips32r6/mips-unknown-linux-gnu/sysroot/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-c' '-march=mips32r6' '-mabi=32' '-mhard-float' '-mllsc' '-mips32r6' '-mnan=2008' '-mno-shared' '-EB' Thank you very much for your work on the Binutils. Best regards, -- Luca Saiu * My personal web site: http://ageinghacker.net * Jitter: http://ageinghacker.net/projects/jitter * GNU epsilon: http://www.gnu.org/software/epsilon I support everyone's freedom of mocking any opinion or belief, no matter how deeply held, with open disrespect and the same unrelented enthusiasm of a toddler who has just learned the word "poo".
interaction
Description: Binary data
testcase-beqzc.s
Description: Binary data
signature.asc
Description: PGP signature