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:
|
ebb2:
|
||||||
jump ebb1(v0)
|
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>'
|
'pub fn emit_inst<CS: CodeSink + ?Sized>'
|
||||||
'(func: &Function, inst: Inst, '
|
'(func: &Function, inst: Inst, '
|
||||||
'divert: &mut RegDiversions, sink: &mut CS) {', '}'):
|
'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() {', '}'):
|
with fmt.indented('match func.encodings[inst].recipe() {', '}'):
|
||||||
for i, recipe in enumerate(isa.all_recipes):
|
for i, recipe in enumerate(isa.all_recipes):
|
||||||
fmt.comment(recipe.name)
|
fmt.comment(recipe.name)
|
||||||
with fmt.indented('{} => {{'.format(i), '}'):
|
with fmt.indented('{} => {{'.format(i), '}'):
|
||||||
gen_recipe(recipe, fmt)
|
gen_recipe(recipe, fmt)
|
||||||
fmt.line('_ => {}')
|
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);')
|
fmt.line('bad_encoding(func, inst);')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ use flowgraph::ControlFlowGraph;
|
|||||||
use ir::entities::AnyEntity;
|
use ir::entities::AnyEntity;
|
||||||
use ir::instructions::{InstructionFormat, BranchInfo, ResolvedConstraint, CallInfo};
|
use ir::instructions::{InstructionFormat, BranchInfo, ResolvedConstraint, CallInfo};
|
||||||
use ir::{types, Function, ValueDef, Ebb, Inst, SigRef, FuncRef, ValueList, JumpTable, StackSlot,
|
use ir::{types, Function, ValueDef, Ebb, Inst, SigRef, FuncRef, ValueList, JumpTable, StackSlot,
|
||||||
Value, Type};
|
Value, Type, Opcode};
|
||||||
use isa::TargetIsa;
|
use isa::TargetIsa;
|
||||||
use std::error as std_error;
|
use std::error as std_error;
|
||||||
use std::fmt::{self, Display, Formatter};
|
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.
|
// Instructions with side effects are not allowed to be ghost instructions.
|
||||||
let opcode = self.func.dfg[inst].opcode();
|
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() {
|
if opcode.is_branch() {
|
||||||
return err!(inst, "Branch must have an encoding");
|
return err!(inst, "Branch must have an encoding");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user