Skip to content

Commit 0387a6a

Browse files
committed
Add tentative (untested) support for A extension
1 parent 4ddce2f commit 0387a6a

File tree

3 files changed

+220
-26
lines changed

3 files changed

+220
-26
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ RISC-V processor in Mindustry logic. Requires Mindustry build 149+.
66

77
## Architecture
88

9-
Extensions: `rv32im_Zicsr_Zicntr_Zihintpause`
9+
Extensions: `rv32ima_Zicsr_Zicntr_Zihintpause`
1010

1111
Memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rw). The third section is an instruction cache, which takes up 4x as much space as the executable portion of memory. The instruction cache is updated at reset and whenever an instruction writes to RAM.
1212

src/main.mlog

Lines changed: 207 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ reset__decode:
134134
op sub decode_duration @time decode_start_time
135135
set STATE "running"
136136

137+
# clear LR/SC reservation set
138+
set reservation_set null
139+
137140
# start executing code at address 4 (address 0 is __etext)
138141
set pc 4
139142
set icache_var null
@@ -238,6 +241,17 @@ done_pause_step:
238241
jump DIVU always
239242
jump REM always
240243
jump REMU always
244+
jump AMOADD.W always
245+
jump AMOSWAP.W always
246+
jump LR.W always
247+
jump SC.W always
248+
jump AMOXOR.W always
249+
jump AMOOR.W always
250+
jump AMOAND.W always
251+
jump AMOMIN.W always
252+
jump AMOMAX.W always
253+
jump AMOMINU.W always
254+
jump AMOMAXU.W always
241255

242256
# we jump here at the start of the main loop if icache_var is null
243257
access_icache:
@@ -387,29 +401,29 @@ extend_sign:
387401

388402
set @counter ret
389403

390-
# converts a pair of two's complement unsigned values to signed, or vice versa
404+
# converts a pair of two's complement unsigned values to signed in-place, or vice versa
391405
# this converts two values at once because most usages of it need to convert two values
392406
# also, the values are assumed to be in rs1 and rs2
393-
# rs1, rs2 -> result1, result2
407+
# rs1, rs2 -> rs1, rs2
394408
swap_signedness_rs1_rs2:
395409
# value < 2^31 ? (value + 2^32) % 2^32 : value - 2^32
396410
jump swap_signedness__s2u_2 lessThan rs2 0x80000000
397-
op sub result2 rs2 0x100000000
411+
op sub rs2 rs2 0x100000000
398412
jump swap_signedness__done_2 always
399413
swap_signedness__s2u_2:
400-
op add result2 rs2 0x100000000
401-
op mod result2 result2 0x100000000
414+
op add rs2 rs2 0x100000000
415+
op mod rs2 rs2 0x100000000
402416
swap_signedness__done_2:
403417

404-
# converts a two's complement unsigned value in rs1 to signed, or vice versa
405-
# rs1 -> result1
418+
# converts a two's complement unsigned value in rs1 to signed in-place, or vice versa
419+
# rs1 -> rs1
406420
swap_signedness_rs1:
407421
jump swap_signedness__s2u_1 lessThan rs1 0x80000000 # 2^31
408-
op sub result1 rs1 0x100000000 # 2^32
422+
op sub rs1 rs1 0x100000000 # 2^32
409423
jump swap_signedness__done_1 always
410424
swap_signedness__s2u_1:
411-
op add result1 rs1 0x100000000
412-
op mod result1 result1 0x100000000
425+
op add rs1 rs1 0x100000000
426+
op mod rs1 rs1 0x100000000
413427
swap_signedness__done_1:
414428

415429
set @counter ret
@@ -572,7 +586,7 @@ decode__ok:
572586
jump decode_STORE always
573587
jump decode_illegal_instruction always # STORE-FP
574588
jump decode_illegal_instruction always # custom-1
575-
jump decode_illegal_instruction always # AMO
589+
jump decode_AMO always
576590
jump decode_OP always
577591
jump decode_LUI always
578592
jump decode_illegal_instruction always # OP-32
@@ -703,6 +717,32 @@ decode_STORE:
703717
op add op_id 16 funct3 # 16 (SB) to 18 (SW)
704718
jump end_decode always
705719

720+
decode_AMO:
721+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
722+
jump decode_illegal_instruction notEqual funct3 0b010
723+
724+
# funct5
725+
# mlogv32 is single-hart, so just ignore aq and rl
726+
op shr funct5 funct7 2
727+
728+
# funct5 either has bits in [4:2] or [1:0] set, never both
729+
# (ab)use that so we don't need 32 lookup table entries
730+
jump decode_AMO__high greaterThan funct5 0b11
731+
732+
# low bits
733+
op add op_id 54 funct5 # 54 (AMOADD.W) to 57 (SC.W)
734+
jump end_decode always
735+
736+
decode_AMO__high:
737+
# high bits
738+
op and low funct5 0b11
739+
jump decode_illegal_instruction notEqual low 0b00
740+
741+
# note: funct5 >> 2 starts at 1, not 0
742+
op shr funct5 funct5 2
743+
op add op_id 57 funct5 # 58 (AMOXOR.W) to 64 (AMOMAXU.W)
744+
jump end_decode always
745+
706746
decode_OP-IMM:
707747
op add @counter @counter funct3_x2
708748

