Path: blob/main/cranelift/codegen/src/isa/s390x/inst/imms.rs
1693 views
//! S390x ISA definitions: immediate constants.12use crate::machinst::PrettyPrint;3use std::string::String;45/// An unsigned 12-bit immediate.6#[derive(Clone, Copy, Debug)]7pub struct UImm12 {8/// The value.9value: u16,10}1112impl UImm12 {13pub fn maybe_from_u64(value: u64) -> Option<UImm12> {14if value < 4096 {15Some(UImm12 {16value: value as u16,17})18} else {19None20}21}2223/// Create a zero immediate of this format.24pub fn zero() -> UImm12 {25UImm12 { value: 0 }26}2728/// Bits for encoding.29pub fn bits(&self) -> u32 {30u32::from(self.value)31}32}3334/// A signed 20-bit immediate.35#[derive(Clone, Copy, Debug)]36pub struct SImm20 {37/// The value.38value: i32,39}4041impl SImm20 {42pub fn maybe_from_i64(value: i64) -> Option<SImm20> {43if value >= -524288 && value < 524288 {44Some(SImm20 {45value: value as i32,46})47} else {48None49}50}5152pub fn from_uimm12(value: UImm12) -> SImm20 {53SImm20 {54value: value.bits() as i32,55}56}5758/// Bits for encoding.59pub fn bits(&self) -> u32 {60let encoded: u32 = self.value as u32;61encoded & 0xfffff62}63}6465/// A 16-bit immediate with a {0,16,32,48}-bit shift.66#[derive(Clone, Copy, Debug)]67pub struct UImm16Shifted {68/// The value.69pub bits: u16,70/// Result is `bits` shifted 16*shift bits to the left.71pub shift: u8,72}7374impl UImm16Shifted {75/// Construct a UImm16Shifted from an arbitrary 64-bit constant if possible.76pub fn maybe_from_u64(value: u64) -> Option<UImm16Shifted> {77let mask0 = 0x0000_0000_0000_ffffu64;78let mask1 = 0x0000_0000_ffff_0000u64;79let mask2 = 0x0000_ffff_0000_0000u64;80let mask3 = 0xffff_0000_0000_0000u64;8182if value == (value & mask0) {83return Some(UImm16Shifted {84bits: (value & mask0) as u16,85shift: 0,86});87}88if value == (value & mask1) {89return Some(UImm16Shifted {90bits: ((value >> 16) & mask0) as u16,91shift: 1,92});93}94if value == (value & mask2) {95return Some(UImm16Shifted {96bits: ((value >> 32) & mask0) as u16,97shift: 2,98});99}100if value == (value & mask3) {101return Some(UImm16Shifted {102bits: ((value >> 48) & mask0) as u16,103shift: 3,104});105}106None107}108109pub fn maybe_with_shift(imm: u16, shift: u8) -> Option<UImm16Shifted> {110let shift_enc = shift / 16;111if shift_enc > 3 {112None113} else {114Some(UImm16Shifted {115bits: imm,116shift: shift_enc,117})118}119}120121pub fn negate_bits(&self) -> UImm16Shifted {122UImm16Shifted {123bits: !self.bits,124shift: self.shift,125}126}127}128129/// A 32-bit immediate with a {0,32}-bit shift.130#[derive(Clone, Copy, Debug)]131pub struct UImm32Shifted {132/// The value.133pub bits: u32,134/// Result is `bits` shifted 32*shift bits to the left.135pub shift: u8,136}137138impl UImm32Shifted {139/// Construct a UImm32Shifted from an arbitrary 64-bit constant if possible.140pub fn maybe_from_u64(value: u64) -> Option<UImm32Shifted> {141let mask0 = 0x0000_0000_ffff_ffffu64;142let mask1 = 0xffff_ffff_0000_0000u64;143144if value == (value & mask0) {145return Some(UImm32Shifted {146bits: (value & mask0) as u32,147shift: 0,148});149}150if value == (value & mask1) {151return Some(UImm32Shifted {152bits: ((value >> 32) & mask0) as u32,153shift: 1,154});155}156None157}158159pub fn maybe_with_shift(imm: u32, shift: u8) -> Option<UImm32Shifted> {160let shift_enc = shift / 32;161if shift_enc > 3 {162None163} else {164Some(UImm32Shifted {165bits: imm,166shift: shift_enc,167})168}169}170171pub fn negate_bits(&self) -> UImm32Shifted {172UImm32Shifted {173bits: !self.bits,174shift: self.shift,175}176}177}178179impl PrettyPrint for UImm12 {180fn pretty_print(&self, _: u8) -> String {181format!("{}", self.value)182}183}184185impl PrettyPrint for SImm20 {186fn pretty_print(&self, _: u8) -> String {187format!("{}", self.value)188}189}190191impl PrettyPrint for UImm16Shifted {192fn pretty_print(&self, _: u8) -> String {193format!("{}", self.bits)194}195}196197impl PrettyPrint for UImm32Shifted {198fn pretty_print(&self, _: u8) -> String {199format!("{}", self.bits)200}201}202203204