8888 } ;
8989 PossibleValueSet :: from_owned_core_raw ( raw_pvs)
9090 }
91+
92+ /// Get the raw operand from the operand list.
93+ ///
94+ /// This has no type information associated with it. It's up to the caller to know what the correct type of the
95+ /// underlying u64 should be.
96+ ///
97+ /// # Panic
98+ /// `idx` must be less than 4. This is to protect against an out of bounds access.
99+ ///
100+ /// # Safety
101+ /// Even if `idx` is valid, it may index to an unitialized or unused value. Make sure you index into an operand that
102+ /// you know should be initialized properly.
103+ pub unsafe fn get_operand ( & self , idx : usize ) -> u64 {
104+ assert ! ( idx < 4 ) ;
105+ self . op . operands [ idx]
106+ }
91107}
92108
93109impl < M , O > Operation < ' _ , M , NonSSA , O >
@@ -214,16 +230,69 @@ where
214230// LLIL_INTRINSIC, LLIL_INTRINSIC_SSA
215231pub struct Intrinsic ;
216232
233+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
234+ pub enum IntrinsicOutput {
235+ Reg ( CoreRegister ) ,
236+ Flag ( CoreFlag ) ,
237+ }
238+
239+ impl From < CoreRegister > for IntrinsicOutput {
240+ fn from ( value : CoreRegister ) -> Self {
241+ Self :: Reg ( value)
242+ }
243+ }
244+
245+ impl From < CoreFlag > for IntrinsicOutput {
246+ fn from ( value : CoreFlag ) -> Self {
247+ Self :: Flag ( value)
248+ }
249+ }
250+
217251impl < M , F > Operation < ' _ , M , F , Intrinsic >
218252where
219253 M : FunctionMutability ,
220254 F : FunctionForm ,
221255{
222- // TODO: Support register and expression lists
223256 pub fn intrinsic ( & self ) -> Option < CoreIntrinsic > {
224257 let raw_id = self . op . operands [ 2 ] as u32 ;
225258 self . function . arch ( ) . intrinsic_from_id ( IntrinsicId ( raw_id) )
226259 }
260+
261+ /// Get the output list.
262+ pub fn outputs ( & self ) -> Vec < IntrinsicOutput > {
263+ // Convert the operand to either a register or flag id.
264+ let operand_to_output = |o : u64 | {
265+ if o & ( 1 << 32 ) != 0 {
266+ self . function
267+ . arch ( )
268+ . flag_from_id ( FlagId ( ( o & 0xffffffff ) as u32 ) )
269+ . expect ( "Invalid core flag ID" )
270+ . into ( )
271+ } else {
272+ self . function
273+ . arch ( )
274+ . register_from_id ( RegisterId ( ( o & 0xffffffff ) as u32 ) )
275+ . expect ( "Invalid register ID" )
276+ . into ( )
277+ }
278+ } ;
279+
280+ self . get_operand_list ( 0 )
281+ . into_iter ( )
282+ . map ( operand_to_output)
283+ . collect :: < Vec < _ > > ( )
284+ }
285+
286+ /// Get the input list for the intrinsic.
287+ ///
288+ /// This will just be a CallParamSsa expression.
289+ #[ inline]
290+ pub fn inputs ( & self ) -> LowLevelILExpression < ' _ , M , F , ValueExpr > {
291+ LowLevelILExpression :: new (
292+ self . function ,
293+ LowLevelExpressionIndex ( self . op . operands [ 3 ] as usize ) ,
294+ )
295+ }
227296}
228297
229298impl < M , F > Debug for Operation < ' _ , M , F , Intrinsic >
@@ -232,9 +301,15 @@ where
232301 F : FunctionForm ,
233302{
234303 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
304+ use crate :: architecture:: Intrinsic ;
235305 f. debug_struct ( "Intrinsic" )
236306 . field ( "address" , & self . address ( ) )
237- . field ( "size" , & self . intrinsic ( ) )
307+ . field (
308+ "intrinsic" ,
309+ & self . intrinsic ( ) . expect ( "Valid intrinsic" ) . name ( ) ,
310+ )
311+ . field ( "outputs" , & self . outputs ( ) )
312+ . field ( "inputs" , & self . inputs ( ) )
238313 . finish ( )
239314 }
240315}
@@ -1013,13 +1088,28 @@ where
10131088// LLIL_FLAG, LLIL_FLAG_SSA
10141089pub struct Flag ;
10151090
1091+ impl < M , F > Operation < ' _ , M , F , Flag >
1092+ where
1093+ M : FunctionMutability ,
1094+ F : FunctionForm ,
1095+ {
1096+ pub fn source_flag ( & self ) -> CoreFlag {
1097+ self . function
1098+ . arch ( )
1099+ . flag_from_id ( FlagId ( self . op . operands [ 0 ] as u32 ) )
1100+ . expect ( "Bad flag ID" )
1101+ }
1102+ }
1103+
10161104impl < M , F > Debug for Operation < ' _ , M , F , Flag >
10171105where
10181106 M : FunctionMutability ,
10191107 F : FunctionForm ,
10201108{
10211109 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
1022- f. debug_struct ( "Flag" ) . finish ( )
1110+ f. debug_struct ( "Flag" )
1111+ . field ( "source_flag" , & self . source_flag ( ) )
1112+ . finish ( )
10231113 }
10241114}
10251115
0 commit comments