I wrote this throwaway piece of code while working on lc-3 vm:
#include <iostream>
#include <cassert>
#include <bitset>
using namespace std;
void decode(int instruction) {
int opcode = instruction >> 12;
const char* operation = "+";
const char* operations[2] = {"+", "-"};
assert(opcode > 0 && opcode < 3);
operation = operations[opcode - 1];
int destination_mask = 0xE00;
int source1_mask = 0x1C0;
int flag_mask = 0x020;
int flag = (instruction & flag_mask) >> 5;
int destination_register = (instruction & destination_mask) >> 9;
int source1_register = (instruction & source1_mask) >> 6;
bitset<16> instruction_bits(instruction);
switch (flag) {
case 0: {
cout << "register mode" << endl;
cout << "bits: " << instruction_bits << endl;
int source2_mask = 0x7;
int source2_register = instruction & source2_mask;
cout << "R" << destination_register << " = "
<< "R" << source1_register << " " + operation + " R" << source2_register << endl;
break;
}
case 1: {
cout << "immediate mode" << endl;
cout << "bits: " << instruction_bits << endl;
int immediate_value_mask = 0x1F;
int immediate_value = instruction & immediate_value_mask;
cout << "R" << destination_register << " = "
<< "R" << source1_register << " " + operation + " " << immediate_value << endl;
break;
}
default: {
break;
}
}
}
int main()
{
// register mode
// ADD R2 R0 F 00 R1
// R2 = R0 + R1
// 0001 010 000 0 00 001
int a = 0b0001010000000001;
// immediate mode
// SUB R2 R0 F IMM5
// R2 = R0 - 5
// 0010 010 000 1 00101
int b = 0b0010010000100101;
decode(a);
cout << endl << endl;
decode(b);
return 0;
}