void n8x300_cpu_device::execute_run() { do { UINT16 opcode; UINT8 src = 0; UINT8 dst; UINT8 rotlen; // rotate amount or I/O field length UINT8 mask; UINT16 result; /* fetch the opcode */ debugger_instruction_hook(this, m_genPC); opcode = FETCHOP(m_genPC); m_PC++; m_PC &= 0x1fff; m_AR = m_PC; m_IR = opcode; m_genPC = m_PC << 1; switch (OP) { case 0x00: // MOVE rotlen = ROTLEN; if(is_rot(opcode)) // MOVE reg,reg { src = get_reg(SRC); dst = rotate(src,rotlen); set_reg(DST,dst); } else { if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length if(is_src_reg(opcode) && !(is_dst_reg(opcode))) { // MOVE reg,IV DST_LATCH; mask = ((1 << rotlen)-1); src = (get_reg(SRC)) << (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (src & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (src & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // MOVE IV,reg SRC_LATCH; if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB); else src = rotate(m_left_IV,7-SRC_LSB); mask = ((1 << rotlen)-1); dst = src & mask; set_reg(DST,dst); } else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) { // MOVE IV,IV SRC_LATCH; if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB); else src = rotate(m_left_IV,7-SRC_LSB); mask = ((1 << rotlen)-1); dst = src & mask; dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(SRC_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV { dst = (m_right_IV & ~mask) | (dst & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (dst & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } } break; case 0x01: // ADD rotlen = ROTLEN; if(is_rot(opcode)) { // ADD reg,reg src = rotate(get_reg(SRC),rotlen); result = src + m_AUX; set_reg(DST,result & 0xff); SET_OVF; } else { if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length if(is_src_reg(opcode) && !(is_dst_reg(opcode))) { // ADD reg,IV DST_LATCH; result = get_reg(SRC) + m_AUX; mask = ((1 << rotlen)-1); dst = (result & 0xff) << DST_LSB; mask <<= DST_LSB; SET_OVF; if(DST_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (dst & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (dst & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // ADD IV,reg SRC_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; result = src + m_AUX; SET_OVF; set_reg(DST,result & 0xff); } else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) { // ADD IV,IV SRC_LATCH; DST_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; result = src + m_AUX; SET_OVF; dst = (result << (7-DST_LSB)) & 0xff; mask <<= (7-DST_LSB); if(SRC_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data { dst = (m_right_IV & ~mask) | (dst & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (dst & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } } break; case 0x02: // AND rotlen = ROTLEN; if(is_rot(opcode)) { // AND reg,reg src = rotate(get_reg(SRC),rotlen); dst = src & m_AUX; set_reg(DST,dst); } else { if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length if(is_src_reg(opcode) && !(is_dst_reg(opcode))) { // AND reg,IV DST_LATCH; src = get_reg(SRC) & m_AUX; mask = ((1 << rotlen)-1); src <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (src & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (src & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // AND IV,reg SRC_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; src &= mask; dst = src & m_AUX; set_reg(DST,dst); } else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) { // AND IV,IV SRC_LATCH; DST_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; src &= mask; dst = src & m_AUX; dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(SRC_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (src & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (src & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } } break; case 0x03: // XOR rotlen = ROTLEN; if(is_rot(opcode)) { // AND reg,reg src = rotate(get_reg(SRC),rotlen); dst = src ^ m_AUX; set_reg(DST,dst); } else { if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length if(is_src_reg(opcode) && !(is_dst_reg(opcode))) { // AND reg,IV DST_LATCH; src = get_reg(SRC) ^ m_AUX; mask = ((1 << rotlen)-1); src <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(DST_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (src & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (src & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) { // AND IV,reg SRC_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; src &= mask; dst = src ^ m_AUX; set_reg(DST,dst); } else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) { // AND IV,IV SRC_LATCH; DST_LATCH; mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB) & mask; else src = rotate(m_left_IV,7-SRC_LSB) & mask; src &= mask; dst = src ^ m_AUX; dst <<= (7-DST_LSB); mask <<= (7-DST_LSB); if(SRC_IS_RIGHT_BANK) { dst = (m_right_IV & ~mask) | (src & mask); m_right_IV = dst; WRITEPORT(m_IVR+0x100,m_right_IV); } else { dst = (m_left_IV & ~mask) | (src & mask); m_left_IV = dst; WRITEPORT(m_IVL,m_left_IV); } } } break; case 0x04: // XEC (Execute) if(is_src_reg(opcode)) { src = get_reg(SRC); src += IMM8; SET_AR((m_AR & 0x1f00) | src); } else { SRC_LATCH; rotlen = ROTLEN; if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB); else src = rotate(m_left_IV,7-SRC_LSB); src &= mask; src += IMM5; SET_AR((m_AR & 0x1fe0) | (src & 0x1f)); } break; case 0x05: // NZT (Non-zero transfer) if(is_src_reg(opcode)) { src = get_reg(SRC); if(src != 0) SET_PC((m_PC & 0x1f00) | IMM8); } else { SRC_LATCH; rotlen = ROTLEN; if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length mask = ((1 << rotlen)-1); if(SRC_IS_RIGHT_BANK) src = rotate(m_right_IV,7-SRC_LSB); else src = rotate(m_left_IV,7-SRC_LSB); rotate(src,SRC_LSB); src &= mask; if(src != 0) SET_PC((m_PC & 0x1fe0) | IMM5); } break; case 0x06: // XMIT (Transmit) // the source is actually the destination for this instruction if(is_src_reg(opcode)) set_reg(SRC,IMM8); else { SRC_LATCH; rotlen = ROTLEN; if(rotlen == 0) rotlen = 8; // 0 = 8-bit I/O field length mask = ((1 << rotlen)-1); dst = IMM5; mask <<= (7-SRC_LSB); dst <<= (7-SRC_LSB); if(SRC_IS_RIGHT_BANK) { m_right_IV = (m_right_IV & ~mask) | (dst & mask); WRITEPORT(m_IVR+0x100,m_right_IV); } else { m_left_IV = (m_left_IV & ~mask) | (dst & mask); WRITEPORT(m_IVL,m_left_IV); } } break; case 0x07: // JMP SET_PC(ADDR); break; } CYCLES(1); // all instructions take 1 cycle (250ns) } while (m_icount > 0); }
/* * Read one taint op from infd * Returns the number of bytes read */ int read_taint_op_extended(int infd, struct taint_op* op, int mergenumbers) { int rc; taint_op_t taint_op; int bytes_read = 0; assert(op); rc = read(infd, op, sizeof(struct taint_op)); if (rc != sizeof(struct taint_op)) { fprintf(stderr, "read_taint_op: cannot read taint op, got %d, expected %d, errno %d\n", rc, sizeof(struct taint_op), errno); exit(-1); } bytes_read += rc; taint_op = op->taint_op; if (taint_op == TAINTOP_SYSCALL) { fprintf(stdout, "SYSCALL %lu, num %lu\n", op->src, op->dst); taint_op_count++; return bytes_read; } if (start) { fprintf(stdout, "%lu taint op: %lx %d %d %s\n", taint_op_count, op->ip, op->threadid, op->taint_op, taint_op_str(op->taint_op)); fflush(stdout); } if (taint_op == TAINT_REP_LBREG2MEM || taint_op == TAINT_REP_UBREG2MEM || taint_op == TAINT_REP_HWREG2MEM || taint_op == TAINT_REP_WREG2MEM || taint_op == TAINT_REP_DWREG2MEM || taint_op == TAINT_REP_QWREG2MEM || taint_op == TAINT_MEM2MEM) { taint_op_count++; return bytes_read; } if (is_src_reg(taint_op)) { int i = 0; int size; taint_t t; size = get_src_size(taint_op); assert(size != 0); // read size number of taints for (i = 0; i < size; i++) { rc = read(infd, &t, sizeof(taint_t)); if (rc != sizeof(taint_t)) { fprintf(stderr, "read_taint_op: cannot read src reg taint\n"); assert(0); } if (t != 0 && !start) { start = 1; fprintf(stdout, "%lu taint op: %lx %d %d %s\n", taint_op_count, op->ip, op->threadid, op->taint_op, taint_op_str(op->taint_op)); } if (start) { if (t) { struct taint_creation_info tci; fprintf(stdout, " src(%lu) %d: ", op->src, i); if (!mergenumbers) { print_leaf_options(&tci, t, 0, leaf_node_table, merge_node_table, option_info_table, filename_table); } else { print_merge_numbers(t, merge_node_table, option_info_table, filename_table); } } } bytes_read += rc; } } else if (is_src_mem(taint_op)) { int i; int size; taint_t t; size = get_src_size(taint_op); assert(size != 0); for (i = 0; i < size; i++) { rc = read(infd, &t, sizeof(taint_t)); if (rc != sizeof(taint_t)) { fprintf(stderr, "read_taint_op: cannot read src mem taint\n"); } if (t != 0 && !start) { start = 1; fprintf(stdout, "%lu taint op: %lx %d %d %s\n", taint_op_count, op->ip, op->threadid, op->taint_op, taint_op_str(op->taint_op)); } if (start) { if (t) { struct taint_creation_info tci; fprintf(stdout, " src(%#lx) %d: ", op->src + i, i); if (!mergenumbers) { print_leaf_options(&tci, t, 0, leaf_node_table, merge_node_table, option_info_table, filename_table); } else { print_merge_numbers(t, merge_node_table, option_info_table, filename_table); } } } bytes_read += rc; } } else { fprintf(stderr, "what is it %d %s\n", taint_op, taint_op_str(taint_op)); assert(0); } if (is_dst_reg(taint_op)) { int i = 0; int size; taint_t t; size = get_dst_size(taint_op); if (size == 0) { fprintf(stderr, "taint_op size is 0?! %d %s\n", taint_op, taint_op_str(taint_op)); } assert(size != 0); // read size number of taints for (i = 0; i < size; i++) { rc = read(infd, &t, sizeof(taint_t)); if (rc != sizeof(taint_t)) { fprintf(stderr, "read_taint_op: cannot read dst reg taint\n"); assert(0); } if (start) { if (t) { struct taint_creation_info tci; fprintf(stdout, " dst(%lu) %d: ", op->dst, i); if (!mergenumbers) { print_leaf_options(&tci, t, 0, leaf_node_table, merge_node_table, option_info_table, filename_table); } else { print_merge_numbers(t, merge_node_table, option_info_table, filename_table); } } } bytes_read += rc; } } else if (is_dst_mem(taint_op)) { int i; int size; taint_t t; size = get_dst_size(taint_op); if (size == 0) { fprintf(stderr, "taint_op %d %s\n", taint_op, taint_op_str(taint_op)); if (taint_op == TAINT_ADD_HWREG2MEM) goto done; } assert(size != 0); for (i = 0; i < size; i++) { rc = read(infd, &t, sizeof(taint_t)); if (rc != sizeof(taint_t)) { fprintf(stderr, "read_taint_op: cannot read dst mem taint\n"); } if (start) { if (t || taint_op == TAINT_QWREG2MEM) { struct taint_creation_info tci; fprintf(stdout, " dst(%#lx) %d: ", op->dst + i, i); if (!t) fprintf(stdout, "0\n"); else { if (!mergenumbers) { print_leaf_options(&tci, t, 0, leaf_node_table, merge_node_table, option_info_table, filename_table); } else { print_merge_numbers(t, merge_node_table, option_info_table, filename_table); } } } else { fprintf(stdout, " dst(%#lx) cleared\n", op->dst + i); } } bytes_read += rc; } } else { assert(0); } done: taint_op_count++; return bytes_read; }