6161
6262
6363class ARMBranchXData (ARMOpcodeXData ):
64+ """Data format (conditional)
65+ - expressions
66+ 0: txpr (true expression)
67+ 1: fxpr (false expression)
68+ 2: tcond (txpr, rewritten)
69+ 3: fcond (fxpr, rewritten)
70+ 4: xtgt (if absolute target address)
71+
72+ - c expressions
73+ 0: ctcond
74+ 1: cfcond
75+
76+ Data format (unconditional, or missing branch conditions)
77+ - expressions
78+ 0: xtgt
79+ 1: xxtgt (rewritten)
80+ """
6481
6582 def __init__ (self , xdata : InstrXData ) -> None :
6683 ARMOpcodeXData .__init__ (self , xdata )
6784
85+ @property
86+ def is_conditional (self ) -> bool :
87+ return (
88+ self ._xdata .has_branch_conditions ()
89+ or self ._xdata .has_missing_branch_conditions ())
90+
6891 @property
6992 def is_unconditional (self ) -> bool :
70- return len (self ._xdata .xprs_r ) == 2
93+ return not self .is_conditional
94+
95+ def has_branch_conditions (self ) -> bool :
96+ return self ._xdata .has_branch_conditions ()
7197
7298 @property
7399 def txpr (self ) -> "XXpr" :
@@ -81,38 +107,62 @@ def fxpr(self) -> "XXpr":
81107 def tcond (self ) -> "XXpr" :
82108 return self .xpr (2 , "tcond" )
83109
110+ @property
111+ def is_tcond_ok (self ) -> bool :
112+ return self .is_xpr_ok (2 )
113+
84114 @property
85115 def fcond (self ) -> "XXpr" :
86116 return self .xpr (3 , "fcond" )
87117
118+ @property
119+ def is_fcond_ok (self ) -> bool :
120+ return self .is_xpr_ok (3 )
121+
122+ @property
123+ def ctcond (self ) -> "XXpr" :
124+ return self .cxpr (0 , "ctcond" )
125+
126+ @property
127+ def is_ctcond_ok (self ) -> bool :
128+ return self .is_cxpr_ok (0 )
129+
130+ @property
131+ def cfcond (self ) -> "XXpr" :
132+ return self .cxpr (1 , "cfcond" )
133+
134+ @property
135+ def is_cfcond_ok (self ) -> bool :
136+ return self .is_cxpr_ok (1 )
137+
88138 @property
89139 def xtgt (self ) -> "XXpr" :
90140 index = 1 if self .is_unconditional else 4
91141 return self .xpr (index , "xtgt" )
92142
93143 @property
94- def is_xtgt_known (self ) -> bool :
144+ def is_xtgt_ok (self ) -> bool :
95145 index = 1 if self .is_unconditional else 4
96- return self .xdata . xprs_r [ index ] is not None
146+ return self .is_xpr_ok ( index )
97147
98148 @property
99149 def annotation (self ) -> str :
100- if self .is_ok :
101- if self ._xdata .has_branch_conditions ():
102- return "if " + str (self .tcond ) + " then goto " + str (self .xtgt )
103- elif self .is_unconditional :
104- return "goto " + str (self .xtgt )
150+ if self .is_conditional :
151+ if self .has_branch_conditions ():
152+ if self .is_ctcond_ok :
153+ cond = str (self .ctcond )
154+ elif self .is_tcond_ok :
155+ cond = str (self .tcond )
156+ else :
157+ cond = str (self .txpr )
158+ return "if " + cond + " then goto " + str (self .xtgt )
105159 else :
106- return "?"
107- elif self .is_xtgt_known :
108- if self ._xdata .has_branch_conditions ():
109- return "if " + str (self .txpr ) + " then goto " + str (self .xtgt )
110- elif self .is_unconditional :
111- return "goto " + str (self .xtgt )
112- else :
113- return "?"
160+ return (
161+ "if ? then goto "
162+ + str (self .xtgt )
163+ + " (no branch conditions found" )
114164 else :
115- return "Error value"
165+ return "goto " + str ( self . xtgt )
116166
117167
118168@armregistry .register_tag ("B" , ARMOpcode )
@@ -125,20 +175,7 @@ class ARMBranch(ARMCallOpcode):
125175 tags[1]: <c>
126176 args[0]: index of target operand in armdictionary
127177 args[1]: is-wide (thumb)
128-
129- xdata format: a:xxxxxr..
130- ------------------------
131- xprs[0]: true condition
132- xprs[1]: false condition
133- xprs[2]: true condition (simplified)
134- xprs[3]: false condition (simplified)
135- xprs[4]: target address (absolute)
136-
137- or, if no conditions
138-
139- xdata format: a:x
140- xprs[0]: target address (absolute)
141- """
178+ """
142179
143180 def __init__ (self , d : "ARMDictionary" , ixval : IndexedTableValue ) -> None :
144181 ARMCallOpcode .__init__ (self , d , ixval )
@@ -157,12 +194,6 @@ def mnemonic_extension(self) -> str:
157194 def opargs (self ) -> List [ARMOperand ]:
158195 return [self .armd .arm_operand (self .args [0 ])]
159196
160- def ft_conditions_basic (self , xdata : InstrXData ) -> Sequence [XXpr ]:
161- if xdata .has_branch_conditions ():
162- return [xdata .xprs [1 ], xdata .xprs [0 ]]
163- else :
164- return []
165-
166197 def ft_conditions (self , xdata : InstrXData ) -> Sequence [XXpr ]:
167198 xd = ARMBranchXData (xdata )
168199 if xdata .has_branch_conditions ():
@@ -289,11 +320,28 @@ def default(condition: XXpr) -> AST.ASTExpr:
289320
290321 ll_astcond = self .ast_cc_expr (astree )
291322
292- if len (ftconds_basic ) == 2 :
293- if reverse :
294- condition = ftconds_basic [0 ]
323+ if xd .is_conditional :
324+ if xd .has_branch_conditions ():
325+ if reverse :
326+ if xd .is_cfcond_ok :
327+ condition = xd .cfcond
328+ elif xd .is_fcond_ok :
329+ condition = xd .fcond
330+ else :
331+ condition = xd .fxpr
332+ else :
333+ if xd .is_ctcond_ok :
334+ condition = xd .ctcond
335+ elif xd .is_tcond_ok :
336+ condition = xd .tcond
337+ else :
338+ condition = xd .txpr
295339 else :
296- condition = ftconds_basic [1 ]
340+ chklogger .logger .error (
341+ "Bxx: conditional branch without branch conditions "
342+ + "at address %s" , iaddr )
343+ hl_astcond = astree .mk_temp_lval_expression ()
344+ return (hl_astcond , ll_astcond )
297345
298346 csetter = xdata .tags [2 ]
299347 hl_astcond = XU .xxpr_to_ast_def_expr (
0 commit comments