Added M (Multiplication) extension
This commit is contained in:
parent
89744626a7
commit
378d0fa463
@ -64,18 +64,33 @@
|
||||
#define FUNC7_SRAI 0x20
|
||||
|
||||
/* OPCODE_ARITHLOG sub functions (func3 + func7) */
|
||||
#define FUNC3_ADD_SUB 0x0
|
||||
#define FUNC3_ADD_SUB_MUL 0x0
|
||||
#define FUNC7_ADD 0x0
|
||||
#define FUNC7_SUB 0x20
|
||||
#define FUNC3_SLL 0x1
|
||||
#define FUNC3_SLT 0x2
|
||||
#define FUNC3_SLTU 0x3
|
||||
#define FUNC3_XOR 0x4
|
||||
#define FUNC3_SRL_SRA 0x5
|
||||
#define FUNC3_SLL_MULH 0x1
|
||||
#define FUNC7_SLL 0x0
|
||||
#define FUNC3_SLT_MULHSU 0x2
|
||||
#define FUNC7_SLT 0x0
|
||||
#define FUNC3_SLTU_MULHU 0x3
|
||||
#define FUNC7_SLTU 0x0
|
||||
#define FUNC3_XOR_DIV 0x4
|
||||
#define FUNC7_XOR 0x0
|
||||
#define FUNC3_SRL_SRA_DIVU 0x5
|
||||
#define FUNC7_SRL 0x0
|
||||
#define FUNC7_SRA 0x20
|
||||
#define FUNC3_OR 0x6
|
||||
#define FUNC3_AND 0x7
|
||||
#define FUNC3_OR_REM 0x6
|
||||
#define FUNC7_OR 0x0
|
||||
#define FUNC3_AND_REMU 0x7
|
||||
#define FUNC7_AND 0x0
|
||||
/* RISC-V RV32 M Extension */
|
||||
#define FUNC7_MUL 0x1
|
||||
#define FUNC7_MULH 0x1
|
||||
#define FUNC7_MULHSU 0x1
|
||||
#define FUNC7_MULHU 0x1
|
||||
#define FUNC7_DIV 0x1
|
||||
#define FUNC7_DIVU 0x1
|
||||
#define FUNC7_REM 0x1
|
||||
#define FUNC7_REMU 0x1
|
||||
|
||||
/* OPCODE_SYSTEM sub functions (func3 + imm) */
|
||||
#define FUNC3_ECALL_EBREAK 0x0
|
||||
|
@ -339,7 +339,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
// To find out which operation, we must analyse func3 and func7
|
||||
switch(instruction->func3)
|
||||
{
|
||||
case FUNC3_ADD_SUB:
|
||||
case FUNC3_ADD_SUB_MUL:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_ADD:
|
||||
@ -348,41 +348,122 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
case FUNC7_SUB:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] - cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
case FUNC7_MUL:
|
||||
cpu->regs.x[instruction->rd] = (uint32_t) (cpu->regs.x[instruction->rs1] * cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog ADD/SUB instruction, could not execute\n", instruction->func7);
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog ADD/SUB/MUL instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLL:
|
||||
// Slide Left Logical
|
||||
uint32_t sll_value = cpu->regs.x[instruction->rs2] & 0x1F;
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] << sll_value;
|
||||
case FUNC3_SLL_MULH:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLL:
|
||||
// Slide Left Logical
|
||||
uint32_t sll_value = cpu->regs.x[instruction->rs2] & 0x1F;
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] << sll_value;
|
||||
break;
|
||||
case FUNC7_MULH:
|
||||
// MULtiplication High (32 high bits) (signed * signed)
|
||||
uint64_t mulh_result = (uint64_t) (((int64_t) cpu->regs.x[instruction->rs1]) * ((int64_t) cpu->regs.x[instruction->rs2]));
|
||||
cpu->regs.x[instruction->rd] = (uint32_t) (mulh_result >> 32);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SLL/MULH instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLT:
|
||||
// Set Less Than
|
||||
if(((int32_t) cpu->regs.x[instruction->rs1]) < ((int32_t) cpu->regs.x[instruction->rs2]))
|
||||
cpu->regs.x[instruction->rd] = 1;
|
||||
else
|
||||
cpu->regs.x[instruction->rd] = 0;
|
||||
case FUNC3_SLT_MULHSU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLT:
|
||||
// Set Less Than
|
||||
if(((int32_t) cpu->regs.x[instruction->rs1]) < ((int32_t) cpu->regs.x[instruction->rs2]))
|
||||
cpu->regs.x[instruction->rd] = 1;
|
||||
else
|
||||
cpu->regs.x[instruction->rd] = 0;
|
||||
break;
|
||||
case FUNC7_MULHSU:
|
||||
// MULtiplication High (32 high bits) (signed * unsigned)
|
||||
uint64_t mulhsu_result = (uint64_t) (((int64_t) cpu->regs.x[instruction->rs1]) * ((uint64_t) cpu->regs.x[instruction->rs2]));
|
||||
cpu->regs.x[instruction->rd] = (uint32_t) (mulhsu_result >> 32);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SLL/MULH instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLTIU:
|
||||
// Set Less Than Unsigned
|
||||
if(cpu->regs.x[instruction->rs1] < cpu->regs.x[instruction->rs2])
|
||||
cpu->regs.x[instruction->rd] = 1;
|
||||
else
|
||||
cpu->regs.x[instruction->rd] = 0;
|
||||
case FUNC3_SLTU_MULHU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLTU:
|
||||
// Set Less Than Unsigned
|
||||
if(cpu->regs.x[instruction->rs1] < cpu->regs.x[instruction->rs2])
|
||||
cpu->regs.x[instruction->rd] = 1;
|
||||
else
|
||||
cpu->regs.x[instruction->rd] = 0;
|
||||
break;
|
||||
case FUNC7_MULHU:
|
||||
// MULtiplication High (32 high bits) (unsigned * unsigned)
|
||||
uint64_t mulhu_result = (((uint64_t) cpu->regs.x[instruction->rs1]) * ((uint64_t) cpu->regs.x[instruction->rs2]));
|
||||
cpu->regs.x[instruction->rd] = (uint32_t) (mulhu_result >> 32);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SLTU/MULHU instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_XOR:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] ^ cpu->regs.x[instruction->rs2];
|
||||
case FUNC3_XOR_DIV:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_XOR:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] ^ cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
case FUNC7_DIV:
|
||||
cpu->regs.x[instruction->rd] = ((int32_t) cpu->regs.x[instruction->rs1]) / ((int32_t) cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog XOR/DIV instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_OR:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] | cpu->regs.x[instruction->rs2];
|
||||
case FUNC3_OR_REM:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_OR:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] | cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
case FUNC7_REM:
|
||||
cpu->regs.x[instruction->rd] = ((int32_t) cpu->regs.x[instruction->rs1]) % ((int32_t) cpu->regs.x[instruction->rs2]);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog OR/REM instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_AND:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] & cpu->regs.x[instruction->rs2];
|
||||
case FUNC3_AND_REMU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_AND:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] & cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
case FUNC7_REMU:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] % cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog AND/REMU instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SRL_SRA:
|
||||
case FUNC3_SRL_SRA_DIVU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SRL:
|
||||
@ -395,8 +476,11 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
|
||||
uint32_t sra_value = cpu->regs.x[instruction->rs2] & 0x1F;
|
||||
cpu->regs.x[instruction->rd] = ((int32_t) cpu->regs.x[instruction->rs1]) >> sra_value;
|
||||
break;
|
||||
case FUNC7_DIVU:
|
||||
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] / cpu->regs.x[instruction->rs2];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SRL/SRA instruction, could not execute\n", instruction->func7);
|
||||
fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SRL/SRA/DIVU instruction, could not execute\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
@ -579,7 +663,7 @@ void cpu_loop(rv32_cpu_t* cpu)
|
||||
|
||||
// Execute
|
||||
cpu_execute(cpu, &instruction);
|
||||
|
||||
|
||||
// Reset value of zero, in case instruction tried to modify
|
||||
cpu->regs.zero = 0;
|
||||
|
||||
@ -787,7 +871,7 @@ static void cpu_print_instruction(instruction_t* instruction)
|
||||
// To find out which operation, we must analyse func3 and func7
|
||||
switch(instruction->func3)
|
||||
{
|
||||
case FUNC3_ADD_SUB:
|
||||
case FUNC3_ADD_SUB_MUL:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_ADD:
|
||||
@ -796,33 +880,105 @@ static void cpu_print_instruction(instruction_t* instruction)
|
||||
case FUNC7_SUB:
|
||||
printf("sub x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_MUL:
|
||||
printf("mul x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog ADD/SUB instruction, could not execute\n", instruction->func7);
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog ADD/SUB/MUL instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLL:
|
||||
// Slide Left Logical
|
||||
printf("sll x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_SLL_MULH:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLL:
|
||||
// Slide Left Logical
|
||||
printf("sll x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_MULH:
|
||||
// MULtiplication High (32 high bits) (signed * signed)
|
||||
printf("mulh x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SLL/MULH instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLT:
|
||||
// Set Less Than
|
||||
printf("slt x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_SLT_MULHSU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLT:
|
||||
// Set Less Than
|
||||
printf("slt x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_MULHSU:
|
||||
// MULtiplication High (32 high bits) (signed * unsigned)
|
||||
printf("mulhsu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SLL/MULH instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SLTIU:
|
||||
// Set Less Than Unsigned
|
||||
printf("sltu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_SLTU_MULHU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SLTU:
|
||||
// Set Less Than Unsigned
|
||||
printf("sltu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_MULHU:
|
||||
// MULtiplication High (32 high bits) (unsigned * unsigned)
|
||||
printf("mulhu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SLTU/MULHU instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_XOR:
|
||||
printf("xor x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_XOR_DIV:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_XOR:
|
||||
printf("xor x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_DIV:
|
||||
printf("div x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog XOR/DIV instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_OR:
|
||||
printf("or x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_OR_REM:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_OR:
|
||||
printf("or x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_REM:
|
||||
printf("rem x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog OR/REM instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_AND:
|
||||
printf("and x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
case FUNC3_AND_REMU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_AND:
|
||||
printf("and x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_REMU:
|
||||
printf("remu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog AND/REMU instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNC3_SRL_SRA:
|
||||
case FUNC3_SRL_SRA_DIVU:
|
||||
switch(instruction->func7)
|
||||
{
|
||||
case FUNC7_SRL:
|
||||
@ -833,15 +989,16 @@ static void cpu_print_instruction(instruction_t* instruction)
|
||||
// Slide Right Arithmetical
|
||||
printf("sra x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
case FUNC7_DIVU:
|
||||
printf("divu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SRL/SRA instruction\n", instruction->func7);
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SRL/SRA/DIVU instruction\n", instruction->func7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Warning: Unknown func3 0x%x for arithlog instruction\n", instruction->func3);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user