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:
Afonso Bordado
2023-02-22 17:41:14 +00:00
committed by GitHub
parent 6e6a1034d7
commit f6c6bc2155
68 changed files with 1922 additions and 1585 deletions

View File

@@ -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)