Skip to content

Commit 7b4e15e

Browse files
committed
Implement multiplication for RV32I
This commit allows shecc to generate a sequence of instructions to perform multiplication for RISC-V targets with RV32I only.
1 parent 0bd63b7 commit 7b4e15e

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

src/riscv-codegen.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
5050
case OP_indirect:
5151
case OP_add:
5252
case OP_sub:
53-
case OP_mul:
5453
case OP_div:
5554
case OP_mod:
5655
case OP_lshift:
@@ -65,6 +64,12 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
6564
case OP_bit_not:
6665
elf_offset += 4;
6766
return;
67+
case OP_mul:
68+
if (hard_mul_div)
69+
elf_offset += 4;
70+
else
71+
elf_offset += 52;
72+
return;
6873
case OP_load_data_address:
6974
case OP_neq:
7075
case OP_geq:
@@ -283,7 +288,23 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
283288
emit(__sub(rd, rs1, rs2));
284289
return;
285290
case OP_mul:
286-
emit(__mul(rd, rs1, rs2));
291+
if (hard_mul_div)
292+
emit(__mul(rd, rs1, rs2));
293+
else {
294+
emit(__addi(__t0, __zero, 0));
295+
emit(__addi(__t1, __zero, 0));
296+
emit(__addi(__t3, rs1, 0));
297+
emit(__addi(__t4, rs2, 0));
298+
emit(__beq(__t3, __zero, 32));
299+
emit(__beq(__t4, __zero, 28));
300+
emit(__andi(__t1, __t4, 1));
301+
emit(__beq(__t1, __zero, 8));
302+
emit(__add(__t0, __t0, __t3));
303+
emit(__slli(__t3, __t3, 1));
304+
emit(__srli(__t4, __t4, 1));
305+
emit(__jal(__zero, -28));
306+
emit(__addi(rd, __t0, 0));
307+
}
287308
return;
288309
case OP_div:
289310
emit(__div(rd, rs1, rs2));

tests/driver.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,39 @@ int main()
592592
}
593593
EOF
594594

595+
# Multiplication for signed integers
596+
try_output 0 "35 -35 -35 35" << EOF
597+
int main()
598+
{
599+
printf("%d %d %d %d\n", 5 * 7, 5 * (-7), (-5) * 7, (-5) * (-7));
600+
return 0;
601+
}
602+
EOF
603+
604+
try_output 0 "-212121 -535050 336105 666666666" << EOF
605+
int main()
606+
{
607+
printf("%d %d %d %d\n", (-333) * 637, 1450 * (-369), 37345 * 9, (-111111111) * (-6));
608+
return 0;
609+
}
610+
EOF
611+
612+
try_output 0 "1073676289 -131071 30" << EOF
613+
int main()
614+
{
615+
printf("%d %d %d\n", 32767 * 32767, 65535 * 65535, 54 * 5 * 954437177);
616+
return 0;
617+
}
618+
EOF
619+
620+
try_output 0 "-2 6 24" << EOF
621+
int main()
622+
{
623+
printf("%d %d %d\n", (-1) * 2, (-1) * 2 * (-3), (-1) * 2 * (-3) * 4);
624+
return 0;
625+
}
626+
EOF
627+
595628
# Division and modulo for signed integers
596629
try_output 0 "-1 -2" << EOF
597630
int main()

0 commit comments

Comments
 (0)