CPU,ASM: Added support for MOV %SP,%Rx
This commit is contained in:
parent
9fbc6bceab
commit
222acaccb3
2
Makefile
2
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
|
||||
|
||||
|
33
assembly.c
33
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]=='('){
|
||||
|
37
cpu.c
37
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;
|
||||
|
5
programs/quicksort.asm
Normal file
5
programs/quicksort.asm
Normal file
@ -0,0 +1,5 @@
|
||||
MOV $0xFF0000,%SP
|
||||
MOV %SP,%R2
|
||||
PUSH %R0
|
||||
MOV %SP,%R2
|
||||
HALT
|
Loading…
Reference in New Issue
Block a user