📄 gencode.c
字号:
/* Simulator/Opcode generator for the Hitachi 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", "", "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)", " | ((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);", }, { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", "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", "{", " 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>", "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;", " float f;", " } u;", " u.f = FR(n);", " FPUL = u.i;", }, /* 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);", " int mi = XD_TO_XF (m);", " SET_XF (ni + 0, XF (mi + 0));", " SET_XF (ni + 1, XF (mi + 1));", "}", "else", "{", " SET_FR (n, FR (m));", "}", }, /* sh2e */ { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " WDAT (R[n], m);", "}", "else", "{", " MA (1);", " WLAT (R[n], FI(m));", "}", }, /* sh2e */ { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " RDAT (R[m], n);", "}", "else", "{", " MA (1);", " SET_FI(n, RLAT(R[m]));", "}", }, /* sh2e */ { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " RDAT (R[m], n);", " R[m] += 8;", "}", "else", "{", " MA (1);", " SET_FI (n, RLAT (R[m]));", " R[m] += 4;", "}", }, /* sh2e */ { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " R[n] -= 8;", " WDAT (R[n], m);", "}", "else", "{", " MA (1);", " R[n] -= 4;", " WLAT (R[n], FI(m));", "}", }, /* sh2e */ { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " RDAT (R[0]+R[m], n);", "}", "else", "{", " MA (1);", " SET_FI(n, RLAT(R[0] + R[m]));", "}", }, /* sh2e */ { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111", /* sh4 */ "if (FPSCR_SZ) {", " MA (2);", " WDAT (R[0]+R[n], m);", "}", "else", "{", " MA (1);", " WLAT((R[0]+R[n]), FI(m));", "}", }, /* 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", "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);", }, /* 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;", " float f;", " } u;", " u.i = FPUL;", " 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]);", "SET_NIP (PT2H (R[n]));", "cycles += 2;", "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", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111", "MA (1);", "CREG (m) = RLAT (R[n]);", "R[n] += 4;", "/* FIXME: user mode */", }, { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111", "MA (1);", "SET_SR (RLAT (R[n]));", "R[n] += 4;", "/* FIXME: user mode */", }, { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111", "MA (1);", "SET_MOD (RLAT (R[n]));", "R[n] += 4;", },#if 0 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110", "MA (1);", "DBR = RLAT (R[n]);", "R[n] += 4;", "/* FIXME: user mode */", },#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", "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", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110", "MA (1);", "SET_FPSCR (RLAT(R[n]));", "R[n] += 4;", }, { "", "", "ldtlb", "0000000000111000", "/* FIXME: XXX*/ abort();", }, { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111", "trap (255, R0, PC, memory, maskl, maskw, endianw);", "/* FIXME: mac.l support */", }, { "", "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);", }, { "n", "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]);", }, { "", "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);", },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -