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
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
AXIL_PROGS=auxiliary_progs/stl_to_source_code

View File

@ -121,7 +121,7 @@
// +-------+---------------------------------------------+--------------+------------+------------+
// | 14'h11| INC | YES | operand | |
// +-------+---------------------------------------------+--------------+------------+------------+
// | 14'h12| MOV | YES | operand | |
// | 14'h12| MOV register to register | YES | operand | |
//
//
// INSTRUCTION FORMAT 2 OPCODE NUM:
@ -246,7 +246,11 @@ char *disassemble(uint32_t opcode_be){
snprintf(ret,MAX_INSTRUCTION_LENGTH,"INC %%R%0d",val1);
break;
case 0x12:
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;
default:
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;
}else
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
return -2;
}else if(line[x]=='('){

35
cpu.c
View File

@ -340,6 +340,7 @@ int exec(struct simdata_t *simdata){
if(simdata->exec_data->valid==0)
return 0;
int condition=0;
#define SANITY_CHECK(x) { if(x>0x0F){return 1;} }
switch(simdata->exec_data->EXEC_ACTION){
case CALL:
case JUMP:
@ -385,6 +386,8 @@ int exec(struct simdata_t *simdata){
uint32_t result;
switch(simdata->exec_data->ALU_OP){
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] +
simdata->registers->GPR[simdata->exec_data->in_op2->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
@ -395,6 +398,8 @@ int exec(struct simdata_t *simdata){
break;
case ALU_SUB:
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] -
simdata->registers->GPR[simdata->exec_data->in_op1->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
@ -404,6 +409,7 @@ int exec(struct simdata_t *simdata){
break;
case ALU_SL:
SANITY_CHECK(simdata->exec_data->in_op1->data);
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;
@ -412,6 +418,7 @@ int exec(struct simdata_t *simdata){
break;
case ALU_SR:
SANITY_CHECK(simdata->exec_data->in_op1->data);
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;
@ -420,6 +427,8 @@ int exec(struct simdata_t *simdata){
break;
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])/
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -427,6 +436,8 @@ int exec(struct simdata_t *simdata){
break;
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])*
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data]));
@ -434,6 +445,8 @@ int exec(struct simdata_t *simdata){
break;
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])+
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -441,6 +454,8 @@ int exec(struct simdata_t *simdata){
break;
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])-
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
@ -448,18 +463,21 @@ int exec(struct simdata_t *simdata){
break;
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])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break;
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])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break;
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;
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;
@ -468,6 +486,7 @@ int exec(struct simdata_t *simdata){
break;
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;
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;
@ -488,6 +507,7 @@ int exec(struct simdata_t *simdata){
switch(simdata->exec_data->out_op->OP_ADDR){
case REGISTERL:
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->exec_data->in_op1->data);
simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
@ -500,6 +520,7 @@ int exec(struct simdata_t *simdata){
break;
case REGISTERH:
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->exec_data->in_op1->data)<<16);
simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
@ -526,13 +547,23 @@ int exec(struct simdata_t *simdata){
return 1;
}
}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 ){
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];
}else
return 2;
}else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){
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];
}else
@ -540,6 +571,8 @@ int exec(struct simdata_t *simdata){
break;
case REGISTER_IND:
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];
if(simdata->registers->GPR[simdata->exec_data->out_op->data]==0x00FFFFFC)
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;
break;
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+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;
@ -569,6 +603,7 @@ int exec(struct simdata_t *simdata){
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
break;
case POP:
SANITY_CHECK(simdata->exec_data->in_op1->data);
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;

5
programs/quicksort.asm Normal file
View File

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