CPU: Added support for PUSH and POP and fixed CALL and RET

This commit is contained in:
(Tim) Efthimis Kritikos 2024-02-12 19:42:27 +00:00
parent 4863db36ee
commit 966a0eee14
4 changed files with 91 additions and 24 deletions

View File

@ -73,6 +73,7 @@
// +-------+----------------------------------+--------------+ // +-------+----------------------------------+--------------+
// | 5'h15 | Call if carry flag is not set | NO | // | 5'h15 | Call if carry flag is not set | NO |
// //
//
// | | | | // | | | |
// +-------+----------------------------------+--------------+ // +-------+----------------------------------+--------------+
// | 5'h0F | MOV immediate to SP | | // | 5'h0F | MOV immediate to SP | |
@ -82,20 +83,24 @@
// //
// //
// INSTRUCTION FORMAT 1 OPCODE NUM: // INSTRUCTION FORMAT 1 OPCODE NUM:
// +-------+----------------------------------+--------------+ // +-------+----------------------------------+--------------+------------+------------+
// | NUM | DESCRIPTION | AFFECT FLAGS | // | NUM | DESCRIPTION | AFFECT FLAGS | SOURCE REG | DEST REG |
// +-------+----------------------------------+--------------+ // +-------+----------------------------------+--------------+------------+------------+
// | 13'd0 | ADD | YES | // | 13'd0 | ADD | YES | operand 1 | operand 1 |
// +-------+----------------------------------+--------------| // +-------+----------------------------------+--------------|------------+------------+
// | 13'd1 | SUBTRACT | YES | // | 13'd1 | SUBTRACT | YES | operand 1 | operand 1 |
// +-------+----------------------------------+--------------| // +-------+----------------------------------+--------------|------------+------------+
// | 13'd2 | SHIFT LEFT | YES | // | 13'd2 | SHIFT LEFT | YES | operand | |
// +-------+----------------------------------+--------------| // +-------+----------------------------------+--------------|------------+------------+
// | 13'd3 | SHIFT RIGHT | YES | // | 13'd3 | SHIFT RIGHT | YES | operand | |
// +-------+----------------------------------+--------------| // +-------+----------------------------------+--------------|------------+------------+
// | 13'd4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | // | 13'd4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | operand 1 | operand 1 |
// +-------+----------------------------------+--------------+ // +-------+----------------------------------+--------------+------------+------------+
// | 13'd5 | HALT | NO | // | 13'd5 | HALT | NO | | |
// +-------+----------------------------------+--------------+------------+------------+
// | 13'd6 | PUSH | NO | operand | |
// +-------+----------------------------------+--------------+------------+------------+
// | 13'd7 | POP | NO | operand | |
// //
// //
// INSTRUCTION FORMAT 2 OPCODE NUM: // INSTRUCTION FORMAT 2 OPCODE NUM:
@ -183,6 +188,12 @@ char *disassemble(uint32_t opcode_be){
case 0x05: case 0x05:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"HALT"); snprintf(ret,MAX_INSTRUCTION_LENGTH,"HALT");
break; break;
case 0x06:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"PUSH %%R%0d",val1);
break;
case 0x07:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"POP %%R%0d",val1);
break;
default: default:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION");
break; break;
@ -407,8 +418,37 @@ uint32_t assemble_line(char *line, struct assembler_context_t *assembler_context
return 0xFFFFFFFF; return 0xFFFFFFFF;
}else if(strncmp(line,"RET",3)==0){ }else if(strncmp(line,"RET",3)==0){
return 0x10000000; return 0x10000000;
}else if(*line==':') }else if(*line==':'){
return 0xFFFFFFF0; return 0xFFFFFFF0;
}else if(strncmp(line,"PUSH",4)==0){
x=4;
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7')
return 0x20060000|(line[x]-'0')<<8;
else
return 0xFFFFFFFF;
}
}else
return 0xFFFFFFFF;
}else if(strncmp(line,"POP",3)==0){
x=3;
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7')
return 0x20070000|(line[x]-'0')<<8;
else
return 0xFFFFFFFF;
}
}else
return 0xFFFFFFFF;
}
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
} }

31
cpu.c
View File

