Generate a RECIPE_PREDICATES table for each ISA.
It turns out that most encoding predicates are expressed as recipe predicates. This means that the encoding tables can be more compact since we can check the recipe predicate separately from individual instruction predicates, and the recipe number is already present in the table. - Don't combine recipe and encoding-specific predicates when creating an Encoding. Keep them separate. - Generate a table of recipe predicates with function pointers. Many of these are null. - Check any recipe predicate before accepting a recipe+bits pair. This has the effect of making almost all instruction predicates CODE_ALWAYS.
This commit is contained in:
@@ -4,7 +4,7 @@ use ir::InstructionData;
|
||||
use ir::types;
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::enc_tables::*;
|
||||
use isa::encoding::RecipeSizing;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-arm32.rs"));
|
||||
|
||||
@@ -73,6 +73,7 @@ impl TargetIsa for Isa {
|
||||
.and_then(|enclist_offset| {
|
||||
Ok(Encodings::new(enclist_offset,
|
||||
&enc_tables::ENCLISTS[..],
|
||||
&enc_tables::RECIPE_PREDICATES[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_view()))
|
||||
|
||||
@@ -4,7 +4,7 @@ use ir::InstructionData;
|
||||
use ir::types;
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::enc_tables::*;
|
||||
use isa::encoding::RecipeSizing;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-arm64.rs"));
|
||||
|
||||
@@ -66,6 +66,7 @@ impl TargetIsa for Isa {
|
||||
.and_then(|enclist_offset| {
|
||||
Ok(Encodings::new(enclist_offset,
|
||||
&enc_tables::ENCLISTS[..],
|
||||
&enc_tables::RECIPE_PREDICATES[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_view()))
|
||||
|
||||
@@ -9,6 +9,13 @@ use isa::{Encoding, Legalize};
|
||||
use settings::PredicateView;
|
||||
use std::ops::Range;
|
||||
|
||||
/// A recipe predicate.
|
||||
///
|
||||
/// This is a predicate function capable of testing ISA and instruction predicates simultaneously.
|
||||
///
|
||||
/// A None predicate is always satisfied.
|
||||
pub type RecipePredicate = Option<fn(PredicateView, &InstructionData) -> bool>;
|
||||
|
||||
/// Legalization action to perform when no encoding can be found for an instruction.
|
||||
///
|
||||
/// This is an index into an ISA-specific table of legalization actions.
|
||||
@@ -147,6 +154,7 @@ pub struct Encodings<'a> {
|
||||
inst: &'a InstructionData,
|
||||
instp: fn(&InstructionData, EncListEntry) -> bool,
|
||||
isa_predicates: PredicateView<'a>,
|
||||
recipe_predicates: &'static [RecipePredicate],
|
||||
}
|
||||
|
||||
impl<'a> Encodings<'a> {
|
||||
@@ -155,8 +163,9 @@ impl<'a> Encodings<'a> {
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `offset` an offset into encoding list returned by `lookup_enclist` function.
|
||||
/// - `inst` the current instruction.
|
||||
/// - `enclist` a list of encoding entries.
|
||||
/// - `recipe_predicates` is a slice of recipe predicate functions.
|
||||
/// - `inst` the current instruction.
|
||||
/// - `instp` an instruction predicate number to be evaluated on the current instruction.
|
||||
/// - `isa_predicate_bytes` an ISA flags as a slice of bytes to evaluate an ISA predicate number
|
||||
/// on the current instruction.
|
||||
@@ -166,6 +175,7 @@ impl<'a> Encodings<'a> {
|
||||
/// or `None`.
|
||||
pub fn new(offset: usize,
|
||||
enclist: &'static [EncListEntry],
|
||||
recipe_predicates: &'static [RecipePredicate],
|
||||
inst: &'a InstructionData,
|
||||
instp: fn(&InstructionData, EncListEntry) -> bool,
|
||||
isa_predicates: PredicateView<'a>)
|
||||
@@ -176,6 +186,15 @@ impl<'a> Encodings<'a> {
|
||||
inst,
|
||||
instp,
|
||||
isa_predicates,
|
||||
recipe_predicates,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the predicate for `recipe` is satisfied.
|
||||
fn check_recipe(&self, recipe: u16) -> bool {
|
||||
match self.recipe_predicates[recipe as usize] {
|
||||
Some(p) => p(self.isa_predicates, self.inst),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,13 +207,13 @@ impl<'a> Iterator for Encodings<'a> {
|
||||
let pred = self.enclist[self.offset];
|
||||
if pred <= CODE_ALWAYS {
|
||||
// This is an instruction predicate followed by recipe and encbits entries.
|
||||
self.offset += 3;
|
||||
if pred == CODE_ALWAYS || (self.instp)(self.inst, pred) {
|
||||
let encoding = Encoding::new(self.enclist[self.offset + 1],
|
||||
self.enclist[self.offset + 2]);
|
||||
self.offset += 3;
|
||||
return Some(encoding);
|
||||
} else {
|
||||
self.offset += 3;
|
||||
let recipe = self.enclist[self.offset - 2];
|
||||
if self.check_recipe(recipe) {
|
||||
let encoding = Encoding::new(recipe, self.enclist[self.offset - 1]);
|
||||
return Some(encoding);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This is an ISA predicate entry.
|
||||
|
||||
@@ -4,7 +4,7 @@ use ir::types;
|
||||
use ir::{Opcode, InstructionData};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::enc_tables::*;
|
||||
use isa::encoding::RecipeSizing;
|
||||
use predicates;
|
||||
use super::registers::*;
|
||||
|
||||
@@ -73,6 +73,7 @@ impl TargetIsa for Isa {
|
||||
.and_then(|enclist_offset| {
|
||||
Ok(Encodings::new(enclist_offset,
|
||||
&enc_tables::ENCLISTS[..],
|
||||
&enc_tables::RECIPE_PREDICATES[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_view()))
|
||||
|
||||
@@ -5,7 +5,7 @@ use ir::types;
|
||||
use ir::{Opcode, InstructionData};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::enc_tables::*;
|
||||
use isa::encoding::RecipeSizing;
|
||||
use predicates;
|
||||
use super::registers::*;
|
||||
|
||||
@@ -73,6 +73,7 @@ impl TargetIsa for Isa {
|
||||
.and_then(|enclist_offset| {
|
||||
Ok(Encodings::new(enclist_offset,
|
||||
&enc_tables::ENCLISTS[..],
|
||||
&enc_tables::RECIPE_PREDICATES[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_view()))
|
||||
|
||||
Reference in New Issue
Block a user