v850 simulator patch for v850e bit twiddle instructions

Jim Wilson wilson@redhat.com
Fri Sep 27 14:46:00 GMT 2002


This fixes bugs in the handling of v850e bit twiddle instructions that take the
bit position operand as a register, e.g. "set1 reg2, [reg1]".   The operand
is a bit position from 0-7 which can be in any register.  The simulator is
masking the operand with 7 and then reading the register.  This is wrong.
We need to read the register first, and then mask with 7.  This patch fixes
the problem.
	
Gcc doesn't generate these instructions unfortunately, so I need an asm to
show the problem.  Gcc also unfortunately doesn't have any print operand code
for the address I need here, so I need a badly written asm (grumble), but
anways, here is a testcase.

char c = 0;

int
sub (int bp)
{
  char *ptr = &c;
  asm volatile ("set1 %1,[%0]" : : "r" (ptr), "r" (bp));
  return 0;
}

int
main()
{
  sub (5);
  if (c != 0x20)
    abort ();
  return 0;
}

If I compile this with -mv850e, and run it with an unpatched simulator it
hits the abort.  With the patched simulator, it runs correctly returning zero.

I ran the gdb testsuite to test this, but it was pretty pointless since the
instruction is not generated by gcc, and it passed with no regressions as
expected.

2002-09-27  Jim Wilson  <wilson@redhat.com>

	* simops.c (OP_E6077E0): And op1 with 7 after reading register, not
	before.
	(BIT_CHANGE_OP): Likewise.

Index: simops.c
===================================================================
RCS file: /cvs/src/src/sim/v850/simops.c,v
retrieving revision 1.4
diff -p -r1.4 simops.c
*** simops.c	27 Sep 2002 18:59:08 -0000	1.4
--- simops.c	27 Sep 2002 21:42:46 -0000
*************** OP_E607E0 (void)
*** 1897,1903 ****
    temp = load_mem (State.regs[ OP[0] ], 1);
    
    PSW &= ~PSW_Z;
!   if ((temp & (1 << State.regs[ OP[1] & 0x7 ])) == 0)
      PSW |= PSW_Z;
    
    trace_output (OP_BIT);
--- 1897,1903 ----
    temp = load_mem (State.regs[ OP[0] ], 1);
    
    PSW &= ~PSW_Z;
!   if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0)
      PSW |= PSW_Z;
    
    trace_output (OP_BIT);
*************** OP_22207E0 (void)
*** 1924,1930 ****
    						\
    trace_input (name, OP_BIT_CHANGE, 0);		\
    						\
!   bit  = 1 << State.regs[ OP[1] & 0x7 ];	\
    temp = load_mem (State.regs[ OP[0] ], 1);	\
  						\
    PSW &= ~PSW_Z;				\
--- 1924,1930 ----
    						\
    trace_input (name, OP_BIT_CHANGE, 0);		\
    						\
!   bit  = 1 << (State.regs[ OP[1] ] & 0x7);	\
    temp = load_mem (State.regs[ OP[0] ], 1);	\
  						\
    PSW &= ~PSW_Z;				\



More information about the Gdb-patches mailing list