CPU: Added support for the add,sub,sl,sr and cmp instructions
This commit is contained in:
parent
e86bf547cb
commit
1dcc69ba50
123
cpu.c
123
cpu.c
@ -25,7 +25,7 @@ void free_decode_data(struct decode_data_t *tofree){
|
|||||||
free(tofree);
|
free(tofree);
|
||||||
}
|
}
|
||||||
int decode(struct simdata_t *simdata){
|
int decode(struct simdata_t *simdata){
|
||||||
uint16_t opcode;
|
uint16_t opcode,op1,op2,imm;
|
||||||
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
|
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
|
||||||
case 0:
|
case 0:
|
||||||
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
|
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
|
||||||
@ -40,10 +40,66 @@ int decode(struct simdata_t *simdata){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
return 1;
|
opcode=(simdata->decode_data->in_bytecode&0x1FFF0000)>>16;
|
||||||
|
op1=(simdata->decode_data->in_bytecode&0x0000FF00)>>8;
|
||||||
|
op2=(simdata->decode_data->in_bytecode&0x000000FF);
|
||||||
|
|
||||||
|
|
||||||
|
simdata->exec_data->in_op1->OP_ADDR=REGISTER;
|
||||||
|
simdata->exec_data->in_op1->data=op1;
|
||||||
|
|
||||||
|
simdata->exec_data->in_op2->OP_ADDR=REGISTER;
|
||||||
|
simdata->exec_data->in_op2->data=op2;
|
||||||
|
|
||||||
|
simdata->exec_data->EXEC_ACTION=EXEC_ALU;
|
||||||
|
|
||||||
|
switch(opcode){
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 4:
|
||||||
|
simdata->exec_data->out_op->OP_ADDR=REGISTER;
|
||||||
|
simdata->exec_data->out_op->data=op2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
case 3:
|
||||||
|
simdata->exec_data->out_op->OP_ADDR=REGISTER;
|
||||||
|
simdata->exec_data->out_op->data=op1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch(opcode){
|
||||||
|
case 0: simdata->exec_data->ALU_OP=ALU_ADD; break;
|
||||||
|
case 1: simdata->exec_data->ALU_OP=ALU_SUB; break;
|
||||||
|
case 2: simdata->exec_data->ALU_OP=ALU_SL; break;
|
||||||
|
case 3: simdata->exec_data->ALU_OP=ALU_SR; break;
|
||||||
|
case 4: simdata->exec_data->ALU_OP=ALU_CMP; break;
|
||||||
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
|
||||||
|
op1=(simdata->decode_data->in_bytecode&0x00FF0000)>>16;
|
||||||
|
imm=(simdata->decode_data->in_bytecode&0x0000FFFF);
|
||||||
|
switch(opcode){
|
||||||
|
case 0:
|
||||||
|
simdata->exec_data->EXEC_ACTION=MOVE;
|
||||||
|
simdata->exec_data->in_op1->OP_ADDR=IMMEDIATE;
|
||||||
|
simdata->exec_data->in_op1->data=imm;
|
||||||
|
|
||||||
|
simdata->exec_data->out_op->OP_ADDR=REGISTERL;
|
||||||
|
simdata->exec_data->out_op->data=op1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
simdata->exec_data->EXEC_ACTION=MOVE;
|
||||||
|
simdata->exec_data->in_op1->OP_ADDR=IMMEDIATE;
|
||||||
|
simdata->exec_data->in_op1->data=imm;
|
||||||
|
|
||||||
|
simdata->exec_data->out_op->OP_ADDR=REGISTERH;
|
||||||
|
simdata->exec_data->out_op->data=op1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
@ -94,8 +150,67 @@ int exec(struct simdata_t *simdata){
|
|||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case EXEC_ALU:
|
case EXEC_ALU:
|
||||||
|
if( simdata->exec_data->in_op1->OP_ADDR==REGISTER &&
|
||||||
|
simdata->exec_data->in_op2->OP_ADDR==REGISTER &&
|
||||||
|
simdata->exec_data->out_op->OP_ADDR==REGISTER ){
|
||||||
|
|
||||||
|
uint32_t result;
|
||||||
|
switch(simdata->exec_data->ALU_OP){
|
||||||
|
case ALU_ADD:
|
||||||
|
result = simdata->registers->GPR[simdata->exec_data->in_op1->data] +
|
||||||
|
simdata->registers->GPR[simdata->exec_data->in_op2->data];
|
||||||
|
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
|
||||||
|
(simdata->registers->GPR[simdata->exec_data->out_op->data] < simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
|
||||||
|
break;
|
||||||
|
case ALU_SUB:
|
||||||
|
case ALU_CMP:
|
||||||
|
result = simdata->registers->GPR[simdata->exec_data->in_op1->data] -
|
||||||
|
simdata->registers->GPR[simdata->exec_data->in_op2->data];
|
||||||
|
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
|
||||||
|
(simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
|
||||||
|
break;
|
||||||
|
case ALU_SL:
|
||||||
|
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
|
||||||
|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x80000000)?2:0);
|
||||||
|
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]<<1;
|
||||||
|
break;
|
||||||
|
case ALU_SR:
|
||||||
|
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
|
||||||
|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0);
|
||||||
|
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFE)|(result==0);
|
||||||
|
if(simdata->exec_data->ALU_OP!=ALU_CMP)
|
||||||
|
simdata->registers->GPR[simdata->exec_data->out_op->data]=result;
|
||||||
|
}else
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case MOVE:
|
||||||
|
switch(simdata->exec_data->out_op->OP_ADDR){
|
||||||
|
case REGISTERL:
|
||||||
|
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE)
|
||||||
|
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF&
|
||||||
|
simdata->exec_data->in_op1->data);
|
||||||
|
else
|
||||||
|
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF&
|
||||||
|
simdata->registers->GPR[simdata->exec_data->in_op1->data]);
|
||||||
|
break;
|
||||||
|
case REGISTERH:
|
||||||
|
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE)
|
||||||
|
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF&
|
||||||
|
simdata->exec_data->in_op1->data)<<16);
|
||||||
|
else
|
||||||
|
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF&
|
||||||
|
simdata->registers->GPR[simdata->exec_data->in_op1->data])<<16);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +222,8 @@ int state=0;
|
|||||||
|
|
||||||
int cpu_cycle_clock(struct simdata_t *simdata){
|
int cpu_cycle_clock(struct simdata_t *simdata){
|
||||||
switch(state){
|
switch(state){
|
||||||
case 0: if( fetch(simdata) ) return 1; break;
|
case 0: if( fetch(simdata) ) return 3; break;
|
||||||
case 1: if( decode(simdata) ) return 1; break;
|
case 1: if( decode(simdata) ) return 2; break;
|
||||||
case 2: if( exec(simdata) ) return 1; break;
|
case 2: if( exec(simdata) ) return 1; break;
|
||||||
}
|
}
|
||||||
if(state==2)
|
if(state==2)
|
||||||
|
3
cpu.h
3
cpu.h
@ -14,6 +14,7 @@ struct decode_data_t{
|
|||||||
///// EXEC DATA STRUCTURES ///////
|
///// EXEC DATA STRUCTURES ///////
|
||||||
enum EXEC_ACTION_t {
|
enum EXEC_ACTION_t {
|
||||||
EXEC_ALU,
|
EXEC_ALU,
|
||||||
|
MOVE,
|
||||||
JUMP
|
JUMP
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ enum ALU_OP_t {
|
|||||||
enum OP_ADDR_t {
|
enum OP_ADDR_t {
|
||||||
IMMEDIATE,
|
IMMEDIATE,
|
||||||
REGISTER,
|
REGISTER,
|
||||||
|
REGISTERL, //low word
|
||||||
|
REGISTERH, //high word
|
||||||
};
|
};
|
||||||
|
|
||||||
struct exec_op_t {
|
struct exec_op_t {
|
||||||
|
15
main.c
15
main.c
@ -170,11 +170,24 @@ int main(int argc, char* argd[] ){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cpu_cycle_clock(simdata)){
|
int ret;
|
||||||
|
if((ret=cpu_cycle_clock(simdata))){
|
||||||
cpu_simdata_free(simdata);
|
cpu_simdata_free(simdata);
|
||||||
free_simdata(simdata);
|
free_simdata(simdata);
|
||||||
end_gui();
|
end_gui();
|
||||||
|
switch(ret){
|
||||||
|
case 1:
|
||||||
printf("Failed to execute instruction\n");
|
printf("Failed to execute instruction\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("Failed to decode instruction\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("Failed to fetch instruction\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unkown CPU failure\n");
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user