Skip to content

Commit d5967b5

Browse files
committed
Fix incorrect MULH[S] implementation and make all of the compliance tests pass!
1 parent 26f2842 commit d5967b5

File tree

3 files changed

+111
-24
lines changed

3 files changed

+111
-24
lines changed

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,67 @@ Assumes Powershell on Windows.
136136
## Attribution
137137

138138
- SortKB: https://github.com/BasedUser/mPC
139+
140+
## riscv-arch-test
141+
142+
mlogv32 currently passes all compliance tests for the `RV32IMA` ISA.
143+
144+
```
145+
TEST NAME : COMMIT ID : STATUS
146+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amoadd.w-01.S : - : Passed
147+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amoand.w-01.S : - : Passed
148+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amomax.w-01.S : - : Passed
149+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amomaxu.w-01.S : - : Passed
150+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amomin.w-01.S : - : Passed
151+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amominu.w-01.S : - : Passed
152+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amoor.w-01.S : - : Passed
153+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amoswap.w-01.S : - : Passed
154+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/A/src/amoxor.w-01.S : - : Passed
155+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/add-01.S : - : Passed
156+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/addi-01.S : - : Passed
157+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/and-01.S : - : Passed
158+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/andi-01.S : - : Passed
159+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/auipc-01.S : - : Passed
160+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/beq-01.S : - : Passed
161+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/bge-01.S : - : Passed
162+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/bgeu-01.S : - : Passed
163+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/blt-01.S : - : Passed
164+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/bltu-01.S : - : Passed
165+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/bne-01.S : - : Passed
166+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/fence-01.S : - : Passed
167+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/jal-01.S : - : Passed
168+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/jalr-01.S : - : Passed
169+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lb-align-01.S : - : Passed
170+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lbu-align-01.S : - : Passed
171+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lh-align-01.S : - : Passed
172+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lhu-align-01.S : - : Passed
173+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lui-01.S : - : Passed
174+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lw-align-01.S : - : Passed
175+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/misalign1-jalr-01.S : - : Passed
176+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/or-01.S : - : Passed
177+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/ori-01.S : - : Passed
178+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sb-align-01.S : - : Passed
179+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sh-align-01.S : - : Passed
180+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sll-01.S : - : Passed
181+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/slli-01.S : - : Passed
182+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/slt-01.S : - : Passed
183+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/slti-01.S : - : Passed
184+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sltiu-01.S : - : Passed
185+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sltu-01.S : - : Passed
186+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sra-01.S : - : Passed
187+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/srai-01.S : - : Passed
188+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/srl-01.S : - : Passed
189+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/srli-01.S : - : Passed
190+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sub-01.S : - : Passed
191+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/sw-align-01.S : - : Passed
192+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/xor-01.S : - : Passed
193+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/xori-01.S : - : Passed
194+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/div-01.S : - : Passed
195+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/divu-01.S : - : Passed
196+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/mul-01.S : - : Passed
197+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/mulh-01.S : - : Passed
198+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/mulhsu-01.S : - : Passed
199+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/mulhu-01.S : - : Passed
200+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/rem-01.S : - : Passed
201+
/workspaces/mlogv32/riscof/riscv-arch-test/riscv-test-suite/rv32i_m/M/src/remu-01.S : - : Passed
202+
```

asm/mul.s

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,12 @@ _start:
4343
mulhu a2, a0, a1
4444
mulhsu a2, a0, a1
4545

46+
ebreak
47+
48+
li a0, 0x66666667
49+
li a1, 0xaaaaaaa9
50+
51+
mulhu a2, a0, a1
52+
4653
loop:
4754
j loop

src/main.mlog

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,6 @@ swap_signedness__s2u_2:
425425
op mod rs2 rs2 0x100000000
426426
swap_signedness__done_2:
427427

