Skip to content

Commit

Permalink
Support software emulation for multiplication on RISC-V targets
Browse files Browse the repository at this point in the history
Previously, shecc would just generate hardware multiplication
instructions for multiplication operations.

This commit adjusts riscv-codegen.c so that shecc can generate
a sequence of instructions to achieve multiplication without
any RV32M instruction if the '+m' option is disable.
  • Loading branch information
DrXiao committed Jun 18, 2024
1 parent 0bd63b7 commit ccc2a95
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/riscv-codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
case OP_indirect:
case OP_add:
case OP_sub:
case OP_mul:
case OP_div:
case OP_mod:
case OP_lshift:
Expand All @@ -65,6 +64,12 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
case OP_bit_not:
elf_offset += 4;
return;
case OP_mul:
if (hard_mul_div)
elf_offset += 4;
else
elf_offset += 52;
return;
case OP_load_data_address:
case OP_neq:
case OP_geq:
Expand Down Expand Up @@ -283,7 +288,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
emit(__sub(rd, rs1, rs2));
return;
case OP_mul:
emit(__mul(rd, rs1, rs2));
if (hard_mul_div)
emit(__mul(rd, rs1, rs2));
else {
emit(__addi(__t0, __zero, 0));
emit(__addi(__t1, __zero, 0));
emit(__addi(__t3, rs1, 0));
emit(__addi(__t4, rs2, 0));
emit(__beq(__t3, __zero, 32));
emit(__beq(__t4, __zero, 28));
emit(__andi(__t1, __t4, 1));
emit(__beq(__t1, __zero, 8));
emit(__add(__t0, __t0, __t3));
emit(__slli(__t3, __t3, 1));
emit(__srli(__t4, __t4, 1));
emit(__jal(__zero, -28));
emit(__addi(rd, __t0, 0));
}
return;
case OP_div:
emit(__div(rd, rs1, rs2));
Expand Down
33 changes: 33 additions & 0 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,39 @@ int main()
}
EOF

# Multiplication for signed integers
try_output 0 "35 -35 -35 35" << EOF
int main()
{
printf("%d %d %d %d\n", 5 * 7, 5 * -7, -5 * 7, -5 * -7);
return 0;
}
EOF

try_output 0 "-212121 -535050 336105 666666666" << EOF
int main()
{
printf("%d %d %d %d\n", -333 * 637, 1450 * -369, 37345 * 9, -111111111 * -6);
return 0;
}
EOF

try_output 0 "1073676289 -131071 30" << EOF
int main()
{
printf("%d %d %d\n", 32767 * 32767, 65535 * 65535, 54 * 5 * 954437177);
return 0;
}
EOF

try_output 0 "-2 6 24" << EOF
int main()
{
printf("%d %d %d\n", -1 * 2, -1 * 2 * -3, -1 * 2 * -3 * 4);
return 0;
}
EOF

# Division and modulo for signed integers
try_output 0 "-1 -2" << EOF
int main()
Expand Down

0 comments on commit ccc2a95

Please sign in to comment.