|
4 | 4 | # ------------------------------------------------------------------------------ |
5 | 5 | # The MIT License (MIT) |
6 | 6 | # |
7 | | -# Copyright (c) 2021 Aarno Labs LLC |
| 7 | +# Copyright (c) 2021-2025 Aarno Labs LLC |
8 | 8 | # |
9 | 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | 10 | # of this software and associated documentation files (the "Software"), to deal |
@@ -79,11 +79,11 @@ def xrprd(self) -> "XXpr": |
79 | 79 |
|
80 | 80 | @property |
81 | 81 | def result(self) -> "XXpr": |
82 | | - return self.xpr(4, "result") |
| 82 | + return self.xpr(5, "result") |
83 | 83 |
|
84 | 84 | @property |
85 | 85 | def rresult(self) -> "XXpr": |
86 | | - return self.xpr(5, "rresult") |
| 86 | + return self.xpr(6, "rresult") |
87 | 87 |
|
88 | 88 | @property |
89 | 89 | def result_simplified_p(self) -> str: |
@@ -123,9 +123,83 @@ def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None: |
123 | 123 | def operands(self) -> List[ARMOperand]: |
124 | 124 | return [self.armd.arm_operand(i) for i in self.args[1:]] |
125 | 125 |
|
| 126 | + @property |
| 127 | + def opargs(self) -> List[ARMOperand]: |
| 128 | + return [self.armd.arm_operand(i) for i in self.args[1:]] |
| 129 | + |
126 | 130 | def annotation(self, xdata: InstrXData) -> str: |
127 | 131 | xd = ARMMultiplyAccumulateXData(xdata) |
128 | 132 | if xd.is_ok: |
129 | 133 | return xd.annotation |
130 | 134 | else: |
131 | 135 | return "Error value" |
| 136 | + |
| 137 | + def ast_prov( |
| 138 | + self, |
| 139 | + astree: ASTInterface, |
| 140 | + iaddr: str, |
| 141 | + bytestring: str, |
| 142 | + xdata: InstrXData) -> Tuple[ |
| 143 | + List[AST.ASTInstruction], List[AST.ASTInstruction]]: |
| 144 | + |
| 145 | + annotations: List[str] = [iaddr, "MLA"] |
| 146 | + |
| 147 | + # low-level assignment |
| 148 | + |
| 149 | + (ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree) |
| 150 | + (ll_rn, _, _) = self.opargs[1].ast_rvalue(astree) |
| 151 | + (ll_rm, _, _) = self.opargs[2].ast_rvalue(astree) |
| 152 | + (ll_ra, _, _) = self.opargs[3].ast_rvalue(astree) |
| 153 | + ll_rhs1 = astree.mk_binary_op("mult", ll_rn, ll_rm) |
| 154 | + ll_rhs = astree.mk_binary_op("plus",ll_rhs1, ll_ra) |
| 155 | + |
| 156 | + ll_assign = astree.mk_assign( |
| 157 | + ll_lhs, |
| 158 | + ll_rhs, |
| 159 | + iaddr=iaddr, |
| 160 | + bytestring=bytestring, |
| 161 | + annotations=annotations) |
| 162 | + |
| 163 | + rdefs = xdata.reachingdefs |
| 164 | + |
| 165 | + astree.add_expr_reachingdefs(ll_rn, [rdefs[0]]) |
| 166 | + astree.add_expr_reachingdefs(ll_rm, [rdefs[1]]) |
| 167 | + astree.add_expr_reachingdefs(ll_ra, [rdefs[2]]) |
| 168 | + |
| 169 | + # high-level assignment |
| 170 | + |
| 171 | + xd = ARMMultiplyAccumulateXData(xdata) |
| 172 | + if not xd.is_ok: |
| 173 | + chklogger.logger.error( |
| 174 | + "Error value encountered for MLA at %s", iaddr) |
| 175 | + return ([], []) |
| 176 | + |
| 177 | + lhs = xd.vrd |
| 178 | + rhs1 = xd.xrn |
| 179 | + rhs2 = xd.xrm |
| 180 | + rhs3 = xd.xra |
| 181 | + rhs4 = xd.rresult |
| 182 | + |
| 183 | + defuses = xdata.defuses |
| 184 | + defuseshigh = xdata.defuseshigh |
| 185 | + |
| 186 | + hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree) |
| 187 | + hl_rhs = XU.xxpr_to_ast_def_expr(rhs4, xdata, iaddr, astree) |
| 188 | + |
| 189 | + hl_assign = astree.mk_assign( |
| 190 | + hl_lhs, |
| 191 | + hl_rhs, |
| 192 | + iaddr=iaddr, |
| 193 | + bytestring=bytestring, |
| 194 | + annotations=annotations) |
| 195 | + |
| 196 | + astree.add_instr_mapping(hl_assign, ll_assign) |
| 197 | + astree.add_instr_address(hl_assign, [iaddr]) |
| 198 | + astree.add_expr_mapping(hl_rhs, ll_rhs) |
| 199 | + astree.add_lval_mapping(hl_lhs, ll_lhs) |
| 200 | + astree.add_expr_reachingdefs(hl_rhs, rdefs[2:]) |
| 201 | + astree.add_expr_reachingdefs(ll_rhs, rdefs[:2]) |
| 202 | + astree.add_lval_defuses(hl_lhs, defuses[0]) |
| 203 | + astree.add_lval_defuses_high(hl_lhs, defuseshigh[0]) |
| 204 | + |
| 205 | + return ([hl_assign], [ll_assign]) |
0 commit comments