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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -135,13 +135,17 @@ 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('_ => {}')
|
||||
# Allow for un-encoded ghost instructions.
|
||||
# Verifier checks the details.
|
||||
with fmt.indented('if encoding.is_legal() {', '}'):
|
||||
fmt.line('bad_encoding(func, inst);')
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user