diff --git a/Makefile b/Makefile index 7b65fe3..30b7289 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/assembly.c b/assembly.c index 8a6980b..107ff8f 100644 --- a/assembly.c +++ b/assembly.c @@ -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: - 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; 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]=='('){ diff --git a/cpu.c b/cpu.c index f84901e..ace01f4 100644 --- a/cpu.c +++ b/cpu.c @@ -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){ - 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]; }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; diff --git a/programs/quicksort.asm b/programs/quicksort.asm new file mode 100644 index 0000000..0b3b919 --- /dev/null +++ b/programs/quicksort.asm @@ -0,0 +1,5 @@ +MOV $0xFF0000,%SP +MOV %SP,%R2 +PUSH %R0 +MOV %SP,%R2 +HALT