@ -86,9 +86,15 @@ int decode(struct simdata_t *simdata){
simdata->exec_data->in_op2->data=op2; simdata->exec_data->in_op2->data=op2;
switch(opcode){ switch(opcode){
case 5: case 0x05:
simdata->exec_data->EXEC_ACTION=HALT; simdata->exec_data->EXEC_ACTION=HALT;
break; break;
case 0x06:
simdata->exec_data->EXEC_ACTION=PUSH;
break;
case 0x07:
simdata->exec_data->EXEC_ACTION=POP;
break;
default: default:
simdata->exec_data->EXEC_ACTION=EXEC_ALU; simdata->exec_data->EXEC_ACTION=EXEC_ALU;
break; break;
@ -116,6 +122,8 @@ int decode(struct simdata_t *simdata){
case 3: simdata->exec_data->ALU_OP=ALU_SR; break; case 3: simdata->exec_data->ALU_OP=ALU_SR; break;
case 4: simdata->exec_data->ALU_OP=ALU_CMP; break; case 4: simdata->exec_data->ALU_OP=ALU_CMP; break;
case 5: break; case 5: break;
case 6: break;
case 7: break;
default: default:
return 1; return 1;
} }
@ -200,17 +208,17 @@ int exec(struct simdata_t *simdata){
} }
if(condition){ if(condition){
if(simdata->exec_data->EXEC_ACTION==CALL){ if(simdata->exec_data->EXEC_ACTION==CALL){
simdata->RAM[simdata->registers->SP]=simdata->registers->PC; *(uint32_t*)(simdata->RAM+simdata->registers->SP)=simdata->registers->PC;
simdata->registers->SP+=6; simdata->registers->SP+=4;
} }
if(simdata->exec_data->out_op->OP_ADDR==IMMEDIATE) if(simdata->exec_data->out_op->OP_ADDR==IMMEDIATE)
simdata->registers->PC=simdata->exec_data->out_op->data; simdata->registers->PC=(uint32_t)(simdata->exec_data->out_op->data);
else else
return 1; return 1;
} }
break; break;
case RET: case RET:
simdata->registers->SP-=6; simdata->registers->SP-=4;
simdata->registers->PC=simdata->RAM[simdata->registers->SP]; simdata->registers->PC=simdata->RAM[simdata->registers->SP];
break; break;
case EXEC_ALU: case EXEC_ALU:
@ -290,7 +298,18 @@ int exec(struct simdata_t *simdata){
case HALT: case HALT:
simdata->cpu_state=CPU_HALTED; simdata->cpu_state=CPU_HALTED;
break; break;
case PUSH:
simdata->RAM[simdata->registers->SP ]=simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x000000FF;
simdata->RAM[simdata->registers->SP+1]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x0000FF00)>>8;
simdata->RAM[simdata->registers->SP+2]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00FF0000)>>16;
simdata->registers->SP+=4;
break;
case POP:
simdata->registers->SP-=4;
simdata->registers->GPR[simdata->exec_data->in_op1->data]=simdata->RAM[simdata->registers->SP];
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+1]<<8;
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+2]<<16;
break;
} }
add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address); add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address);
return 0; return 0;

4
cpu.h
View File

@ -20,7 +20,9 @@ enum EXEC_ACTION_t {
CALL, CALL,
NOP, NOP,
HALT, HALT,
RET RET,
PUSH,
POP
}; };
enum ALU_OP_t { enum ALU_OP_t {

View File

@ -1,13 +1,19 @@
MOV $123456,%SP MOV $FF0000,%SP
MOV $0x0001,%R0l MOV $0x0001,%R0l
MOV $0x0000,%R0h MOV $0x0000,%R0h
MOV $0x0000,%R1l MOV $0xBEEF,%R1l
MOV $0x0000,%R1h MOV $0x0000,%R1h
CALL $SUBROUTINE CALL $SUBROUTINE
CALL $SUBROUTINE CALL $SUBROUTINE
CALL $SUBROUTINE CALL $SUBROUTINE
CALL $SUBROUTINE2
JMP $END JMP $END
:SUBROUTINE :SUBROUTINE
PUSH %R1
ADD %R0,%R1
POP %R1
RET
:SUBROUTINE2
ADD %R0,%R1 ADD %R0,%R1
RET RET
:END :END