This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
SH4 simulator timings (Was: Re: rtlopt loop unroller question (fwd))
- From: Joern Rennecke <joern dot rennecke at superh dot com>
- To: msnyder at redhat dot com (Michael Snyder)
- Cc: amylaar at fairadsl dot co dot uk (Joern Rennecke), joern dot rennecke at superh dot com, gdb-patches at sources dot redhat dot com
- Date: Fri, 6 Feb 2004 12:41:52 +0000 (GMT)
- Subject: SH4 simulator timings (Was: Re: rtlopt loop unroller question (fwd))
>From renneckej Fri Oct 24 18:01:50 2003
Received: from sh-uk-ex01.uk.w2k.superh.com [192.168.16.17]
by localhost with IMAP (fetchmail-5.9.0)
for renneckej@localhost (single-drop); Fri, 24 Oct 2003 18:01:50 +0100 (BST)
Received: from linsvr2.uk.superh.com ([192.168.16.51]) by sh-uk-ex01.uk.w2k.superh.com with Microsoft SMTPSVC(5.0.2195.5329);
Fri, 24 Oct 2003 18:01:29 +0100
Received: (from renneckej@localhost)
by linsvr2.uk.superh.com (8.11.6/8.11.6) id h9OH0TG02288;
Fri, 24 Oct 2003 18:00:29 +0100
From: Joern Rennecke <joern.rennecke@superh.com>
Message-Id: <200310241700.h9OH0TG02288@linsvr2.uk.superh.com>
Subject: Re: rtlopt loop unroller question (fwd)
To: roger@eyesopen.com (Roger Sayle)
Date: Fri, 24 Oct 2003 18:00:29 +0100 (BST)
Cc: joern.rennecke@superh.com (Joern Rennecke)
In-Reply-To: <Pine.LNX.4.44.0310221140280.26690-100000@www.eyesopen.com> from "Roger Sayle" at Oct 22, 2003 11:42:24
X-Mailer: ELM [version 2.5 PL6]
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Return-Path: joern.rennecke@superh.com
X-OriginalArrivalTime: 24 Oct 2003 17:01:29.0451 (UTC) FILETIME=[77CD4BB0:01C39A50]
> Hi Joern,
>
> Is there any chance that you could run some timings on SH for us?
The attached patch for the SH simulator makes it simulate SH4 timings
(approximately). When you use the -v option, the cycle count is displayed
at the end.
2003-10-24 J"orn Rennecke <joern.rennecke@superh.com>
* interp.c (ready_s): New struct.
(saved_state_type): Make prevlock and thislock pointers.
Add new fields sh4_group and ready.
(L_SH4, SH4_GROUP_USE, SH4_MT, SH4_EX, SH4_BR, SH4_LS): New macros.
(SH4_FE, SH4_CO SH4, BRANCH_TAKEN): New macros.
(sh4_units): New enum.
(FP_OP, FP_UNARY, FP_CMP, Delay_Slot, L, TL, TB, MA,
* gencode.c (op): Add new field sh4_group.
(tab): Add initializers for new field. Complete def / ref
information. Add code for latency / cycle count special cases.
(movsxy_tab, ppi_tab): Add initializers for new field.
* (gensim_caselist, sim_resume): Add code for SH4 timings.
* interp.c (fsca_s, fsrra_s): New functions.
* gencode.c (tab): Add entries for fsca and fsrra.
(expand_opcode): Allow variable length n / m fields.
Index: gencode.c
===================================================================
RCS file: /cvs/src/src/sim/sh/gencode.c,v
retrieving revision 1.20
diff -p -r1.20 gencode.c
*** gencode.c 11 Aug 2003 19:28:05 -0000 1.20
--- gencode.c 24 Oct 2003 16:09:29 -0000
***************
*** 36,41 ****
--- 36,42 ----
typedef struct
{
char *defs;
+ char *sh4_group;
char *refs;
char *name;
char *code;
*************** typedef struct
*** 47,181 ****
op tab[] =
{
! { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
"R[n] += SEXT(i);",
"if (i == 0) {",
! " UNDEF(n); /* see #ifdef PARANOID */",
" break;",
"}",
},
! { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
"R[n] += R[m];",
},
! { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
"ult = R[n] + T;",
"SET_SR_T (ult < R[n]);",
"R[n] = ult + R[m];",
"SET_SR_T (T || (R[n] < ult));",
},
! { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
"ult = R[n] + R[m];",
"SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
"R[n] = ult;",
},
! { "0", "", "and #<imm>,R0", "11001001i8*1....",
"R0 &= i;",
},
! { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
"R[n] &= R[m];",
},
! { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
"MA (1);",
"WBAT (GBR + R0, RBAT (GBR + R0) & i);",
},
! { "", "", "bf <bdisp8>", "10001011i8p1....",
"if (!T) {",
! " SET_NIP (PC + 4 + (SEXT(i) * 2));",
! " cycles += 2;",
"}",
},
! { "", "", "bf.s <bdisp8>", "10001111i8p1....",
"if (!T) {",
! " SET_NIP (PC + 4 + (SEXT (i) * 2));",
! " cycles += 2;",
" Delay_Slot (PC + 2);",
"}",
},
! { "", "", "bra <bdisp12>", "1010i12.........",
! "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
! "cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "n", "braf <REG_N>", "0000nnnn00100011",
! "SET_NIP (PC + 4 + R[n]);",
! "cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "", "bsr <bdisp12>", "1011i12.........",
"PR = PH2T (PC + 4);",
! "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
! "cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
"PR = PH2T (PC) + 4;",
! "SET_NIP (PC + 4 + R[n]);",
! "cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "", "bt <bdisp8>", "10001001i8p1....",
"if (T) {",
! " SET_NIP (PC + 4 + (SEXT (i) * 2));",
! " cycles += 2;",
"}",
},
! { "", "", "bt.s <bdisp8>", "10001101i8p1....",
"if (T) {",
! " SET_NIP (PC + 4 + (SEXT (i) * 2));",
! " cycles += 2;",
" Delay_Slot (PC + 2);",
"}",
},
! { "", "", "clrmac", "0000000000101000",
"MACH = 0;",
"MACL = 0;",
},
! { "", "", "clrs", "0000000001001000",
"SET_SR_S (0);",
},
! { "", "", "clrt", "0000000000001000",
"SET_SR_T (0);",
},
! { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
"SET_SR_T (R0 == SEXT (i));",
},
! { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
"SET_SR_T (R[n] == R[m]);",
},
! { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
"SET_SR_T (R[n] >= R[m]);",
},
! { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
"SET_SR_T (R[n] > R[m]);",
},
! { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
"SET_SR_T (UR[n] > UR[m]);",
},
! { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
"SET_SR_T (UR[n] >= UR[m]);",
},
! { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
"SET_SR_T (R[n] > 0);",
},
! { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
"SET_SR_T (R[n] >= 0);",
},
! { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
"ult = R[n] ^ R[m];",
"SET_SR_T (((ult & 0xff000000) == 0)",
" | ((ult & 0xff0000) == 0)",
--- 48,181 ----
op tab[] =
{
! { "n", "ex", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
"R[n] += SEXT(i);",
+ "#ifdef PARANOID",
"if (i == 0) {",
! " UNDEF(n);",
" break;",
"}",
+ "#endif /* PARANOID */",
},
! { "n", "ex", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
"R[n] += R[m];",
},
! { "nt", "ex", "mnt", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
"ult = R[n] + T;",
"SET_SR_T (ult < R[n]);",
"R[n] = ult + R[m];",
"SET_SR_T (T || (R[n] < ult));",
},
! { "nt", "ex", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
"ult = R[n] + R[m];",
"SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
"R[n] = ult;",
},
! { "0", "ex", "", "and #<imm>,R0", "11001001i8*1....",
"R0 &= i;",
},
! { "n", "ex", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
"R[n] &= R[m];",
},
! { "", "co", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
"MA (1);",
+ "cycles += 3;",
"WBAT (GBR + R0, RBAT (GBR + R0) & i);",
},
! { "", "br", "t", "bf <bdisp8>", "10001011i8p1....",
"if (!T) {",
! " BRANCH_TAKEN (PC + 4 + (SEXT(i) * 2));",
"}",
},
! { "", "br", "t", "bf.s <bdisp8>", "10001111i8p1....",
"if (!T) {",
! " BRANCH_TAKEN (PC + 4 + (SEXT (i) * 2));",
" Delay_Slot (PC + 2);",
"}",
},
! { "", "br", "", "bra <bdisp12>", "1010i12.........",
! "BRANCH_TAKEN (PC + 4 + (SEXT12 (i) * 2));",
"Delay_Slot (PC + 2);",
},
! { "", "co", "n", "braf <REG_N>", "0000nnnn00100011",
! "BRANCH_TAKEN (PC + 4 + R[n]);",
! "cycles++;",
"Delay_Slot (PC + 2);",
},
! { "", "br", "", "bsr <bdisp12>", "1011i12.........",
"PR = PH2T (PC + 4);",
! "BRANCH_TAKEN (PC + 4 + (SEXT12 (i) * 2));",
"Delay_Slot (PC + 2);",
},
! { "", "co", "n", "bsrf <REG_N>", "0000nnnn00000011",
"PR = PH2T (PC) + 4;",
! "BRANCH_TAKEN (PC + 4 + R[n]);",
! "cycles++;",
"Delay_Slot (PC + 2);",
},
! { "", "br", "t", "bt <bdisp8>", "10001001i8p1....",
"if (T) {",
! " BRANCH_TAKEN (PC + 4 + (SEXT (i) * 2));",
"}",
},
! { "", "br", "t", "bt.s <bdisp8>", "10001101i8p1....",
"if (T) {",
! " BRANCH_TAKEN (PC + 4 + (SEXT (i) * 2));",
" Delay_Slot (PC + 2);",
"}",
},
! { "", "co", "", "clrmac", "0000000000101000",
! "L_SH4 (mach, 3);",
! "L_SH4 (macl, 3);",
"MACH = 0;",
"MACL = 0;",
},
! { "", "co", "", "clrs", "0000000001001000",
"SET_SR_S (0);",
},
! { "t", "mt", "", "clrt", "0000000000001000",
"SET_SR_T (0);",
},
! { "t", "mt", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
"SET_SR_T (R0 == SEXT (i));",
},
! { "t", "mt", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
"SET_SR_T (R[n] == R[m]);",
},
! { "t", "mt", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
"SET_SR_T (R[n] >= R[m]);",
},
! { "t", "mt", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
"SET_SR_T (R[n] > R[m]);",
},
! { "t", "mt", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
"SET_SR_T (UR[n] > UR[m]);",
},
! { "t", "mt", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
"SET_SR_T (UR[n] >= UR[m]);",
},
! { "t", "mt", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
"SET_SR_T (R[n] > 0);",
},
! { "t", "mt", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
"SET_SR_T (R[n] >= 0);",
},
! { "t", "mt", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
"ult = R[n] ^ R[m];",
"SET_SR_T (((ult & 0xff000000) == 0)",
" | ((ult & 0xff0000) == 0)",
*************** op tab[] =
*** 183,253 ****
" | ((ult & 0xff) == 0));",
},
! { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
"SET_SR_Q ((R[n] & sbit) != 0);",
"SET_SR_M ((R[m] & sbit) != 0);",
"SET_SR_T (M != Q);",
},
! { "", "", "div0u", "0000000000011001",
"SET_SR_M (0);",
"SET_SR_Q (0);",
"SET_SR_T (0);",
},
! { "", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", /* ? MVS */
"div1 (R, m, n/*, T*/);",
},
! { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
"dmul (1/*signed*/, R[n], R[m]);",
},
! { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
"dmul (0/*unsigned*/, R[n], R[m]);",
},
! { "n", "n", "dt <REG_N>", "0100nnnn00010000",
"R[n]--;",
"SET_SR_T (R[n] == 0);",
},
! { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
"R[n] = SEXT (R[m]);",
},
! { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
"R[n] = SEXTW (R[m]);",
},
! { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
"R[n] = (R[m] & 0xff);",
},
! { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
"R[n] = (R[m] & 0xffff);",
},
/* sh2e */
! { "", "", "fabs <FREG_N>", "1111nnnn01011101",
! "FP_UNARY (n, fabs);",
"/* FIXME: FR(n) &= 0x7fffffff; */",
},
/* sh2e */
! { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
! "FP_OP (n, +, m);",
},
/* sh2e */
! { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
"FP_CMP (n, ==, m);",
},
/* sh2e */
! { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
"FP_CMP (n, >, m);",
},
/* sh4 */
! { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
"if (! FPSCR_PR || n & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
--- 183,260 ----
" | ((ult & 0xff) == 0));",
},
! { "t", "ex", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
"SET_SR_Q ((R[n] & sbit) != 0);",
"SET_SR_M ((R[m] & sbit) != 0);",
"SET_SR_T (M != Q);",
},
! { "t", "ex", "", "div0u", "0000000000011001",
"SET_SR_M (0);",
"SET_SR_Q (0);",
"SET_SR_T (0);",
},
! { "nt", "ex", "nmt", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
"div1 (R, m, n/*, T*/);",
},
! { "", "co", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
! "L_SH4 (macl, 4);",
! "L_SH4 (mach, 4);",
! "cycles++;",
"dmul (1/*signed*/, R[n], R[m]);",
},
! { "", "co", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
! "L_SH4 (macl, 4);",
! "L_SH4 (mach, 4);",
! "cycles++;",
"dmul (0/*unsigned*/, R[n], R[m]);",
},
! { "nt", "ex", "n", "dt <REG_N>", "0100nnnn00010000",
"R[n]--;",
"SET_SR_T (R[n] == 0);",
},
! { "n", "ex", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
"R[n] = SEXT (R[m]);",
},
! { "n", "ex", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
"R[n] = SEXTW (R[m]);",
},
! { "n", "ex", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
"R[n] = (R[m] & 0xff);",
},
! { "n", "ex", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
"R[n] = (R[m] & 0xffff);",
},
/* sh2e */
! { "", "ls", "", "fabs <FREG_N>", "1111nnnn01011101",
! "FP_UNARY (n, fabs, 0, 0);",
"/* FIXME: FR(n) &= 0x7fffffff; */",
},
/* sh2e */
! { "", "fe", "c", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
! "SH4_FE;",
! "FP_OP (n, +, m, 3, 8);",
},
/* sh2e */
! { "", "", "c", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
"FP_CMP (n, ==, m);",
},
/* sh2e */
! { "", "", "c", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
"FP_CMP (n, >, m);",
},
/* sh4 */
! { "", "fe", "c", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
"if (! FPSCR_PR || n & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
*************** op tab[] =
*** 259,269 ****
" } u;",
" u.f = DR(n);",
" FPUL = u.i;",
"}",
},
/* sh4 */
! { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
"if (! FPSCR_PR || n & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
--- 266,277 ----
" } u;",
" u.f = DR(n);",
" FPUL = u.i;",
+ " L_SH4 (fpul, 4);",
"}",
},
/* sh4 */
! { "", "fe", "c", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
"if (! FPSCR_PR || n & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
*************** op tab[] =
*** 275,310 ****
" } u;",
" u.i = FPUL;",
" SET_DR(n, u.f);",
"}",
},
/* sh2e */
! { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
! "FP_OP (n, /, m);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh4 */
! { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
"/* FIXME: not implemented */",
"RAISE_EXCEPTION (SIGILL);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
"SET_FR (n, (float)0.0);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
"SET_FR (n, (float)1.0);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
" union",
" {",
" int i;",
--- 283,319 ----
" } u;",
" u.i = FPUL;",
" SET_DR(n, u.f);",
+ " L_SH4 (FR[n], 4);",
"}",
},
/* sh2e */
! { "", "fe", "c", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
! "FP_OP (n, /, m, 12, 25);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh4 */
! { "", "fe", "c", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
"/* FIXME: not implemented */",
"RAISE_EXCEPTION (SIGILL);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "ls", "", "fldi0 <FREG_N>", "1111nnnn10001101",
"SET_FR (n, (float)0.0);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "ls", "", "fldi1 <FREG_N>", "1111nnnn10011101",
"SET_FR (n, (float)1.0);",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "ls", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
" union",
" {",
" int i;",
*************** op tab[] =
*** 315,338 ****
},
/* sh2e */
! { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
/* sh4 */
"if (FPSCR_PR)",
! " SET_DR (n, (double)FPUL);",
"else",
! "{",
! " SET_FR (n, (float)FPUL);",
! "}",
},
/* sh2e */
! { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
"SET_FR (n, FR(m) * FR(0) + FR(n));",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
/* sh4 */
"if (FPSCR_SZ) {",
" int ni = XD_TO_XF (n);",
--- 324,352 ----
},
/* sh2e */
! { "", "fe", "c", "float FPUL,<FREG_N>", "1111nnnn00101101",
/* sh4 */
"if (FPSCR_PR)",
! " {",
! " L_SH4 (FR[n], 4);",
! " SET_DR (n, (double)FPUL);",
! " }",
"else",
! " {",
! " L_SH4 (FR[n], 3);",
! " SET_FR (n, (float)FPUL);",
! " }",
},
/* sh2e */
! { "", "fe", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
! " L_SH4 (FR[n], 3);",
"SET_FR (n, FR(m) * FR(0) + FR(n));",
"/* FIXME: check for DP and (n & 1) == 0? */",
},
/* sh2e */
! { "", "ls", "c", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
/* sh4 */
"if (FPSCR_SZ) {",
" int ni = XD_TO_XF (n);",
*************** op tab[] =
*** 346,352 ****
"}",
},
/* sh2e */
! { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 360,366 ----
"}",
},
/* sh2e */
! { "", "ls", "nc", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 359,365 ****
"}",
},
/* sh2e */
! { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 373,379 ----
"}",
},
/* sh2e */
! { "f", "ld", "mc", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 372,378 ****
"}",
},
/* sh2e */
! { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 386,392 ----
"}",
},
/* sh2e */
! { "mf", "ld", "mc", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 387,393 ****
"}",
},
/* sh2e */
! { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 401,407 ----
"}",
},
/* sh2e */
! { "n", "ls", "nc", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 402,408 ****
"}",
},
/* sh2e */
! { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 416,422 ----
"}",
},
/* sh2e */
! { "f", "ld", "0mc", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 415,421 ****
"}",
},
/* sh2e */
! { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
--- 429,435 ----
"}",
},
/* sh2e */
! { "", "ls", "0nc", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
/* sh4 */
"if (FPSCR_SZ) {",
" MA (2);",
*************** op tab[] =
*** 431,447 ****
/* sh4: See fmov instructions above for move to/from extended fp registers */
/* sh2e */
! { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
! "FP_OP(n, *, m);",
},
/* sh2e */
! { "", "", "fneg <FREG_N>", "1111nnnn01001101",
! "FP_UNARY(n, -);",
},
/* sh4 */
! { "", "", "frchg", "1111101111111101",
"if (FPSCR_PR)",
" RAISE_EXCEPTION (SIGILL);",
"else",
--- 445,461 ----
/* sh4: See fmov instructions above for move to/from extended fp registers */
/* sh2e */
! { "", "fe", "c", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
! "FP_OP(n, *, m, 3, 8);",
},
/* sh2e */
! { "", "ls", "", "fneg <FREG_N>", "1111nnnn01001101",
! "FP_UNARY(n, -, 0, 0);",
},
/* sh4 */
! { "", "fe", "", "frchg", "1111101111111101",
"if (FPSCR_PR)",
" RAISE_EXCEPTION (SIGILL);",
"else",
*************** op tab[] =
*** 449,486 ****
},
/* sh4 */
! { "", "", "fschg", "1111001111111101",
"SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
},
/* sh3e */
! { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
! "FP_UNARY(n, sqrt);",
},
/* sh2e */
! { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
! "FP_OP(n, -, m);",
},
/* sh2e */
! { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
/* sh4 */
"if (FPSCR_PR) {",
" if (DR(n) != DR(n)) /* NaN */",
" FPUL = 0x80000000;",
" else",
" FPUL = (int)DR(n);",
"}",
"else",
! "if (FR(n) != FR(n)) /* NaN */",
! " FPUL = 0x80000000;",
! "else",
! " FPUL = (int)FR(n);",
},
/* sh2e */
! { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
" union",
" {",
" int i;",
--- 463,528 ----
},
/* sh4 */
! { "", "fe", "c", "fsca", "1111nnn011111101",
! "if (FPSCR_PR)",
! " RAISE_EXCEPTION (SIGILL);",
! "else",
! " {",
! " L_SH4 (FR[n], 11);",
! " L_SH4 (FR[n+1], 11);",
! " SET_FR (n, fsca_s (FPUL, &sin));",
! " SET_FR (n+1, fsca_s (FPUL, &cos));",
! " }",
! },
!
! /* sh4 */
! { "", "fe", "", "fschg", "1111001111111101",
"SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
},
/* sh3e */
! { "", "fe", "c", "fsqrt <FREG_N>", "1111nnnn01101101",
! "FP_UNARY(n, sqrt, 11, 24);",
! },
!
! /* sh4 */
! { "", "fe", "c", "fsrra", "1111nnnn01111101",
! "if (FPSCR_PR)",
! " RAISE_EXCEPTION (SIGILL);",
! "else",
! " {",
! " L_SH4 (FR[n], 11);",
! " SET_FR (n, fsrra_s (FR (n)));",
! " }",
},
/* sh2e */
! { "", "fe", "c", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
! "FP_OP(n, -, m, 3, 8);",
},
/* sh2e */
! { "", "fe", "c", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
/* sh4 */
"if (FPSCR_PR) {",
" if (DR(n) != DR(n)) /* NaN */",
" FPUL = 0x80000000;",
" else",
" FPUL = (int)DR(n);",
+ " L_SH4 (fpul, 4);",
"}",
"else",
! " {",
! " if (FR(n) != FR(n)) /* NaN */",
! " FPUL = 0x80000000;",
! " else",
! " FPUL = (int)FR(n);",
! " L_SH4 (fpul, 3);",
! " }",
},
/* sh2e */
! { "", "ls", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
" union",
" {",
" int i;",
*************** op tab[] =
*** 490,502 ****
" SET_FR (n, u.f);",
},
! { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
"SET_NIP (PT2H (R[n]));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
"PR = PH2T (PC + 4);",
"if (~doprofile)",
" gotcall (PR, R[n]);",
--- 532,544 ----
" SET_FR (n, u.f);",
},
! { "", "co", "n", "jmp @<REG_N>", "0100nnnn00101011",
"SET_NIP (PT2H (R[n]));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
! { "", "co", "n", "jsr @<REG_N>", "0100nnnn00001011",
"PR = PH2T (PC + 4);",
"if (~doprofile)",
" gotcall (PR, R[n]);",
*************** op tab[] =
*** 505,546 ****
"Delay_Slot (PC + 2);",
},
! { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
"CREG (m) = R[n];",
"/* FIXME: user mode */",
},
! { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
"SET_SR (R[n]);",
"/* FIXME: user mode */",
},
! { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
"SET_MOD (R[n]);",
},
#if 0
! { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
"DBR = R[n];",
"/* FIXME: user mode */",
},
#endif
! { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
"MA (1);",
"CREG (m) = RLAT (R[n]);",
"R[n] += 4;",
"/* FIXME: user mode */",
},
! { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
"MA (1);",
"SET_SR (RLAT (R[n]));",
"R[n] += 4;",
"/* FIXME: user mode */",
},
! { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
"MA (1);",
"SET_MOD (RLAT (R[n]));",
"R[n] += 4;",
},
#if 0
! { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
"MA (1);",
"DBR = RLAT (R[n]);",
"R[n] += 4;",
--- 547,590 ----
"Delay_Slot (PC + 2);",
},
! { "", "co", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
"CREG (m) = R[n];",
"/* FIXME: user mode */",
},
! { "", "co", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
! "cycles += 3;",
"SET_SR (R[n]);",
"/* FIXME: user mode */",
},
! { "", "co", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
"SET_MOD (R[n]);",
},
#if 0
! { "", "co", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
"DBR = R[n];",
"/* FIXME: user mode */",
},
#endif
! { "n", "co", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
"MA (1);",
"CREG (m) = RLAT (R[n]);",
"R[n] += 4;",
"/* FIXME: user mode */",
},
! { "n", "co", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
"MA (1);",
+ "cycles += 3;",
"SET_SR (RLAT (R[n]));",
"R[n] += 4;",
"/* FIXME: user mode */",
},
! { "n", "co", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
"MA (1);",
"SET_MOD (RLAT (R[n]));",
"R[n] += 4;",
},
#if 0
! { "n", "co", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
"MA (1);",
"DBR = RLAT (R[n]);",
"R[n] += 4;",
*************** op tab[] =
*** 549,862 ****
#endif
/* sh-dsp */
! { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
"RE = SEXT (i) * 2 + 4 + PH2T (PC);",
},
! { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
"RS = SEXT (i) * 2 + 4 + PH2T (PC);",
},
! { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
"SREG (m) = R[n];",
},
! { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
"MA (1);",
"SREG (m) = RLAT(R[n]);",
"R[n] += 4;",
},
/* sh2e / sh-dsp (lds <REG_N>,DSR) */
! { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
"SET_FPSCR(R[n]);",
},
/* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
! { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
"MA (1);",
"SET_FPSCR (RLAT(R[n]));",
"R[n] += 4;",
},
! { "", "", "ldtlb", "0000000000111000",
"/* We don't implement cache or tlb, so this is a noop. */",
},
!
! { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
"macl(&R0,memory,n,m);",
},
! { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
"macw(&R0,memory,n,m,endianw);",
},
! { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
"R[n] = SEXT(i);",
},
! { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
"R[n] = R[m];",
},
! { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
"MA (1);",
"R0 = RSBAT (i + GBR);",
! "L (0);",
},
! { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
"MA (1);",
"R0 = RSBAT (i + R[m]);",
! "L (0);",
},
! { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
"MA (1);",
"R[n] = RSBAT (R0 + R[m]);",
! "L (n);",
},
! { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
"MA (1);",
"R[n] = RSBAT (R[m]);",
"R[m] += 1;",
! "L (n);",
},
! { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
"MA (1);",
"WBAT (R[n], R[m]);",
},
! { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
"MA (1);",
"WBAT (i + GBR, R0);",
},
! { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
"MA (1);",
"WBAT (i + R[m], R0);",
},
! { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
"MA (1);",
"WBAT (R[n] + R0, R[m]);",
},
! { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
"MA (1);",
"R[n] -= 1;",
"WBAT (R[n], R[m]);",
},
! { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
"MA (1);",
"R[n] = RSBAT (R[m]);",
! "L (n);",
},
! { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
"MA (1);",
"R0 = RLAT (i + GBR);",
! "L (0);",
},
! { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
"MA (1);",
"R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
! "L (n);",
},
! { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
"MA (1);",
"R[n] = RLAT (i + R[m]);",
! "L (n);",
},
! { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
"MA (1);",
"R[n] = RLAT (R0 + R[m]);",
! "L (n);",
},
! { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
"MA (1);",
"R[n] = RLAT (R[m]);",
"R[m] += 4;",
! "L (n);",
},
! { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
"MA (1);",
"R[n] = RLAT (R[m]);",
! "L (n);",
},
! { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
"MA (1);",
"WLAT (i + GBR, R0);",
},
! { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
"MA (1);",
"WLAT (i + R[n], R[m]);",
},
! { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
"MA (1);",
"WLAT (R0 + R[n], R[m]);",
},
! { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
"MA (1) ;",
"R[n] -= 4;",
"WLAT (R[n], R[m]);",
},
! { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
"MA (1);",
"WLAT (R[n], R[m]);",
},
! { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
"MA (1);",
"R0 = RSWAT (i + GBR);",
! "L (0);",
},
! { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
"MA (1);",
"R[n] = RSWAT (PH2T (PC + 4 + i));",
! "L (n);",
},
! { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
"MA (1);",
"R0 = RSWAT (i + R[m]);",
! "L (0);",
},
! { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
"MA (1);",
"R[n] = RSWAT (R0 + R[m]);",
! "L (n);",
},
! { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
"MA (1);",
"R[n] = RSWAT (R[m]);",
"R[m] += 2;",
! "L (n);",
},
! { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
"MA (1);",
"R[n] = RSWAT (R[m]);",
! "L (n);",
},
! { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
"MA (1);",
"WWAT (i + GBR, R0);",
},
! { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
"MA (1);",
"WWAT (i + R[m], R0);",
},
! { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
"MA (1);",
"WWAT (R0 + R[n], R[m]);",
},
! { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], R[m]);",
},
! { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
"MA (1);",
"WWAT (R[n], R[m]);",
},
! { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
"R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
},
! { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
"/* We don't simulate cache, so this insn is identical to mov. */",
"MA (1);",
"WLAT (R[n], R[0]);",
},
! { "n", "", "movt <REG_N>", "0000nnnn00101001",
"R[n] = T;",
},
! { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
"MACL = ((int)R[n]) * ((int)R[m]);",
},
#if 0
! { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
"MACL = R[n] * R[m];",
},
#endif
/* muls.w - see muls */
! { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
"MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
},
/* mulu.w - see mulu */
! { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
"MACL = (((unsigned int)(unsigned short)R[n])",
" * ((unsigned int)(unsigned short)R[m]));",
},
! { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
"R[n] = - R[m];",
},
! { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
"ult = -T;",
"SET_SR_T (ult > 0);",
"R[n] = ult - R[m];",
"SET_SR_T (T || (R[n] > ult));",
},
! { "", "", "nop", "0000000000001001",
"/* nop */",
},
! { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
"R[n] = ~R[m];",
},
! { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "0", "", "or #<imm>,R0", "11001011i8*1....",
"R0 |= i;",
},
! { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
"R[n] |= R[m];",
},
! { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
"MA (1);",
"WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
},
! { "", "n", "pref @<REG_N>", "0000nnnn10000011",
"/* Except for the effect on the cache - which is not simulated -",
" this is like a nop. */",
},
! { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
"ult = R[n] < 0;",
"R[n] = (R[n] << 1) | T;",
"SET_SR_T (ult);",
},
! { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
"ult = R[n] & 1;",
"R[n] = (UR[n] >> 1) | (T << 31);",
"SET_SR_T (ult);",
},
! { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
"R[n] |= T;",
},
! { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
"SET_SR_T (R[n] & 1);",
"R[n] = UR[n] >> 1;",
"R[n] |= (T << 31);",
},
! { "", "", "rte", "0000000000101011",
#if 0
/* SH-[12] */
"int tmp = PC;",
--- 593,916 ----
#endif
/* sh-dsp */
! { "", "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
"RE = SEXT (i) * 2 + 4 + PH2T (PC);",
},
! { "", "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
"RS = SEXT (i) * 2 + 4 + PH2T (PC);",
},
! { "", "co", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
"SREG (m) = R[n];",
},
! { "n", "co", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
"MA (1);",
"SREG (m) = RLAT(R[n]);",
"R[n] += 4;",
},
/* sh2e / sh-dsp (lds <REG_N>,DSR) */
! { "", "co", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
"SET_FPSCR(R[n]);",
},
/* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
! { "n", "co", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
! "L_SH4 (fpscr, 4);",
"MA (1);",
"SET_FPSCR (RLAT(R[n]));",
"R[n] += 4;",
},
! { "", "", "", "ldtlb", "0000000000111000",
"/* We don't implement cache or tlb, so this is a noop. */",
},
! /* mac / mac doesn't incur an extra latency penalty. */
! { "nm", "co", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
! "cycles++;",
"macl(&R0,memory,n,m);",
},
! { "nm", "co", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
! "cycles++;",
"macw(&R0,memory,n,m,endianw);",
},
! { "n", "ex", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
"R[n] = SEXT(i);",
},
! { "n", "mt", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
"R[n] = R[m];",
},
! { "0", "ld", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
"MA (1);",
"R0 = RSBAT (i + GBR);",
! "L (R[0]);",
},
! { "0", "ld", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
"MA (1);",
"R0 = RSBAT (i + R[m]);",
! "L (R[0]);",
},
! { "n", "ld", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
"MA (1);",
"R[n] = RSBAT (R0 + R[m]);",
! "L (R[n]);",
},
! { "nm", "ld", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
"MA (1);",
"R[n] = RSBAT (R[m]);",
"R[m] += 1;",
! "L (R[n]);",
},
! { "", "ls", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
"MA (1);",
"WBAT (R[n], R[m]);",
},
! { "", "ls", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
"MA (1);",
"WBAT (i + GBR, R0);",
},
! { "", "ls", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
"MA (1);",
"WBAT (i + R[m], R0);",
},
! { "", "ls", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
"MA (1);",
"WBAT (R[n] + R0, R[m]);",
},
! { "n", "ls", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
"MA (1);",
"R[n] -= 1;",
"WBAT (R[n], R[m]);",
},
! { "n", "ld", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
"MA (1);",
"R[n] = RSBAT (R[m]);",
! "L (R[n]);",
},
! { "0", "ld", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
"MA (1);",
"R0 = RLAT (i + GBR);",
! "L (R[0]);",
},
! { "n", "ld", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
"MA (1);",
"R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
! "L (R[n]);",
},
! { "n", "ld", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
"MA (1);",
"R[n] = RLAT (i + R[m]);",
! "L (R[n]);",
},
! { "n", "ld", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
"MA (1);",
"R[n] = RLAT (R0 + R[m]);",
! "L (R[n]);",
},
! { "nm", "ld", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
"MA (1);",
"R[n] = RLAT (R[m]);",
"R[m] += 4;",
! "L (R[n]);",
},
! { "n", "ld", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
"MA (1);",
"R[n] = RLAT (R[m]);",
! "L (R[n]);",
},
! { "", "ls", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
"MA (1);",
"WLAT (i + GBR, R0);",
},
! { "", "ls", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
"MA (1);",
"WLAT (i + R[n], R[m]);",
},
! { "", "ls", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
"MA (1);",
"WLAT (R0 + R[n], R[m]);",
},
! { "n", "ls", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
"MA (1) ;",
"R[n] -= 4;",
"WLAT (R[n], R[m]);",
},
! { "", "ls", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
"MA (1);",
"WLAT (R[n], R[m]);",
},
! { "0", "ld", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
"MA (1);",
"R0 = RSWAT (i + GBR);",
! "L (R[0]);",
},
! { "n", "ld", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
"MA (1);",
"R[n] = RSWAT (PH2T (PC + 4 + i));",
! "L (R[n]);",
},
! { "0", "ld", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
"MA (1);",
"R0 = RSWAT (i + R[m]);",
! "L (R[0]);",
},
! { "n", "ld", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
"MA (1);",
"R[n] = RSWAT (R0 + R[m]);",
! "L (R[n]);",
},
! { "nm", "ld", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
"MA (1);",
"R[n] = RSWAT (R[m]);",
"R[m] += 2;",
! "L (R[n]);",
},
! { "n", "ld", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
"MA (1);",
"R[n] = RSWAT (R[m]);",
! "L (R[n]);",
},
! { "", "ls", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
"MA (1);",
"WWAT (i + GBR, R0);",
},
! { "", "ls", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
"MA (1);",
"WWAT (i + R[m], R0);",
},
! { "", "ls", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
"MA (1);",
"WWAT (R0 + R[n], R[m]);",
},
! { "n", "ls", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], R[m]);",
},
! { "", "ls", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
"MA (1);",
"WWAT (R[n], R[m]);",
},
! { "0", "ex", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
"R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
},
! { "", "ls", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
"/* We don't simulate cache, so this insn is identical to mov. */",
"MA (1);",
"WLAT (R[n], R[0]);",
},
! { "n", "ex", "", "movt <REG_N>", "0000nnnn00101001",
"R[n] = T;",
},
! { "", "co", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
! "L_SH4 (macl, 4);",
! "cycles++;",
"MACL = ((int)R[n]) * ((int)R[m]);",
},
#if 0
! { "", "co", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
"MACL = R[n] * R[m];",
},
#endif
/* muls.w - see muls */
! { "", "co", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
! "L_SH4 (macl, 4);",
! "cycles++;",
"MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
},
/* mulu.w - see mulu */
! { "", "co", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
! "L_SH4 (macl, 4);",
! "cycles++;",
"MACL = (((unsigned int)(unsigned short)R[n])",
" * ((unsigned int)(unsigned short)R[m]));",
},
! { "n", "ex", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
"R[n] = - R[m];",
},
! { "nt", "ex", "mt", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
"ult = -T;",
"SET_SR_T (ult > 0);",
"R[n] = ult - R[m];",
"SET_SR_T (T || (R[n] > ult));",
},
! { "", "mt", "", "nop", "0000000000001001",
"/* nop */",
},
! { "n", "ex", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
"R[n] = ~R[m];",
},
! { "", "ls", "n", "ocbi @<REG_N>", "0000nnnn10010011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "", "ls", "n", "ocbp @<REG_N>", "0000nnnn10100011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "", "ls", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
"RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
"/* FIXME: Cache not implemented */",
},
! { "0", "ex", "", "or #<imm>,R0", "11001011i8*1....",
"R0 |= i;",
},
! { "n", "ex", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
"R[n] |= R[m];",
},
! { "", "co", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
"MA (1);",
+ "cycles += 3;",
"WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
},
! { "", "ls", "n", "pref @<REG_N>", "0000nnnn10000011",
"/* Except for the effect on the cache - which is not simulated -",
" this is like a nop. */",
},
! { "nt", "ex", "nt", "rotcl <REG_N>", "0100nnnn00100100",
"ult = R[n] < 0;",
"R[n] = (R[n] << 1) | T;",
"SET_SR_T (ult);",
},
! { "nt", "ex", "nt", "rotcr <REG_N>", "0100nnnn00100101",
"ult = R[n] & 1;",
"R[n] = (UR[n] >> 1) | (T << 31);",
"SET_SR_T (ult);",
},
! { "nt", "ex", "n", "rotl <REG_N>", "0100nnnn00000100",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
"R[n] |= T;",
},
! { "nt", "ex", "n", "rotr <REG_N>", "0100nnnn00000101",
"SET_SR_T (R[n] & 1);",
"R[n] = UR[n] >> 1;",
"R[n] |= (T << 31);",
},
! { "", "co", "", "rte", "0000000000101011",
#if 0
/* SH-[12] */
"int tmp = PC;",
*************** op tab[] =
*** 868,889 ****
#else
"SET_SR (SSR);",
"SET_NIP (PT2H (SPC));",
! "cycles += 2;",
"Delay_Slot (PC + 2);",
#endif
},
! { "", "", "rts", "0000000000001011",
"SET_NIP (PT2H (PR));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
/* sh-dsp */
! { "", "n", "setrc <REG_N>", "0100nnnn00010100",
"SET_RC (R[n]);",
},
! { "", "", "setrc #<imm>", "10000010i8*1....",
/* It would be more realistic to let loop_start point to some static
memory that contains an illegal opcode and then give a bus error when
the loop is eventually encountered, but it seems not only simpler,
--- 922,943 ----
#else
"SET_SR (SSR);",
"SET_NIP (PT2H (SPC));",
! "cycles += 4;",
"Delay_Slot (PC + 2);",
#endif
},
! { "", "co", "", "rts", "0000000000001011",
"SET_NIP (PT2H (PR));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
/* sh-dsp */
! { "", "", "n", "setrc <REG_N>", "0100nnnn00010100",
"SET_RC (R[n]);",
},
! { "", "", "", "setrc #<imm>", "10000010i8*1....",
/* It would be more realistic to let loop_start point to some static
memory that contains an illegal opcode and then give a bus error when
the loop is eventually encountered, but it seems not only simpler,
*************** op tab[] =
*** 897,1037 ****
"}",
},
! { "", "", "sets", "0000000001011000",
"SET_SR_S (1);",
},
! { "", "", "sett", "0000000000011000",
"SET_SR_T (1);",
},
! { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
"R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
},
! { "n", "n", "shal <REG_N>", "0100nnnn00100000",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
},
! { "n", "n", "shar <REG_N>", "0100nnnn00100001",
"SET_SR_T (R[n] & 1);",
"R[n] = R[n] >> 1;",
},
! { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
"R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
},
! { "n", "n", "shll <REG_N>", "0100nnnn00000000",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
},
! { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
"R[n] <<= 2;",
},
! { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
"R[n] <<= 8;",
},
! { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
"R[n] <<= 16;",
},
! { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
"SET_SR_T (R[n] & 1);",
"R[n] = UR[n] >> 1;",
},
! { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
"R[n] = UR[n] >> 2;",
},
! { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
"R[n] = UR[n] >> 8;",
},
! { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
"R[n] = UR[n] >> 16;",
},
! { "", "", "sleep", "0000000000011011",
"nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
},
! { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
"R[n] = CREG (m);",
},
#if 0
! { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
"R[n] = SGR;",
},
! { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
"R[n] = DBR;",
},
#endif
! { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], CREG (m));",
},
#if 0
! { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], SGR);",
},
! { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], DBR);",
},
#endif
! { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
"R[n] = SREG (m);",
},
! { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], SREG (m));",
},
! { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
"R[n] -= R[m];",
},
! { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
"ult = R[n] - T;",
"SET_SR_T (ult > R[n]);",
"R[n] = ult - R[m];",
"SET_SR_T (T || (R[n] > ult));",
},
! { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
"ult = R[n] - R[m];",
"SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
"R[n] = ult;",
},
! { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
"R[n] = ((R[m] & 0xffff0000)",
" | ((R[m] << 8) & 0xff00)",
" | ((R[m] >> 8) & 0x00ff));",
},
! { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
"R[n] = (((R[m] << 16) & 0xffff0000)",
" | ((R[m] >> 16) & 0x00ffff));",
},
! { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
"MA (1);",
"ult = RBAT(R[n]);",
"SET_SR_T (ult == 0);",
"WBAT(R[n],ult|0x80);",
},
! { "0", "", "trapa #<imm>", "11000011i8*1....",
"long imm = 0xff & i;",
"if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
" nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
#if 0
--- 951,1102 ----
"}",
},
! { "", "co", "", "sets", "0000000001011000",
"SET_SR_S (1);",
},
! { "t", "mt", "", "sett", "0000000000011000",
"SET_SR_T (1);",
},
! { "n", "ex", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
"R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
},
! { "nt", "ex", "n", "shal <REG_N>", "0100nnnn00100000",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
},
! { "nt", "ex", "n", "shar <REG_N>", "0100nnnn00100001",
"SET_SR_T (R[n] & 1);",
"R[n] = R[n] >> 1;",
},
! { "n", "ex", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
"R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
},
! { "nt", "ex", "n", "shll <REG_N>", "0100nnnn00000000",
"SET_SR_T (R[n] < 0);",
"R[n] <<= 1;",
},
! { "n", "ex", "n", "shll2 <REG_N>", "0100nnnn00001000",
"R[n] <<= 2;",
},
! { "n", "ex", "n", "shll8 <REG_N>", "0100nnnn00011000",
"R[n] <<= 8;",
},
! { "n", "ex", "n", "shll16 <REG_N>", "0100nnnn00101000",
"R[n] <<= 16;",
},
! { "nt", "ex", "n", "shlr <REG_N>", "0100nnnn00000001",
"SET_SR_T (R[n] & 1);",
"R[n] = UR[n] >> 1;",
},
! { "n", "ex", "n", "shlr2 <REG_N>", "0100nnnn00001001",
"R[n] = UR[n] >> 2;",
},
! { "n", "ex", "n", "shlr8 <REG_N>", "0100nnnn00011001",
"R[n] = UR[n] >> 8;",
},
! { "n", "ex", "n", "shlr16 <REG_N>", "0100nnnn00101001",
"R[n] = UR[n] >> 16;",
},
! { "", "co", "", "sleep", "0000000000011011",
! "cycles += 3;",
"nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
},
! { "n", "co", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
! "cycles++;",
"R[n] = CREG (m);",
},
#if 0
! { "n", "co", "", "stc SGR,<REG_N>", "0000nnnn00111010",
! "cycles += 2;",
"R[n] = SGR;",
},
! { "n", "co", "", "stc DBR,<REG_N>", "0000nnnn11111010",
! "cycles++;",
"R[n] = DBR;",
},
#endif
! { "n", "co", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
"MA (1);",
+ "cycles++;",
"R[n] -= 4;",
"WLAT (R[n], CREG (m));",
},
#if 0
! { "n", "co", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
"MA (1);",
+ "cycles += 2;",
"R[n] -= 4;",
"WLAT (R[n], SGR);",
},
! { "n", "co", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
"MA (1);",
+ "cycles++;",
"R[n] -= 4;",
"WLAT (R[n], DBR);",
},
#endif
! { "n", "co", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
! "L_SH4 (R[n], 3);", /* This is the mach / macl timing. */
"R[n] = SREG (m);",
},
! { "n", "co", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
"MA (1);",
+ "cycles++;", /* This is the PR timing. */
"R[n] -= 4;",
"WLAT (R[n], SREG (m));",
},
! { "n", "ex", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
"R[n] -= R[m];",
},
! { "nt", "ex", "nmt", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
"ult = R[n] - T;",
"SET_SR_T (ult > R[n]);",
"R[n] = ult - R[m];",
"SET_SR_T (T || (R[n] > ult));",
},
! { "nt", "ex", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
"ult = R[n] - R[m];",
"SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
"R[n] = ult;",
},
! { "n", "ex", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
"R[n] = ((R[m] & 0xffff0000)",
" | ((R[m] << 8) & 0xff00)",
" | ((R[m] >> 8) & 0x00ff));",
},
! { "n", "ex", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
"R[n] = (((R[m] << 16) & 0xffff0000)",
" | ((R[m] >> 16) & 0x00ffff));",
},
! { "", "co", "n", "tas.b @<REG_N>", "0100nnnn00011011",
"MA (1);",
+ "cycles += 4;",
"ult = RBAT(R[n]);",
"SET_SR_T (ult == 0);",
"WBAT(R[n],ult|0x80);",
},
! { "0", "co", "", "trapa #<imm>", "11000011i8*1....",
"long imm = 0xff & i;",
+ "cycles += 6;",
"if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
" nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
#if 0
*************** op tab[] =
*** 1052,1082 ****
"}",
},
! { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
"SET_SR_T ((R[n] & R[m]) == 0);",
},
! { "", "0", "tst #<imm>,R0", "11001000i8*1....",
"SET_SR_T ((R0 & i) == 0);",
},
! { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
"MA (1);",
"SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
},
! { "", "0", "xor #<imm>,R0", "11001010i8*1....",
"R0 ^= i;",
},
! { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
"R[n] ^= R[m];",
},
! { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
"MA (1);",
"ult = RBAT (GBR+R0);",
"ult ^= i;",
"WBAT (GBR + R0, ult);",
},
! { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
"R[n] = (((R[n] >> 16) & 0xffff)",
" | ((R[m] << 16) & 0xffff0000));",
},
--- 1117,1148 ----
"}",
},
! { "t", "mt", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
"SET_SR_T ((R[n] & R[m]) == 0);",
},
! { "t", "mt", "0", "tst #<imm>,R0", "11001000i8*1....",
"SET_SR_T ((R0 & i) == 0);",
},
! { "t", "mt", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
"MA (1);",
"SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
},
! { "0", "ex", "0", "xor #<imm>,R0", "11001010i8*1....",
"R0 ^= i;",
},
! { "n", "ex", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
"R[n] ^= R[m];",
},
! { "", "co", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
"MA (1);",
+ "cycles += 3;",
"ult = RBAT (GBR+R0);",
"ult ^= i;",
"WBAT (GBR + R0, ult);",
},
! { "n", "ex", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
"R[n] = (((R[n] >> 16) & 0xffff)",
" | ((R[m] << 16) & 0xffff0000));",
},
*************** op movsxy_tab[] =
*** 1098,1298 ****
450 MHz PIII - 9% with ACE_FAST.
Maybe we should have separate simulator loops? */
#if 1
! { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
"MA (1);",
"R[n] -= 2;",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += 2;",
},
! { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
"MA (1);",
"R[n] -= 2;",
"DSP_R (m) = RSWAT (R[n]);",
},
! { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
},
! { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
"R[n] += 2;",
},
! { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
"R[n] += R[8];",
},
! { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += 2;",
},
! { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += R[8];",
},
! { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], SEXT (DSP_R (m)));",
},
! { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
},
! { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
"R[n] += 2;",
},
! { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
"R[n] += R[8];",
},
! { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
"MA (1);",
"R[n] -= 4;",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += 4;",
},
! { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], DSP_R (m));",
},
! { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
},
! { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
"R[n] += 4;",
},
! { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], SEXT (DSP_R (m)));",
},
! { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
},
! { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
"R[n] += 4;",
},
! { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
"R[n] += R[8];",
},
! { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"iword &= 0xfd53; goto top;",
},
! { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
"iword &= 0xfd53; goto top;",
},
! { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001100",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
"iword &= 0xfd53; goto top;",
},
! { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
"WWAT (R[n], DSP_R (m) >> 16);",
"iword &= 0xfd53; goto top;",
},
! { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
"iword &= 0xfd53; goto top;",
},
! { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
"iword &= 0xfd53; goto top;",
},
! { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
"DSP_R (m) = RSWAT (R[n]) << 16;",
},
! { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
},
! { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000011",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
},
! { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
},
! { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010011",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
},
! { "", "", "nopx nopy", "1111000000000000",
"/* nop */",
},
! { "", "", "ppi", "1111100000000000",
"ppi_insn (RIAT (nip));",
"nip += 2;",
"iword &= 0xf7ff; goto top;",
--- 1164,1364 ----
450 MHz PIII - 9% with ACE_FAST.
Maybe we should have separate simulator loops? */
#if 1
! { "n", "", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
"MA (1);",
"R[n] -= 2;",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "", "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "n", "", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += 2;",
},
! { "n", "", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
"MA (1);",
"R[n] -= 2;",
"DSP_R (m) = RSWAT (R[n]);",
},
! { "", "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
},
! { "n", "", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
"R[n] += 2;",
},
! { "n", "", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
"MA (1);",
"DSP_R (m) = RSWAT (R[n]);",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "", "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "n", "", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += 2;",
},
! { "n", "", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
"MA (1);",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
"MA (1);",
"R[n] -= 2;",
"WWAT (R[n], SEXT (DSP_R (m)));",
},
! { "", "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
},
! { "n", "", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
"R[n] += 2;",
},
! { "n", "", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
"MA (1);",
"WWAT (R[n], SEXT (DSP_R (m)));",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
"MA (1);",
"R[n] -= 4;",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "", "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
},
! { "n", "", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += 4;",
},
! { "n", "", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
"MA (1);",
"DSP_R (m) = RLAT (R[n]);",
"DSP_GRD (m) = SIGN32 (DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], DSP_R (m));",
},
! { "", "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
},
! { "n", "", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
"R[n] += 4;",
},
! { "n", "", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
"MA (1);",
"WLAT (R[n], DSP_R (m));",
"R[n] += R[8];",
},
! { "n", "", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
"MA (1);",
"R[n] -= 4;",
"WLAT (R[n], SEXT (DSP_R (m)));",
},
! { "", "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
},
! { "n", "", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
"R[n] += 4;",
},
! { "n", "", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
"MA (1);",
"WLAT (R[n], SEXT (DSP_R (m)));",
"R[n] += R[8];",
},
! { "", "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"iword &= 0xfd53; goto top;",
},
! { "n", "", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
"iword &= 0xfd53; goto top;",
},
! { "n", "", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001100",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
"iword &= 0xfd53; goto top;",
},
! { "", "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
"WWAT (R[n], DSP_R (m) >> 16);",
"iword &= 0xfd53; goto top;",
},
! { "n", "", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
"iword &= 0xfd53; goto top;",
},
! { "n", "", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
"iword &= 0xfd53; goto top;",
},
! { "", "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
"DSP_R (m) = RSWAT (R[n]) << 16;",
},
! { "n", "", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
},
! { "n", "", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000011",
"DSP_R (m) = RSWAT (R[n]) << 16;",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
},
! { "", "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
"WWAT (R[n], DSP_R (m) >> 16);",
},
! { "n", "", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
},
! { "n", "", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010011",
"WWAT (R[n], DSP_R (m) >> 16);",
"R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
},
! { "", "", "", "nopx nopy", "1111000000000000",
"/* nop */",
},
! { "", "", "", "ppi", "1111100000000000",
"ppi_insn (RIAT (nip));",
"nip += 2;",
"iword &= 0xf7ff; goto top;",
*************** op movsxy_tab[] =
*** 1302,1308 ****
op ppi_tab[] =
{
! { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
"int Sz = DSP_R (z) & 0xffff0000;",
"",
"if (i <= 16)",
--- 1368,1374 ----
op ppi_tab[] =
{
! { "", "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
"int Sz = DSP_R (z) & 0xffff0000;",
"",
"if (i <= 16)",
*************** op ppi_tab[] =
*** 1318,1324 ****
"res_grd = 0;",
"goto logical;",
},
! { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
"int Sz = DSP_R (z);",
"int Sz_grd = GET_DSP_GRD (z);",
"",
--- 1384,1390 ----
"res_grd = 0;",
"goto logical;",
},
! { "", "","", "psha #<imm>,dz", "00010iiim32.zzzz",
"int Sz = DSP_R (z);",
"int Sz_grd = GET_DSP_GRD (z);",
"",
*************** op ppi_tab[] =
*** 1360,1366 ****
"COMPUTE_OVERFLOW;",
"greater_equal = 0;",
},
! { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
"res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
"if (res == 0x80000000)",
" res = 0x7fffffff;",
--- 1426,1432 ----
"COMPUTE_OVERFLOW;",
"greater_equal = 0;",
},
! { "", "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
"res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
"if (res == 0x80000000)",
" res = 0x7fffffff;",
*************** op ppi_tab[] =
*** 1368,1374 ****
"DSP_GRD (g) = SIGN32 (res);",
"return;",
},
! { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1434,1440 ----
"DSP_GRD (g) = SIGN32 (res);",
"return;",
},
! { "", "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1387,1393 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1453,1459 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1405,1411 ****
"res_grd = Sx_grd + Sy_grd + carry;",
"COMPUTE_OVERFLOW;",
},
! { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1471,1477 ----
"res_grd = Sx_grd + Sy_grd + carry;",
"COMPUTE_OVERFLOW;",
},
! { "", "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1424,1430 ****
"DSR |= carry;\n",
"goto assign_z;\n",
},
! { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1490,1496 ----
"DSR |= carry;\n",
"goto assign_z;\n",
},
! { "", "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1443,1449 ****
"DSR |= carry;\n",
"goto assign_z;\n",
},
! { "","", "pcmp Sx,Sy", "10000100xxyy....",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1509,1515 ----
"DSR |= carry;\n",
"goto assign_z;\n",
},
! { "", "","", "pcmp Sx,Sy", "10000100xxyy....",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1456,1466 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
},
! { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
},
! { "","", "pabs Sx,Dz", "10001000xx..zzzz",
"res = DSP_R (x);",
"res_grd = GET_DSP_GRD (x);",
"if (res >= 0)",
--- 1522,1532 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
},
! { "", "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
},
! { "", "","", "pabs Sx,Dz", "10001000xx..zzzz",
"res = DSP_R (x);",
"res_grd = GET_DSP_GRD (x);",
"if (res >= 0)",
*************** op ppi_tab[] =
*** 1477,1483 ****
"overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
"ADD_SUB_GE;",
},
! { "","", "prnd Sx,Dz", "10011000xx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
--- 1543,1549 ----
"overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
"ADD_SUB_GE;",
},
! { "", "","", "prnd Sx,Dz", "10011000xx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
*************** op ppi_tab[] =
*** 1487,1493 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "pabs Sy,Dz", "10101000..yyzzzz",
"res = DSP_R (y);",
"res_grd = 0;",
"overflow = 0;",
--- 1553,1559 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "pabs Sy,Dz", "10101000..yyzzzz",
"res = DSP_R (y);",
"res_grd = 0;",
"overflow = 0;",
*************** op ppi_tab[] =
*** 1510,1516 ****
" }",
" }",
},
! { "","", "prnd Sy,Dz", "10111000..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
--- 1576,1582 ----
" }",
" }",
},
! { "", "","", "prnd Sy,Dz", "10111000..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
*************** op ppi_tab[] =
*** 1520,1526 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
"int Sx = DSP_R (x) & 0xffff0000;",
"int Sy = DSP_R (y) >> 16 & 0x7f;",
"",
--- 1586,1592 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
"int Sx = DSP_R (x) & 0xffff0000;",
"int Sy = DSP_R (y) >> 16 & 0x7f;",
"",
*************** op ppi_tab[] =
*** 1535,1541 ****
" }",
"goto cond_logical;",
},
! { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y) >> 16 & 0x7f;",
--- 1601,1607 ----
" }",
"goto cond_logical;",
},
! { "", "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y) >> 16 & 0x7f;",
*************** op ppi_tab[] =
*** 1578,1584 ****
"COMPUTE_OVERFLOW;",
"greater_equal = 0;",
},
! { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1644,1650 ----
"COMPUTE_OVERFLOW;",
"greater_equal = 0;",
},
! { "", "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1590,1596 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
--- 1656,1662 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int Sy = DSP_R (y);",
*************** op ppi_tab[] =
*** 1602,1608 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
"res = DSP_R (x) & DSP_R (y);",
"cond_logical:",
"res &= 0xffff0000;",
--- 1668,1674 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
"res = DSP_R (x) & DSP_R (y);",
"cond_logical:",
"res &= 0xffff0000;",
*************** op ppi_tab[] =
*** 1620,1634 ****
" DSR |= DSR_MASK_Z;\n",
"goto assign_dc;\n",
},
! { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
"res = DSP_R (x) ^ DSP_R (y);",
"goto cond_logical;",
},
! { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
"res = DSP_R (x) | DSP_R (y);",
"goto cond_logical;",
},
! { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
--- 1686,1700 ----
" DSR |= DSR_MASK_Z;\n",
"goto assign_dc;\n",
},
! { "", "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
"res = DSP_R (x) ^ DSP_R (y);",
"goto cond_logical;",
},
! { "", "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
"res = DSP_R (x) | DSP_R (y);",
"goto cond_logical;",
},
! { "", "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
*************** op ppi_tab[] =
*** 1639,1645 ****
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
--- 1705,1711 ----
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "", "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
*************** op ppi_tab[] =
*** 1650,1656 ****
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
--- 1716,1722 ----
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "", "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
*************** op ppi_tab[] =
*** 1661,1667 ****
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
--- 1727,1733 ----
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "", "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
*************** op ppi_tab[] =
*** 1672,1685 ****
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "","", "(if cc) pclr Dz", "100011cc....zzzz",
"res = 0;",
"res_grd = 0;",
"carry = 0;",
"overflow = 0;",
"greater_equal = 1;",
},
! { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
"unsigned Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int i = 16;",
--- 1738,1751 ----
"ADD_SUB_GE;",
"res &= 0xffff0000;",
},
! { "", "","", "(if cc) pclr Dz", "100011cc....zzzz",
"res = 0;",
"res_grd = 0;",
"carry = 0;",
"overflow = 0;",
"greater_equal = 1;",
},
! { "", "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
"unsigned Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"int i = 16;",
*************** op ppi_tab[] =
*** 1713,1719 ****
"overflow = 0;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
"unsigned Sy = DSP_R (y);",
"int i;",
"",
--- 1779,1785 ----
"overflow = 0;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
"unsigned Sy = DSP_R (y);",
"int i;",
"",
*************** op ppi_tab[] =
*** 1736,1742 ****
"overflow = 0;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
--- 1802,1808 ----
"overflow = 0;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
"int Sx = DSP_R (x);",
"int Sx_grd = GET_DSP_GRD (x);",
"",
*************** op ppi_tab[] =
*** 1746,1759 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
"res = DSP_R (x);",
"res_grd = GET_DSP_GRD (x);",
"carry = 0;",
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
--- 1812,1825 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
"res = DSP_R (x);",
"res_grd = GET_DSP_GRD (x);",
"carry = 0;",
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
"int Sy = DSP_R (y);",
"int Sy_grd = SIGN32 (Sy);",
"",
*************** op ppi_tab[] =
*** 1763,1793 ****
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
"res = DSP_R (y);",
"res_grd = SIGN32 (res);",
"carry = 0;",
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
"res = MACH;",
"res_grd = SIGN32 (res);",
"goto assign_z;",
},
! { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
"res = MACL;",
"res_grd = SIGN32 (res);",
"goto assign_z;",
},
! { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
"if (0xa05f >> z & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
" MACH = DSP_R (z);",
"return;",
},
! { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
"if (0xa05f >> z & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
--- 1829,1859 ----
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
"res = DSP_R (y);",
"res_grd = SIGN32 (res);",
"carry = 0;",
"COMPUTE_OVERFLOW;",
"ADD_SUB_GE;",
},
! { "", "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
"res = MACH;",
"res_grd = SIGN32 (res);",
"goto assign_z;",
},
! { "", "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
"res = MACL;",
"res_grd = SIGN32 (res);",
"goto assign_z;",
},
! { "", "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
"if (0xa05f >> z & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
" MACH = DSP_R (z);",
"return;",
},
! { "", "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
"if (0xa05f >> z & 1)",
" RAISE_EXCEPTION (SIGILL);",
"else",
*************** expand_opcode (shift, val, i, s)
*** 2003,2014 ****
}
case 'n':
case 'm':
! for (j = 0; j < 16; j++)
! {
! expand_opcode (shift - 4, val | (j << shift), i, s + 4);
!
! }
! break;
case 'M':
/* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
for (j = 5; j < 16; j++)
--- 2069,2085 ----
}
case 'n':
case 'm':
! {
! int digits = 1;
! while (s[digits] == s[0])
! digits++;
! for (j = 0; j < (1 << digits); j++)
! {
! expand_opcode (shift - digits, val | (j << shift), i,
! s + digits);
! }
! break;
! }
case 'M':
/* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
for (j = 5; j < 16; j++)
*************** gensim_caselist (p)
*** 2129,2137 ****
--- 2200,2215 ----
int sextbit = -1;
int needm = 0;
int needn = 0;
+ int needm_int = 0;
+ int needn_int = 0;
char *s = p->code;
+ char *fp_pref = "R";
+ int latency = 1;
+ #ifdef SH4_TIMINGS
+ fp_pref = strncmp (p->code, "1111", 4) == 0 ? "FR" : "R";
+ #endif
printf (" /* %s %s */\n", p->name, p->code);
printf (" case %d: \n", p->index);
*************** gensim_caselist (p)
*** 2141,2148 ****
switch (*s)
{
default:
! fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
! *s);
exit (1);
break;
case '0':
--- 2219,2227 ----
switch (*s)
{
default:
! fprintf (stderr,
! "gencode/gensim_caselist: illegal char '%c' in %s\n",
! *s, p->name);
exit (1);
break;
case '0':
*************** gensim_caselist (p)
*** 2236,2258 ****
sextbit - 1, sextbit - 1);
}
- if (needm && needn)
- printf (" TB(m,n);\n");
- else if (needm)
- printf (" TL(m);\n");
- else if (needn)
- printf (" TL(n);\n");
-
{
/* Do the refs */
char *r;
for (r = p->refs; *r; r++)
{
! if (*r == '0') printf(" CREF(0);\n");
if (*r == '8') printf(" CREF(8);\n");
if (*r == '9') printf(" CREF(9);\n");
! if (*r == 'n') printf(" CREF(n);\n");
! if (*r == 'm') printf(" CREF(m);\n");
}
}
--- 2315,2367 ----
sextbit - 1, sextbit - 1);
}
{
/* Do the refs */
char *r;
for (r = p->refs; *r; r++)
{
! if (*r == '0') printf(" CREF(0);\n TL(R[0]);\n");
if (*r == '8') printf(" CREF(8);\n");
if (*r == '9') printf(" CREF(9);\n");
! if (*r == 'n') printf(" CREF(n);\n"), needn_int = 1;
! if (*r == 'm') printf(" CREF(m);\n"), needm_int = 1;
! #if SH4_TIMINGS
! if (*r == 't') printf(" TL(t);\n");
! if (*r == 'c') printf(" TL(fpscr);\n");
! #endif
! }
! }
! if (needm && needn)
! printf (" TB(%s[m],%s[n]);\n",
! needm_int ? "R" : fp_pref, needn_int ? "R" : fp_pref);
! else if (needm)
! printf (" TL(%s[m]);\n", needm_int ? "R" : fp_pref);
! else if (needn)
! printf (" TL(%s[n]);\n", needn_int ? "R" : fp_pref);
!
! if (*p->sh4_group)
! {
! if (strcmp (p->sh4_group, "ld") == 0)
! {
! printf ("SH4_LS;\n");
! latency = 2;
! }
! else
! printf ("SH4_%c%c;\n",
! toupper (p->sh4_group[0]), toupper (p->sh4_group[1]));
! }
!
! if (strcmp (p->sh4_group, "co") != 0) {
! /* Do the def latencies */
! char *r;
! for (r = p->defs; *r; r++)
! {
! if (*r == '0') printf(" L_SH4 (R[0], %d);\n", latency);
! if (*r == 'n' && strcmp (p->sh4_group, "mt") != 0)
! printf(" L_SH4 (R[n], %d);\n", latency);
! if (*r == 'm') printf(" L_SH4 (R[m], 1);\n");
! if (*r == 'f') printf(" L_SH4 (FR[n], %d);\n", latency);
! if (*r == 't') printf(" L_SH4 (t, 1);\n");
}
}
*************** gensim_caselist (p)
*** 2274,2279 ****
--- 2383,2389 ----
if (*r == '0') printf(" CDEF(0);\n");
if (*r == 'n') printf(" CDEF(n);\n");
if (*r == 'm') printf(" CDEF(m);\n");
+ if (*r == 't') printf(" L_SH4(t, 1);\n");
}
}
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/sh/interp.c,v
retrieving revision 1.11
diff -p -r1.11 interp.c
*** interp.c 15 Oct 2003 12:30:47 -0000 1.11
--- interp.c 24 Oct 2003 16:09:29 -0000
*************** int sim_write (SIM_DESC sd, SIM_ADDR add
*** 65,70 ****
--- 65,78 ----
for a quit. */
#define POLL_QUIT_INTERVAL 0x60000
+ struct ready_s {
+ int R[16];
+ int FR[16];
+ int macl, mach;
+ int t;
+ int fpscr, fpul;
+ };
+
typedef union
{
*************** typedef union
*** 132,139 ****
int cycles;
int insts;
! int prevlock;
! int thislock;
int exception;
int end_of_registers;
--- 140,149 ----
int cycles;
int insts;
! int *prevlock;
! int *thislock;
! int sh4_group;
! struct ready_s ready;
int exception;
int end_of_registers;
*************** do { \
*** 398,403 ****
--- 408,415 ----
#define PARANOID
*/
+ #define SH4_TIMINGS
+
#ifdef PARANOID
int valid[16];
#define CREF(x) if(!valid[x]) fail();
*************** set_dr (n, exp)
*** 510,552 ****
#define MOD_ME DSP_GRD (17)
#define MOD_DELTA DSP_GRD (18)
! #define FP_OP(n, OP, m) \
{ \
if (FPSCR_PR) \
{ \
if (((n) & 1) || ((m) & 1)) \
RAISE_EXCEPTION (SIGILL); \
else \
! SET_DR(n, (DR(n) OP DR(m))); \
} \
else \
! SET_FR(n, (FR(n) OP FR(m))); \
} while (0)
! #define FP_UNARY(n, OP) \
{ \
if (FPSCR_PR) \
{ \
if ((n) & 1) \
RAISE_EXCEPTION (SIGILL); \
else \
! SET_DR(n, (OP (DR(n)))); \
} \
else \
! SET_FR(n, (OP (FR(n)))); \
} while (0)
#define FP_CMP(n, OP, m) \
{ \
if (FPSCR_PR) \
{ \
if (((n) & 1) || ((m) & 1)) \
RAISE_EXCEPTION (SIGILL); \
else \
SET_SR_T (DR(n) OP DR(m)); \
} \
else \
! SET_SR_T (FR(n) OP FR(m)); \
} while (0)
static void
--- 522,584 ----
#define MOD_ME DSP_GRD (17)
#define MOD_DELTA DSP_GRD (18)
! #define FP_OP(n, OP, m, s_latency, d_latency) \
{ \
if (FPSCR_PR) \
{ \
if (((n) & 1) || ((m) & 1)) \
RAISE_EXCEPTION (SIGILL); \
else \
! { \
! SET_DR(n, (DR(n) OP DR(m))); \
! L_SH4 (FR[n], d_latency); \
! } \
} \
else \
! { \
! SET_FR(n, (FR(n) OP FR(m))); \
! L_SH4 (FR[n], s_latency); \
! } \
} while (0)
! #define FP_UNARY(n, OP, s_latency, d_latency) \
{ \
if (FPSCR_PR) \
{ \
if ((n) & 1) \
RAISE_EXCEPTION (SIGILL); \
else \
! { \
! SET_DR(n, (OP (DR(n)))); \
! if (d_latency) \
! L_SH4 (FR[n], d_latency); \
! } \
} \
else \
! { \
! SET_FR(n, (OP (FR(n)))); \
! if (s_latency) \
! L_SH4 (FR[n], s_latency); \
! } \
} while (0)
#define FP_CMP(n, OP, m) \
{ \
if (FPSCR_PR) \
{ \
+ SH4_CO; \
+ cycles++; \
if (((n) & 1) || ((m) & 1)) \
RAISE_EXCEPTION (SIGILL); \
else \
SET_SR_T (DR(n) OP DR(m)); \
} \
else \
! { \
! SH4_FE; \
! SET_SR_T (FR(n) OP FR(m)); \
! } \
! L_SH4 (t, 2); \
} while (0)
static void
*************** process_rbat_addr (addr)
*** 775,782 ****
#define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip);
- #define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); goto top;
-
#define CHECK_INSN_PTR(p) \
do { \
if (saved_state.asregs.exception || PH2T (p) & maskw) \
--- 807,812 ----
*************** do { \
*** 794,808 ****
#define TL(x)
#define TB(x)
! #else
#define MA(n) \
do { memstalls += ((((int) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
! #define L(x) thislock = x;
! #define TL(x) if ((x) == prevlock) stalls++;
! #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
#endif
#if defined(__GO32__) || defined(_WIN32)
--- 824,881 ----
#define TL(x)
#define TB(x)
! #elif ! defined (SH4_TIMINGS)
#define MA(n) \
do { memstalls += ((((int) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
! /* instead of x / y use R[x] / R[y] */
! #define L(x) thislock = &(x);
! #define L_SH4(x,n)
! #define TL(x) if (&(x) == prevlock) stalls++;
! #define TB(x,y) if (&(x) == prevlock || &(y)==prevlock) stalls++;
!
! #endif
!
! #ifdef SH4_TIMINGS
! enum
! {
! sh4_mt = 1, sh4_ex = 2, sh4_br = 4, sh4_ls = 8, sh4_fe = 16, sh4_issue = 32
! } sh4_units;
!
! #define MA(n)
! #define L(x) ready->x = cycles + 2
! #define L_SH4(x,n) ready->x = cycles + (n)
! #define TL(x) \
! if (ready->x > cycles) cycles = ready->x - 1, sh4_group = sh4_issue
! #define TB (x,y) \
! if (ready->x > cycles || ready->y > cycles) \
! cycles = (ready->x >= ready->y ? ready->x : ready->y) - 1, \
! sh4_group = sh4_issue
!
! #define SH4_GROUP_USE(gt, gs) \
! if (sh4_group & (sh4_issue | (gt))) \
! cycles++, sh4_group = gs; \
! else \
! sh4_group = sh4_issue;
+ #define SH4_MT SH4_GROUP_USE (0, sh4_mt)
+ #define SH4_EX SH4_GROUP_USE (sh4_ex, sh4_ex)
+ #define SH4_BR SH4_GROUP_USE (sh4_br, sh4_br)
+ #define SH4_LS SH4_GROUP_USE (sh4_ls, sh4_ls)
+ #define SH4_FE SH4_GROUP_USE (sh4_fe, sh4_fe)
+ #define SH4_CO SH4_GROUP_USE (sh4_mt|sh4_ex|sh4_br|sh4_ls|sh4_fe, sh4_issue)
+ #define BRANCH_TAKEN(addr) SET_NIP (addr); cycles += 1; sh4_group = sh4_issue
+ #define Delay_Slot(TEMPPC) sh4_group = 0, iword = RIAT (TEMPPC); goto top;
+ #else
+ #define SH4_MT
+ #define SH4_EX
+ #define SH4_BR
+ #define SH4_LS
+ #define SH4_FE
+ #define SH4_CO
+ #define BRANCH_TAKEN(addr) SET_NIP (addr); cycles += 2
+ #define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); goto top;
#endif
#if defined(__GO32__) || defined(_WIN32)
*************** macl (regs, memory, n, m)
*** 1411,1416 ****
--- 1484,1538 ----
MACH = mach;
}
+ float
+ fsca_s (int in, double (*f) (double))
+ {
+ double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383;
+ double result = (*f) (rad);
+ double error, upper, lower, frac;
+ int exp;
+
+ /* Search the value with the maximum error that is still within the
+ architectural spec. */
+ error = ldexp (1., -21);
+ /* compensate for calculation inaccuracy by reducing error. */
+ error = error - ldexp (1., -50);
+ upper = result + error;
+ frac = frexp (upper, &exp);
+ upper = ldexp (floor (ldexp (frac, 24)), exp - 24);
+ lower = result - error;
+ frac = frexp (lower, &exp);
+ lower = ldexp (ceil (ldexp (frac, 24)), exp - 24);
+ return abs (upper - result) >= abs (lower - result) ? upper : lower;
+ }
+
+ float
+ fsrra_s (float in)
+ {
+ double result = 1. / sqrt (in);
+ int exp;
+ double frac, upper, lower, error, eps;
+
+ /* refine result */
+ result = result - (result * result * in - 1) * 0.5 * result;
+ /* Search the value with the maximum error that is still within the
+ architectural spec. */
+ frac = frexp (result, &exp);
+ frac = ldexp (frac, 24);
+ error = 4.; /* 1 << 24-1-21 */
+ /* use eps to compensate for possible 1 ulp error in our 'exact' result. */
+ eps = ldexp (1., -29);
+ upper = floor (frac + error - eps);
+ if (upper > 16777216.)
+ upper = floor ((frac + error - eps) * 0.5) * 2.;
+ lower = ceil ((frac - error + eps) * 2) * .5;
+ if (lower > 8388608.)
+ lower = ceil (frac - error + eps);
+ upper = ldexp (upper, exp - 24);
+ lower = ldexp (lower, exp - 24);
+ return upper - result >= result - lower ? upper : lower;
+ }
+
static struct loop_bounds
get_loop_bounds (rs, re, memory, mem_end, maskw, endianw)
int rs, re;
*************** sim_resume (sd, step, siggnal)
*** 1656,1663 ****
register int stalls = 0;
register int memstalls = 0;
register int insts = 0;
! register int prevlock;
! register int thislock;
register unsigned int doprofile;
register int pollcount = 0;
/* endianw is used for every insn fetch, hence it makes sense to cache it.
--- 1778,1787 ----
register int stalls = 0;
register int memstalls = 0;
register int insts = 0;
! register int *prevlock;
! register int *thislock;
! struct ready_s *ready;
! int sh4_group;
register unsigned int doprofile;
register int pollcount = 0;
/* endianw is used for every insn fetch, hence it makes sense to cache it.
*************** sim_resume (sd, step, siggnal)
*** 1701,1706 ****
--- 1825,1832 ----
/*T = GET_SR () & SR_MASK_T;*/
prevlock = saved_state.asregs.prevlock;
thislock = saved_state.asregs.thislock;
+ ready = &saved_state.asregs.ready;
+ sh4_group = saved_state.asregs.sh4_group;
doprofile = saved_state.asregs.profile;
/* If profiling not enabled, disable it by asking for
*************** sim_resume (sd, step, siggnal)
*** 1749,1761 ****
}
#ifndef ACE_FAST
prevlock = thislock;
! thislock = 30;
cycles++;
if (cycles >= doprofile)
{
saved_state.asregs.cycles += doprofile;
cycles -= doprofile;
if (saved_state.asregs.profile_hist)
--- 1875,1899 ----
}
#ifndef ACE_FAST
+ #ifndef SH4_TIMINGS
prevlock = thislock;
! thislock = NULL;
cycles++;
+ #endif
if (cycles >= doprofile)
{
+ #ifdef SH4_TIMINGS
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ ready->R[i] -= doprofile;
+ ready->FR[i] -= doprofile;
+ }
+ }
+ #endif /* SH4_TIMINGS */
saved_state.asregs.cycles += doprofile;
cycles -= doprofile;
if (saved_state.asregs.profile_hist)
*************** sim_resume (sd, step, siggnal)
*** 1806,1811 ****
--- 1944,1950 ----
saved_state.asregs.prevlock = prevlock;
saved_state.asregs.thislock = thislock;
+ saved_state.asregs.sh4_group = sh4_group;
if (profile_file)
{
*************** sim_create_inferior (sd, prog_bfd, argv,
*** 2309,2314 ****
--- 2448,2454 ----
/* Clear the registers. */
memset (&saved_state, 0,
(char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
+ saved_state.asregs.sh4_group = sh4_issue;
/* Set the PC. */
if (prog_bfd != NULL)