Skip to content

Commit 71af819

Browse files
committed
Fix incorrect memory writes in RV32A
The current implementation of RV32A instructions encountered issues when rd and rs1 were the same registers, leading to incorrect memory writes due to the modification of the memory location before writing. To address this, the fix involves storing the address, the value of mem_read_w(rv->X[ir->rs1]), and rv->X[ir->rs2] before proceeding with further operations.
1 parent 5861bb4 commit 71af819

File tree

1 file changed

+57
-32
lines changed

1 file changed

+57
-32
lines changed

src/rv32_template.c

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,9 +1349,12 @@ RVOP(
13491349
RVOP(
13501350
amoswapw,
13511351
{
1352+
const uint32_t addr = rv->X[ir->rs1];
1353+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1354+
const uint32_t value2 = rv->X[ir->rs2];
13521355
if (ir->rd)
1353-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1354-
rv->io.mem_write_w(rv->X[ir->rs1], rv->X[ir->rs2]);
1356+
rv->X[ir->rd] = value1;
1357+
rv->io.mem_write_w(addr, value2);
13551358
},
13561359
GEN({
13571360
assert; /* FIXME: Implement */
@@ -1361,10 +1364,13 @@ RVOP(
13611364
RVOP(
13621365
amoaddw,
13631366
{
1367+
const uint32_t addr = rv->X[ir->rs1];
1368+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1369+
const uint32_t value2 = rv->X[ir->rs2];
13641370
if (ir->rd)
1365-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1366-
const uint32_t res = rv->X[ir->rd] + rv->X[ir->rs2];
1367-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1371+
rv->X[ir->rd] = value1;
1372+
const uint32_t res = value1 + value2;
1373+
rv->io.mem_write_w(addr, res);
13681374
},
13691375
GEN({
13701376
assert; /* FIXME: Implement */
@@ -1374,10 +1380,13 @@ RVOP(
13741380
RVOP(
13751381
amoxorw,
13761382
{
1383+
const uint32_t addr = rv->X[ir->rs1];
1384+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1385+
const uint32_t value2 = rv->X[ir->rs2];
13771386
if (ir->rd)
1378-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1379-
const uint32_t res = rv->X[ir->rd] ^ rv->X[ir->rs2];
1380-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1387+
rv->X[ir->rd] = value1;
1388+
const uint32_t res = value1 ^ value2;
1389+
rv->io.mem_write_w(addr, res);
13811390
},
13821391
GEN({
13831392
assert; /* FIXME: Implement */
@@ -1387,10 +1396,13 @@ RVOP(
13871396
RVOP(
13881397
amoandw,
13891398
{
1399+
const uint32_t addr = rv->X[ir->rs1];
1400+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1401+
const uint32_t value2 = rv->X[ir->rs2];
13901402
if (ir->rd)
1391-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1392-
const uint32_t res = rv->X[ir->rd] & rv->X[ir->rs2];
1393-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1403+
rv->X[ir->rd] = value1;
1404+
const uint32_t res = value1 & value2;
1405+
rv->io.mem_write_w(addr, res);
13941406
},
13951407
GEN({
13961408
assert; /* FIXME: Implement */
@@ -1400,10 +1412,13 @@ RVOP(
14001412
RVOP(
14011413
amoorw,
14021414
{
1415+
const uint32_t addr = rv->X[ir->rs1];
1416+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1417+
const uint32_t value2 = rv->X[ir->rs2];
14031418
if (ir->rd)
1404-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1405-
const uint32_t res = rv->X[ir->rd] | rv->X[ir->rs2];
1406-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1419+
rv->X[ir->rd] = value1;
1420+
const uint32_t res = value1 | value2;
1421+
rv->io.mem_write_w(addr, res);
14071422
},
14081423
GEN({
14091424
assert; /* FIXME: Implement */
@@ -1413,12 +1428,15 @@ RVOP(
14131428
RVOP(
14141429
amominw,
14151430
{
1431+
const uint32_t addr = rv->X[ir->rs1];
1432+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1433+
const uint32_t value2 = rv->X[ir->rs2];
14161434
if (ir->rd)
1417-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1418-
const int32_t a = rv->X[ir->rd];
1419-
const int32_t b = rv->X[ir->rs2];
1420-
const uint32_t res = a < b ? rv->X[ir->rd] : rv->X[ir->rs2];
1421-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1435+
rv->X[ir->rd] = value1;
1436+
const int32_t a = value1;
1437+
const int32_t b = value2;
1438+
const uint32_t res = a < b ? value1 : value2;
1439+
rv->io.mem_write_w(addr, res);
14221440
},
14231441
GEN({
14241442
assert; /* FIXME: Implement */
@@ -1428,12 +1446,15 @@ RVOP(
14281446
RVOP(
14291447
amomaxw,
14301448
{
1449+
const uint32_t addr = rv->X[ir->rs1];
1450+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1451+
const uint32_t value2 = rv->X[ir->rs2];
14311452
if (ir->rd)
1432-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1433-
const int32_t a = rv->X[ir->rd];
1434-
const int32_t b = rv->X[ir->rs2];
1435-
const uint32_t res = a > b ? rv->X[ir->rd] : rv->X[ir->rs2];
1436-
rv->io.mem_write_w(rv->X[ir->rs1], res);
1453+
rv->X[ir->rd] = value1;
1454+
const int32_t a = value1;
1455+
const int32_t b = value2;
1456+
const uint32_t res = a > b ? value1 : value2;
1457+
rv->io.mem_write_w(addr, res);
14371458
},
14381459
GEN({
14391460
assert; /* FIXME: Implement */
@@ -1443,11 +1464,13 @@ RVOP(
14431464
RVOP(
14441465
amominuw,
14451466
{
1467+
const uint32_t addr = rv->X[ir->rs1];
1468+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1469+
const uint32_t value2 = rv->X[ir->rs2];
14461470
if (ir->rd)
1447-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1448-
const uint32_t ures =
1449-
rv->X[ir->rd] < rv->X[ir->rs2] ? rv->X[ir->rd] : rv->X[ir->rs2];
1450-
rv->io.mem_write_w(rv->X[ir->rs1], ures);
1471+
rv->X[ir->rd] = value1;
1472+
const uint32_t ures = value1 < value2 ? value1 : value2;
1473+
rv->io.mem_write_w(addr, ures);
14511474
},
14521475
GEN({
14531476
assert; /* FIXME: Implement */
@@ -1457,11 +1480,13 @@ RVOP(
14571480
RVOP(
14581481
amomaxuw,
14591482
{
1483+
const uint32_t addr = rv->X[ir->rs1];
1484+
const uint32_t value1 = rv->io.mem_read_w(rv->X[ir->rs1]);
1485+
const uint32_t value2 = rv->X[ir->rs2];
14601486
if (ir->rd)
1461-
rv->X[ir->rd] = rv->io.mem_read_w(rv->X[ir->rs1]);
1462-
const uint32_t ures =
1463-
rv->X[ir->rd] > rv->X[ir->rs2] ? rv->X[ir->rd] : rv->X[ir->rs2];
1464-
rv->io.mem_write_w(rv->X[ir->rs1], ures);
1487+
rv->X[ir->rd] = value1;
1488+
const uint32_t ures = value1 > value2 ? value1 : value2;
1489+
rv->io.mem_write_w(addr, ures);
14651490
},
14661491
GEN({
14671492
assert; /* FIXME: Implement */

0 commit comments

Comments
 (0)