* gencode.c (movua.l): Compensate for endianness.

* interp.c (RAISE_EXCEPTION_IF_IN_DELAY_SLOT): New macro.
	(in_delay_slot): New flag variable.
	(Delay_Slot): Set in_delay_slot.
	(sim_resume): Reset in_delay_slot after leaving code switch.
	* gencode.c (op tab): Call RAISE_EXCEPTION_IF_IN_DELAY_SLOT for all
	instructions not allowed in delay slots.

	Commited by Corinna Vinschen <vinschen@redhat.com>
	Introduce SH2a support.
	* interp.c: Change type of jump table to short.  Add various macros.
	(sim_load): Save the bfd machine code.
	(sim_create_inferior): Ditto.
	(union saved_state_type): Add tbr, ibnr and ibcr registers.
	Move bfd_mach to end of struct.  Add regstack pointer.
	(init_dsp): Don't swap contents of sh_dsp_table any more.  Instead
	use it directly in its own switch statement.  Allocate space for 512
	register banks.
	(do_long_move_insn): New function.
	(do_blog_insn): Ditto.
	(trap): Use trap #13 and trap #14 to set ibnr and ibcr.
	* gencode.c: Move movx/movy insns into separate switch statement.
	(op tab): Add sh2a insns.  Reject instructions that are disabled
	on that chip.
	(gensim_caselist): Generate default case here instead of in caller.
	(gensim): Generate two separate switch statements.  Call
	gensim_caselist once for each (for movsxy_tab and for tab).
	Add tokens for r15 and multiple regs.
	(conflict_warn, warn_conflicts): Add for debugging.
This commit is contained in:
Corinna Vinschen 2004-09-08 09:11:50 +00:00
parent 899a8cf07b
commit ae0a84af70
3 changed files with 783 additions and 35 deletions

View File

@ -1,3 +1,41 @@
2004-09-08 DJ Delorie <dj@redhat.com>
Commited by Corinna Vinschen <vinschen@redhat.com>
* gencode.c (movua.l): Compensate for endianness.
2004-09-08 Corinna Vinschen <vinschen@redhat.com>
* interp.c (RAISE_EXCEPTION_IF_IN_DELAY_SLOT): New macro.
(in_delay_slot): New flag variable.
(Delay_Slot): Set in_delay_slot.
(sim_resume): Reset in_delay_slot after leaving code switch.
* gencode.c (op tab): Call RAISE_EXCEPTION_IF_IN_DELAY_SLOT for all
instructions not allowed in delay slots.
2004-09-08 Michael Snyder <msnyder@redhat.com>
Commited by Corinna Vinschen <vinschen@redhat.com>
Introduce SH2a support.
* interp.c: Change type of jump table to short. Add various macros.
(sim_load): Save the bfd machine code.
(sim_create_inferior): Ditto.
(union saved_state_type): Add tbr, ibnr and ibcr registers.
Move bfd_mach to end of struct. Add regstack pointer.
(init_dsp): Don't swap contents of sh_dsp_table any more. Instead
use it directly in its own switch statement. Allocate space for 512
register banks.
(do_long_move_insn): New function.
(do_blog_insn): Ditto.
(trap): Use trap #13 and trap #14 to set ibnr and ibcr.
* gencode.c: Move movx/movy insns into separate switch statement.
(op tab): Add sh2a insns. Reject instructions that are disabled
on that chip.
(gensim_caselist): Generate default case here instead of in caller.
(gensim): Generate two separate switch statements. Call
gensim_caselist once for each (for movsxy_tab and for tab).
Add tokens for r15 and multiple regs.
(conflict_warn, warn_conflicts): Add for debugging.
2004-08-18 J"orn Rennecke <joern.rennecke@superh.com>
* gencode.c (tab): For shad snd shld, fix result for

View File

