Skip to content

Commit 8507ff7

Browse files
committed
Update RISC-V bitmanip lifting and WCH fixtures
Use first-class LLIL ops for RISC-V Zbb min/max, clz/ctz, popcount, and rev8 lifting instead of custom branches or intrinsics. Rename the WCH architecture to rv32gc_wch and update its calling convention registration for the current Rust API. Add separate test fixtures for Zba/Zbb/Zbs and WCH instruction decoding.
1 parent 0f83383 commit 8507ff7

1 file changed

Lines changed: 21 additions & 51 deletions

File tree

arch/riscv/src/lib.rs

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,34 +1289,32 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
12891289
Op::RorI(i) => simple_i!(i, |rs1, imm| il.ror(max_width, rs1, imm)),
12901290
Op::Clz(i) => {
12911291
let rd = Register::from(i.rd());
1292-
let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
12931292

12941293
if i.rd().id() == 0 {
12951294
il.nop().append();
12961295
} else {
1297-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Clz), [rs1])
1298-
.append();
1296+
let rs1 = Register::from(i.rs1());
1297+
il.set_reg(max_width, rd, il.clz(max_width, rs1)).append();
12991298
}
13001299
}
13011300
Op::Ctz(i) => {
13021301
let rd = Register::from(i.rd());
1303-
let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
13041302

13051303
if i.rd().id() == 0 {
13061304
il.nop().append();
13071305
} else {
1308-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Ctz), [rs1])
1309-
.append();
1306+
let rs1 = Register::from(i.rs1());
1307+
il.set_reg(max_width, rd, il.ctz(max_width, rs1)).append();
13101308
}
13111309
}
13121310
Op::Cpop(i) => {
13131311
let rd = Register::from(i.rd());
1314-
let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
13151312

13161313
if i.rd().id() == 0 {
13171314
il.nop().append();
13181315
} else {
1319-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Popcount), [rs1])
1316+
let rs1 = Register::from(i.rs1());
1317+
il.set_reg(max_width, rd, il.popcnt(max_width, rs1))
13201318
.append();
13211319
}
13221320
}
@@ -1333,13 +1331,12 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
13331331
}
13341332
Op::Rev8(i) => {
13351333
let rd = Register::from(i.rd());
1336-
let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
13371334

13381335
if i.rd().id() == 0 {
13391336
il.nop().append();
13401337
} else {
1341-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Rev8), [rs1])
1342-
.append();
1338+
let rs1 = Register::from(i.rs1());
1339+
il.set_reg(max_width, rd, il.bswap(max_width, rs1)).append();
13431340
}
13441341
}
13451342

@@ -1396,37 +1393,10 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
13961393
let shamt = il.and(max_width, rs2, (max_width * 8 - 1) as u64);
13971394
il.ror(max_width, rs1, shamt)
13981395
}),
1399-
Op::Max(r) | Op::MaxU(r) | Op::Min(r) | Op::MinU(r) => {
1400-
let rd = Register::from(r.rd());
1401-
if rd.id.0 == 0 {
1402-
il.nop().append()
1403-
} else {
1404-
let rs1 = Register::from(r.rs1());
1405-
let rs2 = Register::from(r.rs2());
1406-
1407-
let cond = match op {
1408-
Op::Max(..) => il.cmp_sgt(max_width, rs1, rs2),
1409-
Op::MaxU(..) => il.cmp_ugt(max_width, rs1, rs2),
1410-
Op::Min(..) => il.cmp_slt(max_width, rs1, rs2),
1411-
Op::MinU(..) => il.cmp_ult(max_width, rs1, rs2),
1412-
_ => unreachable!(),
1413-
};
1414-
1415-
let mut t = LowLevelILLabel::new();
1416-
let mut f = LowLevelILLabel::new();
1417-
let mut end = LowLevelILLabel::new();
1418-
1419-
il.if_expr(cond, &mut t, &mut f).append();
1420-
1421-
il.mark_label(&mut t);
1422-
il.set_reg(max_width, rd, rs1).append();
1423-
il.goto(&mut end).append();
1424-
1425-
il.mark_label(&mut f);
1426-
il.set_reg(max_width, rd, rs2).append();
1427-
il.mark_label(&mut end);
1428-
}
1429-
}
1396+
Op::Max(r) => simple_r!(r, |rs1, rs2| il.max_signed(max_width, rs1, rs2)),
1397+
Op::MaxU(r) => simple_r!(r, |rs1, rs2| il.max_unsigned(max_width, rs1, rs2)),
1398+
Op::Min(r) => simple_r!(r, |rs1, rs2| il.min_signed(max_width, rs1, rs2)),
1399+
Op::MinU(r) => simple_r!(r, |rs1, rs2| il.min_unsigned(max_width, rs1, rs2)),
14301400

14311401
Op::WchMcpy(r) => {
14321402
let dst = LiftableLowLevelIL::lift(il, Register::from(r.rd()));
@@ -1453,37 +1423,37 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
14531423
Op::RorIW(i) => simple_i!(i, |rs1, imm| il.sx(max_width, il.ror(4, rs1, imm))),
14541424
Op::ClzW(i) => {
14551425
let rd = Register::from(i.rd());
1456-
let rs1 =
1457-
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
14581426

14591427
if i.rd().id() == 0 {
14601428
il.nop().append();
14611429
} else {
1462-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Clz), [rs1])
1430+
let rs1 =
1431+
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
1432+
il.set_reg(max_width, rd, il.zx(max_width, il.clz(4, rs1)))
14631433
.append();
14641434
}
14651435
}
14661436
Op::CtzW(i) => {
14671437
let rd = Register::from(i.rd());
1468-
let rs1 =
1469-
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
14701438

14711439
if i.rd().id() == 0 {
14721440
il.nop().append();
14731441
} else {
1474-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Ctz), [rs1])
1442+
let rs1 =
1443+
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
1444+
il.set_reg(max_width, rd, il.zx(max_width, il.ctz(4, rs1)))
14751445
.append();
14761446
}
14771447
}
14781448
Op::CpopW(i) => {
14791449
let rd = Register::from(i.rd());
1480-
let rs1 =
1481-
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
14821450

14831451
if i.rd().id() == 0 {
14841452
il.nop().append();
14851453
} else {
1486-
il.intrinsic([rd], RiscVIntrinsic::<D>::from(Intrinsic::Popcount), [rs1])
1454+
let rs1 =
1455+
LiftableLowLevelILWithSize::lift_with_size(il, Register::from(i.rs1()), 4);
1456+
il.set_reg(max_width, rd, il.zx(max_width, il.popcnt(4, rs1)))
14871457
.append();
14881458
}
14891459
}

0 commit comments

Comments
 (0)