From da8ffaf3a47e2986483c0cbde01d5ee640d33cd8 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Fri, 16 Feb 2024 19:46:25 +0000 Subject: [PATCH] CPU,ASM: Added the trigonometric instructions SIN and COS --- Makefile | 2 +- assembly.c | 28 +++++++++++++++++++++++----- cpu.c | 17 +++++++++++++++-- cpu.h | 4 +++- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index d3af674..b7b0aca 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ all:${MAIN_ROM} first: ${OBJECT_FILES} ${QUIET_LINK} - ${Q}gcc -ggdb $^ -fsanitize=address -fsanitize=undefined -fsanitize=leak -lncursesw -ltinfow -o $@ + ${Q}gcc -ggdb $^ -fsanitize=address -fsanitize=undefined -fsanitize=leak -lncursesw -ltinfow -lm -o $@ %.rom:%.asm first $(QUIET_FAS) diff --git a/assembly.c b/assembly.c index b398dfc..850577c 100644 --- a/assembly.c +++ b/assembly.c @@ -112,6 +112,10 @@ // | 14'hC | Floating point addition | YES | operand 1 | operand 2 | // +-------+---------------------------------------------+--------------+------------+------------+ // | 14'hD | Floating point subtraction | YES | operand 1 | operand 2 | +// +-------+---------------------------------------------+--------------+------------+------------+ +// | 14'hE | Calculate the sin of a register | YES | operand | | +// +-------+---------------------------------------------+--------------+------------+------------+ +// | 14'hF | Calculate the cos of a register | YES | operand | | // // // INSTRUCTION FORMAT 2 OPCODE NUM: @@ -223,6 +227,12 @@ char *disassemble(uint32_t opcode_be){ case 0x0D: snprintf(ret,MAX_INSTRUCTION_LENGTH,"FSUB %%R%0d,%%R%0d",val1,val2); break; + case 0x0E: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"SIN %%R%0d",val1); + break; + case 0x0F: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"COS %%R%0d",val1); + break; default: snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); break; @@ -416,21 +426,29 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context) opcode=0x2004; params=2; }else if(strncmp(line,"FDIV ",5)==0){ - x=5; + x=4; opcode=0x200A; params=2; }else if(strncmp(line,"FMUL ",5)==0){ - x=5; + x=4; opcode=0x200B; params=2; }else if(strncmp(line,"FADD ",5)==0){ - x=5; + x=4; opcode=0x200C; params=2; }else if(strncmp(line,"FSUB ",5)==0){ - x=5; + x=4; opcode=0x200D; params=2; + }else if(strncmp(line,"SIN ",4)==0){ + x=3; + opcode=0x200E; + params=1; + }else if(strncmp(line,"COS ",4)==0){ + x=3; + opcode=0x200F; + params=1; }else params=0; if(params!=0){ @@ -463,7 +481,7 @@ int64_t assemble_line(char *line, struct assembler_context_t *assembler_context) }else return -2; }else - return (opcode<<16)|r0<<2; + return (opcode<<16)|r0<<8; }else return -2; }else diff --git a/cpu.c b/cpu.c index a61965c..55a6b55 100644 --- a/cpu.c +++ b/cpu.c @@ -1,6 +1,7 @@ #include "simdata.h" #include "cpu.h" #include +#include @@ -94,6 +95,8 @@ int decode(struct simdata_t *simdata){ case 0x0B: case 0x0C: case 0x0D: + case 0x0E: + case 0x0F: simdata->exec_data->in_op1->OP_ADDR=REGISTER; simdata->exec_data->in_op2->OP_ADDR=REGISTER; break; @@ -137,8 +140,10 @@ int decode(struct simdata_t *simdata){ simdata->exec_data->out_op->OP_ADDR=REGISTER; simdata->exec_data->out_op->data=op2; break; - case 2: - case 3: + case 0x02: + case 0x03: + case 0x0E: + case 0x0F: simdata->exec_data->out_op->OP_ADDR=REGISTER; simdata->exec_data->out_op->data=op1; break; @@ -169,6 +174,8 @@ int decode(struct simdata_t *simdata){ case 0x0B: simdata->exec_data->ALU_OP=ALU_FMUL; break; case 0x0C: simdata->exec_data->ALU_OP=ALU_FADD; break; case 0x0D: simdata->exec_data->ALU_OP=ALU_FSUB; break; + case 0x0E: simdata->exec_data->ALU_OP=ALU_FSIN; break; + case 0x0F: simdata->exec_data->ALU_OP=ALU_FCOS; break; default: return 1; } @@ -312,6 +319,12 @@ int exec(struct simdata_t *simdata){ *(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_FSIN: + *(float*)&result = sinf(*(float*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])); + break; + case ALU_FCOS: + *(float*)&result = cosf(*(float*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])); + break; default: return 1; } diff --git a/cpu.h b/cpu.h index e4e96cc..9de0e9d 100644 --- a/cpu.h +++ b/cpu.h @@ -34,7 +34,9 @@ enum ALU_OP_t { ALU_FDIV, ALU_FMUL, ALU_FADD, - ALU_FSUB + ALU_FSUB, + ALU_FSIN, + ALU_FCOS }; enum OP_ADDR_t {