@@ -906,15 +946,15 @@ BLT:
906946
op add ret @counter 1
907947
jump swap_signedness_rs1_rs2 always
908948

909-
jump conditional_branch lessThan result1 result2
949+
jump conditional_branch lessThan rs1 rs2
910950
jump end_instruction always
911951

912952
BGE:
913953
# B-type: arg1=rs1, arg2=rs2, arg3=imm
914954
op add ret @counter 1
915955
jump swap_signedness_rs1_rs2 always
916956

917-
jump conditional_branch greaterThanEq result1 result2
957+
jump conditional_branch greaterThanEq rs1 rs2
918958
jump end_instruction always
919959

920960
BLTU:
@@ -1070,6 +1110,152 @@ SW:
10701110
set length 32
10711111
jump store_value always
10721112

1113+
LR.W:
1114+
# R-type: arg1=rs1, arg2=0, arg3=rd
1115+
# check alignment
1116+
op mod alignment rs1 4
1117+
jump misaligned_load notEqual alignment 0
1118+
1119+
# load value
1120+
set address rs1
1121+
op add ret @counter 1
1122+
jump load_word always
1123+
1124+
# register reservation set
1125+
# TODO: implement Za64rs?
1126+
set reservation_set rs1
1127+
1128+
jump end_instruction equal arg3 0
1129+
write result REGISTERS arg3
1130+
jump end_instruction always
1131+
1132+
SC.W:
1133+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1134+
1135+
# check address and alignment
1136+
jump inaccessible_store lessThan rs1 RAM_START
1137+
jump inaccessible_store greaterThanEq rs1 RAM_END
1138+
1139+
op mod alignment rs1 4
1140+
jump misaligned_load notEqual alignment 0
1141+
1142+
# check if reservation is valid and contains rs1
1143+
op strictEqual success rs1 reservation_set
1144+
1145+
# invalidate reservation
1146+
set reservation_set null
1147+
1148+
# write 0 to rd if successful, else write 1
1149+
jump SC.W__no_write_rd equal arg3 0
1150+
op notEqual result success true
1151+
write result REGISTERS arg3
1152+
SC.W__no_write_rd:
1153+
1154+
# conditionally write value
1155+
jump end_instruction notEqual success true
1156+
1157+
set address rs1
1158+
op add access_ram__ret @counter 1
1159+
jump access_ram always
1160+
1161+
set value rs2
1162+
1163+
atomic_store_word:
1164+
op add ret @counter 1
1165+
jump swap_endianness always
1166+
1167+
write result ram variable
1168+
1169+
set instruction value
1170+
set decode_var null
1171+
op add decode_ret @counter 1
1172+
jump decode always
1173+
1174+
jump end_instruction always
1175+
1176+
AMOSWAP.W:
1177+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1178+
set amo_op 0 # swap
1179+
1180+
amo:
1181+
# check address and alignment
1182+
jump inaccessible_store lessThan rs1 RAM_START
1183+
jump inaccessible_store greaterThanEq rs1 RAM_END
1184+
1185+
op mod alignment rs1 4
1186+
jump misaligned_load notEqual alignment 0
1187+
1188+
# read
1189+
set address rs1
1190+
op add ret @counter 1
1191+
jump load_word always
1192+
1193+
# put value in rd
1194+
jump amo__no_write_rd equal arg3 0
1195+
write result REGISTERS arg3
1196+
amo__no_write_rd:
1197+
1198+
# modify
1199+
op add @counter @counter amo_op
1200+
1201+
set result rs2; jump amo__done_modify always # swap
1202+
op add result result rs2; jump amo__done_modify always # add
1203+
op and result result rs2; jump amo__done_modify always # and
1204+
op or result result rs2; jump amo__done_modify always # or
1205+
op xor result result rs2; jump amo__done_modify always # xor
1206+
op min result result rs2; jump amo__done_modify always # min
1207+
op max result result rs2 # max
1208+
1209+
amo__done_modify:
1210+
1211+
# write
1212+
op and value result 0xffffffff
1213+
jump atomic_store_word always
1214+
1215+
AMOADD.W:
1216+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1217+
set amo_op 2 # add
1218+
jump amo always
1219+
1220+
AMOAND.W:
1221+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1222+
set amo_op 4 # and
1223+
jump amo always
1224+
1225+
AMOOR.W:
1226+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1227+
set amo_op 6 # or
1228+
jump amo always
1229+
1230+
AMOXOR.W:
1231+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1232+
set amo_op 8 # xor
1233+
jump amo always
1234+
1235+
AMOMIN.W:
1236+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1237+
op add ret @counter 1
1238+
jump swap_signedness_rs1_rs2 always
1239+
set amo_op 10 # min
1240+
jump amo always
1241+
1242+
AMOMAX.W:
1243+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1244+
op add ret @counter 1
1245+
jump swap_signedness_rs1_rs2 always
1246+
set amo_op 12 # max
1247+
jump amo always
1248+
1249+
AMOMINU.W:
1250+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1251+
set amo_op 10 # min
1252+
jump amo always
1253+
1254+
AMOMAXU.W:
1255+
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1256+
set amo_op 12 # max
1257+
jump amo always
1258+
10731259
ADDI:
10741260
# I-type: arg1=rs1, arg2=imm, arg3=rd
10751261
jump end_instruction equal arg3 0
@@ -1088,7 +1274,7 @@ SLTI:
10881274
op add ret @counter 1
10891275
jump swap_signedness_rs1_rs2 always
10901276

