riscv64: Improve signed and zero extend codegen (#5844)
* riscv64: Remove unused code * riscv64: Group extend rules * riscv64: Remove more unused rules * riscv64: Cleanup existing extension rules * riscv64: Move the existing Extend rules to ISLE * riscv64: Use `sext.w` when extending * riscv64: Remove duplicate extend tests * riscv64: Use `zbb` instructions when extending values * riscv64: Use `zbkb` extensions when zero extending * riscv64: Enable additional tests for extend i128 * riscv64: Fix formatting for `Inst::Extend` * riscv64: Reverse register for pack * riscv64: Misc Cleanups * riscv64: Cleanup extend rules
This commit is contained in:
@@ -845,16 +845,6 @@ impl Inst {
|
||||
x
|
||||
};
|
||||
|
||||
fn format_extend_op(signed: bool, from_bits: u8, _to_bits: u8) -> String {
|
||||
let type_name = match from_bits {
|
||||
1 => "b1",
|
||||
8 => "b",
|
||||
16 => "h",
|
||||
32 => "w",
|
||||
_ => unreachable!("from_bits:{:?}", from_bits),
|
||||
};
|
||||
format!("{}ext.{}", if signed { "s" } else { "u" }, type_name)
|
||||
}
|
||||
fn format_frm(rounding_mode: Option<FRM>) -> String {
|
||||
if let Some(r) = rounding_mode {
|
||||
format!(",{}", r.to_static_str(),)
|
||||
@@ -1341,15 +1331,23 @@ impl Inst {
|
||||
} => {
|
||||
let rs_s = format_reg(rs, allocs);
|
||||
let rd = format_reg(rd.to_reg(), allocs);
|
||||
// check if it is a load constant.
|
||||
if alu_op == AluOPRRI::Addi && rs == zero_reg() {
|
||||
format!("li {},{}", rd, imm12.as_i16())
|
||||
} else if alu_op == AluOPRRI::Xori && imm12.as_i16() == -1 {
|
||||
format!("not {},{}", rd, rs_s)
|
||||
} else {
|
||||
if alu_op.option_funct12().is_some() {
|
||||
|
||||
// Some of these special cases are better known as
|
||||
// their pseudo-instruction version, so prefer printing those.
|
||||
match (alu_op, rs, imm12) {
|
||||
(AluOPRRI::Addi, rs, _) if rs == zero_reg() => {
|
||||
return format!("li {},{}", rd, imm12.as_i16());
|
||||
}
|
||||
(AluOPRRI::Addiw, _, imm12) if imm12.as_i16() == 0 => {
|
||||
return format!("sext.w {},{}", rd, rs_s);
|
||||
}
|
||||
(AluOPRRI::Xori, _, imm12) if imm12.as_i16() == -1 => {
|
||||
return format!("not {},{}", rd, rs_s);
|
||||
}
|
||||
(alu_op, _, _) if alu_op.option_funct12().is_some() => {
|
||||
format!("{} {},{}", alu_op.op_name(), rd, rs_s)
|
||||
} else {
|
||||
}
|
||||
(alu_op, _, imm12) => {
|
||||
format!("{} {},{},{}", alu_op.op_name(), rd, rs_s, imm12.as_i16())
|
||||
}
|
||||
}
|
||||
@@ -1402,16 +1400,17 @@ impl Inst {
|
||||
rn,
|
||||
signed,
|
||||
from_bits,
|
||||
to_bits,
|
||||
..
|
||||
} => {
|
||||
let rn = format_reg(rn, allocs);
|
||||
let rm = format_reg(rd.to_reg(), allocs);
|
||||
format!(
|
||||
"{} {},{}",
|
||||
format_extend_op(signed, from_bits, to_bits),
|
||||
rm,
|
||||
rn
|
||||
)
|
||||
let rd = format_reg(rd.to_reg(), allocs);
|
||||
return if signed == false && from_bits == 8 {
|
||||
format!("andi {rd},{rn}")
|
||||
} else {
|
||||
let op = if signed { "srai" } else { "srli" };
|
||||
let shift_bits = (64 - from_bits) as i16;
|
||||
format!("slli {rd},{rn},{shift_bits}; {op} {rd},{rd},{shift_bits}")
|
||||
};
|
||||
}
|
||||
&MInst::AjustSp { amount } => {
|
||||
format!("{} sp,{:+}", "add", amount)
|
||||
|
||||
Reference in New Issue
Block a user