/* Basic integer 3-address imm16 format: * mnemonic #imm16,%rs2,%rd */ static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Sign extend the 16-bit immediate. Print as hex for the bitwise operations. */ int upper_6bits = (insn >> 26) & 0x3f; if (upper_6bits >= 0x30 && upper_6bits <= 0x3f) util::stream_format(stream, "%s\t0x%04x,%%r%d,%%r%d", mnemonic, (uint32_t)(get_imm16 (insn)), get_isrc2 (insn), get_idest (insn)); else util::stream_format(stream, "%s\t%d,%%r%d,%%r%d", mnemonic, sign_ext(get_imm16 (insn), 16), get_isrc2 (insn), get_idest (insn)); }
/* Basic integer 3-address imm16 format: * mnemonic #imm16,%rs2,%rd */ static void int_i2d(char *buf, char *mnemonic, UINT32 pc, UINT32 insn) { /* Sign extend the 16-bit immediate. Print as hex for the bitwise operations. */ int upper_6bits = (insn >> 26) & 0x3f; if (upper_6bits >= 0x30 && upper_6bits <= 0x3f) sprintf(buf, "%s\t0x%04x,%%r%d,%%r%d", mnemonic, (UINT32)(get_imm16 (insn)), get_isrc2 (insn), get_idest (insn)); else sprintf(buf, "%s\t%d,%%r%d,%%r%d", mnemonic, sign_ext(get_imm16 (insn), 16), get_isrc2 (insn), get_idest (insn)); }
void execute(ui32 ins) { opcode_t op; register_t r1, r2; ui32 imm16, imm21; op = get_opcode(ins); r1 = get_r1(ins); r2 = get_r2(ins); imm21 = get_imm21(ins); imm16 = get_imm16(ins); switch (op) { case OPCODE_COUNT: case NOT_AN_OPCODE: fputs("'NOT AN OPCODE'", stderr); abort(); /* NO_OPERANDS */ /* oooooo 00000000000000000000000000 */ /* 6 26 */ case HALT: program_halted = 1; break; case NOP: registers[PC] += 4; break; case RET: registers[SP] += 4; registers[PC] = *((ui32*)(memspace + registers[SP])); break; case SYSCALL: registers[R1] = syscall(registers[SYS]); registers[PC] += 4; break; /* REGISTER_REGISTER */ /* oooooo rrrrr rrrrr 0000000000000000 */ /* 6 5 5 16 */ case ADD: registers[r1] += registers[r2]; registers[PC] += 4; break; case MUL: registers[r1] *= registers[r2]; registers[PC] += 4; break; case DIV: registers[r1] /= registers[r2]; registers[PC] += 4; break; case EQ: registers[Z] = registers[r1] == registers[r2]; registers[PC] += 4; break; case NE: registers[Z] = registers[r1] != registers[r2]; registers[PC] += 4; break; case LT: registers[Z] = registers[r1] < registers[r2]; registers[PC] += 4; break; case LE: registers[Z] = registers[r1] <= registers[r2]; registers[PC] += 4; break; case GT: registers[Z] = registers[r1] > registers[r2]; registers[PC] += 4; break; case GE: registers[Z] = registers[r1] >= registers[r2]; registers[PC] += 4; break; case AND: registers[r1] &= registers[r2]; registers[PC] += 4; break; case OR: registers[r1] |= registers[r2]; registers[PC] += 4; break; case XOR: registers[r1] ^= registers[r2]; registers[PC] += 4; break; case SLL: registers[r1] <<= registers[r2]; registers[PC] += 4; break; case SRL: registers[r1] >>= registers[r2]; registers[PC] += 4; break; case MOV: registers[r1] = registers[r2]; registers[PC] += 4; break; /* REGISTER_REGISTER_OFFSET */ /* oooooo rrrrr rrrrr mmmmmmmmmmmmmmmm */ /* 6 5 5 16 */ case LW: registers[r1] = *((ui32*)(imm16 + memspace + registers[r2])); registers[PC] += 4; break; case SW: *((ui32*)(imm16 + memspace + registers[r2])) = registers[r1]; registers[PC] += 4; break; case LB: registers[r1] = *((ui8*)(imm16 + memspace + registers[r2])); registers[PC] += 4; break; case SB: *((ui8*)(imm16 + memspace + registers[r2])) = registers[r1]; registers[PC] += 4; break; /* REGISTER_IMMEDIATE */ /* oooooo rrrrr mmmmmmmmmmmmmmmmmmmmm */ /* 6 5 21 */ case ADDI: registers[r1] += imm21; registers[PC] += 4; break; case MULI: registers[r1] *= imm21; registers[PC] += 4; break; case DIVI: registers[r1] /= imm21; registers[PC] += 4; break; case LI: registers[r1] = imm21; registers[PC] += 4; break; /* REGISTER_NO_IMMEDIATE */ /* oooooo rrrrr 000000000000000000000 */ /* 6 5 21 */ case JR: registers[PC] = registers[r1]; break; case PUSH: *((ui32*)(memspace + registers[SP])) = registers[r1]; registers[SP] -= 4; registers[PC] += 4; break; case POP: registers[SP] += 4; registers[r1] = *((ui32*)(memspace + registers[SP])); registers[PC] += 4; break; case PRINTS: printf("%s", ((char*)(memspace + registers[r1]))); registers[PC] += 4; break; case PRINTI: printf("%d", registers[r1]); registers[PC] += 4; break; /* IMMEDIATE_NO_REGISTER */ /* oooooo 00000 mmmmmmmmmmmmmmmmmmmmm */ /* 6 21 */ case J: registers[PC] = imm21; break; case JS: registers[PC] += imm21; break; case JZ: if (registers[Z]) { registers[PC] = imm21; registers[Z] = 0; } else { registers[PC] += 4; } break; case JZS: if (registers[Z]) { registers[PC] += imm21; registers[Z] = 0; } else { registers[PC] += 4; } break; case CALL: /* Push return address to stack */ *((ui32*)(memspace + registers[SP])) = registers[PC] + 4; registers[SP] -= 4; registers[PC] = imm21; break; case PUSHI: *((ui32*)(memspace + registers[SP])) = imm21; registers[SP] -= 4; registers[PC] += 4; break; case PRINTC: printf("%c", imm21); registers[PC] += 4; break; } }