diff --git a/src/a64instruction_DPImmediate.h b/src/a64instruction_DPImmediate.h index 2c02c2f..8b5e68c 100644 --- a/src/a64instruction_DPImmediate.h +++ b/src/a64instruction_DPImmediate.h @@ -33,10 +33,7 @@ typedef struct { typedef struct { a64inst_regType regType; a64inst_DPIOpType DPIOpType; - union { - a64inst_arithmOp arithmOp; - a64inst_wideMovOp movOp; - } processOpId; + unsigned int processOp; union { a64inst_DPImmediate_ArithmData arithmData; a64inst_DPImmediate_WideMovData wideMovData; diff --git a/src/decode.c b/src/decode.c index a607e18..3610811 100644 --- a/src/decode.c +++ b/src/decode.c @@ -8,12 +8,14 @@ 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); + assert(lsb < msb && msb <= WORD_BITS); wrd &= (1 << msb) - 1; return wrd >> lsb; } +// Given a binary word, return its internal representation as an a64instruction struct encoding the same +// information. a64inst_instruction *decode(word wrd) { a64inst_instruction *inst = malloc(sizeof(a64inst_instruction)); @@ -22,14 +24,40 @@ a64inst_instruction *decode(word wrd) { exit(1); } - word DPImmFlag = getBits(wrd, BRANCH_CONDITIONAL_COND_LSB, BRANCH_CONDITIONAL_COND_MSB); + word typeId = getBits(wrd, TYPE_ID_LSB, TYPE_ID_MSB); + // Halt interpretation if (wrd == HALT_WORD) { inst->type = a64inst_HALT; - - } else if (DPImmFlag == 0) { - inst->type = a64inst_DPIMMEDIATE; - }else if (DPImmFlag == 1) { + // Data Processing Immediate interpretation + } else if (typeId == DP_IMM_ID) { + inst->type = a64inst_DPIMMEDIATE; + inst->data.DPImmediateData.regType = getBits(wrd, DP_IMM_WIDTH_LSB, DP_IMM_WIDTH_MSB); + inst->data.DPImmediateData.processOp = getBits(wrd, DP_IMM_OP_LSB, DP_IMM_OP_MSB); + inst->data.DPImmediateData.dest = getBits(wrd, DP_IMM_DEST_LSB, DP_IMM_DEST_MSB); + + switch(getBits(wrd, DP_IMM_OPTYPE_LSB, DP_IMM_OPTYPE_MSB)) { + + case DP_IMM_OPTYPE_ARITHM: + inst->data.DPImmediateData.DPIOpType = a64inst_DPI_ARITHM; + inst->data.DPImmediateData.processOpData.arithmData.shiftImmediate = getBits(wrd, DP_IMM_ARITHM_SHIFTFLAG_LSB, DP_IMM_ARITHM_SHIFTFLAG_MSB); + inst->data.DPImmediateData.processOpData.arithmData.immediate = getBits(wrd, DP_IMM_ARITHM_IMMVAL_LSB, DP_IMM_ARITHM_IMMVAL_MSB); + inst->data.DPImmediateData.processOpData.arithmData.src = getBits(wrd, DP_IMM_ARITHM_DEST_LSB, DP_IMM_ARITHM_DEST_MSB); + break; + + case DP_IMM_OPTYPE_WIDEMOV: + inst->data.DPImmediateData.DPIOpType = a64inst_DPI_WIDEMOV; + inst->data.DPImmediateData.processOpData.wideMovData.shiftScalar = getBits(wrd, DP_IMM_WIDEMOV_SHIFTSCALAR_LSB, DP_IMM_WIDEMOV_SHIFTSCALAR_MSB); + inst->data.DPImmediateData.processOpData.wideMovData.immediate = getBits(wrd, DP_IMM_WIDEMOV_IMMVAL_LSB, DP_IMM_WIDEMOV_IMMVAL_MSB); + break; + + default: + fprintf(stderr, "Unknown immediate data processing operation type found!\n"); + exit(1); + break; + } + + } else if (typeId == BRANCH_ID) { inst->type = a64inst_BRANCH; word branchTypeFlag = getBits(wrd, BRANCH_TYPE_LSB, BRANCH_TYPE_MSB); @@ -48,7 +76,7 @@ a64inst_instruction *decode(word wrd) { if(conditionFlag <= 1 || (conditionFlag >= 10 && conditionFlag <= 14)) { inst->data.BranchData.processOpData.conditionalData.cond = conditionFlag; } else { - fprintf(stderr, "Error: Unknown condition detected.\n"); + fprintf(stderr, "Unknown condition detected!\n"); exit(1); } @@ -64,12 +92,12 @@ a64inst_instruction *decode(word wrd) { break; } - } else if (getBits(wrd, DATA_PROCESSING_REG_LSB, DATA_PROCESSING_REG_MSB) == 1) { + } else if (getBits(wrd, DP_REG_LSB, DP_REG_MSB) == 1) { inst->type = a64inst_DPREGISTER; } else { // Load and Store, or unknown } - + return inst; } diff --git a/src/decode.h b/src/decode.h index 280d473..6494f0f 100644 --- a/src/decode.h +++ b/src/decode.h @@ -1,14 +1,37 @@ #include "global.h" #include "a64instruction.h" -#define BYTE_BITS 8 +#define WORD_BITS 32 #define HALT_WORD 0x8a000000 -#define DATA_PROCESSING_IMM_LSB 26 -#define DATA_PROCESSING_IMM_MSB 29 +#define TYPE_ID_LSB 26 +#define TYPE_ID_MSB 29 +#define DP_IMM_ID 4 +#define BRANCH_ID 5 -#define DATA_PROCESSING_REG_LSB 25 -#define DATA_PROCESSING_REG_MSB 26 +#define DP_REG_LSB 25 +#define DP_REG_MSB 26 + +#define DP_IMM_WIDTH_LSB 31 +#define DP_IMM_WIDTH_MSB 32 +#define DP_IMM_OP_LSB 29 +#define DP_IMM_OP_MSB 31 +#define DP_IMM_DEST_LSB 0 +#define DP_IMM_DEST_MSB 5 +#define DP_IMM_OPTYPE_LSB 23 +#define DP_IMM_OPTYPE_MSB 26 +#define DP_IMM_OPTYPE_ARITHM 2 +#define DP_IMM_OPTYPE_WIDEMOV 5 +#define DP_IMM_ARITHM_SHIFTFLAG_LSB 22 +#define DP_IMM_ARITHM_SHIFTFLAG_MSB 23 +#define DP_IMM_ARITHM_IMMVAL_LSB 10 +#define DP_IMM_ARITHM_IMMVAL_MSB 22 +#define DP_IMM_ARITHM_DEST_LSB 5 +#define DP_IMM_ARITHM_DEST_MSB 10 +#define DP_IMM_WIDEMOV_SHIFTSCALAR_LSB 21 +#define DP_IMM_WIDEMOV_SHIFTSCALAR_MSB 23 +#define DP_IMM_WIDEMOV_IMMVAL_LSB 5 +#define DP_IMM_WIDEMOV_IMMVAL_MSB 21 #define BRANCH_TYPE_LSB 30 #define BRANCH_TYPE_MSB 32