Add a PredicateView type to abstract the predicate bit vector a bit.
The encoding tables contain references to numbered ISA predicates. - Give the ISA Flags types a predicate_view() method which returns a PredicateView. - Delete the old predicate_bytes() method which returned a raw &[u8]. - Use a 'static lifetime for the encoding list slice in the Encodings iterator, and a single 'a lifetime for everything else.
This commit is contained in:
@@ -87,16 +87,20 @@ def gen_getters(sgrp, fmt):
|
||||
"""
|
||||
fmt.doc_comment("User-defined settings.")
|
||||
with fmt.indented('impl Flags {', '}'):
|
||||
fmt.doc_comment('Returns inner slice of bytes.')
|
||||
fmt.doc_comment('The byte-sized settings are not included.')
|
||||
with fmt.indented('pub fn predicate_bytes(&self) -> &[u8] {', '}'):
|
||||
fmt.line('&self.bytes[{}..]'.format(sgrp.boolean_offset))
|
||||
fmt.doc_comment('Dynamic numbered predicate getter.')
|
||||
fmt.doc_comment('Get a view of the boolean predicates.')
|
||||
with fmt.indented(
|
||||
'pub fn numbered_predicate(&self, p: usize) -> bool {', '}'):
|
||||
fmt.line(
|
||||
'self.bytes[{} + p/8] & (1 << (p%8)) != 0'
|
||||
.format(sgrp.boolean_offset))
|
||||
'pub fn predicate_view(&self) -> ::settings::PredicateView {',
|
||||
'}'):
|
||||
fmt.format(
|
||||
'::settings::PredicateView::new(&self.bytes[{}..])',
|
||||
sgrp.boolean_offset)
|
||||
if sgrp.settings:
|
||||
fmt.doc_comment('Dynamic numbered predicate getter.')
|
||||
with fmt.indented(
|
||||
'fn numbered_predicate(&self, p: usize) -> bool {', '}'):
|
||||
fmt.line(
|
||||
'self.bytes[{} + p / 8] & (1 << (p % 8)) != 0'
|
||||
.format(sgrp.boolean_offset))
|
||||
for setting in sgrp.settings:
|
||||
gen_getter(setting, sgrp, fmt)
|
||||
for pred in sgrp.named_predicates:
|
||||
|
||||
@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn legal_encodings<'a, 'b>(&'a self,
|
||||
_dfg: &'b ir::DataFlowGraph,
|
||||
inst: &'b ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a, 'b>, Legalize> {
|
||||
fn legal_encodings<'a>(&'a self,
|
||||
_dfg: &'a ir::DataFlowGraph,
|
||||
inst: &'a ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a>, Legalize> {
|
||||
lookup_enclist(ctrl_typevar,
|
||||
inst.opcode(),
|
||||
self.cpumode,
|
||||
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
|
||||
&enc_tables::ENCLISTS[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_bytes()))
|
||||
self.isa_flags.predicate_view()))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ impl TargetIsa for Isa {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn legal_encodings<'a, 'b>(&'a self,
|
||||
_dfg: &'b ir::DataFlowGraph,
|
||||
inst: &'b ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a, 'b>, Legalize> {
|
||||
fn legal_encodings<'a>(&'a self,
|
||||
_dfg: &'a ir::DataFlowGraph,
|
||||
inst: &'a ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a>, Legalize> {
|
||||
lookup_enclist(ctrl_typevar,
|
||||
inst.opcode(),
|
||||
&enc_tables::LEVEL1_A64[..],
|
||||
@@ -68,7 +68,7 @@ impl TargetIsa for Isa {
|
||||
&enc_tables::ENCLISTS[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_bytes()))
|
||||
self.isa_flags.predicate_view()))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
//!
|
||||
//! This module contains types and functions for working with the encoding tables generated by
|
||||
//! `lib/cretonne/meta/gen_encoding.py`.
|
||||
|
||||
use constant_hash::{Table, probe};
|
||||
use ir::{Type, Opcode, InstructionData};
|
||||
use isa::{Encoding, Legalize};
|
||||
use constant_hash::{Table, probe};
|
||||
use settings::PredicateView;
|
||||
use std::ops::Range;
|
||||
|
||||
/// Level 1 hash table entry.
|
||||
@@ -127,15 +129,15 @@ const CODE_ALWAYS: EncListEntry = PRED_MASK;
|
||||
const CODE_FAIL: EncListEntry = 0xffff;
|
||||
|
||||
/// An iterator over legal encodings for the instruction.
|
||||
pub struct Encodings<'a, 'b> {
|
||||
pub struct Encodings<'a> {
|
||||
offset: usize,
|
||||
enclist: &'b [EncListEntry],
|
||||
inst: &'b InstructionData,
|
||||
enclist: &'static [EncListEntry],
|
||||
inst: &'a InstructionData,
|
||||
instp: fn(&InstructionData, EncListEntry) -> bool,
|
||||
isa_predicate_bytes: &'a [u8],
|
||||
isa_predicates: PredicateView<'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Encodings<'a, 'b> {
|
||||
impl<'a> Encodings<'a> {
|
||||
/// Creates a new instance of `Encodings`.
|
||||
///
|
||||
/// # Parameters
|
||||
@@ -151,29 +153,25 @@ impl<'a, 'b> Encodings<'a, 'b> {
|
||||
/// encoding lists are laid out such that first call to `next` returns valid entry in the list
|
||||
/// or `None`.
|
||||
pub fn new(offset: usize,
|
||||
enclist: &'b [EncListEntry],
|
||||
inst: &'b InstructionData,
|
||||
enclist: &'static [EncListEntry],
|
||||
inst: &'a InstructionData,
|
||||
instp: fn(&InstructionData, EncListEntry) -> bool,
|
||||
isa_predicate_bytes: &'a [u8])
|
||||
isa_predicates: PredicateView<'a>)
|
||||
-> Self {
|
||||
Encodings {
|
||||
offset,
|
||||
enclist,
|
||||
inst,
|
||||
instp,
|
||||
isa_predicate_bytes,
|
||||
isa_predicates,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Iterator for Encodings<'a, 'b> {
|
||||
impl<'a> Iterator for Encodings<'a> {
|
||||
type Item = Encoding;
|
||||
|
||||
fn next(&mut self) -> Option<Encoding> {
|
||||
fn numbered_predicate(bytes: &[u8], p: usize) -> bool {
|
||||
bytes[p / 8] & (1 << (p % 8)) != 0
|
||||
}
|
||||
|
||||
while self.enclist[self.offset] != CODE_FAIL {
|
||||
let pred = self.enclist[self.offset];
|
||||
if pred <= CODE_ALWAYS {
|
||||
@@ -189,7 +187,7 @@ impl<'a, 'b> Iterator for Encodings<'a, 'b> {
|
||||
} else {
|
||||
// This is an ISA predicate entry.
|
||||
self.offset += 1;
|
||||
if !numbered_predicate(self.isa_predicate_bytes, (pred & PRED_MASK) as usize) {
|
||||
if !self.isa_predicates.test((pred & PRED_MASK) as usize) {
|
||||
// ISA predicate failed, skip the next N entries.
|
||||
self.offset += 3 * (pred >> PRED_BITS) as usize;
|
||||
}
|
||||
|
||||
@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn legal_encodings<'a, 'b>(&'a self,
|
||||
_dfg: &'b ir::DataFlowGraph,
|
||||
inst: &'b ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a, 'b>, Legalize> {
|
||||
fn legal_encodings<'a>(&'a self,
|
||||
_dfg: &'a ir::DataFlowGraph,
|
||||
inst: &'a ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a>, Legalize> {
|
||||
lookup_enclist(ctrl_typevar,
|
||||
inst.opcode(),
|
||||
self.cpumode,
|
||||
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
|
||||
&enc_tables::ENCLISTS[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_bytes()))
|
||||
self.isa_flags.predicate_view()))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -138,11 +138,11 @@ pub trait TargetIsa {
|
||||
fn register_info(&self) -> RegInfo;
|
||||
|
||||
/// Returns an iterartor over legal encodings for the instruction.
|
||||
fn legal_encodings<'a, 'b>(&'a self,
|
||||
dfg: &'b ir::DataFlowGraph,
|
||||
inst: &'b ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a, 'b>, Legalize>;
|
||||
fn legal_encodings<'a>(&'a self,
|
||||
dfg: &'a ir::DataFlowGraph,
|
||||
inst: &'a ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a>, Legalize>;
|
||||
|
||||
/// Encode an instruction after determining it is legal.
|
||||
///
|
||||
|
||||
@@ -61,11 +61,11 @@ impl TargetIsa for Isa {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn legal_encodings<'a, 'b>(&'a self,
|
||||
_dfg: &'b ir::DataFlowGraph,
|
||||
inst: &'b ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a, 'b>, Legalize> {
|
||||
fn legal_encodings<'a>(&'a self,
|
||||
_dfg: &'a ir::DataFlowGraph,
|
||||
inst: &'a ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encodings<'a>, Legalize> {
|
||||
lookup_enclist(ctrl_typevar,
|
||||
inst.opcode(),
|
||||
self.cpumode,
|
||||
@@ -75,7 +75,7 @@ impl TargetIsa for Isa {
|
||||
&enc_tables::ENCLISTS[..],
|
||||
inst,
|
||||
enc_tables::check_instp,
|
||||
self.isa_flags.predicate_bytes()))
|
||||
self.isa_flags.predicate_view()))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,28 @@ pub enum Error {
|
||||
/// A result returned when changing a setting.
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
/// A reference to just the boolean predicates of a settings object.
|
||||
///
|
||||
/// The settings objects themselves are generated and appear in the `isa/*/settings.rs` modules.
|
||||
/// Each settings object provides a `predicate_view()` method that makes it possible to query
|
||||
/// ISA predicates by number.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PredicateView<'a>(&'a [u8]);
|
||||
|
||||
impl<'a> PredicateView<'a> {
|
||||
/// Create a new view of a precomputed predicate vector.
|
||||
///
|
||||
/// See the `predicate_view()` method on the various `Flags` types defined for each ISA.
|
||||
pub fn new(bits: &'a [u8]) -> PredicateView {
|
||||
PredicateView(bits)
|
||||
}
|
||||
|
||||
/// Check a numbered predicate.
|
||||
pub fn test(self, p: usize) -> bool {
|
||||
self.0[p / 8] & (1 << (p % 8)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation details for generated code.
|
||||
///
|
||||
/// This module holds definitions that need to be public so the can be instantiated by generated
|
||||
|
||||
Reference in New Issue
Block a user