@@ -718,7 +718,7 @@ enum ValueData {
718718/// Layout:
719719///
720720/// ```plain
721- /// | tag:2 | type:14 | x:24 | y:24 |
721+ /// | tag:2 | type:14 | x:32 | y:32 |
722722///
723723/// Inst 00 ty inst output inst index
724724/// Param 01 ty blockparam num block index
@@ -727,76 +727,50 @@ enum ValueData {
727727/// ```
728728#[ derive( Clone , Copy , Debug , PartialEq , Hash ) ]
729729#[ cfg_attr( feature = "enable-serde" , derive( Serialize , Deserialize ) ) ]
730- struct ValueDataPacked ( u64 ) ;
731-
732- /// Encodes a value in 0..2^32 into 0..2^n, where n is less than 32
733- /// (and is implied by `mask`), by translating 2^32-1 (0xffffffff)
734- /// into 2^n-1 and panic'ing on 2^n..2^32-1.
735- fn encode_narrow_field ( x : u32 , bits : u8 ) -> u32 {
736- let max = ( 1 << bits) - 1 ;
737- if x == 0xffff_ffff {
738- max
739- } else {
740- debug_assert ! (
741- x < max,
742- "{x} does not fit into {bits} bits (must be less than {max} to \
743- allow for a 0xffffffff sentinel)"
744- ) ;
745- x
746- }
747- }
748-
749- /// The inverse of the above `encode_narrow_field`: unpacks 2^n-1 into
750- /// 2^32-1.
751- fn decode_narrow_field ( x : u32 , bits : u8 ) -> u32 {
752- if x == ( 1 << bits) - 1 { 0xffff_ffff } else { x }
730+ #[ repr( Rust , packed) ]
731+ struct ValueDataPacked {
732+ x : u32 ,
733+ y : u32 ,
734+ flags_and_type : u16 ,
753735}
754736
755737impl ValueDataPacked {
756- const Y_SHIFT : u8 = 0 ;
757- const Y_BITS : u8 = 24 ;
758- const X_SHIFT : u8 = Self :: Y_SHIFT + Self :: Y_BITS ;
759- const X_BITS : u8 = 24 ;
760- const TYPE_SHIFT : u8 = Self :: X_SHIFT + Self :: X_BITS ;
738+ const TYPE_SHIFT : u8 = 0 ;
761739 const TYPE_BITS : u8 = 14 ;
762740 const TAG_SHIFT : u8 = Self :: TYPE_SHIFT + Self :: TYPE_BITS ;
763741 const TAG_BITS : u8 = 2 ;
764742
765- const TAG_INST : u64 = 0 ;
766- const TAG_PARAM : u64 = 1 ;
767- const TAG_ALIAS : u64 = 2 ;
768- const TAG_UNION : u64 = 3 ;
743+ const TAG_INST : u16 = 0 ;
744+ const TAG_PARAM : u16 = 1 ;
745+ const TAG_ALIAS : u16 = 2 ;
746+ const TAG_UNION : u16 = 3 ;
769747
770- fn make ( tag : u64 , ty : Type , x : u32 , y : u32 ) -> ValueDataPacked {
748+ fn make ( tag : u16 , ty : Type , x : u32 , y : u32 ) -> ValueDataPacked {
771749 debug_assert ! ( tag < ( 1 << Self :: TAG_BITS ) ) ;
772750 debug_assert ! ( ty. repr( ) < ( 1 << Self :: TYPE_BITS ) ) ;
773751
774- let x = encode_narrow_field ( x, Self :: X_BITS ) ;
775- let y = encode_narrow_field ( y, Self :: Y_BITS ) ;
776-
777- ValueDataPacked (
778- ( tag << Self :: TAG_SHIFT )
779- | ( ( ty. repr ( ) as u64 ) << Self :: TYPE_SHIFT )
780- | ( ( x as u64 ) << Self :: X_SHIFT )
781- | ( ( y as u64 ) << Self :: Y_SHIFT ) ,
782- )
752+ ValueDataPacked {
753+ x,
754+ y,
755+ flags_and_type : ( tag << Self :: TAG_SHIFT ) | ( ty. repr ( ) << Self :: TYPE_SHIFT ) ,
756+ }
783757 }
784758
785759 #[ inline( always) ]
786- fn field ( self , shift : u8 , bits : u8 ) -> u64 {
787- ( self . 0 >> shift) & ( ( 1 << bits) - 1 )
760+ fn field ( self , shift : u8 , bits : u8 ) -> u16 {
761+ ( self . flags_and_type >> shift) & ( ( 1 << bits) - 1 )
788762 }
789763
790764 #[ inline( always) ]
791765 fn ty ( self ) -> Type {
792- let ty = self . field ( ValueDataPacked :: TYPE_SHIFT , ValueDataPacked :: TYPE_BITS ) as u16 ;
766+ let ty = self . field ( ValueDataPacked :: TYPE_SHIFT , ValueDataPacked :: TYPE_BITS ) ;
793767 Type :: from_repr ( ty)
794768 }
795769
796770 #[ inline( always) ]
797771 fn set_type ( & mut self , ty : Type ) {
798- self . 0 &= !( ( ( 1 << Self :: TYPE_BITS ) - 1 ) << Self :: TYPE_SHIFT ) ;
799- self . 0 |= ( ty. repr ( ) as u64 ) << Self :: TYPE_SHIFT ;
772+ self . flags_and_type &= !( ( ( 1 << Self :: TYPE_BITS ) - 1 ) << Self :: TYPE_SHIFT ) ;
773+ self . flags_and_type |= ty. repr ( ) << Self :: TYPE_SHIFT ;
800774 }
801775}
802776
@@ -824,33 +798,29 @@ impl From<ValueDataPacked> for ValueData {
824798 let tag = data. field ( ValueDataPacked :: TAG_SHIFT , ValueDataPacked :: TAG_BITS ) ;
825799 let ty = u16:: try_from ( data. field ( ValueDataPacked :: TYPE_SHIFT , ValueDataPacked :: TYPE_BITS ) )
826800 . expect ( "Mask should ensure result fits in a u16" ) ;
827- let x = u32:: try_from ( data. field ( ValueDataPacked :: X_SHIFT , ValueDataPacked :: X_BITS ) )
828- . expect ( "Mask should ensure result fits in a u32" ) ;
829- let y = u32:: try_from ( data. field ( ValueDataPacked :: Y_SHIFT , ValueDataPacked :: Y_BITS ) )
830- . expect ( "Mask should ensure result fits in a u32" ) ;
831801
832802 let ty = Type :: from_repr ( ty) ;
833803 match tag {
834804 ValueDataPacked :: TAG_INST => ValueData :: Inst {
835805 ty,
836- num : u16:: try_from ( x) . expect ( "Inst result num should fit in u16" ) ,
837- inst : Inst :: from_bits ( decode_narrow_field ( y , ValueDataPacked :: Y_BITS ) ) ,
806+ num : u16:: try_from ( data . x ) . expect ( "Inst result num should fit in u16" ) ,
807+ inst : Inst :: from_bits ( data . y ) ,
838808 } ,
839809 ValueDataPacked :: TAG_PARAM => ValueData :: Param {
840810 ty,
841- num : u16:: try_from ( x) . expect ( "Blockparam index should fit in u16" ) ,
842- block : Block :: from_bits ( decode_narrow_field ( y , ValueDataPacked :: Y_BITS ) ) ,
811+ num : u16:: try_from ( data . x ) . expect ( "Blockparam index should fit in u16" ) ,
812+ block : Block :: from_bits ( data . y ) ,
843813 } ,
844814 ValueDataPacked :: TAG_ALIAS => ValueData :: Alias {
845815 ty,
846- original : Value :: from_bits ( decode_narrow_field ( y , ValueDataPacked :: Y_BITS ) ) ,
816+ original : Value :: from_bits ( data . y ) ,
847817 } ,
848818 ValueDataPacked :: TAG_UNION => ValueData :: Union {
849819 ty,
850- x : Value :: from_bits ( decode_narrow_field ( x , ValueDataPacked :: X_BITS ) ) ,
851- y : Value :: from_bits ( decode_narrow_field ( y , ValueDataPacked :: Y_BITS ) ) ,
820+ x : Value :: from_bits ( data . x ) ,
821+ y : Value :: from_bits ( data . y ) ,
852822 } ,
853- _ => panic ! ( "Invalid tag {} in ValueDataPacked 0x{:x} " , tag, data . 0 ) ,
823+ _ => panic ! ( "Invalid tag {} in ValueDataPacked" , tag) ,
854824 }
855825 }
856826}
0 commit comments