1091-
op lessThan result result1 result2
1277+
op lessThan result rs1 rs2
10921278

10931279
write result REGISTERS arg3
10941280
jump end_instruction always
@@ -1259,7 +1445,7 @@ MULH:
12591445
mulh_s_u:
12601446
jump end_instruction equal arg3 0
12611447

1262-
op mul result result1 result2
1448+
op mul result rs1 rs2
12631449
op shr result result 32
12641450
op and result result 0xffffffff
12651451

@@ -1270,25 +1456,22 @@ MULHSU:
12701456
# R-type: arg1=rs1, arg2=rs2, arg3=rd
12711457
op add ret @counter 1
12721458
jump swap_signedness_rs1 always
1273-
set result2 rs2
12741459
jump mulh_s_u always
12751460

12761461
MULHU:
12771462
# R-type: arg1=rs1, arg2=rs2, arg3=rd
1278-
set result1 rs1
1279-
set result2 rs2
12801463
jump mulh_s_u always
12811464

12821465
DIV:
12831466
# R-type: arg1=rs1, arg2=rs2, arg3=rd
12841467
jump end_instruction equal arg3 0
12851468

1286-
jump div_by_zero equal arg2 0
1469+
jump div_by_zero equal rs2 0
12871470

12881471
op add ret @counter 1
12891472
jump swap_signedness_rs1_rs2 always
12901473

1291-
op idiv result result1 result2
1474+
op idiv result rs1 rs2
12921475
op and result result 0xffffffff
12931476

12941477
write result REGISTERS arg3
@@ -1298,7 +1481,7 @@ DIVU:
12981481
# R-type: arg1=rs1, arg2=rs2, arg3=rd
12991482
jump end_instruction equal arg3 0
13001483

1301-
jump div_by_zero equal arg2 0
1484+
jump div_by_zero equal rs2 0
13021485

13031486
op idiv result rs1 rs2
13041487

@@ -1314,12 +1497,12 @@ REM:
13141497
# R-type: arg1=rs1, arg2=rs2, arg3=rd
13151498
jump end_instruction equal arg3 0
13161499

1317-
jump rem_by_zero equal arg2 0
1500+
jump rem_by_zero equal rs2 0
13181501

13191502
op add ret @counter 1
13201503
jump swap_signedness_rs1_rs2 always
13211504

1322-
op mod result result1 result2
1505+
op mod result rs1 rs2
13231506
op and result result 0xffffffff
13241507

13251508
write result REGISTERS arg3
@@ -1329,7 +1512,7 @@ REMU:
13291512
# R-type: arg1=rs1, arg2=rs2, arg3=rd
13301513
jump end_instruction equal arg3 0
13311514

1332-
jump rem_by_zero equal arg2 0
1515+
jump rem_by_zero equal rs2 0
13331516

13341517
op mod result rs1 rs2
13351518

src/tools/registers.mlog

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ format_bin__next:
453453
set @counter ret
454454

455455
format_op_id:
456-
jump format_op_id__unknown greaterThan n 46
456+
jump format_op_id__unknown greaterThan n 64
457457
op mul n n 2
458458
op add @counter @counter n
459459
format "illegal_instruction"; set @counter ret
@@ -510,6 +510,17 @@ format_op_id:
510510
format "DIVU"; set @counter ret
511511
format "REM"; set @counter ret
512512
format "REMU"; set @counter ret
513+
format "AMOADD.W"; set @counter ret
514+
format "AMOSWAP.W"; set @counter ret
515+
format "LR.W"; set @counter ret
516+
format "SC.W"; set @counter ret
517+
format "AMOXOR.W"; set @counter ret
518+
format "AMOOR.W"; set @counter ret
519+
format "AMOAND.W"; set @counter ret
520+
format "AMOMIN.W"; set @counter ret
521+
format "AMOMAX.W"; set @counter ret
522+
format "AMOMINU.W"; set @counter ret
523+
format "AMOMAXU.W"; set @counter ret
513524
format_op_id__unknown:
514525
format n; set @counter ret
515526

0 commit comments

Comments
 (0)