diff --git a/assembly.c b/assembly.c index 872cb06..d101581 100644 --- a/assembly.c +++ b/assembly.c @@ -85,15 +85,15 @@ // +-------+---------------------------------------------+--------------+------------+------------+ // | NUM | DESCRIPTION | AFFECT FLAGS | SOURCE REG | DEST REG | // +-------+---------------------------------------------+--------------+------------+------------+ -// | 13'h0 | ADD | YES | operand 1 | operand 1 | +// | 13'h0 | ADD | YES | operand 1 | operand 2 | // +-------+---------------------------------------------+--------------|------------+------------+ -// | 13'h1 | SUBTRACT | YES | operand 1 | operand 1 | +// | 13'h1 | SUBTRACT | YES | operand 1 | operand 2 | // +-------+---------------------------------------------+--------------|------------+------------+ // | 13'h2 | SHIFT LEFT | YES | operand | | // +-------+---------------------------------------------+--------------|------------+------------+ // | 13'h3 | SHIFT RIGHT | YES | operand | | // +-------+---------------------------------------------+--------------|------------+------------+ -// | 13'h4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | operand 1 | operand 1 | +// | 13'h4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | operand 1 | operand 2 | // +-------+---------------------------------------------+--------------+------------+------------+ // | 13'h5 | HALT | NO | | | // +-------+---------------------------------------------+--------------+------------+------------+ @@ -104,6 +104,10 @@ // | 13'h8 | MOV register to indirect register ( 32-bit )| NO | operand | (operand) | // +-------+---------------------------------------------+--------------+------------+------------+ // | 13'h9 | MOV indirect register to register ( 32-bit )| NO | (operand) | operand | +// +-------+---------------------------------------------+--------------+------------+------------+ +// | 14'hA | Floating point devision | YES | operand | operand | +// +-------+---------------------------------------------+--------------+------------+------------+ +// | 14'hB | Floating point Multiplication | YES | operand 1 | operand 2 | // // // INSTRUCTION FORMAT 2 OPCODE NUM: @@ -203,6 +207,12 @@ char *disassemble(uint32_t opcode_be){ case 0x09: snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV (%%R%0d),%%R%0d",val1,val2); break; + case 0x0A: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"FDIV %%R%0d,%%R%0d",val1,val2); + break; + case 0x0B: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"FMUL %%R%0d,%%R%0d",val1,val2); + break; default: snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); break; @@ -335,6 +345,14 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context) x=3; opcode=0x2004; params=2; + }else if(strncmp(line,"FDIV ",5)==0){ + x=5; + opcode=0x200A; + params=2; + }else if(strncmp(line,"FMUL ",5)==0){ + x=5; + opcode=0x200B; + params=2; }else params=0; if(params!=0){ diff --git a/cpu.c b/cpu.c index 2213520..482997b 100644 --- a/cpu.c +++ b/cpu.c @@ -89,6 +89,8 @@ int decode(struct simdata_t *simdata){ case 0x05: case 0x06: case 0x07: + case 0x0A: + case 0x0B: simdata->exec_data->in_op1->OP_ADDR=REGISTER; simdata->exec_data->in_op2->OP_ADDR=REGISTER; break; @@ -122,9 +124,11 @@ int decode(struct simdata_t *simdata){ } switch(opcode){ - case 0: - case 1: - case 4: + case 0x00: + case 0x01: + case 0x04: + case 0x0A: + case 0x0B: simdata->exec_data->out_op->OP_ADDR=REGISTER; simdata->exec_data->out_op->data=op2; break; @@ -145,17 +149,19 @@ int decode(struct simdata_t *simdata){ switch(opcode){ - case 0: simdata->exec_data->ALU_OP=ALU_ADD; break; - case 1: simdata->exec_data->ALU_OP=ALU_SUB; break; - case 2: simdata->exec_data->ALU_OP=ALU_SL; break; - case 3: simdata->exec_data->ALU_OP=ALU_SR; break; - case 4: simdata->exec_data->ALU_OP=ALU_CMP; break; - case 5: - case 6: - case 7: - case 8: - case 9: + case 0x00: simdata->exec_data->ALU_OP=ALU_ADD; break; + case 0x01: simdata->exec_data->ALU_OP=ALU_SUB; break; + case 0x02: simdata->exec_data->ALU_OP=ALU_SL; break; + case 0x03: simdata->exec_data->ALU_OP=ALU_SR; break; + case 0x04: simdata->exec_data->ALU_OP=ALU_CMP; break; + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: break; + case 0x0A: simdata->exec_data->ALU_OP=ALU_FDIV; break; + case 0x0B: simdata->exec_data->ALU_OP=ALU_FMUL; break; default: return 1; } @@ -283,6 +289,14 @@ int exec(struct simdata_t *simdata){ ((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0); result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1; break; + case ALU_FDIV: + *(float*)&result = *(float*)(&simdata->registers->GPR[simdata->exec_data->in_op2->data])/ + *(float*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data]); + break; + case ALU_FMUL: + *(float*)&result = *(float*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])* + *(float*)(&simdata->registers->GPR[simdata->exec_data->in_op2->data]); + break; default: return 1; } diff --git a/cpu.h b/cpu.h index 0fbf126..c10b79f 100644 --- a/cpu.h +++ b/cpu.h @@ -30,7 +30,9 @@ enum ALU_OP_t { ALU_SUB, ALU_SL, ALU_SR, - ALU_CMP + ALU_CMP, + ALU_FDIV, + ALU_FMUL }; enum OP_ADDR_t { diff --git a/test.asm b/test.asm index bbf80dd..f9757a5 100644 --- a/test.asm +++ b/test.asm @@ -56,10 +56,24 @@ MOV %R1,(%R0) MOV $0xcccd,%R1l MOV $0x3f4c,%R1h MOV %R1,(%R0) -MOV $0x00D0,%R0l +MOV $0xF0D0,%R0l MOV $0x0000,%R0h MOV %R1,(%R0) MOV (%R0),%R5 + +#Test mul/div +#R1=pi +MOV $0x0fdb,%R1l +MOV $0x4049,%R1h +#R0=1.3 +MOV $0x6666,%R0l +MOV $0x3fa6,%R0h +#R2=2 +MOV $0x0000,%R2l +MOV $0x4000,%R2h + +FMUL %R0,%R1 +FDIV %R2,%R1 HALT :TR_LOW DDW $0xDEADBEEF