| 1268 | |
| 1269 | |
| 1270 | bool GetLowLevelILForInstruction( |
| 1271 | Architecture* arch, uint64_t addr, LowLevelILFunction& il, Instruction& instr, size_t addrSize, bool requireAlignment, std::function<bool()> _preferIntrinsics) |
| 1272 | { |
| 1273 | bool SetPacAttr = false; |
| 1274 | |
| 1275 | InstructionOperand& operand1 = instr.operands[0]; |
| 1276 | InstructionOperand& operand2 = instr.operands[1]; |
| 1277 | InstructionOperand& operand3 = instr.operands[2]; |
| 1278 | InstructionOperand& operand4 = instr.operands[3]; |
| 1279 | InstructionOperand& operand5 = instr.operands[4]; |
| 1280 | |
| 1281 | const size_t pairedSize = REGSZ_O(operand1) * 2; |
| 1282 | |
| 1283 | |
| 1284 | if (requireAlignment && (addr % 4 != 0)) { |
| 1285 | return false; |
| 1286 | } |
| 1287 | |
| 1288 | int n_instrs_before = il.GetInstructionCount(); |
| 1289 | |
| 1290 | auto preferIntrinsics = [&]() -> bool { |
| 1291 | if (_preferIntrinsics()) |
| 1292 | { |
| 1293 | NeonGetLowLevelILForInstruction(arch, addr, il, instr, addrSize); |
| 1294 | return (il.GetInstructionCount() > n_instrs_before); |
| 1295 | } |
| 1296 | return false; |
| 1297 | }; |
| 1298 | |
| 1299 | // printf("%s() operation:%d encoding:%d\n", __func__, instr.operation, instr.encoding); |
| 1300 | |
| 1301 | LowLevelILLabel trueLabel, falseLabel; |
| 1302 | switch (instr.operation) |
| 1303 | { |
| 1304 | case ARM64_ADD: |
| 1305 | switch (instr.encoding) |
| 1306 | { |
| 1307 | case ENC_ADD_Z_P_ZZ_: |
| 1308 | case ENC_ADD_Z_ZI_: |
| 1309 | case ENC_ADD_Z_ZZ_: |
| 1310 | if (!preferIntrinsics()) |
| 1311 | il.AddInstruction(il.Unimplemented()); |
| 1312 | return true; |
| 1313 | default: break; |
| 1314 | } |
| 1315 | case ARM64_ADDS: |
| 1316 | il.AddInstruction( |
| 1317 | ILSETREG_O(operand1, il.Add(REGSZ_O(operand1), ILREG_O(operand2), |
| 1318 | ReadILOperand(il, operand3, REGSZ_O(operand1)), SETFLAGS))); |
| 1319 | break; |
| 1320 | case ARM64_ADC: |
| 1321 | case ARM64_ADCS: |
| 1322 | il.AddInstruction(ILSETREG_O(operand1, |
| 1323 | il.AddCarry(REGSZ_O(operand1), ILREG_O(operand2), |
| 1324 | ReadILOperand(il, operand3, REGSZ_O(operand1)), il.Flag(IL_FLAG_C), SETFLAGS))); |
| 1325 | break; |
| 1326 | case ARM64_AND: |
| 1327 | case ARM64_ANDS: |
no test coverage detected