|
|
|
@ -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: |
|
|
|
|
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 FUNC3_SLT: |
|
|
|
|
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_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 FUNC3_SLTIU: |
|
|
|
|
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_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 FUNC3_XOR: |
|
|
|
|
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_DIV: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_XOR: |
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] ^ cpu->regs.x[instruction->rs2]; |
|
|
|
|
break; |
|
|
|
|
case FUNC3_OR: |
|
|
|
|
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_REM: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_OR: |
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] | cpu->regs.x[instruction->rs2]; |
|
|
|
|
break; |
|
|
|
|
case FUNC3_AND: |
|
|
|
|
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_REMU: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_AND: |
|
|
|
|
cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] & cpu->regs.x[instruction->rs2]; |
|
|
|
|
break; |
|
|
|
|
case FUNC3_SRL_SRA: |
|
|
|
|
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_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; |
|
|
|
|
} |
|
|
|
@ -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: |
|
|
|
|
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 FUNC3_SLT: |
|
|
|
|
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_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 FUNC3_SLTIU: |
|
|
|
|
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_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 FUNC3_XOR: |
|
|
|
|
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_DIV: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_XOR: |
|
|
|
|
printf("xor x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_OR: |
|
|
|
|
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_REM: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_OR: |
|
|
|
|
printf("or x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_AND: |
|
|
|
|
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_REMU: |
|
|
|
|
switch(instruction->func7) |
|
|
|
|
{ |
|
|
|
|
case FUNC7_AND: |
|
|
|
|
printf("and x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2); |
|
|
|
|
break; |
|
|
|
|
case FUNC3_SRL_SRA: |
|
|
|
|
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_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; |
|
|
|
|