Tweak comments;
This commit is contained in:
@@ -279,7 +279,8 @@ impl PerCpuModeEncodings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the same encoding to both X86_32 and X86_64; assumes configuration (e.g. REX, operand binding) has already happened
|
/// Add the same encoding to both X86_32 and X86_64; assumes configuration (e.g. REX, operand
|
||||||
|
/// binding) has already happened.
|
||||||
fn enc_32_64_maybe_isap(
|
fn enc_32_64_maybe_isap(
|
||||||
&mut self,
|
&mut self,
|
||||||
inst: impl Clone + Into<InstSpec>,
|
inst: impl Clone + Into<InstSpec>,
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ where
|
|||||||
|
|
||||||
sink.begin_jumptables();
|
sink.begin_jumptables();
|
||||||
|
|
||||||
// output jump tables
|
// Output jump tables.
|
||||||
for (jt, jt_data) in func.jump_tables.iter() {
|
for (jt, jt_data) in func.jump_tables.iter() {
|
||||||
let jt_offset = func.jt_offsets[jt];
|
let jt_offset = func.jt_offsets[jt];
|
||||||
for ebb in jt_data.iter() {
|
for ebb in jt_data.iter() {
|
||||||
@@ -196,7 +196,7 @@ where
|
|||||||
|
|
||||||
sink.begin_rodata();
|
sink.begin_rodata();
|
||||||
|
|
||||||
// output constants
|
// Output constants.
|
||||||
for (_, constant_data) in func.dfg.constants.iter() {
|
for (_, constant_data) in func.dfg.constants.iter() {
|
||||||
for byte in constant_data.iter() {
|
for byte in constant_data.iter() {
|
||||||
sink.put1(*byte)
|
sink.put1(*byte)
|
||||||
|
|||||||
@@ -129,8 +129,7 @@ pub fn relax_branches(
|
|||||||
|
|
||||||
for (jt, jt_data) in func.jump_tables.iter() {
|
for (jt, jt_data) in func.jump_tables.iter() {
|
||||||
func.jt_offsets[jt] = offset;
|
func.jt_offsets[jt] = offset;
|
||||||
// TODO: this should be computed based on the min size needed to hold
|
// TODO: this should be computed based on the min size needed to hold the furthest branch.
|
||||||
// the furthest branch.
|
|
||||||
offset += jt_data.len() as u32 * 4;
|
offset += jt_data.len() as u32 * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
//! Constants
|
//! Constants
|
||||||
//!
|
//!
|
||||||
//! The constant pool defined here allows cranelift to avoid emitting the same constant multiple
|
//! The constant pool defined here allows Cranelift to avoid emitting the same constant multiple
|
||||||
//! times. As constants are inserted in the pool, a handle is returned; the handle is a cranelift
|
//! times. As constants are inserted in the pool, a handle is returned; the handle is a Cranelift
|
||||||
//! Entity. Inserting the same data multiple times will always return the same handle. Future work
|
//! Entity. Inserting the same data multiple times will always return the same handle.
|
||||||
//! could include: ensuring alignment of constants within the pool, bucketing constants by size.
|
//!
|
||||||
|
//! Future work could include:
|
||||||
|
//! - ensuring alignment of constants within the pool,
|
||||||
|
//! - bucketing constants by size.
|
||||||
|
|
||||||
use crate::ir::Constant;
|
use crate::ir::Constant;
|
||||||
use cranelift_entity::EntityRef;
|
use cranelift_entity::EntityRef;
|
||||||
@@ -19,8 +22,8 @@ pub type ConstantOffset = u32;
|
|||||||
/// Inner type for storing data and offset together in the constant pool. The offset is optional
|
/// Inner type for storing data and offset together in the constant pool. The offset is optional
|
||||||
/// because it must be set relative to the function code size (i.e. constants are emitted after the
|
/// because it must be set relative to the function code size (i.e. constants are emitted after the
|
||||||
/// function body); because the function is not yet compiled when constants are inserted,
|
/// function body); because the function is not yet compiled when constants are inserted,
|
||||||
/// [`set_offset`](crate::ir::ConstantPool::set_offset) must be called once a constant's
|
/// [`set_offset`](crate::ir::ConstantPool::set_offset) must be called once a constant's offset
|
||||||
/// offset from the beginning of the function is known (see
|
/// from the beginning of the function is known (see
|
||||||
/// [`relaxation.rs`](crate::binemit::relaxation)).
|
/// [`relaxation.rs`](crate::binemit::relaxation)).
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ConstantPoolEntry {
|
pub struct ConstantPoolEntry {
|
||||||
@@ -30,7 +33,7 @@ pub struct ConstantPoolEntry {
|
|||||||
|
|
||||||
impl ConstantPoolEntry {
|
impl ConstantPoolEntry {
|
||||||
fn new(data: ConstantData) -> Self {
|
fn new(data: ConstantData) -> Self {
|
||||||
ConstantPoolEntry { data, offset: None }
|
Self { data, offset: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the size of the constant at this entry.
|
/// Return the size of the constant at this entry.
|
||||||
@@ -44,21 +47,23 @@ impl ConstantPoolEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maintains the mapping between a constant handle (i.e.
|
/// Maintains the mapping between a constant handle (i.e. [`Constant`](crate::ir::Constant)) and
|
||||||
/// [`Constant`](crate::ir::Constant)) and its constant data (i.e.
|
/// its constant data (i.e. [`ConstantData`](crate::ir::ConstantData)).
|
||||||
/// [`ConstantData`](crate::ir::ConstantData)).
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ConstantPool {
|
pub struct ConstantPool {
|
||||||
/// This mapping maintains the insertion order as long as Constants are created with sequentially increasing integers.
|
/// This mapping maintains the insertion order as long as Constants are created with
|
||||||
|
/// sequentially increasing integers.
|
||||||
handles_to_values: BTreeMap<Constant, ConstantPoolEntry>,
|
handles_to_values: BTreeMap<Constant, ConstantPoolEntry>,
|
||||||
/// This mapping is unordered (no need for lexicographic ordering) but allows us to map constant data back to handles.
|
|
||||||
|
/// This mapping is unordered (no need for lexicographic ordering) but allows us to map
|
||||||
|
/// constant data back to handles.
|
||||||
values_to_handles: HashMap<ConstantData, Constant>,
|
values_to_handles: HashMap<ConstantData, Constant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstantPool {
|
impl ConstantPool {
|
||||||
/// Create a new constant pool instance.
|
/// Create a new constant pool instance.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ConstantPool {
|
Self {
|
||||||
handles_to_values: BTreeMap::new(),
|
handles_to_values: BTreeMap::new(),
|
||||||
values_to_handles: HashMap::new(),
|
values_to_handles: HashMap::new(),
|
||||||
}
|
}
|
||||||
@@ -75,10 +80,7 @@ impl ConstantPool {
|
|||||||
/// returned.
|
/// returned.
|
||||||
pub fn insert(&mut self, constant_value: ConstantData) -> Constant {
|
pub fn insert(&mut self, constant_value: ConstantData) -> Constant {
|
||||||
if self.values_to_handles.contains_key(&constant_value) {
|
if self.values_to_handles.contains_key(&constant_value) {
|
||||||
self.values_to_handles
|
self.values_to_handles.get(&constant_value).unwrap().clone()
|
||||||
.get(&constant_value)
|
|
||||||
.expect("A constant handle must have a corresponding constant value; this is an implementation error in ConstantPool")
|
|
||||||
.clone()
|
|
||||||
} else {
|
} else {
|
||||||
let constant_handle = Constant::new(self.len());
|
let constant_handle = Constant::new(self.len());
|
||||||
self.values_to_handles
|
self.values_to_handles
|
||||||
@@ -94,16 +96,17 @@ impl ConstantPool {
|
|||||||
/// Retrieve the constant data given a handle.
|
/// Retrieve the constant data given a handle.
|
||||||
pub fn get(&self, constant_handle: Constant) -> &ConstantData {
|
pub fn get(&self, constant_handle: Constant) -> &ConstantData {
|
||||||
assert!(self.handles_to_values.contains_key(&constant_handle));
|
assert!(self.handles_to_values.contains_key(&constant_handle));
|
||||||
&self.handles_to_values
|
&self.handles_to_values.get(&constant_handle).unwrap().data
|
||||||
.get(&constant_handle)
|
|
||||||
.expect("A constant handle must have a corresponding constant value; was a constant handle created outside of the pool?")
|
|
||||||
.data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assign an offset to a given constant, where the offset is the number of bytes from the
|
/// Assign an offset to a given constant, where the offset is the number of bytes from the
|
||||||
/// beginning of the function to the beginning of the constant data inside the pool.
|
/// beginning of the function to the beginning of the constant data inside the pool.
|
||||||
pub fn set_offset(&mut self, constant_handle: Constant, constant_offset: ConstantOffset) {
|
pub fn set_offset(&mut self, constant_handle: Constant, constant_offset: ConstantOffset) {
|
||||||
assert!(self.handles_to_values.contains_key(&constant_handle), "A constant handle must have already been inserted into the pool; perhaps a constant pool was created outside of the pool?");
|
assert!(
|
||||||
|
self.handles_to_values.contains_key(&constant_handle),
|
||||||
|
"A constant handle must have already been inserted into the pool; perhaps a \
|
||||||
|
constant pool was created outside of the pool?"
|
||||||
|
);
|
||||||
self.handles_to_values
|
self.handles_to_values
|
||||||
.entry(constant_handle)
|
.entry(constant_handle)
|
||||||
.and_modify(|e| e.offset = Some(constant_offset));
|
.and_modify(|e| e.offset = Some(constant_offset));
|
||||||
@@ -112,10 +115,17 @@ impl ConstantPool {
|
|||||||
/// Retrieve the offset of a given constant, where the offset is the number of bytes from the
|
/// Retrieve the offset of a given constant, where the offset is the number of bytes from the
|
||||||
/// beginning of the function to the beginning of the constant data inside the pool.
|
/// beginning of the function to the beginning of the constant data inside the pool.
|
||||||
pub fn get_offset(&self, constant_handle: Constant) -> ConstantOffset {
|
pub fn get_offset(&self, constant_handle: Constant) -> ConstantOffset {
|
||||||
self.handles_to_values.get(&constant_handle)
|
self.handles_to_values
|
||||||
.expect("A constant handle must have a corresponding constant value; was a constant handle created outside of the pool?")
|
.get(&constant_handle)
|
||||||
|
.expect(
|
||||||
|
"A constant handle must have a corresponding constant value; was a constant \
|
||||||
|
handle created outside of the pool?",
|
||||||
|
)
|
||||||
.offset
|
.offset
|
||||||
.expect("A constant offset has not yet been set; verify that `set_offset` has been called before this point")
|
.expect(
|
||||||
|
"A constant offset has not yet been set; verify that `set_offset` has been \
|
||||||
|
called before this point",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate over the constants in insertion order.
|
/// Iterate over the constants in insertion order.
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ impl FromStr for Uimm32 {
|
|||||||
|
|
||||||
/// A 128-bit unsigned integer immediate operand.
|
/// A 128-bit unsigned integer immediate operand.
|
||||||
///
|
///
|
||||||
/// This is used as an immediate value in SIMD instructions
|
/// This is used as an immediate value in SIMD instructions.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct Uimm128(pub [u8; 16]);
|
pub struct Uimm128(pub [u8; 16]);
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ impl Uimm128 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Uimm128 {
|
impl Display for Uimm128 {
|
||||||
// print a 128-bit vector in hexadecimal, e.g. 0x000102030405060708090a0b0c0d0e0f
|
// Print a 128-bit vector in hexadecimal, e.g. 0x000102030405060708090a0b0c0d0e0f.
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "0x")?;
|
write!(f, "0x")?;
|
||||||
let mut anything_written = false;
|
let mut anything_written = false;
|
||||||
|
|||||||
@@ -595,7 +595,8 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match and consume a Uimm128 immediate; due to size restrictions on InstructionData, Uimm128 is boxed in cranelift-codegen/meta/src/shared/immediates.rs
|
// Match and consume a Uimm128 immediate; due to size restrictions on InstructionData, Uimm128
|
||||||
|
// is boxed in cranelift-codegen/meta/src/shared/immediates.rs
|
||||||
fn match_uimm128(&mut self, err_msg: &str) -> ParseResult<Uimm128> {
|
fn match_uimm128(&mut self, err_msg: &str) -> ParseResult<Uimm128> {
|
||||||
if let Some(Token::Integer(text)) = self.token() {
|
if let Some(Token::Integer(text)) = self.token() {
|
||||||
self.consume();
|
self.consume();
|
||||||
|
|||||||
Reference in New Issue
Block a user