Implementing instruction decoder

This commit is contained in:
2020-08-07 20:04:11 -05:00
parent ddbde757ae
commit 0bf2d80a04
5 changed files with 504 additions and 0 deletions
+137
View File
@@ -17,6 +17,143 @@
#define CPU_DUMP 6
#define CPU_RESTORE 7
/* Intermediate instruction IDs */
#define BITSTRING -2
#define FLOATENDO -3
/* Opcode lookup table */
static const int8_t LOOKUP_OPCODE[] = {
VUE_MOV_REG, 1, VUE_ADD_REG, 1, VUE_SUB , 1, VUE_CMP_REG, 1,
VUE_SHL_REG, 1, VUE_SHR_REG, 1, VUE_JMP , 1, VUE_SAR_REG, 1,
VUE_MUL , 1, VUE_DIV , 1, VUE_MULU , 1, VUE_DIVU , 1,
VUE_OR , 1, VUE_AND , 1, VUE_XOR , 1, VUE_NOT , 1,
VUE_MOV_IMM,-2, VUE_ADD_IMM,-2, VUE_SETF , 2, VUE_CMP_IMM,-2,
VUE_SHL_IMM, 2, VUE_SHR_IMM, 2, VUE_CLI , 2, VUE_SAR_IMM, 2,
VUE_TRAP , 2, VUE_RETI , 2, VUE_HALT , 2, VUE_ILLEGAL, 0,
VUE_LDSR , 2, VUE_STSR , 2, VUE_SEI , 2, BITSTRING , 2,
VUE_BCOND , 3, VUE_BCOND , 3, VUE_BCOND , 3, VUE_BCOND , 3,
VUE_BCOND , 3, VUE_BCOND , 3, VUE_BCOND , 3, VUE_BCOND , 3,
VUE_MOVEA ,-5, VUE_ADDI ,-5, VUE_JR , 4, VUE_JAL , 4,
VUE_ORI , 5, VUE_ANDI , 5, VUE_XORI , 5, VUE_MOVHI , 5,
VUE_LD_B , 6, VUE_LD_H , 6, VUE_ILLEGAL, 0, VUE_LD_W , 6,
VUE_ST_B , 6, VUE_ST_H , 6, VUE_ILLEGAL, 0, VUE_ST_W , 6,
VUE_IN_B , 6, VUE_IN_H , 6, VUE_CAXI , 6, VUE_IN_W , 6,
VUE_OUT_B , 6, VUE_OUT_H , 6, FLOATENDO , 7, VUE_OUT_W , 6
};
/* Bit string lookup table */
static const int8_t LOOKUP_BITSTRING[] = {
VUE_SCH0BSU, VUE_SCH0BSD, VUE_SCH1BSU, VUE_SCH1BSD,
VUE_ILLEGAL, VUE_ILLEGAL, VUE_ILLEGAL, VUE_ILLEGAL,
VUE_ORBSU , VUE_ANDBSU , VUE_XORBSU , VUE_MOVBSU ,
VUE_ORNBSU , VUE_ANDNBSU, VUE_XORNBSU, VUE_XORNBSU
};
/* Floating-point and Nintendo lookup table */
static const int8_t LOOKUP_FLOATENDO[] = {
VUE_CMPF_S , VUE_ILLEGAL, VUE_CVT_WS , VUE_CVT_SW ,
VUE_ADDF_S , VUE_SUBF_S , VUE_MULF_S , VUE_DIVF_S ,
VUE_XB , VUE_XH , VUE_REV , VUE_TRNC_SW,
VUE_MPYHW , VUE_ILLEGAL, VUE_ILLEGAL, VUE_ILLEGAL
};
/*****************************************************************************
* Instruction Functions *
*****************************************************************************/
/* Decoder for Format I */
static void cpuFormatI(VUE_INST *inst) {
inst->reg2 = inst->bits >> 21 & 31;
inst->reg1 = inst->bits >> 16 & 31;
}
/* Decoder for Format II */
static void cpuFormatII(VUE_INST *inst, int extend) {
int32_t imm = inst->bits >> 16 & 31;
inst->reg2 = inst->bits >> 21 & 31;
inst->imm = extend ? SIGN_EXTEND(5, imm) : imm;
}
/* Decoder for Format III */
static void cpuFormatIII(VUE_INST *inst) {
int32_t disp = inst->bits >> 16 & 0x1FF;
inst->opcode = 0x20;
inst->cond = inst->bits >> 25 & 15;
inst->disp = SIGN_EXTEND(9, disp);
}
/* Decoder for Format IV */
static void cpuFormatIV(VUE_INST *inst) {
int32_t disp = inst->bits & 0x3FFFFFF;
inst->disp = SIGN_EXTEND(26, disp);
}
/* Decoder for Format V */
static void cpuFormatV(VUE_INST *inst, int extend) {
int32_t imm = inst->bits & 0xFFFF;
inst->reg2 = inst->bits >> 21 & 31;
inst->reg1 = inst->bits >> 16 & 31;
inst->imm = extend ? SIGN_EXTEND(16, imm) : imm;
}
/* Decoder for Format VI */
static void cpuFormatVI(VUE_INST *inst) {
int32_t disp = inst->bits & 0xFFFF;
inst->reg2 = inst->bits >> 21 & 31;
inst->reg1 = inst->bits >> 16 & 31;
inst->disp = SIGN_EXTEND(16, disp);
}
/* Decoder for Format VII */
static void cpuFormatVII(VUE_INST *inst) {
inst->reg2 = inst->bits >> 21 & 31;
inst->reg1 = inst->bits >> 16 & 31;
inst->subopcode = inst->bits >> 10 & 63;
}
/* Decode an instruction from its binary encoding */
static void cpuDecode(VUE_INST *inst, int32_t bits) {
int extend;
/* Configure instance fields */
inst->bits = bits;
inst->opcode = bits >> 26 & 63;
inst->id = inst->opcode << 1 | 1;
inst->format = LOOKUP_OPCODE[inst->id + 1];
inst->id = LOOKUP_OPCODE[inst->id];
/* Determine whether to sign-extend the immediate operand */
if ((extend = inst->format < 0))
inst->format = -inst->format;
/* Determine the size in bytes of the instruction */
inst->size = inst->format < 4 ? 2 : 4;
if (inst->size == 2)
inst->bits &= 0xFFFF0000;
/* Decode by format */
switch (inst->format) {
case 0: return; /* Nothing to do */
case 1: cpuFormatI (inst ); break;
case 2: cpuFormatII (inst, extend); break;
case 3: cpuFormatIII(inst ); break;
case 4: cpuFormatIV (inst ); break;
case 5: cpuFormatV (inst, extend); break;
case 6: cpuFormatVI (inst ); break;
case 7: cpuFormatVII(inst ); break;
}
/* Resolve final instruction ID by subopcode */
if (inst->id == FLOATENDO)
inst->id = inst->subopcode >= 16 ? VUE_ILLEGAL :
LOOKUP_FLOATENDO[inst->subopcode];
else if (inst->id == BITSTRING)
inst->id = inst->imm >= 16 ? VUE_ILLEGAL :
LOOKUP_BITSTRING[inst->imm ];
}
/*****************************************************************************
+96
View File
@@ -54,6 +54,85 @@ extern "C" {
#define VUE_SP 3
#define VUE_TP 5
/* Instruction IDs */
#define VUE_ILLEGAL -1
#define VUE_ADD_IMM 0
#define VUE_ADD_REG 1
#define VUE_ADDF_S 2
#define VUE_ADDI 3
#define VUE_AND 4
#define VUE_ANDBSU 5
#define VUE_ANDI 6
#define VUE_ANDNBSU 7
#define VUE_BCOND 8
#define VUE_CAXI 9
#define VUE_CLI 10
#define VUE_CMP_IMM 11
#define VUE_CMP_REG 12
#define VUE_CMPF_S 13
#define VUE_CVT_SW 14
#define VUE_CVT_WS 15
#define VUE_DIV 16
#define VUE_DIVF_S 17
#define VUE_DIVU 18
#define VUE_HALT 19
#define VUE_IN_B 20
#define VUE_IN_H 21
#define VUE_IN_W 22
#define VUE_JAL 23
#define VUE_JMP 24
#define VUE_JR 25
#define VUE_LD_B 26
#define VUE_LD_H 27
#define VUE_LD_W 28
#define VUE_LDSR 29
#define VUE_MOV_IMM 30
#define VUE_MOV_REG 31
#define VUE_MOVBSU 32
#define VUE_MOVEA 33
#define VUE_MOVHI 34
#define VUE_MPYHW 35
#define VUE_MUL 36
#define VUE_MULF_S 37
#define VUE_MULU 38
#define VUE_NOT 39
#define VUE_NOTBSU 40
#define VUE_OR 41
#define VUE_ORBSU 42
#define VUE_ORI 43
#define VUE_ORNBSU 44
#define VUE_OUT_B 45
#define VUE_OUT_H 46
#define VUE_OUT_W 47
#define VUE_RETI 48
#define VUE_REV 49
#define VUE_SAR_IMM 50
#define VUE_SAR_REG 51
#define VUE_SCH0BSD 52
#define VUE_SCH0BSU 53
#define VUE_SCH1BSD 54
#define VUE_SCH1BSU 55
#define VUE_SEI 56
#define VUE_SETF 57
#define VUE_SHL_IMM 58
#define VUE_SHL_REG 59
#define VUE_SHR_IMM 60
#define VUE_SHR_REG 61
#define VUE_ST_B 62
#define VUE_ST_H 63
#define VUE_ST_W 64
#define VUE_STSR 65
#define VUE_SUB 66
#define VUE_SUBF_S 67
#define VUE_TRAP 68
#define VUE_TRNC_SW 69
#define VUE_XB 70
#define VUE_XH 71
#define VUE_XOR 72
#define VUE_XORBSU 73
#define VUE_XORI 74
#define VUE_XORNBSU 75
/*****************************************************************************
@@ -63,6 +142,21 @@ extern "C" {
/* Boolean */
typedef int vbool;
/* Instruction state */
typedef struct {
int32_t bits; /* Binary encoding */
int32_t disp; /* Displacement for jumps and branches */
int32_t imm; /* Immediate operand */
uint8_t cond; /* Condition for Bcond */
int8_t format; /* Binary format */
int8_t id; /* Library-specific identifier */
uint8_t opcode; /* Instruction opcode */
uint8_t reg1; /* Source/right register */
uint8_t reg2; /* Destination/left register */
uint8_t size; /* Number of bytes in encoding */
uint8_t subopcode; /* Instruction subopcode */
} VUE_INST;
/* Emulation state */
typedef struct {
@@ -127,6 +221,8 @@ typedef struct {
uint16_t ecr_fecc; /* Fatal Error Cause Code */
} cpu;
/* Additional fields */
VUE_INST inst; /* Instruction state */
} VUE;
+11
View File
@@ -2,6 +2,17 @@
#include <vue.h>
/*****************************************************************************
* Macros *
*****************************************************************************/
/* Sign-extend a value */
#define SIGN_EXTEND(bits, value) \
((value) & 1 << (bits - 1) ? (value) | (~(1 << bits) + 1) : (value))
/*****************************************************************************
* Constants *
*****************************************************************************/