@ -84,6 +84,7 @@ op tab[] =
},
{ "", "", "bf <bdisp8>", "10001011i8p1....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (!T) {",
" SET_NIP (PC + 4 + (SEXT (i) * 2));",
" cycles += 2;",
@ -91,6 +92,7 @@ op tab[] =
},
{ "", "", "bf.s <bdisp8>", "10001111i8p1....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (!T) {",
" SET_NIP (PC + 4 + (SEXT (i) * 2));",
" cycles += 2;",
@ -98,19 +100,35 @@ op tab[] =
"}",
},
{ "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
"/* 32-bit logical bit-manipulation instructions. */",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"int word2 = RIAT (nip);",
"i >>= 4; /* BOGUS: Using only three bits of 'i'. */",
"/* MSB of 'i' must be zero. */",
"if (i > 7)",
" RAISE_EXCEPTION (SIGILL);",
"MA (1);",
"do_blog_insn (1 << i, (word2 & 0xfff) + R[n], ",
" (word2 >> 12) & 0xf, memory, maskb);",
"SET_NIP (nip + 2); /* Consume 2 more bytes. */",
},
{ "", "", "bra <bdisp12>", "1010i12.........",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
{ "", "n", "braf <REG_N>", "0000nnnn00100011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_NIP (PC + 4 + R[n]);",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
{ "", "", "bsr <bdisp12>", "1011i12.........",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"PR = PH2T (PC + 4);",
"SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
"cycles += 2;",
@ -118,6 +136,7 @@ op tab[] =
},
{ "", "n", "bsrf <REG_N>", "0000nnnn00000011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"PR = PH2T (PC) + 4;",
"SET_NIP (PC + 4 + R[n]);",
"cycles += 2;",
@ -125,13 +144,187 @@ op tab[] =
},
{ "", "", "bt <bdisp8>", "10001001i8p1....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (T) {",
" SET_NIP (PC + 4 + (SEXT (i) * 2));",
" cycles += 2;",
"}",
},
{ "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
"/* MSB of 'i' is true for load, false for store. */",
"if (i <= 7)",
" if (T)",
" R[m] |= (1 << i);",
" else",
" R[m] &= ~(1 << i);",
"else",
" SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
},
{ "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
"/* MSB of 'i' is true for set, false for clear. */",
"if (i <= 7)",
" R[m] &= ~(1 << i);",
"else",
" R[m] |= (1 << (i - 8));",
},
{ "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
"if (R[n] < -128 || R[n] > 127) {",
" L (n);",
" SET_SR_CS (1);",
" if (R[n] > 127)",
" R[n] = 127;",
" else if (R[n] < -128)",
" R[n] = -128;",
"}",
},
{ "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
"if (R[n] < -32768 || R[n] > 32767) {",
" L (n);",
" SET_SR_CS (1);",
" if (R[n] > 32767)",
" R[n] = 32767;",
" else if (R[n] < -32768)",
" R[n] = -32768;",
"}",
},
{ "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
"if (R[n] < -256 || R[n] > 255) {",
" L (n);",
" SET_SR_CS (1);",
" R[n] = 255;",
"}",
},
{ "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
"if (R[n] < -65536 || R[n] > 65535) {",
" L (n);",
" SET_SR_CS (1);",
" R[n] = 65535;",
"}",
},
{ "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (R0 == 0)",
" R[n] = 0x7fffffff;",
"else if (R0 == -1 && R[n] == 0x80000000)",
" R[n] = 0x7fffffff;",
"else R[n] /= R0;",
"L (n);",
},
{ "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (R0 == 0)",
" R[n] = 0xffffffff;",
"else (unsigned int) R[n] = (unsigned int) R[n] / (unsigned int) R0;",
"L (n);",
},
{ "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
"R[n] = (R[n] * R0) & 0xffffffff;",
"L (n);",
},
{ "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
"int regn = (R[n] >> 2) & 0x1f;",
"int bankn = (R[n] >> 7) & 0x1ff;",
"if (regn > 19)",
" regn = 19; /* FIXME what should happen? */",
"R0 = saved_state.asregs.regstack[bankn].regs[regn];",
"L (0);",
},
{ "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
"int regn = (R[n] >> 2) & 0x1f;",
"int bankn = (R[n] >> 7) & 0x1ff;",
"if (regn > 19)",
" regn = 19; /* FIXME what should happen? */",
"saved_state.asregs.regstack[bankn].regs[regn] = R0;",
},
{ "", "", "resbank", "0000000001011011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
/* FIXME: cdef all */
"int i;",
"if (BO) { /* Bank Overflow */",
/* FIXME: how do we know when to reset BO? */
" for (i = 0; i <= 14; i++) {",
" R[i] = RLAT (R[15]);",
" MA (1);",
" R[15] += 4;",
" }",
" PR = RLAT (R[15]);",
" R[15] += 4;",
" MA (1);",
" GBR = RLAT (R[15]);",
" R[15] += 4;",
" MA (1);",
" MACH = RLAT (R[15]);",
" R[15] += 4;",
" MA (1);",
" MACL = RLAT (R[15]);",
" R[15] += 4;",
" MA (1);",
"}",
"else if (BANKN == 0) /* Bank Underflow */",
" RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
"else {",
" SET_BANKN (BANKN - 1);",
" for (i = 0; i <= 14; i++)",
" R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
" MACH = saved_state.asregs.regstack[BANKN].regs[15];",
" PR = saved_state.asregs.regstack[BANKN].regs[17];",
" GBR = saved_state.asregs.regstack[BANKN].regs[18];",
" MACL = saved_state.asregs.regstack[BANKN].regs[19];",
"}",
},
{ "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
"/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
"do {",
" MA (1);",
" R[15] -= 4;",
" if (n == 15)",
" WLAT (R[15], PR);",
" else",
" WLAT (R[15], R[n]);",
"} while (n-- > 0);",
},
{ "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
"/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
"int i = 0;\n",
"do {",
" MA (1);",
" if (i == 15)",
" PR = RLAT (R[15]);",
" else",
" R[i] = RLAT (R[15]);",
" R[15] += 4;",
"} while (i++ < n);",
},
{ "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
"/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
"int i = 15;\n",
"do {",
" MA (1);",
" R[15] -= 4;",
" if (i == 15)",
" WLAT (R[15], PR);",
" else",
" WLAT (R[15], R[i]);",
"} while (i-- > n);",
},
{ "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
"/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
"do {",
" MA (1);",
" if (n == 15)",
" PR = RLAT (R[15]);",
" else",
" R[n] = RLAT (R[15]);",
" R[15] += 4;",
"} while (n++ < 15);",
},
{ "", "", "nott", "0000000001101000",
"SET_SR_T (T == 0);",
},
{ "", "", "bt.s <bdisp8>", "10001101i8p1....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"if (T) {",
" SET_NIP (PC + 4 + (SEXT (i) * 2));",
" cycles += 2;",
@ -297,6 +490,8 @@ op tab[] =
"else",
"{",
" double fsum = 0;",
" if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
" RAISE_EXCEPTION (SIGILL);",
" /* FIXME: check for nans and infinities. */",
" fsum += FR (v1+0) * FR (v2+0);",
" fsum += FR (v1+1) * FR (v2+1);",
@ -386,6 +581,18 @@ op tab[] =
" SET_FI (n, RLAT (R[m]));",
"}",
},
/* sh2a */
{ "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
"/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
" and mov.bwl <REG_N>, @(disp12,<REG_M>)",
" and mov.bwl @(disp12,<REG_N>),<REG_M>",
" and movu.bw @(disp12,<REG_N>),<REG_M>. */",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"int word2 = RIAT (nip);",
"SET_NIP (nip + 2); /* Consume 2 more bytes. */",
"MA (1);",
"do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
},
/* sh2e */
{ "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
/* sh4 */
@ -465,6 +672,8 @@ op tab[] =
{ "", "", "frchg", "1111101111111101",
"if (FPSCR_PR)",
" RAISE_EXCEPTION (SIGILL);",
"else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
" RAISE_EXCEPTION (SIGILL);",
"else",
" SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
},
@ -473,6 +682,8 @@ op tab[] =
{ "", "", "fsca", "1111eeee11111101",
"if (FPSCR_PR)",
" RAISE_EXCEPTION (SIGILL);",
"else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
" RAISE_EXCEPTION (SIGILL);",
"else",
" {",
" SET_FR (n, fsca_s (FPUL, &sin));",
@ -494,6 +705,8 @@ op tab[] =
{ "", "", "fsrra <FREG_N>", "1111nnnn01111101",
"if (FPSCR_PR)",
" RAISE_EXCEPTION (SIGILL);",
"else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
" RAISE_EXCEPTION (SIGILL);",
"else",
" SET_FR (n, fsrra_s (FR (n)));",
},
@ -525,6 +738,8 @@ op tab[] =
" RAISE_EXCEPTION (SIGILL);",
"else",
"{",
" if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
" RAISE_EXCEPTION (SIGILL);",
" /* FIXME not implemented. */",
" printf (\"ftrv xmtrx, FV%d\\n\", v1);",
"}",
@ -542,12 +757,14 @@ op tab[] =
},
{ "", "n", "jmp @<REG_N>", "0100nnnn00101011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_NIP (PT2H (R[n]));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
{ "", "n", "jsr @<REG_N>", "0100nnnn00001011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"PR = PH2T (PC + 4);",
"if (~doprofile)",
" gotcall (PR, R[n]);",
@ -555,6 +772,20 @@ op tab[] =
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
{ "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"PR = PH2T (PC + 2);",
"if (~doprofile)",
" gotcall (PR, R[n]);",
"SET_NIP (PT2H (R[n]));",
},
{ "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"PR = PH2T (PC + 2);",
"if (~doprofile)",
" gotcall (PR, i + TBR);",
"SET_NIP (PT2H (i + TBR));",
},
{ "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
"CREG (m) = R[n];",
@ -579,6 +810,12 @@ op tab[] =
"else",
" RAISE_EXCEPTION (SIGILL); /* user mode */",
},
{ "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
"if (SR_MD)", /* FIXME? */
" TBR = R[n]; /* priv mode */",
"else",
" RAISE_EXCEPTION (SIGILL); /* user mode */",
},
{ "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
"MA (1);",
"CREG (m) = RLAT (R[n]);",
@ -673,6 +910,16 @@ op tab[] =
{ "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
"R[n] = SEXT (i);",
},
{ "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"R[n] = ((i << 24) >> 12) | RIAT (nip);",
"SET_NIP (nip + 2); /* Consume 2 more bytes. */",
},
{ "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
"SET_NIP (nip + 2); /* Consume 2 more bytes. */",
},
{ "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
"R[n] = R[m];",
},
@ -698,6 +945,12 @@ op tab[] =
"R[m] += 1;",
"L (n);",
},
{ "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
"MA (1);",
"R[n] -= 1;",
"R0 = RSBAT (R[n]);",
"L (0);",
},
{ "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
"MA (1);",
"WBAT (R[n], R[m]);",
@ -719,6 +972,11 @@ op tab[] =
"R[n] -= 1;",
"WBAT (R[n], R[m]);",
},
{ "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
"MA (1);",
"WBAT (R[n], R0);",
"R[n] += 1;",
},
{ "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
"MA (1);",
"R[n] = RSBAT (R[m]);",
@ -751,6 +1009,12 @@ op tab[] =
"R[m] += 4;",
"L (n);",
},
{ "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
"MA (1);",
"R[n] -= 4;",
"R0 = RLAT (R[n]);",
"L (0);",
},
{ "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
"MA (1);",
"R[n] = RLAT (R[m]);",
@ -773,6 +1037,11 @@ op tab[] =
"R[n] -= 4;",
"WLAT (R[n], R[m]);",
},
{ "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
"MA (1) ;",
"WLAT (R[n], R0);",
"R[n] += 4;",
},
{ "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
"MA (1);",
"WLAT (R[n], R[m]);",
@ -804,6 +1073,12 @@ op tab[] =
"R[m] += 2;",
"L (n);",
},
{ "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
"MA (1);",
"R[n] -= 2;",
"R0 = RSWAT (R[n]);",
"L (0);",
},
{ "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
"MA (1);",
"R[n] = RSWAT (R[m]);",
@ -826,6 +1101,11 @@ op tab[] =
"R[n] -= 2;",
"WWAT (R[n], R[m]);",
},
{ "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
"MA (1);",
"WWAT (R[n], R0);",
"R[n] += 2;",
},
{ "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
"MA (1);",
"WWAT (R[n], R[m]);",
@ -863,19 +1143,23 @@ op tab[] =
{ "n", "", "movt <REG_N>", "0000nnnn00101001",
"R[n] = T;",
},
{ "", "", "movrt <REG_N>", "0000nnnn00111001",
"R[n] = (T == 0);",
},
{ "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
"int regn = R[n];",
"int e = target_little_endian ? 3 : 0;",
"MA (1);",
"R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
" (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
"R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
" (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
"L (0);",
},
{ "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
"int regn = R[n];",
"int e = target_little_endian ? 3 : 0;",
"MA (1);",
"R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
" (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
"R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
" (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
"R[n] += 4;",
"L (0);",
},
@ -1002,6 +1286,7 @@ op tab[] =
"R[15] += 4;",
"Delay_Slot (PC + 2);",
#else
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_SR (SSR);",
"SET_NIP (PT2H (SPC));",
"cycles += 2;",
@ -1010,10 +1295,21 @@ op tab[] =
},
{ "", "", "rts", "0000000000001011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_NIP (PT2H (PR));",
"cycles += 2;",
"Delay_Slot (PC + 2);",
},
{ "", "", "rts/n", "0000000001101011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"SET_NIP (PT2H (PR));",
},
{ "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"R0 = R[n];",
"L (0);",
"SET_NIP (PT2H (PR));",
},
/* sh4a */
{ "", "", "setdmx", "0000000010011000",
@ -1121,6 +1417,12 @@ op tab[] =
"else",
" RAISE_EXCEPTION (SIGILL); /* user mode */",
},
{ "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
"if (SR_MD)", /* FIXME? */
" R[n] = TBR; /* priv mode */",
"else",
" RAISE_EXCEPTION (SIGILL); /* user mode */",
},
{ "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
"MA (1);",
"R[n] -= 4;",
@ -1191,6 +1493,7 @@ op tab[] =
},
{ "0", "", "trapa #<imm>", "11000011i8*1....",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"long imm = 0xff & i;",
"if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
" nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
@ -1515,8 +1818,9 @@ op movsxy_tab[] =
"/* nop */",
},
{ "", "", "ppi", "1111100000000000",
"RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
"ppi_insn (RIAT (nip));",
"nip += 2;",
"SET_NIP (nip + 2);",
"iword &= 0xf7ff; goto top;",
},
#endif
@ -2267,6 +2571,58 @@ gengastab ()
static unsigned short table[1 << 16];
static int warn_conflicts = 0;
static void
conflict_warn (val, i)
int val;
int i;
{
int ix, key;
int j = table[val];
fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
val, i, table[val]);
for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
if (tab[ix].index == i || tab[ix].index == j)
{
key = ((tab[ix].code[0] - '0') << 3) +
((tab[ix].code[1] - '0') << 2) +
((tab[ix].code[2] - '0') << 1) +
((tab[ix].code[3] - '0'));
if (val >> 12 == key)
fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
}
for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
{
key = ((movsxy_tab[ix].code[0] - '0') << 3) +
((movsxy_tab[ix].code[1] - '0') << 2) +
((movsxy_tab[ix].code[2] - '0') << 1) +
((movsxy_tab[ix].code[3] - '0'));
if (val >> 12 == key)
fprintf (stderr, " %s -- %s\n",
movsxy_tab[ix].code, movsxy_tab[ix].name);
}
for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
{
key = ((ppi_tab[ix].code[0] - '0') << 3) +
((ppi_tab[ix].code[1] - '0') << 2) +
((ppi_tab[ix].code[2] - '0') << 1) +
((ppi_tab[ix].code[3] - '0'));
if (val >> 12 == key)
fprintf (stderr, " %s -- %s\n",
ppi_tab[ix].code, ppi_tab[ix].name);
}
}
/* Take an opcode, expand all varying fields in it out and fill all the
right entries in 'table' with the opcode index. */
@ -2278,6 +2634,8 @@ expand_opcode (val, i, s)
{
if (*s == 0)
{
if (warn_conflicts && table[val] != 0)
conflict_warn (val, i);
table[val] = i;
}
else
@ -2599,6 +2957,12 @@ gensim_caselist (p)
switch (s[1])
{
default:
fprintf (stderr,
"gensim_caselist: Unknown char '%c' in %s\n",
s[1], s);
exit (1);
break;
case '4':
printf ("f");
break;
@ -2607,7 +2971,6 @@ gensim_caselist (p)
break;
case '1':
sextbit = 12;
printf ("fff");
break;
}
@ -2615,6 +2978,14 @@ gensim_caselist (p)
switch (s[3])
{
default:
fprintf (stderr,
"gensim_caselist: Unknown char '%c' in %s\n",
s[3], s);
exit (1);
break;
case '.': /* eg. "i12." */
break;
case '1':
break;
case '2':
@ -2646,6 +3017,25 @@ gensim_caselist (p)
char *r;
for (r = p->refs; *r; r++)
{
if (*r == 'f') printf (" CREF (15);\n");
if (*r == '-')
{
printf (" {\n");
printf (" int i = n;\n");
printf (" do {\n");
printf (" CREF (i);\n");
printf (" } while (i-- > 0);\n");
printf (" }\n");
}
if (*r == '+')
{
printf (" {\n");
printf (" int i = n;\n");
printf (" do {\n");
printf (" CREF (i);\n");
printf (" } while (i++ < 14);\n");
printf (" }\n");
}
if (*r == '0') printf (" CREF (0);\n");
if (*r == '8') printf (" CREF (8);\n");
if (*r == '9') printf (" CREF (9);\n");
@ -2669,9 +3059,28 @@ gensim_caselist (p)
char *r;
for (r = p->defs; *r; r++)
{
if (*r == '0') printf(" CDEF (0);\n");
if (*r == 'n') printf(" CDEF (n);\n");
if (*r == 'm') printf(" CDEF (m);\n");
if (*r == 'f') printf (" CDEF (15);\n");
if (*r == '-')
{
printf (" {\n");
printf (" int i = n;\n");
printf (" do {\n");
printf (" CDEF (i);\n");
printf (" } while (i-- > 0);\n");
printf (" }\n");
}
if (*r == '+')
{
printf (" {\n");
printf (" int i = n;\n");
printf (" do {\n");
printf (" CDEF (i);\n");
printf (" } while (i++ < 14);\n");
printf (" }\n");
}
if (*r == '0') printf (" CDEF (0);\n");
if (*r == 'n') printf (" CDEF (n);\n");
if (*r == 'm') printf (" CDEF (m);\n");
}
}
@ -2757,6 +3166,9 @@ expand_ppi_code (val, i, s)
break;
case 'g':
case 'z':
if (warn_conflicts && table[val] != 0)
conflict_warn (val, i);
/* The last four bits are disregarded for the switch table. */
table[val] = i;
return;
@ -2992,6 +3404,10 @@ main (ac, av)
/* Now generate the requested data. */
if (ac > 1)
{
if (ac > 2 && strcmp (av[2], "-w") == 0)
{
warn_conflicts = 1;
}
if (strcmp (av[1], "-t") == 0)
{
gengastab ();

View File

@ -65,6 +65,11 @@ int sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size);
for a quit. */
#define POLL_QUIT_INTERVAL 0x60000
typedef struct
{
int regs[20];
} regstacktype;
typedef union
{
@ -123,6 +128,9 @@ typedef union
int dbr; /* debug base register */
int sgr; /* saved gr15 */
int ldst; /* load/store flag (boolean) */
int tbr;
int ibcr; /* sh2a bank control register */
int ibnr; /* sh2a bank number register */
} named;
int i[16];
} cregs;
@ -152,6 +160,8 @@ typedef union
unsigned char *ymem;
unsigned char *xmem_offset;
unsigned char *ymem_offset;
unsigned long bfd_mach;
regstacktype *regstack;
}
asregs;
int asints[40];
@ -175,6 +185,7 @@ static int maskl = 0;
static SIM_OPEN_KIND sim_kind;
static char *myname;
static int tracing = 0;
/* Short hand definitions of the registers */
@ -191,6 +202,11 @@ static char *myname;
#define GBR saved_state.asregs.cregs.named.gbr
#define VBR saved_state.asregs.cregs.named.vbr
#define DBR saved_state.asregs.cregs.named.dbr
#define TBR saved_state.asregs.cregs.named.tbr
#define IBCR saved_state.asregs.cregs.named.ibcr
#define IBNR saved_state.asregs.cregs.named.ibnr
#define BANKN (saved_state.asregs.cregs.named.ibnr & 0x1ff)
#define ME ((saved_state.asregs.cregs.named.ibnr >> 14) & 0x3)
#define SSR saved_state.asregs.cregs.named.ssr
#define SPC saved_state.asregs.cregs.named.spc
#define SGR saved_state.asregs.cregs.named.sgr
@ -213,6 +229,8 @@ static char *myname;
/* Manipulate SR */
#define SR_MASK_BO (1 << 14)
#define SR_MASK_CS (1 << 13)
#define SR_MASK_DMY (1 << 11)
#define SR_MASK_DMX (1 << 10)
#define SR_MASK_M (1 << 9)
@ -227,6 +245,8 @@ static char *myname;
#define SR_MASK_RC 0x0fff0000
#define SR_RC_INCREMENT -0x00010000
#define BO ((saved_state.asregs.cregs.named.sr & SR_MASK_BO) != 0)
#define CS ((saved_state.asregs.cregs.named.sr & SR_MASK_CS) != 0)
#define M ((saved_state.asregs.cregs.named.sr & SR_MASK_M) != 0)
#define Q ((saved_state.asregs.cregs.named.sr & SR_MASK_Q) != 0)
#define S ((saved_state.asregs.cregs.named.sr & SR_MASK_S) != 0)
@ -249,6 +269,16 @@ do { \
saved_state.asregs.cregs.named.sr &= ~(BIT); \
} while (0)
#define SET_SR_BO(EXP) SET_SR_BIT ((EXP), SR_MASK_BO)
#define SET_SR_CS(EXP) SET_SR_BIT ((EXP), SR_MASK_CS)
#define SET_BANKN(EXP) \
do { \
IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \
} while (0)
#define SET_ME(EXP) \
do { \
IBNR = (IBNR & 0x3fff) | ((EXP & 0x3) << 14); \
} while (0)
#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
@ -323,6 +353,9 @@ fail ()
#define RAISE_EXCEPTION(x) \
(saved_state.asregs.exception = x, saved_state.asregs.insn_end = 0)
#define RAISE_EXCEPTION_IF_IN_DELAY_SLOT() \
if (in_delay_slot) RAISE_EXCEPTION (SIGILL)
/* This function exists mainly for the purpose of setting a breakpoint to
catch simulated bus errors when running the simulator under GDB. */
@ -780,7 +813,8 @@ process_rbat_addr (addr)
#define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip);
#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); goto top;
static int in_delay_slot = 0;
#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); in_delay_slot = 1; goto top;
#define CHECK_INSN_PTR(p) \
do { \
@ -1181,6 +1215,12 @@ trap (i, regs, insn_ptr, memory, maskl, maskw, endianw)
}
break;
case 13: /* Set IBNR */
IBNR = regs[0] & 0xffff;
break;
case 14: /* Set IBCR */
IBCR = regs[0] & 0xffff;
break;
case 0xc3:
case 255:
raise_exception (SIGTRAP);
@ -1419,32 +1459,140 @@ macl (regs, memory, n, m)
MACH = mach;
}
enum {
B_BCLR = 0,
B_BSET = 1,
B_BST = 2,
B_BLD = 3,
B_BAND = 4,
B_BOR = 5,
B_BXOR = 6,
B_BLDNOT = 11,
B_BANDNOT = 12,
B_BORNOT = 13,
MOVB_RM = 0x0000,
MOVW_RM = 0x1000,
MOVL_RM = 0x2000,
FMOV_RM = 0x3000,
MOVB_MR = 0x4000,
MOVW_MR = 0x5000,
MOVL_MR = 0x6000,
FMOV_MR = 0x7000,
MOVU_BMR = 0x8000,
MOVU_WMR = 0x9000,
};
/* GET_LOOP_BOUNDS {EXTENDED}
These two functions compute the actual starting and ending point
of the repeat loop, based on the RS and RE registers (repeat start,
repeat stop). The extended version is called for LDRC, and the
regular version is called for SETRC. The difference is that for
LDRC, the loop start and end instructions are literally the ones
pointed to by RS and RE -- for SETRC, they're not (see docs). */
static struct loop_bounds
get_loop_bounds_ext (rs, re, memory, mem_end, maskw, endianw)
int rs, re;
unsigned char *memory, *mem_end;
int maskw, endianw;
/* Do extended displacement move instructions. */
void
do_long_move_insn (int op, int disp12, int m, int n, int *thatlock)
{
struct loop_bounds loop;
int memstalls = 0;
int thislock = *thatlock;
int endianw = global_endianw;
int *R = &(saved_state.asregs.regs[0]);
unsigned char *memory = saved_state.asregs.memory;
int maskb = ~((saved_state.asregs.msize - 1) & ~0);
unsigned char *insn_ptr = PT2H (saved_state.asregs.pc);
/* FIXME: should I verify RS < RE? */
loop.start = PT2H (RS); /* FIXME not using the params? */
loop.end = PT2H (RE & ~1); /* Ignore bit 0 of RE. */
SKIP_INSN (loop.end);
if (loop.end >= mem_end)
loop.end = PT2H (0);
return loop;
switch (op) {
case MOVB_RM: /* signed */
WBAT (disp12 * 1 + R[n], R[m]);
break;
case MOVW_RM:
WWAT (disp12 * 2 + R[n], R[m]);
break;
case MOVL_RM:
WLAT (disp12 * 4 + R[n], R[m]);
break;
case FMOV_RM: /* floating point */
if (FPSCR_SZ)
{
MA (1);
WDAT (R[n] + 8 * disp12, m);
}
else
WLAT (R[n] + 4 * disp12, FI (m));
break;
case MOVB_MR:
R[n] = RSBAT (disp12 * 1 + R[m]);
L (n);
break;
case MOVW_MR:
R[n] = RSWAT (disp12 * 2 + R[m]);
L (n);
break;
case MOVL_MR:
R[n] = RLAT (disp12 * 4 + R[m]);
L (n);
break;
case FMOV_MR:
if (FPSCR_SZ) {
MA (1);
RDAT (R[m] + 8 * disp12, n);
}
else
SET_FI (n, RLAT (R[m] + 4 * disp12));
break;
case MOVU_BMR: /* unsigned */
R[n] = RBAT (disp12 * 1 + R[m]);
L (n);
break;
case MOVU_WMR:
R[n] = RWAT (disp12 * 2 + R[m]);
L (n);
break;
default:
RAISE_EXCEPTION (SIGINT);
exit (1);
}
saved_state.asregs.memstalls += memstalls;
*thatlock = thislock;
}
/* Do binary logical bit-manipulation insns. */
void
do_blog_insn (int imm, int addr, int binop,
unsigned char *memory, int maskb)
{
int oldval = RBAT (addr);
switch (binop) {
case B_BCLR: /* bclr.b */
WBAT (addr, oldval & ~imm);
break;
case B_BSET: /* bset.b */
WBAT (addr, oldval | imm);
break;
case B_BST: /* bst.b */
if (T)
WBAT (addr, oldval | imm);
else
WBAT (addr, oldval & ~imm);
break;
case B_BLD: /* bld.b */
SET_SR_T ((oldval & imm) != 0);
break;
case B_BAND: /* band.b */
SET_SR_T (T && ((oldval & imm) != 0));
break;
case B_BOR: /* bor.b */
SET_SR_T (T || ((oldval & imm) != 0));
break;
case B_BXOR: /* bxor.b */
SET_SR_T (T ^ ((oldval & imm) != 0));
break;
case B_BLDNOT: /* bldnot.b */
SET_SR_T ((oldval & imm) == 0);
break;
case B_BANDNOT: /* bandnot.b */
SET_SR_T (T && ((oldval & imm) == 0));
break;
case B_BORNOT: /* bornot.b */
SET_SR_T (T || ((oldval & imm) == 0));
break;
}
}
float
fsca_s (int in, double (*f) (double))
{
@ -1494,6 +1642,32 @@ fsrra_s (float in)
return upper - result >= result - lower ? upper : lower;
}
/* GET_LOOP_BOUNDS {EXTENDED}
These two functions compute the actual starting and ending point
of the repeat loop, based on the RS and RE registers (repeat start,
repeat stop). The extended version is called for LDRC, and the
regular version is called for SETRC. The difference is that for
LDRC, the loop start and end instructions are literally the ones
pointed to by RS and RE -- for SETRC, they're not (see docs). */
static struct loop_bounds
get_loop_bounds_ext (rs, re, memory, mem_end, maskw, endianw)
int rs, re;
unsigned char *memory, *mem_end;
int maskw, endianw;
{
struct loop_bounds loop;
/* FIXME: should I verify RS < RE? */
loop.start = PT2H (RS); /* FIXME not using the params? */
loop.end = PT2H (RE & ~1); /* Ignore bit 0 of RE. */
SKIP_INSN (loop.end);
if (loop.end >= mem_end)
loop.end = PT2H (0);
return loop;
}
static struct loop_bounds
get_loop_bounds (rs, re, memory, mem_end, maskw, endianw)
int rs, re;
@ -1607,8 +1781,10 @@ init_dsp (abfd)
saved_state.asregs.xyram_select = new_select;
free (saved_state.asregs.xmem);
free (saved_state.asregs.ymem);
saved_state.asregs.xmem = (unsigned char *) calloc (1, ram_area_size);
saved_state.asregs.ymem = (unsigned char *) calloc (1, ram_area_size);
saved_state.asregs.xmem =
(unsigned char *) calloc (1, ram_area_size);
saved_state.asregs.ymem =
(unsigned char *) calloc (1, ram_area_size);
/* Disable use of X / Y mmeory if not allocated. */
if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem)
@ -1642,6 +1818,10 @@ init_dsp (abfd)
saved_state.asregs.yram_start = 1;
}
if (saved_state.asregs.regstack == NULL)
saved_state.asregs.regstack =
calloc (512, sizeof *saved_state.asregs.regstack);
if (target_dsp != was_dsp)
{
int i, tmp;
@ -1741,7 +1921,11 @@ sim_resume (sd, step, siggnal)
register int memstalls = 0;
register int insts = 0;
register int prevlock;
#if 1
int thislock;
#else
register int thislock;
#endif
register unsigned int doprofile;
register int pollcount = 0;
/* endianw is used for every insn fetch, hence it makes sense to cache it.
@ -1820,10 +2004,13 @@ sim_resume (sd, step, siggnal)
insts++;
#endif
top:
if (tracing)
fprintf (stderr, "PC: %08x, insn: %04x\n", PH2T (insn_ptr), iword);
#include "code.c"
in_delay_slot = 0;
insn_ptr = nip;
if (--pollcount < 0)
@ -1940,6 +2127,15 @@ sim_read (sd, addr, buffer, size)
return size;
}
static int gdb_bank_number;
enum {
REGBANK_MACH = 15,
REGBANK_IVN = 16,
REGBANK_PR = 17,
REGBANK_GBR = 18,
REGBANK_MACL = 19
};
int
sim_store_register (sd, rn, memory, length)
SIM_DESC sd;
@ -2050,6 +2246,12 @@ sim_store_register (sd, rn, memory, length)
case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
{
rn -= SIM_SH_R0_BANK0_REGNUM;
saved_state.asregs.regstack[gdb_bank_number].regs[rn] = val;
}
else
if (SR_MD && SR_RB)
Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) = val;
else
@ -2059,6 +2261,12 @@ sim_store_register (sd, rn, memory, length)
case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
{
rn -= SIM_SH_R0_BANK1_REGNUM;
saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8] = val;
}
else
if (SR_MD && SR_RB)
saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM] = val;
else
@ -2070,6 +2278,35 @@ sim_store_register (sd, rn, memory, length)
case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
SET_Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM, val);
break;
case SIM_SH_TBR_REGNUM:
TBR = val;
break;
case SIM_SH_IBNR_REGNUM:
IBNR = val;
break;
case SIM_SH_IBCR_REGNUM:
IBCR = val;
break;
case SIM_SH_BANK_REGNUM:
/* This is a pseudo-register maintained just for gdb.
It tells us what register bank gdb would like to read/write. */
gdb_bank_number = val;
break;
case SIM_SH_BANK_MACL_REGNUM:
saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL] = val;
break;
case SIM_SH_BANK_GBR_REGNUM:
saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR] = val;
break;
case SIM_SH_BANK_PR_REGNUM:
saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR] = val;
break;
case SIM_SH_BANK_IVN_REGNUM:
saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN] = val;
break;
case SIM_SH_BANK_MACH_REGNUM:
saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH] = val;
break;
default:
return 0;
}
@ -2185,6 +2422,12 @@ sim_fetch_register (sd, rn, memory, length)
case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
{
rn -= SIM_SH_R0_BANK0_REGNUM;
val = saved_state.asregs.regstack[gdb_bank_number].regs[rn];
}
else
val = (SR_MD && SR_RB
? Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM)
: saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM]);
@ -2193,6 +2436,12 @@ sim_fetch_register (sd, rn, memory, length)
case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
{
rn -= SIM_SH_R0_BANK1_REGNUM;
val = saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8];
}
else
val = (! SR_MD || ! SR_RB
? Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM)
: saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM]);
@ -2203,6 +2452,35 @@ sim_fetch_register (sd, rn, memory, length)
case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
val = Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM);
break;
case SIM_SH_TBR_REGNUM:
val = TBR;
break;
case SIM_SH_IBNR_REGNUM:
val = IBNR;
break;
case SIM_SH_IBCR_REGNUM:
val = IBCR;
break;
case SIM_SH_BANK_REGNUM:
/* This is a pseudo-register maintained just for gdb.
It tells us what register bank gdb would like to read/write. */
val = gdb_bank_number;
break;
case SIM_SH_BANK_MACL_REGNUM:
val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL];
break;
case SIM_SH_BANK_GBR_REGNUM:
val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR];
break;
case SIM_SH_BANK_PR_REGNUM:
val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR];
break;
case SIM_SH_BANK_IVN_REGNUM:
val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN];
break;
case SIM_SH_BANK_MACH_REGNUM:
val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH];
break;
default:
return 0;
}
@ -2214,7 +2492,10 @@ int
sim_trace (sd)
SIM_DESC sd;
{
return 0;
tracing = 1;
sim_resume (sd, 0, 0);
tracing = 0;
return 1;
}
void
@ -2381,6 +2662,15 @@ sim_load (sd, prog, abfd, from_tty)
prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
sim_kind == SIM_OPEN_DEBUG,
0, sim_write);
/* Set the bfd machine type. */
if (prog_bfd)
saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
else if (abfd)
saved_state.asregs.bfd_mach = bfd_get_mach (abfd);
else
saved_state.asregs.bfd_mach = 0;
if (prog_bfd == NULL)
return SIM_RC_FAIL;
if (abfd == NULL)
@ -2403,6 +2693,10 @@ sim_create_inferior (sd, prog_bfd, argv, env)
if (prog_bfd != NULL)
saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
/* Set the bfd machine type. */
if (prog_bfd != NULL)
saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
/* Record the program's arguments. */
prog_argv = argv;