Add decode for DP immediate instructions w/ S#

This commit is contained in:
Themis Demetriades 2024-06-02 20:57:49 +01:00
parent bfb8bfdace
commit 074de73e8e
3 changed files with 66 additions and 18 deletions

View File

@ -33,10 +33,7 @@ typedef struct {
typedef struct { typedef struct {
a64inst_regType regType; a64inst_regType regType;
a64inst_DPIOpType DPIOpType; a64inst_DPIOpType DPIOpType;
union { unsigned int processOp;
a64inst_arithmOp arithmOp;
a64inst_wideMovOp movOp;
} processOpId;
union { union {
a64inst_DPImmediate_ArithmData arithmData; a64inst_DPImmediate_ArithmData arithmData;
a64inst_DPImmediate_WideMovData wideMovData; a64inst_DPImmediate_WideMovData wideMovData;

View File

@ -8,12 +8,14 @@
static word getBits(word wrd, uint8_t lsb, uint8_t msb) { 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 // 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; wrd &= (1 << msb) - 1;
return wrd >> lsb; 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 *decode(word wrd) {
a64inst_instruction *inst = malloc(sizeof(a64inst_instruction)); a64inst_instruction *inst = malloc(sizeof(a64inst_instruction));
@ -22,14 +24,40 @@ a64inst_instruction *decode(word wrd) {
exit(1); 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) { if (wrd == HALT_WORD) {
inst->type = a64inst_HALT; inst->type = a64inst_HALT;
} else if (DPImmFlag == 0) { // Data Processing Immediate interpretation
} else if (typeId == DP_IMM_ID) {
inst->type = a64inst_DPIMMEDIATE; 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);
}else if (DPImmFlag == 1) { 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; inst->type = a64inst_BRANCH;
word branchTypeFlag = getBits(wrd, BRANCH_TYPE_LSB, BRANCH_TYPE_MSB); 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)) { if(conditionFlag <= 1 || (conditionFlag >= 10 && conditionFlag <= 14)) {
inst->data.BranchData.processOpData.conditionalData.cond = conditionFlag; inst->data.BranchData.processOpData.conditionalData.cond = conditionFlag;
} else { } else {
fprintf(stderr, "Error: Unknown condition detected.\n"); fprintf(stderr, "Unknown condition detected!\n");
exit(1); exit(1);
} }
@ -64,12 +92,12 @@ a64inst_instruction *decode(word wrd) {
break; 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; inst->type = a64inst_DPREGISTER;
} else { } else {
// Load and Store, or unknown // Load and Store, or unknown
} }
return inst;
} }

View File

@ -1,14 +1,37 @@
#include "global.h" #include "global.h"
#include "a64instruction.h" #include "a64instruction.h"
#define BYTE_BITS 8 #define WORD_BITS 32
#define HALT_WORD 0x8a000000 #define HALT_WORD 0x8a000000
#define DATA_PROCESSING_IMM_LSB 26 #define TYPE_ID_LSB 26
#define DATA_PROCESSING_IMM_MSB 29 #define TYPE_ID_MSB 29
#define DP_IMM_ID 4
#define BRANCH_ID 5
#define DATA_PROCESSING_REG_LSB 25 #define DP_REG_LSB 25
#define DATA_PROCESSING_REG_MSB 26 #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_LSB 30
#define BRANCH_TYPE_MSB 32 #define BRANCH_TYPE_MSB 32