Пример #1
0
/** 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);
    }
}
Пример #2
0
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;
        }
    }
}