diff --git a/cranelift/src/libcretonne/ir/immediates.rs b/cranelift/src/libcretonne/ir/immediates.rs index 99276bfd66..e8d4a20773 100644 --- a/cranelift/src/libcretonne/ir/immediates.rs +++ b/cranelift/src/libcretonne/ir/immediates.rs @@ -123,6 +123,11 @@ impl FromStr for Imm64 { } } +/// 8-bit unsigned integer immediate operand. +/// +/// This is used to indicate lane indexes typically. +pub type Uimm8 = u8; + /// An IEEE binary32 immediate floating point value. /// /// All bit patterns are allowed. @@ -420,6 +425,12 @@ impl FromStr for Ieee64 { } } +/// Arbitrary vector immediate. +/// +/// This kind of immediate can represent any kind of SIMD vector constant. +/// The representation is simply the sequence of bytes that would be used to store the vector. +pub type ImmVector = Vec; + #[cfg(test)] mod tests { use super::*; diff --git a/cranelift/src/libcretonne/ir/instructions.rs b/cranelift/src/libcretonne/ir/instructions.rs index 56ce5ed5fd..b971a05ffa 100644 --- a/cranelift/src/libcretonne/ir/instructions.rs +++ b/cranelift/src/libcretonne/ir/instructions.rs @@ -11,7 +11,7 @@ use std::str::FromStr; use std::ops::{Deref, DerefMut}; use ir::{Value, Type, Ebb, JumpTable, FuncRef}; -use ir::immediates::{Imm64, Ieee32, Ieee64}; +use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, ImmVector}; use ir::condcodes::*; use ir::types; @@ -117,7 +117,8 @@ pub enum InstructionData { }, UnaryImmVector { opcode: Opcode, - ty: Type, // TBD: imm: Box + ty: Type, + data: Box, }, UnarySplit { opcode: Opcode, @@ -162,13 +163,13 @@ pub enum InstructionData { InsertLane { opcode: Opcode, ty: Type, - lane: u8, + lane: Uimm8, args: [Value; 2], }, ExtractLane { opcode: Opcode, ty: Type, - lane: u8, + lane: Uimm8, arg: Value, }, IntCompare { @@ -264,6 +265,22 @@ impl Default for VariableArgs { } } +/// Payload data for `vconst`. +#[derive(Clone, Debug)] +pub struct UnaryImmVectorData { + pub imm: ImmVector, +} + +impl Display for UnaryImmVectorData { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + try!(write!(f, "#")); + for b in &self.imm { + try!(write!(f, "{:02x}", b)); + } + Ok(()) + } +} + /// Payload data for ternary instructions with multiple results, such as `iadd_carry`. #[derive(Clone, Debug)] pub struct TernaryOverflowData { diff --git a/cranelift/src/libcretonne/write.rs b/cranelift/src/libcretonne/write.rs index e49c8382bf..3ef72d7178 100644 --- a/cranelift/src/libcretonne/write.rs +++ b/cranelift/src/libcretonne/write.rs @@ -184,7 +184,7 @@ fn write_instruction(w: &mut Write, UnaryImm { imm, .. } => writeln!(w, " {}", imm), UnaryIeee32 { imm, .. } => writeln!(w, " {}", imm), UnaryIeee64 { imm, .. } => writeln!(w, " {}", imm), - UnaryImmVector { .. } => writeln!(w, " [...]"), + UnaryImmVector { ref data, .. } => writeln!(w, " {}", data), UnarySplit { arg, .. } => writeln!(w, " {}", arg), Binary { args, .. } => writeln!(w, " {}, {}", args[0], args[1]), BinaryImm { arg, imm, .. } => writeln!(w, " {}, {}", arg, imm), diff --git a/meta/cretonne/formats.py b/meta/cretonne/formats.py index 11a1c5ef3b..8e5d4e25cb 100644 --- a/meta/cretonne/formats.py +++ b/meta/cretonne/formats.py @@ -16,7 +16,7 @@ Unary = InstructionFormat(value) UnaryImm = InstructionFormat(imm64) UnaryIeee32 = InstructionFormat(ieee32) UnaryIeee64 = InstructionFormat(ieee64) -UnaryImmVector = InstructionFormat(immvector) +UnaryImmVector = InstructionFormat(immvector, boxed_storage=True) UnarySplit = InstructionFormat(value, multiple_results=True) Binary = InstructionFormat(value, value)