428-
# converts a two's complement unsigned value in rs1 to signed in-place, or vice versa
429-
# rs1 -> rs1
430-
swap_signedness_rs1:
431428
jump swap_signedness__s2u_1 lessThan rs1 0x80000000 # 2^31
432429
op sub rs1 rs1 0x100000000 # 2^32
433430
jump swap_signedness__done_1 always
@@ -1444,52 +1441,71 @@ SUB:
14441441

14451442
MUL:
14461443
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1444+
op add ret @counter 1
1445+
jump mul_decomp always
14471446

1448-
# https://github.com/es-shims/Math.imul/blob/dab2a3bfc9ce5f4af97057c64ae1880fdbac57a5/implementation.js
1447+
op add result high_low low_high
1448+
op shl result result 16
1449+
op add result result low_low
14491450

1450-
op shr rs1_high rs1 16
1451-
op and rs1_high rs1_high 0xffff
1451+
op and result result 0xffffffff
14521452

1453-
op and rs1_low rs1 0xffff
1453+
jump end_instruction_with_result always
14541454

1455-
op shr rs2_high rs2 16
1456-
op and rs2_high rs2_high 0xffff
1455+
mul_decomp:
1456+
# https://github.com/es-shims/Math.imul/blob/dab2a3bfc9ce5f4af97057c64ae1880fdbac57a5/implementation.js
14571457

1458+
op shr rs1_high rs1 16 # no truncate necessary, rs1 is already 32 bits
1459+
op and rs1_low rs1 0xffff
1460+
op shr rs2_high rs2 16
14581461
op and rs2_low rs2 0xffff
14591462

1460-
op mul low_low rs1_low rs2_low
1463+
op mul high_high rs1_high rs2_high
14611464
op mul high_low rs1_high rs2_low
14621465
op mul low_high rs1_low rs2_high
1466+
op mul low_low rs1_low rs2_low
14631467

1464-
op add result high_low low_high
1465-
op shl result result 16
1466-
op add result result low_low
1467-
op and result result 0xffffffff
1468-
1469-
jump end_instruction_with_result always
1470-
1471-
# MULH[[S]U] can safely be implemented using double multiplication because we only care about the high order bits
1468+
set @counter ret
14721469

14731470
MULH:
14741471
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1475-
op add ret @counter 1
1476-
jump swap_signedness_rs1_rs2 always
1472+
op greaterThanEq rs1_negative rs1 0x80000000 # check if the sign bit is set
1473+
op greaterThanEq rs2_negative rs2 0x80000000
14771474

14781475
mulh_s_u:
1479-
op mul result rs1 rs2
1480-
op idiv result result 0x100000000 # shr 32 - we need to use idiv for this because large negative values cause issues when cast to long
1476+
op add ret @counter 1
1477+
jump mul_decomp always
1478+
1479+
# https://github.com/scala-js/scala-js/blob/7e9dbfcd5c9a9eb3fe065db568c4c96ef4e19a81/linker-private-library/src/main/scala/org/scalajs/linker/runtime/RuntimeLong.scala#L422
1480+
op shr result low_low 16
1481+
op add result result low_high
1482+
op add result result high_low
1483+
op shr result result 16
1484+
op add result result high_high
1485+
1486+
# https://stackoverflow.com/a/22847373
1487+
jump mulh_s_u__rs1_positive notEqual rs1_negative true
1488+
op sub result result rs2
1489+
mulh_s_u__rs1_positive:
1490+
1491+
jump mulh_s_u__rs2_positive notEqual rs2_negative true
1492+
op sub result result rs1
1493+
mulh_s_u__rs2_positive:
1494+
14811495
op and result result 0xffffffff
14821496

14831497
jump end_instruction_with_result always
14841498

14851499
MULHSU:
14861500
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1487-
op add ret @counter 1
1488-
jump swap_signedness_rs1 always
1501+
op greaterThanEq rs1_negative rs1 0x80000000
1502+
set rs2_negative false
14891503
jump mulh_s_u always
14901504

14911505
MULHU:
14921506
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1507+
set rs1_negative false
1508+
set rs2_negative false
14931509
jump mulh_s_u always
14941510

14951511
DIV:

0 commit comments

Comments
 (0)