cranelift: Sign extend Imm64 immediates

When an instruction has an `Imm64` immediate, but operates on values of a
narrower width, we need to sign extend the value.

Fixes #1095
This commit is contained in:
Nick Fitzgerald
2020-05-12 14:19:45 -07:00
parent 0bc0503f3f
commit 9b867b09c7
4 changed files with 103 additions and 1 deletions

View File

@@ -874,17 +874,32 @@ fn gen_format_constructor(format: &InstructionFormat, fmt: &mut Formatter) {
args.join(", ")
);
let imms_need_sign_extension = format
.imm_fields
.iter()
.any(|f| f.kind.rust_type == "ir::immediates::Imm64");
fmt.doc_comment(format.to_string());
fmt.line("#[allow(non_snake_case)]");
fmtln!(fmt, "fn {} {{", proto);
fmt.indent(|fmt| {
// Generate the instruction data.
fmtln!(fmt, "let data = ir::InstructionData::{} {{", format.name);
fmtln!(
fmt,
"let{} data = ir::InstructionData::{} {{",
if imms_need_sign_extension { " mut" } else { "" },
format.name
);
fmt.indent(|fmt| {
fmt.line("opcode,");
gen_member_inits(format, fmt);
});
fmtln!(fmt, "};");
if imms_need_sign_extension {
fmtln!(fmt, "data.sign_extend_immediates(ctrl_typevar);");
}
fmt.line("self.build(data, ctrl_typevar)");
});
fmtln!(fmt, "}");