* rx.c (lsb_count): New.
(divu_cycles): New. (div_cycles): New. (decode_opcode): Fix cycle count math for div, divu, suntil, and swhile.
This commit is contained in:
parent
e493c3b7f3
commit
5cbc4f2ea1
|
@ -1,3 +1,11 @@
|
|||
2010-11-11 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* rx.c (lsb_count): New.
|
||||
(divu_cycles): New.
|
||||
(div_cycles): New.
|
||||
(decode_opcode): Fix cycle count math for div, divu, suntil, and
|
||||
swhile.
|
||||
|
||||
2010-09-29 Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
* mem.c (rx_mem_ptr): When invalidating the decode cache, account
|
||||
|
|
93
sim/rx/rx.c
93
sim/rx/rx.c
|
@ -136,7 +136,7 @@ static const char * id_names[] = {
|
|||
};
|
||||
|
||||
static const char * optype_names[] = {
|
||||
" ",
|
||||
" - ",
|
||||
"#Imm", /* #addend */
|
||||
" Rn ", /* Rn */
|
||||
"[Rn]", /* [Rn + addend] */
|
||||
|
@ -264,6 +264,52 @@ cycles (int throughput)
|
|||
new_rt = r; \
|
||||
}
|
||||
|
||||
static int
|
||||
lsb_count (unsigned long v, int is_signed)
|
||||
{
|
||||
int i, lsb;
|
||||
if (is_signed && (v & 0x80000000U))
|
||||
v = (unsigned long)(long)(-v);
|
||||
for (i=31; i>=0; i--)
|
||||
if (v & (1 << i))
|
||||
{
|
||||
/* v is 0..31, we want 1=1-2, 2=3-4, 3=5-6, etc. */
|
||||
lsb = (i + 2) / 2;
|
||||
return lsb;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
divu_cycles(unsigned long num, unsigned long den)
|
||||
{
|
||||
int nb = lsb_count (num, 0);
|
||||
int db = lsb_count (den, 0);
|
||||
int rv;
|
||||
|
||||
if (nb < db)
|
||||
rv = 2;
|
||||
else
|
||||
rv = 3 + nb - db;
|
||||
E (rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
div_cycles(long num, long den)
|
||||
{
|
||||
int nb = lsb_count ((unsigned long)num, 1);
|
||||
int db = lsb_count ((unsigned long)den, 1);
|
||||
int rv;
|
||||
|
||||
if (nb < db)
|
||||
rv = 3;
|
||||
else
|
||||
rv = 5 + nb - db;
|
||||
E (rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#else /* !CYCLE_ACCURATE */
|
||||
|
||||
#define cycles(t)
|
||||
|
@ -274,6 +320,9 @@ cycles (int throughput)
|
|||
#define RL(r)
|
||||
#define RLD(r)
|
||||
|
||||
#define divu_cycles(n,d)
|
||||
#define div_cycles(n,d)
|
||||
|
||||
#endif /* else CYCLE_ACCURATE */
|
||||
|
||||
static int size2bytes[] = {
|
||||
|
@ -1126,6 +1175,7 @@ decode_opcode ()
|
|||
{
|
||||
tprintf("#NAN\n");
|
||||
set_flags (FLAGBIT_O, FLAGBIT_O);
|
||||
cycles (3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1133,9 +1183,8 @@ decode_opcode ()
|
|||
tprintf("%d\n", v);
|
||||
set_flags (FLAGBIT_O, 0);
|
||||
PD (v);
|
||||
div_cycles (mb, ma);
|
||||
}
|
||||
/* Note: spec says 3 to 22 cycles, we are pessimistic. */
|
||||
cycles (22);
|
||||
break;
|
||||
|
||||
case RXO_divu: /* d = d / s */
|
||||
|
@ -1146,6 +1195,7 @@ decode_opcode ()
|
|||
{
|
||||
tprintf("#NAN\n");
|
||||
set_flags (FLAGBIT_O, FLAGBIT_O);
|
||||
cycles (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1153,9 +1203,8 @@ decode_opcode ()
|
|||
tprintf("%u\n", v);
|
||||
set_flags (FLAGBIT_O, 0);
|
||||
PD (v);
|
||||
divu_cycles (umb, uma);
|
||||
}
|
||||
/* Note: spec says 2 to 20 cycles, we are pessimistic. */
|
||||
cycles (20);
|
||||
break;
|
||||
|
||||
case RXO_emul:
|
||||
|
@ -1906,7 +1955,7 @@ decode_opcode ()
|
|||
case RXO_suntil:
|
||||
RL(3);
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx = regs.r[3];
|
||||
tx = 0;
|
||||
#endif
|
||||
if (regs.r[3] == 0)
|
||||
{
|
||||
|
@ -1922,10 +1971,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_si (get_reg (1));
|
||||
regs.r[1] += 4;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb == uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * tx);
|
||||
#endif
|
||||
break;
|
||||
case RX_Word:
|
||||
uma = get_reg (2) & 0xffff;
|
||||
|
@ -1934,10 +1988,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_hi (get_reg (1));
|
||||
regs.r[1] += 2;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb == uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
|
||||
#endif
|
||||
break;
|
||||
case RX_Byte:
|
||||
uma = get_reg (2) & 0xff;
|
||||
|
@ -1946,10 +2005,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_qi (regs.r[1]);
|
||||
regs.r[1] += 1;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb == uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
|
@ -1963,7 +2027,7 @@ decode_opcode ()
|
|||
case RXO_swhile:
|
||||
RL(3);
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx = regs.r[3];
|
||||
tx = 0;
|
||||
#endif
|
||||
if (regs.r[3] == 0)
|
||||
break;
|
||||
|
@ -1976,10 +2040,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_si (get_reg (1));
|
||||
regs.r[1] += 4;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb != uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * tx);
|
||||
#endif
|
||||
break;
|
||||
case RX_Word:
|
||||
uma = get_reg (2) & 0xffff;
|
||||
|
@ -1988,10 +2057,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_hi (get_reg (1));
|
||||
regs.r[1] += 2;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb != uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * (tx / 2) + 3 * (tx % 2));
|
||||
#endif
|
||||
break;
|
||||
case RX_Byte:
|
||||
uma = get_reg (2) & 0xff;
|
||||
|
@ -2000,10 +2074,15 @@ decode_opcode ()
|
|||
regs.r[3] --;
|
||||
umb = mem_get_qi (regs.r[1]);
|
||||
regs.r[1] += 1;
|
||||
#ifdef CYCLE_ACCURATE
|
||||
tx ++;
|
||||
#endif
|
||||
if (umb != uma)
|
||||
break;
|
||||
}
|
||||
#ifdef CYCLE_ACCURATE
|
||||
cycles (3 + 3 * (tx / 4) + 3 * (tx % 4));
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
|
|
Loading…
Reference in New Issue