RFA: RX Sim: Use unsigned masks when setting flag bits

Nick Clifton
2010-06-07T07:50:28Z

Hi Guys,

The patch below fixes a small bug in the RX simulator.

The b2mask[] array contains unsigned bit masks that are used to check
for a zero result of an arithmetic, logic or comparison operation.
But the masks were being placed into signed integers and then compared
against a signed long long value. This meant that if the 32-bit mask
(0xFFFFFFFF) was being used, it would be sign-extended to 64-bits
(0xFFFFFFFFFFFFFFFF) before being compared against the result of the
operation. If that operation resulted in a 64-bit value with the
bottom 32-bits clear but the any of the top 32-bits set, then the AND
of the mask and value would be non-zero, and so the Z bit would not be
set. This is despite the fact that the value that would be stored in
the destination register would be exactly 0.

The patch fixes the problem by using unsigned integers to hold the
selected mask value. Tested by building and regression testing an
rx-elf toolchain. This patch fixes a regression in the gcc testsuite,
specifically the gcc.c-torture/execute/vrp-5.c test.

OK to apply ?

Cheers
Nick

sim/rx/ChangeLog
2010-06-07 Nick Clifton <nickc@redhat.com>

* reg.c (set_oszc): Use unsigned int for the mask.
(set_szc, set_osz, set_sz): Likewise.

Index: sim/rx/reg.c
===================================================================
RCS file: /cvs/src/src/sim/rx/reg.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 reg.c
*** sim/rx/reg.c 1 Jan 2010 10:03:33 -0000 1.2
--- sim/rx/reg.c 7 Jun 2010 07:16:11 -0000
*************** set_flags (int mask, int newbits)
*** 377,383 ****
void
set_oszc (long long value, int b, int c)
{
! int mask = b2mask[b];
int f = 0;

if (c)
--- 377,383 ----
void
set_oszc (long long value, int b, int c)
{
! unsigned int mask = b2mask[b];
int f = 0;

if (c)
*************** set_oszc (long long value, int b, int c)
*** 394,400 ****
void
set_szc (long long value, int b, int c)
{
! int mask = b2mask[b];
int f = 0;

if (c)
--- 394,400 ----
void
set_szc (long long value, int b, int c)
{
! unsigned int mask = b2mask[b];
int f = 0;

if (c)
*************** set_szc (long long value, int b, int c)
*** 409,415 ****
void
set_osz (long long value, int b)
{
! int mask = b2mask[b];
int f = 0;

if ((value & mask) == 0)
--- 409,415 ----
void
set_osz (long long value, int b)
{
! unsigned int mask = b2mask[b];
int f = 0;

if ((value & mask) == 0)
*************** set_osz (long long value, int b)
*** 424,430 ****
void
set_sz (long long value, int b)
{
! int mask = b2mask[b];
int f = 0;

if ((value & mask) == 0)
--- 424,430 ----
void
set_sz (long long value, int b)
{
! unsigned int mask = b2mask[b];
int f = 0;

if ((value & mask) == 0)