Skip to content

SH4: SUBV instruction not emulated properly

Host environment

  • Operating system: Debian testing
  • OS/kernel version: 6.7.9
  • Architecture: x86_64
  • QEMU flavor: qemu-sh4
  • QEMU version: qemu-sh4 version 8.2.1 (Debian 1:8.2.1+ds-2)
  • QEMU command line:

Emulated/Virtualized environment

  • Operating system: Buildroot uClibc (qemu-user)
  • OS/kernel version: 6.7.9 (qemu-user)
  • Architecture: SH4

Description of problem

SUBV opcode is emulated incorrectly.

The documentation says:

SUBV Rm, Rn Rn - Rm -> Rn, underflow -> T

Qemu seems to perform the subtraction correctly, but will not detect an underflow.

Steps to reproduce

#include <stdio.h>

int main(void)
{
	register unsigned int a asm("r8") = 0x80000001;
	register unsigned int b asm("r9") = 0x2;
	register unsigned int c asm("r10");

	asm volatile("subv %2,%0\n"
		     "movt %1\n"
		     : "+r"(a), "=r"(c) : "r"(b) :);

	printf("Values: a=0x%x b=0x%x c=0x%x\n", a, b, c);

	return 0;
}

Additional information

Tested on real hardware (SEGA Dreamcast, GCC 15.0), the program above prints: Values: a=0x7fffffff b=0x2 c=0x1

Running with Qemu (and GCC 13.0), the same program prints: Values: a=0x7fffffff b=0x2 c=0x0

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