@@ -98,6 +98,31 @@ impl Bindable for X86Model {
9898 }
9999}
100100
101+ #[ derive( Serialize , Deserialize , Debug ) ]
102+ pub struct X86Family {
103+ pub name : String ,
104+ }
105+
106+ const EXTENDED_FAMILY_START_BIT : u8 = 20 ;
107+ impl Bindable for X86Family {
108+ type Rep = u32 ;
109+ fn value ( & self , reg_val : Register ) -> Option < Self :: Rep > {
110+ let reg32 = reg_val as u32 ;
111+ const FAMILY_MASK : u32 = 0xF ;
112+ const EXT_FAMILY_MASK : u32 = 0xFF ;
113+ let family = ( reg32 >> FAMILY_START_BIT ) & FAMILY_MASK ;
114+ let extended_family = ( reg32 >> EXTENDED_FAMILY_START_BIT ) & EXT_FAMILY_MASK ;
115+
116+ match family {
117+ 0xF => Some ( extended_family + family) ,
118+ _ => Some ( family) ,
119+ }
120+ }
121+ fn name ( & self ) -> & String {
122+ & self . name
123+ }
124+ }
125+
101126pub struct Bound < ' a , T : Bindable > {
102127 reg_val : Register ,
103128 bits : & ' a T ,
@@ -162,18 +187,31 @@ impl<'a> fmt::Display for Bound<'a, X86Model> {
162187 }
163188}
164189
190+ impl < ' a > fmt:: Display for Bound < ' a , X86Family > {
191+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , std:: fmt:: Error > {
192+ write ! (
193+ f,
194+ "{} = {:>10}" ,
195+ self . bits. name,
196+ self . bits. value( self . reg_val) . unwrap_or( 0 )
197+ )
198+ }
199+ }
200+
165201#[ derive( Debug , Serialize , Deserialize ) ]
166202#[ serde( tag = "type" ) ]
167203pub enum Field {
168204 Int ( Int ) ,
169205 Flag ( Flag ) ,
170206 X86Model ( X86Model ) ,
207+ X86Family ( X86Family ) ,
171208}
172209
173210pub enum BoundField < ' a > {
174211 Int ( Bound < ' a , Int > ) ,
175212 Flag ( Bound < ' a , Flag > ) ,
176213 X86Model ( Bound < ' a , X86Model > ) ,
214+ X86Family ( Bound < ' a , X86Family > ) ,
177215}
178216
179217impl < ' a > BoundField < ' a > {
@@ -182,6 +220,7 @@ impl<'a> BoundField<'a> {
182220 Field :: Int ( bits) => Self :: Int ( Bound { reg_val, bits } ) ,
183221 Field :: Flag ( bits) => Self :: Flag ( Bound { reg_val, bits } ) ,
184222 Field :: X86Model ( bits) => Self :: X86Model ( Bound { reg_val, bits } ) ,
223+ Field :: X86Family ( bits) => Self :: X86Family ( Bound { reg_val, bits } ) ,
185224 }
186225 }
187226}
@@ -192,6 +231,7 @@ impl<'a> fmt::Display for BoundField<'a> {
192231 Self :: Int ( bound) => bound. fmt ( f) ,
193232 Self :: Flag ( bound) => bound. fmt ( f) ,
194233 Self :: X86Model ( bound) => bound. fmt ( f) ,
234+ Self :: X86Family ( bound) => bound. fmt ( f) ,
195235 }
196236 }
197237}
@@ -202,6 +242,7 @@ impl<'a, T: From<bool> + From<u32>> Facter<T> for BoundField<'a> {
202242 Self :: Int ( bound) => bound. collect_fact ( ) ,
203243 Self :: Flag ( bound) => bound. collect_fact ( ) ,
204244 Self :: X86Model ( bound) => bound. collect_fact ( ) ,
245+ Self :: X86Family ( bound) => bound. collect_fact ( ) ,
205246 }
206247 }
207248}
@@ -222,4 +263,17 @@ mod test {
222263 let extended_family_model: super :: Register = 0x0AF50F41 ;
223264 assert_eq ! ( field_definition. value( extended_family_model) . unwrap( ) , 0x54 ) ;
224265 }
266+ #[ test]
267+ fn x86_family_test ( ) {
268+ let field_definition = super :: X86Family {
269+ name : "model" . to_string ( ) ,
270+ } ;
271+ let regular_model: super :: Register = 0x0AE50341 ;
272+ assert_eq ! ( field_definition. value( regular_model) . unwrap( ) , 0x3 ) ;
273+ let extended_family_model: super :: Register = 0x0AE50F41 ;
274+ assert_eq ! (
275+ field_definition. value( extended_family_model) . unwrap( ) ,
276+ 0xAE + 0xF
277+ ) ;
278+ }
225279}
0 commit comments