CPU,ASM: Added support for MOV %SP,%Rx

This commit is contained in:
(Tim) Efthimis Kritikos 2024-05-02 21:51:37 +01:00
parent 9fbc6bceab
commit 222acaccb3
4 changed files with 73 additions and 4 deletions

View File

@ -5,7 +5,7 @@ USE_AALIB=1
OBJECT_FILES=gui.o gui_display.o gui_internals.o main.o simdata.o assembly.o cpu.o OBJECT_FILES=gui.o gui_display.o gui_internals.o main.o simdata.o assembly.o cpu.o
MAIN_ROM=programs/utah_teapot.rom MAIN_ROM=programs/utah_teapot.rom
ROMS=test.rom ${MAIN_ROM} programs/cube.rom ROMS=test.rom ${MAIN_ROM} programs/cube.rom programs/quicksort.rom
UTAH_TEAPOT_ASCII_STL=assets/Utah_teapot_ascii.stl UTAH_TEAPOT_ASCII_STL=assets/Utah_teapot_ascii.stl
AXIL_PROGS=auxiliary_progs/stl_to_source_code AXIL_PROGS=auxiliary_progs/stl_to_source_code

View File

@ -121,7 +121,7 @@
// +-------+---------------------------------------------+--------------+------------+------------+ // +-------+---------------------------------------------+--------------+------------+------------+
// | 14'h11| INC | YES | operand | | // | 14'h11| INC | YES | operand | |
// +-------+---------------------------------------------+--------------+------------+------------+ // +-------+---------------------------------------------+--------------+------------+------------+
// | 14'h12| MOV | YES | operand | | // | 14'h12| MOV register to register | YES | operand | |
// //
// //
// INSTRUCTION FORMAT 2 OPCODE NUM: // INSTRUCTION FORMAT 2 OPCODE NUM:
@ -246,7 +246,11 @@ char *disassemble(uint32_t opcode_be){
snprintf(ret,MAX_INSTRUCTION_LENGTH,"INC %%R%0d",val1); snprintf(ret,MAX_INSTRUCTION_LENGTH,"INC %%R%0d",val1);
break; break;
case 0x12: case 0x12:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV %%R%0d,%%R%0d",val1,val2); if(val1==0xFF){ //make it a global thing where every time we reference a register, 0xFF will refer to the SP since it seems to have become a standard
snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV %%SP,%%R%0d",val2);
}else{
snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV %%R%0d,%%R%0d",val1,val2);
}
break; break;
default: default:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION");
@ -619,6 +623,31 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context)
return -2; return -2;
}else }else
return -2; return -2;
}else if(line[x]=='S'){
x++;
if(line[x]=='P'){
x++;
while(line[x]==' ')x++;
if(line[x]==','){
x++;
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7'){
r1=line[x]-'0';
return 0x20120000|0xFF<<8|(r1&0xFF);
}else
return -2;
}else
return -2;
}else
return -2;
}else
return -2;
}else
return -2;
}else }else
return -2; return -2;
}else if(line[x]=='('){ }else if(line[x]=='('){

37
cpu.c
View File

@ -340,6 +340,7 @@ int exec(struct simdata_t *simdata){
if(simdata->exec_data->valid==0) if(simdata->exec_data->valid==0)
return 0; return 0;
int condition=0; int condition=0;
#define SANITY_CHECK(x) { if(x>0x0F){return 1;} }
switch(simdata->exec_data->EXEC_ACTION){ switch(simdata->exec_data->EXEC_ACTION){
case CALL: case CALL:
case JUMP: case JUMP:
@ -385,6 +386,8 @@ int exec(struct simdata_t *simdata){
uint32_t result; uint32_t result;
switch(simdata->exec_data->ALU_OP){ switch(simdata->exec_data->ALU_OP){
case ALU_ADD: case ALU_ADD:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = simdata->registers->GPR[simdata->exec_data->in_op1->data] + result = simdata->registers->GPR[simdata->exec_data->in_op1->data] +
simdata->registers->GPR[simdata->exec_data->in_op2->data]; simdata->registers->GPR[simdata->exec_data->in_op2->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
@ -395,6 +398,8 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_SUB: case ALU_SUB:
case ALU_CMP: case ALU_CMP:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = simdata->registers->GPR[simdata->exec_data->in_op2->data] - result = simdata->registers->GPR[simdata->exec_data->in_op2->data] -
simdata->registers->GPR[simdata->exec_data->in_op1->data]; simdata->registers->GPR[simdata->exec_data->in_op1->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
@ -404,6 +409,7 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_SL: case ALU_SL:
SANITY_CHECK(simdata->exec_data->in_op1->data);
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x80000000)?2:0); ((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x80000000)?2:0);
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]<<1; result = simdata->registers->GPR[simdata->exec_data->in_op1->data]<<1;
@ -412,6 +418,7 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_SR: case ALU_SR:
SANITY_CHECK(simdata->exec_data->in_op1->data);
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0); ((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0);
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1; result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1;
@ -420,6 +427,8 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_FDIV: case ALU_FDIV:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])/ result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])/
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -427,6 +436,8 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_FMUL: case ALU_FMUL:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])* result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])*
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data]));
@ -434,6 +445,8 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_FADD: case ALU_FADD:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])+ result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])+
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -441,6 +454,8 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_FSUB: case ALU_FSUB:
SANITY_CHECK(simdata->exec_data->in_op1->data);
SANITY_CHECK(simdata->exec_data->in_op2->data);
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])- result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])-
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -448,18 +463,21 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_FSIN: case ALU_FSIN:
SANITY_CHECK(simdata->exec_data->in_op1->data);
result = ieee754_float_to_uint32(sinf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]))); result = ieee754_float_to_uint32(sinf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX]; simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break; break;
case ALU_FCOS: case ALU_FCOS:
SANITY_CHECK(simdata->exec_data->in_op1->data);
result = ieee754_float_to_uint32(cosf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]))); result = ieee754_float_to_uint32(cosf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX]; simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break; break;
case ALU_DEC: case ALU_DEC:
SANITY_CHECK(simdata->exec_data->in_op1->data);
*(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])-1; *(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])-1;
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| 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; (simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
@ -468,6 +486,7 @@ int exec(struct simdata_t *simdata){
break; break;
case ALU_INC: case ALU_INC:
SANITY_CHECK(simdata->exec_data->in_op1->data);
*(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])+1; *(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])+1;
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| 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; (simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
@ -488,6 +507,7 @@ int exec(struct simdata_t *simdata){
switch(simdata->exec_data->out_op->OP_ADDR){ switch(simdata->exec_data->out_op->OP_ADDR){
case REGISTERL: case REGISTERL:
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){ if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){
SANITY_CHECK(simdata->exec_data->out_op->data);
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->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF&
simdata->exec_data->in_op1->data); simdata->exec_data->in_op1->data);
simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX]; simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
@ -500,6 +520,7 @@ int exec(struct simdata_t *simdata){
break; break;
case REGISTERH: case REGISTERH:
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){ if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){
SANITY_CHECK(simdata->exec_data->out_op->data);
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->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF&
simdata->exec_data->in_op1->data)<<16); simdata->exec_data->in_op1->data)<<16);
simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX]; simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
@ -526,13 +547,23 @@ int exec(struct simdata_t *simdata){
return 1; return 1;
} }
}else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER_IND){ }else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER_IND){
SANITY_CHECK(simdata->exec_data->out_op->data);
SANITY_CHECK(simdata->exec_data->in_op1->data);
if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ){ if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ){
simdata->registers->GPR[simdata->exec_data->out_op->data]=*(uint32_t*)(simdata->RAM+simdata->registers->GPR[simdata->exec_data->in_op1->data]); simdata->registers->GPR[simdata->exec_data->out_op->data]=*(uint32_t*)(simdata->RAM+simdata->registers->GPR[simdata->exec_data->in_op1->data]);
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX]; simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
}else }else
return 2; return 2;
}else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){ }else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){
simdata->registers->GPR[simdata->exec_data->out_op->data]=simdata->registers->GPR[simdata->exec_data->in_op1->data]; if(simdata->exec_data->in_op1->data==0xFF){
/*Reading from SP*/
SANITY_CHECK(simdata->exec_data->out_op->data);
simdata->registers->GPR[simdata->exec_data->out_op->data]=simdata->registers->SP;
}else{
SANITY_CHECK(simdata->exec_data->out_op->data);
SANITY_CHECK(simdata->exec_data->in_op1->data);
simdata->registers->GPR[simdata->exec_data->out_op->data]=simdata->registers->GPR[simdata->exec_data->in_op1->data];
}
simdata->exec_data->cycles_left=delay_values[RR_MOVE_INDX]; simdata->exec_data->cycles_left=delay_values[RR_MOVE_INDX];
}else }else
@ -540,6 +571,8 @@ int exec(struct simdata_t *simdata){
break; break;
case REGISTER_IND: case REGISTER_IND:
if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){ if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){
SANITY_CHECK(simdata->exec_data->out_op->data);
SANITY_CHECK(simdata->exec_data->in_op1->data);
*(uint32_t*)(simdata->RAM+(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x00FFFFFF))=simdata->registers->GPR[simdata->exec_data->in_op1->data]; *(uint32_t*)(simdata->RAM+(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x00FFFFFF))=simdata->registers->GPR[simdata->exec_data->in_op1->data];
if(simdata->registers->GPR[simdata->exec_data->out_op->data]==0x00FFFFFC) if(simdata->registers->GPR[simdata->exec_data->out_op->data]==0x00FFFFFC)
if(terminal_output(simdata->registers->GPR[simdata->exec_data->in_op1->data],simdata)) if(terminal_output(simdata->registers->GPR[simdata->exec_data->in_op1->data],simdata))
@ -561,6 +594,7 @@ int exec(struct simdata_t *simdata){
simdata->cpu_state=CPU_HALTED; simdata->cpu_state=CPU_HALTED;
break; break;
case PUSH: case PUSH:
SANITY_CHECK(simdata->exec_data->in_op1->data);
simdata->RAM[simdata->registers->SP ]=simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x000000FF; 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+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->RAM[simdata->registers->SP+2]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00FF0000)>>16;
@ -569,6 +603,7 @@ int exec(struct simdata_t *simdata){
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX]; simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
break; break;
case POP: case POP:
SANITY_CHECK(simdata->exec_data->in_op1->data);
simdata->registers->SP-=4; 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];
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+1]<<8;

5
programs/quicksort.asm Normal file
View File

@ -0,0 +1,5 @@
MOV $0xFF0000,%SP
MOV %SP,%R2
PUSH %R0
MOV %SP,%R2
HALT