#include #include #include #include "decode.h" // Retrieve the bits between positions 'lsb' (inclusive) and 'msb' (exclusive) from a given word // as a new zero-extended word. static word getBits(word wrd, uint8_t lsb, uint8_t msb) { // Ensure LSB and MSB are within range of word size, and in the correct order assert(lsb < msb && msb < BYTE_BITS); wrd &= (1 << msb) - 1; return wrd >> lsb; } a64inst_instruction *decode(word wrd) { a64inst_instruction *inst = malloc(sizeof(a64inst_instruction)); if (inst == NULL) { fprintf(stderr, "Ran out of memory while attempting to decode an instruction!\n"); exit(1); } word DPImmFlag = getBits(wrd, BRANCH_CONDITIONAL_COND_LSB, BRANCH_CONDITIONAL_COND_MSB); if (wrd == HALT_WORD) { inst->type = a64inst_HALT; } else if (DPImmFlag == 0) { inst->type = a64inst_DPIMMEDIATE; }else if (DPImmFlag == 1) { inst->type = a64inst_BRANCH; word branchTypeFlag = getBits(wrd, BRANCH_TYPE_LSB, BRANCH_TYPE_MSB); inst->data.BranchData.BranchType = branchTypeFlag; switch (branchTypeFlag) { case a64inst_UNCONDITIONAL: inst->data.BranchData.processOpData.unconditionalData.unconditionalOffset = getBits(wrd, BRANCH_UNCONDITIONAL_OFFSET_LSB, BRANCH_UNCONDITIONAL_OFFSET_MSB); break; case a64inst_CONDITIONAL: inst->data.BranchData.processOpData.conditionalData.offset = getBits(wrd, BRANCH_CONDITIONAL_OFFSET_LSB, BRANCH_CONDITIONAL_OFFSET_MSB); word conditionFlag = getBits(wrd, BRANCH_CONDITIONAL_COND_LSB, BRANCH_CONDITIONAL_COND_MSB); if(conditionFlag <= 1 || (conditionFlag >= 10 && conditionFlag <= 14)) { inst->data.BranchData.processOpData.conditionalData.cond = conditionFlag; } else { fprintf(stderr, "Error: Unknown condition detected.\n"); exit(1); } break; case a64inst_REGISTER: inst->data.BranchData.processOpData.registerData.src = getBits(wrd, BRANCH_REGISTER_SRC_LSB, BRANCH_REGISTER_SRC_MSB); break; default: fprintf(stderr, "Undefined branch type detected!\n"); exit(1); break; } } else if (getBits(wrd, DATA_PROCESSING_REG_LSB, DATA_PROCESSING_REG_MSB) == 1) { inst->type = a64inst_DPREGISTER; } else { // Load and Store, or unknown } }