+
+ { "", "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;",
+ "/* FIXME: The result may be implementation-defined if it is outside */",
+ "/* the range of signed int (i.e. if R[n] was negative and R0 == 1). */",
+ "else R[n] = 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",
+ "int i;",
+ "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
+ /* FIXME: cdef all */
+ "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);",
+ },