/** lc3_execute * * Execute the given instruction * * @param state LC3 simulator * @param instruction Command to execute */ void lc3_execute(lc3machine* state, unsigned short instruction) { // create all the different variables that make up each command unsigned char strCommand = (instruction & 0xF000) >> 12; unsigned char DR = (instruction & 0x0E00) >> 9; unsigned char SR1 = (instruction & 0x01C0) >> 6; unsigned char SR2 = instruction & 0x0007; char bit5 = (instruction & 0x20) >> 5; char bit9 = (instruction & 0x0200) >> 9; char bit10 = (instruction & 0x0400) >> 10; char bit11 = (instruction & 0x0800) >> 11; char imm5 = (instruction & 0x1F) | (instruction & 0x10 ? 0xF0 : 0); char offset6 = (instruction & 0x3F) | (instruction & 0x20 ? 0xE0 : 0); unsigned char offset8 = instruction & 0xFF; short offset9 = (instruction & 0x01FF) | (instruction & 0x100 ? 0xFF00 : 0); short offset11 = (instruction & 0x07FF) | (instruction & 0x400 ? 0xFC00 : 0); // figure out which command it is if (strCommand == 1) { // ADD state->regs[DR] = state->regs[SR1] + (bit5 ? imm5 : state->regs[SR2]); state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 5) { // AND state->regs[DR] = state->regs[SR1] & (bit5 ? imm5 : state->regs[SR2]); state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 0) { // BR if ((bit11 && state->cc == 4) || (bit10 && state->cc == 2) || (bit9 && state->cc == 1)) state->pc += offset9; } else if (strCommand == 12) { // JMP state->pc = state->regs[SR1]; } else if (strCommand == 4) { // JSR state->regs[7] = state->pc; state->pc = bit11 ? (state->pc + offset11) : state->regs[SR1]; } else if (strCommand == 2) { // LD state->regs[DR] = state->mem[state->pc + offset9]; // take into account array starts at 1 state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 10) { // LDI state->regs[DR] = state->mem[state->mem[state->pc + offset9]]; state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 6) { // LDR state->regs[DR] = state->mem[state->regs[SR1] + offset6]; state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 14) { // LEA state->regs[DR] = state->pc + offset9; state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 9) { // NOT state->regs[DR] = ~ state->regs[SR1]; state->cc = state->regs[DR] > 0 ? 1 : (state->regs[DR] < 0 ? 4 : 2); } else if (strCommand == 3) { // ST state->mem[state->pc + offset9] = state->regs[DR]; } else if (strCommand == 11) { // STI state->mem[state->mem[state->pc + offset9]] = state->regs[DR]; } else if (strCommand == 7) { // STR state->mem[state->regs[SR1] + offset6] = state->regs[DR]; } else if(strCommand == 15) { // TRAP state->regs[7] = state->pc; lc3_trap(state, offset8); } }
void lc3_execute(lc3machine* state, unsigned short instruction) { // Get the opcode and choose actions based on that. u32 operation = GET_SUBWORD(instruction, 15, 12); switch (operation) { case (LC3_OP_ADD): { if (GET_SUBWORD(instruction, 5, 5)) { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 sr1 = GET_SUBWORD(instruction, 8, 6); u32 imm5 = GET_SUBWORD(instruction, 4, 0); lc3_add_imm(state, dr, sr1, imm5); } else { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 sr1 = GET_SUBWORD(instruction, 8, 6); u32 sr2 = GET_SUBWORD(instruction, 2, 0); lc3_add_reg(state, dr, sr1, sr2); } break; } case (LC3_OP_AND): { if (GET_SUBWORD(instruction, 5, 5)) { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 sr1 = GET_SUBWORD(instruction, 8, 6); u32 imm5 = GET_SUBWORD(instruction, 4, 0); lc3_and_imm(state, dr, sr1, imm5); } else { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 sr1 = GET_SUBWORD(instruction, 8, 6); u32 sr2 = GET_SUBWORD(instruction, 2, 0); lc3_and_reg(state, dr, sr1, sr2); } break; } case (LC3_OP_BR): { u32 cc = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_br(state, cc, offset); break; } case (LC3_OP_JMP): { u32 reg = GET_SUBWORD(instruction, 8, 6); lc3_jmp(state, reg); break; } case (LC3_OP_JSR): { if (GET_SUBWORD(instruction, 11, 11)) { u32 offset = GET_SUBWORD(instruction, 10, 0); lc3_jsr_offset(state, offset); } else { u32 baser = GET_SUBWORD(instruction, 8, 6); lc3_jsr_reg(state, baser); } break; } case (LC3_OP_LD): { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_ld(state, dr, offset); break; } case (LC3_OP_LDI): { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_ldi(state, dr, offset); break; } case (LC3_OP_LDR): { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 baser = GET_SUBWORD(instruction, 8, 6); u32 offset = GET_SUBWORD(instruction, 5, 0); lc3_ldr(state, dr, baser, offset); break; } case (LC3_OP_LEA): { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_lea(state, dr, offset); break; } case (LC3_OP_NOT): { u32 dr = GET_SUBWORD(instruction, 11, 9); u32 sr = GET_SUBWORD(instruction, 8, 6); lc3_not(state, dr, sr); break; } case (LC3_OP_RTI): { // Not using RTI break; } case (LC3_OP_ST): { u32 sr = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_st(state, sr, offset); break; } case (LC3_OP_STI): { u32 sr = GET_SUBWORD(instruction, 11, 9); u32 offset = GET_SUBWORD(instruction, 8, 0); lc3_sti(state, sr, offset); break; } case (LC3_OP_STR): { u32 sr = GET_SUBWORD(instruction, 11, 9); u32 baser = GET_SUBWORD(instruction, 8, 6); u32 offset = GET_SUBWORD(instruction, 5, 0); lc3_str(state, sr, baser, offset); break; } case (LC3_OP_TRAP): { u32 trapvect = GET_SUBWORD(instruction, 7, 0); lc3_trap(state, trapvect); break; } } }