Sparc: fdtox/fqtox instructions incorrectly select destination register

Host environment

  • Operating system: Debian 12 container running on Arch Linux
  • OS/kernel version: Linux hostname 6.12.10-hardened1-1-hardened #1 SMP PREEMPT_DYNAMIC Thu, 23 Jan 2025 18:43:01 +0000 x86_64 GNU/Linux
  • Architecture: x86_64
  • QEMU flavor: qemu-sparc64
  • QEMU version: 9.2.0
  • QEMU command line: qemu-sparc64-static ./test_program

Emulated/Virtualized environment

  • Architecture: Sparc64

Description of problem

This bug report is mostly for informational purposes as I will be posting a fix for the bug.

The fdtox and fqtox instructions incorrectly select the destination register when the destination register is higher than f31.

Steps to reproduce

  1. Install Sparc cross compiler gcc-12-sparc64-linux-gnu(in Debian)
  2. Compile the test program using sparc64-linux-gnu-gcc-12 -m64 -o test_program -static test_program.c
  3. Run the test program using qemu-sparc64-static ./test_program
  4. Expected output is 60. Prints 0 instead.

Additional information

Test program to test the issue:

#include <stdio.h>

int main(int argc, char** argv) {
    long long truncated = 0;
    __asm__("fdtox %0,%%f32\n\t" :: "f"(60.0));
    __asm__("fmovd %%f32,%0\n\t" : "=f"(truncated));
    printf("%lld\n", truncated);
    return 0;
}

The issue is caused by the commit 0bba7572. Where certain changes were made in the way destination registers are selected(moving the DFPREG/QFPREG to decodetree).

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information