Skip to content

Commit

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

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 19, 2024
1 parent 0bd63b7 commit 90f1058
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 90f1058

Please sign in to comment.