Don't require that the fallthrough instruction has an encoding.

A fallthrough jump is actually represented as 0 bytes, so no encoding is
needed.

Also allow for unencoded instructions in the generated emit_inst
implementations. The verifier has stricter rules for when this is
allowed.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-19 09:30:04 -07:00
parent 0a7087732e
commit 5a81831c69
3 changed files with 24 additions and 3 deletions

View File

@@ -32,3 +32,14 @@ ebb1(v2: i32):
ebb2:
jump ebb1(v0)
}
function %br_if_fallthrough(i32) -> i32 {
ebb0(v0: i32):
v1 = iconst.i32 1
brz v0, ebb1(v1)
; This jump gets converted to a fallthrough.
jump ebb1(v0)
ebb1(v2: i32):
return v2
}

View File

@@ -135,14 +135,18 @@ def gen_isa(isa, fmt):
'pub fn emit_inst<CS: CodeSink + ?Sized>'
'(func: &Function, inst: Inst, '
'divert: &mut RegDiversions, sink: &mut CS) {', '}'):
fmt.line('let bits = func.encodings[inst].bits();')
fmt.line('let encoding = func.encodings[inst];')
fmt.line('let bits = encoding.bits();')
with fmt.indented('match func.encodings[inst].recipe() {', '}'):
for i, recipe in enumerate(isa.all_recipes):
fmt.comment(recipe.name)
with fmt.indented('{} => {{'.format(i), '}'):
gen_recipe(recipe, fmt)
fmt.line('_ => {}')
fmt.line('bad_encoding(func, inst);')
# Allow for un-encoded ghost instructions.
# Verifier checks the details.
with fmt.indented('if encoding.is_legal() {', '}'):
fmt.line('bad_encoding(func, inst);')
def generate(isas, out_dir):

View File

@@ -57,7 +57,7 @@ use flowgraph::ControlFlowGraph;
use ir::entities::AnyEntity;
use ir::instructions::{InstructionFormat, BranchInfo, ResolvedConstraint, CallInfo};
use ir::{types, Function, ValueDef, Ebb, Inst, SigRef, FuncRef, ValueList, JumpTable, StackSlot,
Value, Type};
Value, Type, Opcode};
use isa::TargetIsa;
use std::error as std_error;
use std::fmt::{self, Display, Formatter};
@@ -711,6 +711,12 @@ impl<'a> Verifier<'a> {
// Instructions with side effects are not allowed to be ghost instructions.
let opcode = self.func.dfg[inst].opcode();
// The `fallthrough` instruction is marked as a terminator and a branch, but it is not
// required to have an encoding.
if opcode == Opcode::Fallthrough {
return Ok(());
}
if opcode.is_branch() {
return err!(inst, "Branch must have an encoding");
}