📄 gencode.c
字号:
/* Simulator/Opcode generator for the Renesas (formerly Hitachi) / SuperH Inc. Super-H architecture. Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com This file is part of SH sim. THIS SOFTWARE IS NOT COPYRIGHTED Cygnus offers the following for use in the public domain. Cygnus makes no warranty with regard to the software or it's performance and the user accepts the software "AS IS" with all faults. CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.*//* This program generates the opcode table for the assembler and the simulator code. -t prints a pretty table for the assembler manual -s generates the simulator code jump table -d generates a define table -x generates the simulator code switch statement default used to generate the opcode tables*/#include <stdio.h>#define MAX_NR_STUFF 42typedef struct{ char *defs; char *refs; char *name; char *code; char *stuff[MAX_NR_STUFF]; int index;} op;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", "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....", "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", "if (!T) {", " SET_NIP (PC + 4 + (SEXT (i) * 2));", " cycles += 2;", "}", }, { "", "", "bf.s <bdisp8>", "10001111i8p1....", "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", "if (!T) {", " SET_NIP (PC + 4 + (SEXT (i) * 2));", " cycles += 2;", " Delay_Slot (PC + 2);", "}", }, { "", "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;", "Delay_Slot (PC + 2);", }, { "", "n", "bsrf <REG_N>", "0000nnnn00000011", "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", "PR = PH2T (PC) + 4;", "SET_NIP (PC + 4 + R[n]);", "cycles += 2;", "Delay_Slot (PC + 2);", }, { "", "", "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;", " Delay_Slot (PC + 2);", "}", }, { "", "", "clrmac", "0000000000101000", "MACH = 0;", "MACL = 0;", }, { "", "", "clrs", "0000000001001000", "SET_SR_S (0);", }, { "", "", "clrt", "0000000000001000", "SET_SR_T (0);", }, /* sh4a */ { "", "", "clrdmxy", "0000000010001000", "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);" }, { "", "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)", " | ((ult & 0xff00) == 0)", " | ((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);", }, { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", "div1 (&R0, 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", "{", " union", " {", " int i;", " float f;", " } u;", " u.f = DR (n);", " FPUL = u.i;", "}", }, /* sh4 */ { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101", "if (! FPSCR_PR || n & 1)", " RAISE_EXCEPTION (SIGILL);", "else", "{", " union", " {", " int i;", " float f;", " } 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>", "1111vvVV11101101", "if (FPSCR_PR)", " RAISE_EXCEPTION (SIGILL);", "else", "{", " double fsum = 0;", " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", " RAISE_EXCEPTION (SIGILL);",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -