Add InstructionData::imm_value()
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
//! This module gives users to instantiate values that Cranelift understands. These values are used,
|
//! This module gives users to instantiate values that Cranelift understands. These values are used,
|
||||||
//! for example, during interpretation and for wrapping immediates.
|
//! for example, during interpretation and for wrapping immediates.
|
||||||
use crate::ir::immediates::{Ieee32, Ieee64, Imm64};
|
use crate::ir::immediates::{Ieee32, Ieee64, Imm64, Offset32};
|
||||||
use crate::ir::{types, ConstantData, Type};
|
use crate::ir::{types, ConstantData, Type};
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
use core::fmt::{self, Display, Formatter};
|
use core::fmt::{self, Display, Formatter};
|
||||||
@@ -100,6 +100,21 @@ build_conversion_impl!(i64, I64, I64);
|
|||||||
build_conversion_impl!(f32, F32, F32);
|
build_conversion_impl!(f32, F32, F32);
|
||||||
build_conversion_impl!(f64, F64, F64);
|
build_conversion_impl!(f64, F64, F64);
|
||||||
build_conversion_impl!([u8; 16], V128, I8X16);
|
build_conversion_impl!([u8; 16], V128, I8X16);
|
||||||
|
impl From<Ieee64> for DataValue {
|
||||||
|
fn from(f: Ieee64) -> Self {
|
||||||
|
DataValue::from(f64::from_bits(f.bits()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<Ieee32> for DataValue {
|
||||||
|
fn from(f: Ieee32) -> Self {
|
||||||
|
DataValue::from(f32::from_bits(f.bits()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<Offset32> for DataValue {
|
||||||
|
fn from(o: Offset32) -> Self {
|
||||||
|
DataValue::from(Into::<i32>::into(o))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for DataValue {
|
impl Display for DataValue {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use crate::ir::{self, trapcode::TrapCode, types, Block, FuncRef, JumpTable, SigR
|
|||||||
use crate::isa;
|
use crate::isa;
|
||||||
|
|
||||||
use crate::bitset::BitSet;
|
use crate::bitset::BitSet;
|
||||||
|
use crate::data_value::DataValue;
|
||||||
use crate::entity;
|
use crate::entity;
|
||||||
use ir::condcodes::{FloatCC, IntCC};
|
use ir::condcodes::{FloatCC, IntCC};
|
||||||
|
|
||||||
@@ -284,6 +285,41 @@ impl InstructionData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the value of an immediate if the instruction has one or `None` otherwise. Only
|
||||||
|
/// immediate values are considered, not global values, constant handles, condition codes, etc.
|
||||||
|
pub fn imm_value(&self) -> Option<DataValue> {
|
||||||
|
match self {
|
||||||
|
&InstructionData::UnaryBool { imm, .. } => Some(DataValue::from(imm)),
|
||||||
|
// 8-bit.
|
||||||
|
&InstructionData::BinaryImm8 { imm, .. }
|
||||||
|
| &InstructionData::BranchTableEntry { imm, .. } => Some(DataValue::from(imm as i8)), // Note the switch from unsigned to signed.
|
||||||
|
// 32-bit
|
||||||
|
&InstructionData::UnaryIeee32 { imm, .. } => Some(DataValue::from(imm)),
|
||||||
|
&InstructionData::HeapAddr { imm, .. } => {
|
||||||
|
let imm: u32 = imm.into();
|
||||||
|
Some(DataValue::from(imm as i32)) // Note the switch from unsigned to signed.
|
||||||
|
}
|
||||||
|
&InstructionData::Load { offset, .. }
|
||||||
|
| &InstructionData::LoadComplex { offset, .. }
|
||||||
|
| &InstructionData::Store { offset, .. }
|
||||||
|
| &InstructionData::StoreComplex { offset, .. }
|
||||||
|
| &InstructionData::StackLoad { offset, .. }
|
||||||
|
| &InstructionData::StackStore { offset, .. }
|
||||||
|
| &InstructionData::TableAddr { offset, .. } => Some(DataValue::from(offset)),
|
||||||
|
// 64-bit.
|
||||||
|
&InstructionData::UnaryImm { imm, .. }
|
||||||
|
| &InstructionData::BinaryImm64 { imm, .. }
|
||||||
|
| &InstructionData::IntCompareImm { imm, .. } => Some(DataValue::from(imm.bits())),
|
||||||
|
&InstructionData::UnaryIeee64 { imm, .. } => Some(DataValue::from(imm)),
|
||||||
|
// 128-bit; though these immediates are present logically in the IR they are not
|
||||||
|
// included in the `InstructionData` for memory-size reasons. This case, returning
|
||||||
|
// `None`, is left here to alert users of this method that they should retrieve the
|
||||||
|
// value using the `DataFlowGraph`.
|
||||||
|
&InstructionData::Shuffle { mask: _, .. } => None,
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// If this is a trapping instruction, get its trap code. Otherwise, return
|
/// If this is a trapping instruction, get its trap code. Otherwise, return
|
||||||
/// `None`.
|
/// `None`.
|
||||||
pub fn trap_code(&self) -> Option<TrapCode> {
|
pub fn trap_code(&self) -> Option<TrapCode> {
|
||||||
|
|||||||
Reference in New Issue
Block a user