From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15276 invoked by alias); 12 Nov 2010 01:01:25 -0000 Received: (qmail 15258 invoked by uid 22791); 12 Nov 2010 01:01:23 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL,BAYES_05,MAY_BE_FORGED,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 12 Nov 2010 01:01:18 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oAC11GrT019138 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 11 Nov 2010 20:01:17 -0500 Received: from greed.delorie.com ([10.3.112.3]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oAC11Ec7003265 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 11 Nov 2010 20:01:16 -0500 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1] (may be forged)) by greed.delorie.com (8.14.3/8.14.3) with ESMTP id oAC11EUB000438 for ; Thu, 11 Nov 2010 20:01:14 -0500 Received: (from dj@localhost) by greed.delorie.com (8.14.3/8.14.3/Submit) id oAC11E3L000435; Thu, 11 Nov 2010 20:01:14 -0500 Date: Fri, 12 Nov 2010 01:01:00 -0000 Message-Id: <201011120101.oAC11E3L000435@greed.delorie.com> From: DJ Delorie To: gdb-patches@sourceware.org Subject: [sim/rx] fix cycle count math X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-11/txt/msg00151.txt.bz2 Got better specs on how div/udiv worked, plus fixed suntil/swhile. Committed. * rx.c (lsb_count): New. (divu_cycles): New. (div_cycles): New. (decode_opcode): Fix cycle count math for div, divu, suntil, and swhile. Index: rx.c =================================================================== RCS file: /cvs/src/src/sim/rx/rx.c,v retrieving revision 1.10 diff -p -U3 -r1.10 rx.c --- rx.c 29 Sep 2010 15:47:45 -0000 1.10 +++ rx.c 12 Nov 2010 00:58:17 -0000 @@ -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();