Skip to content

Instantly share code, notes, and snippets.

@pepplejoshua
Last active August 22, 2024 17:55
Show Gist options
  • Save pepplejoshua/490fe6d201b29f940ff2564956453a75 to your computer and use it in GitHub Desktop.
Save pepplejoshua/490fe6d201b29f940ff2564956453a75 to your computer and use it in GitHub Desktop.
Decoding sections of a 16 bit instruction using bit manipulation

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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment