diff --git a/src/a64instruction_DP.h b/src/a64instruction_DP.h index 113f589..8ffb1f7 100644 --- a/src/a64instruction_DP.h +++ b/src/a64instruction_DP.h @@ -1,3 +1,6 @@ +#ifndef __A64INSTRUCTION_DP__ +#define __A64INSTRUCTION_DP__ + // Denotes the type of arithmetic operations supported by the architecture typedef enum { a64inst_ADD = 0, @@ -5,3 +8,5 @@ typedef enum { a64inst_SUB = 2, a64inst_SUBS = 3 } a64inst_arithmOp; + +#endif diff --git a/src/a64instruction_DPRegister.h b/src/a64instruction_DPRegister.h index 401f225..d82510a 100644 --- a/src/a64instruction_DPRegister.h +++ b/src/a64instruction_DPRegister.h @@ -4,8 +4,8 @@ // Denotes the type of data processing operation typedef enum { - a64inst_DPR_ARITHMLOGIC, - a64inst_DPR_MULTIPLY + a64inst_DPR_ARITHMLOGIC = 0, + a64inst_DPR_MULTIPLY = 1 } a64inst_DPROpType; // Denotes the logical operations supported by the architecture @@ -31,6 +31,7 @@ typedef struct { a64inst_DPR_LOGIC = 1 } type; a64inst_ShiftType shiftType; + uint8_t shiftAmount; bool negShiftedSrc2; // Guaranteed to be 0 for arithmetic instructions } a64inst_DPRegister_ArithmLogicData; @@ -44,10 +45,7 @@ typedef struct { typedef struct { a64inst_regType regType; a64inst_DPROpType DPROpType; - union { - a64inst_logicOp logicOp; - a64inst_arithmOp arithmOp; - } processOp; + uint8_t processOp; a64inst_regSpecifier src2; union { a64inst_DPRegister_ArithmLogicData arithmLogicData; diff --git a/src/decode.c b/src/decode.c index f7161f9..6c969d8 100644 --- a/src/decode.c +++ b/src/decode.c @@ -33,9 +33,9 @@ a64inst_instruction *decode(word wrd) { // 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); + inst->data.DPImmediateData.regType = getBits(wrd, DP_WIDTH_LSB, DP_WIDTH_MSB); + inst->data.DPImmediateData.processOp = getBits(wrd, DP_OP_LSB, DP_OP_MSB); + inst->data.DPImmediateData.dest = getBits(wrd, DP_DEST_LSB, DP_DEST_MSB); switch(getBits(wrd, DP_IMM_OPTYPE_LSB, DP_IMM_OPTYPE_MSB)) { @@ -93,8 +93,40 @@ a64inst_instruction *decode(word wrd) { break; } + // TODO: Some minor code duplication between DPR and DPI data interpretation + // Data Processing Register interpretation } else if (getBits(wrd, DP_REG_LSB, DP_REG_MSB) == 1) { inst->type = a64inst_DPREGISTER; + inst->data.DPRegisterData.regType = getBits(wrd, DP_WIDTH_LSB, DP_WIDTH_MSB); + inst->data.DPRegisterData.processOp = getBits(wrd, DP_OP_LSB, DP_OP_MSB); + inst->data.DPRegisterData.dest = getBits(wrd, DP_DEST_LSB, DP_DEST_MSB); + inst->data.DPRegisterData.src1 = getBits(wrd, DP_REG_SRC1_LSB, DP_REG_SRC1_MSB); + inst->data.DPRegisterData.src2 = getBits(wrd, DP_REG_SRC2_LSB, DP_REG_SRC2_MSB); + inst->data.DPRegisterData.DPROpType = getBits(wrd, DP_REG_OPTYPE_LSB, DP_REG_OPTYPE_MSB); + + a64inst_DPRegister_ArithmLogicData arithmLogicData = inst->data.DPRegisterData.processOpData.arithmLogicData; + + arithmLogicData.type = getBits(wrd, DP_REG_ARITHMLOGIC_ARITHMFLAG_LSB, DP_REG_ARITHMLOGIC_ARITHMFLAG_MSB); + arithmLogicData.shiftType = getBits(wrd, DP_REG_ARITHMLOGIC_SHIFTTYPE_LSB, DP_REG_ARITHMLOGIC_SHIFTTYPE_MSB); + arithmLogicData.negShiftedSrc2 = getBits(wrd, DP_REG_ARITHMLOGIC_NEGSRC2FLAG_LSB, DP_REG_ARITHMLOGIC_NEGSRC2FLAG_MSB); + + switch(inst->data.DPRegisterData.DPROpType) { + + case a64inst_DPR_ARITHMLOGIC: + arithmLogicData.shiftAmount = getBits(wrd, DP_REG_ARITHMLOGIC_SHIFTAMOUNT_LSB, DP_REG_ARITHMLOGIC_SHIFTAMOUNT_MSB); + break; + + case a64inst_DPR_MULTIPLY:; + if (!(inst->data.DPRegisterData.processOp == DP_REG_MULTIPLY_PROCESSOP && + arithmLogicData.type == DP_REG_MULTIPLY_ARITHMFLAG && + arithmLogicData.shiftType == DP_REG_MULTIPLY_SHIFTTYPE && + arithmLogicData.negShiftedSrc2 == DP_REG_MULTIPLY_NEGSRC2FLAG)) { + fprintf(stderr, "Attempting to decode multiply instruction with invalid format!\n"); + } + inst->data.DPRegisterData.processOpData.multiplydata.summand = getBits(wrd, DP_REG_MULTIPLY_SUMMAND_LSB, DP_REG_MULTIPLY_SUMMAND_MSB); + inst->data.DPRegisterData.processOpData.multiplydata.negProd = getBits(wrd, DP_REG_MULTIPLY_NEGPROD_LSB, DP_REG_MULTIPLY_NEGPROD_MSB); + break; + } } else { // Load and Store, or unknown diff --git a/src/decode.h b/src/decode.h index 6741c95..132130e 100644 --- a/src/decode.h +++ b/src/decode.h @@ -11,12 +11,13 @@ #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_WIDTH_LSB 31 +#define DP_WIDTH_MSB 32 +#define DP_OP_LSB 29 +#define DP_OP_MSB 31 +#define DP_DEST_LSB 0 +#define DP_DEST_MSB 5 + #define DP_IMM_OPTYPE_LSB 23 #define DP_IMM_OPTYPE_MSB 26 #define DP_IMM_OPTYPE_ARITHM 2 @@ -32,6 +33,31 @@ #define DP_IMM_WIDEMOV_IMMVAL_LSB 5 #define DP_IMM_WIDEMOV_IMMVAL_MSB 21 +#define DP_REG_SRC1_LSB 5 +#define DP_REG_SRC1_MSB 10 +#define DP_REG_SRC2_LSB 16 +#define DP_REG_SRC2_MSB 21 +#define DP_REG_OPTYPE_LSB 28 +#define DP_REG_OPTYPE_MSB 29 +#define DP_REG_ARITHMLOGIC_ARITHMFLAG_LSB 24 +#define DP_REG_ARITHMLOGIC_ARITHMFLAG_MSB 25 +#define DP_REG_ARITHMLOGIC_SHIFTTYPE_LSB 22 +#define DP_REG_ARITHMLOGIC_SHIFTTYPE_MSB 24 +#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_LSB 21 +#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_MSB 22 +#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_LSB 10 +#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_MSB 16 +#define DP_REG_MULTIPLY_SUMMAND_LSB 10 +#define DP_REG_MULTIPLY_SUMMAND_MSB 15 +#define DP_REG_MULTIPLY_NEGPROD_LSB 15 +#define DP_REG_MULTIPLY_NEGPROD_MSB 16 +// Defines the values for fields used for arithmetic/logic DPR instructions +// that are necessary to indicate a multiplication instruction +#define DP_REG_MULTIPLY_PROCESSOP 0 +#define DP_REG_MULTIPLY_ARITHMFLAG 1 +#define DP_REG_MULTIPLY_SHIFTTYPE 0 +#define DP_REG_MULTIPLY_NEGSRC2FLAG 0 + #define SDT_OPTYPE_FLAG_LSB 31 #define SDT_OPTYPE_FLAG_MSB 32 #define SDT_REGTYPE_FLAG_LSB 30