Allow for unencoded instructions in the binemit tests.

If an instruction doesn't have an associated encoding, use the standard
TargetIsa hook to encode it.

The test still fails if an instruction can't be encoded. There is no
legalization step.
This commit is contained in:
Jakob Stoklund Olesen
2017-03-29 09:48:25 -07:00
parent 36eb39a1f8
commit 1d6049b8f8
3 changed files with 28 additions and 4 deletions

View File

@@ -336,3 +336,11 @@ that instruction is compared to the directive::
[R#200c,%x8] v11 = isub v1, v2 ; bin: 40628433 [R#200c,%x8] v11 = isub v1, v2 ; bin: 40628433
return return
} }
If any instructions are unencoded (indicated with a `[-]` encoding field), they
will be encoded using the same mechanism as the legalizer uses. However,
illegal instructions for the ISA won't be expanded into other instruction
sequences. Instead the test will fail.
Value locations must be present if they are required to compute the binary
bits. Missing value locations will cause the test to crash.

View File

@@ -6,7 +6,7 @@ function int32() {
ebb0: ebb0:
[-,%x5] v1 = iconst.i32 1 [-,%x5] v1 = iconst.i32 1
[-,%x6] v2 = iconst.i32 2 [-,%x6] v2 = iconst.i32 2
[R#0c,%x7] v10 = iadd v1, v2 ; bin: 006283b3 [-,%x7] v10 = iadd v1, v2 ; bin: 006283b3
[R#200c,%x8] v11 = isub v1, v2 ; bin: 40628433 [R#200c,%x8] v11 = isub v1, v2 ; bin: 40628433
[R#10c] v12 = imul v1, v2 [R#10c] v12 = imul v1, v2
return return

View File

@@ -3,7 +3,7 @@
//! The `binemit` test command generates binary machine code for every instruction in the input //! The `binemit` test command generates binary machine code for every instruction in the input
//! functions and compares the results to the expected output. //! functions and compares the results to the expected output.
use std::borrow::{Borrow, Cow}; use std::borrow::Cow;
use std::fmt::Write; use std::fmt::Write;
use cretonne::binemit; use cretonne::binemit;
use cretonne::ir; use cretonne::ir;
@@ -60,7 +60,7 @@ impl SubTest for TestBinEmit {
} }
fn is_mutating(&self) -> bool { fn is_mutating(&self) -> bool {
false true
} }
fn needs_isa(&self) -> bool { fn needs_isa(&self) -> bool {
@@ -71,7 +71,7 @@ impl SubTest for TestBinEmit {
let isa = context.isa.expect("binemit needs an ISA"); let isa = context.isa.expect("binemit needs an ISA");
// TODO: Run a verifier pass over the code first to detect any bad encodings or missing/bad // TODO: Run a verifier pass over the code first to detect any bad encodings or missing/bad
// value locations. The current error reporting is just crashing... // value locations. The current error reporting is just crashing...
let func = func.borrow(); let mut func = func.into_owned();
let mut sink = TextSink { text: String::new() }; let mut sink = TextSink { text: String::new() };
@@ -85,6 +85,22 @@ impl SubTest for TestBinEmit {
comment.text)) comment.text))
} }
}; };
// Compute an encoding for `inst` if one wasn't provided.
if !func.encodings
.get(inst)
.map(|e| e.is_legal())
.unwrap_or(false) {
match isa.encode(&func.dfg, &func.dfg[inst]) {
Ok(enc) => *func.encodings.ensure(inst) = enc,
Err(_) => {
return Err(format!("{} can't be encoded: {}",
inst,
func.dfg.display_inst(inst)))
}
}
}
sink.text.clear(); sink.text.clear();
isa.emit_inst(&func, inst, &mut sink); isa.emit_inst(&func, inst, &mut sink);
let have = sink.text.trim(); let have = sink.text.trim();