| 489 | |
| 490 | |
| 491 | bool GetLowLevelILForInstruction(Architecture* arch, const uint64_t addr, LowLevelILFunction& il, const xed_decoded_inst_t* const xedd) |
| 492 | { |
| 493 | LowLevelILLabel trueLabel, falseLabel, doneLabel, dirFlagSet, dirFlagClear, dirFlagDone, startLabel; |
| 494 | LowLevelILLabel trueLabel2, falseLabel2; |
| 495 | |
| 496 | const xed_iclass_enum_t xedd_iClass = xed_decoded_inst_get_iclass(xedd); |
| 497 | const xed_iform_enum_t xedd_iForm = xed_decoded_inst_get_iform_enum(xedd); |
| 498 | const xed_inst_t* const xi = xed_decoded_inst_inst(xedd); |
| 499 | // const xed_operand_values_t* const ov = xed_decoded_inst_operands_const(xedd); |
| 500 | const unsigned short instLen = xed_decoded_inst_get_length(xedd); |
| 501 | // mode_bits can be used to determine whether the current instruciton is in 16/32/64 bit mode |
| 502 | const size_t mode_bits = xed_decoded_inst_get_machine_mode_bits(xedd); |
| 503 | const size_t addrSize = mode_bits / 8; |
| 504 | |
| 505 | const unsigned short opOneLen = xed_decoded_inst_operand_length_bits(xedd, 0) / 8; |
| 506 | const unsigned short opTwoLen = xed_decoded_inst_operand_length_bits(xedd, 1) / 8; |
| 507 | [[maybe_unused]] const unsigned short |
| 508 | opTreLen = xed_decoded_inst_operand_length_bits(xedd, 2) / 8; |
| 509 | const xed_operand_t* const opOne = xed_inst_operand(xi, 0); |
| 510 | const xed_operand_t* const opTwo = xed_inst_operand(xi, 1); |
| 511 | // this is problematic as operand three may or may not exist at all |
| 512 | // latest version of xed will complain about this |
| 513 | const xed_operand_t* const opTre = xed_inst_operand(xi, 2); |
| 514 | const xed_operand_enum_t opOne_name = xed_operand_name(opOne); |
| 515 | const xed_operand_enum_t opTwo_name = xed_operand_name(opTwo); |
| 516 | const xed_operand_enum_t opTre_name = xed_operand_name(opTre); |
| 517 | const xed_reg_enum_t regOne = xed_decoded_inst_get_reg(xedd, opOne_name); |
| 518 | const xed_reg_enum_t regTwo = xed_decoded_inst_get_reg(xedd, opTwo_name); |
| 519 | // const xed_reg_enum_t regTre = xed_decoded_inst_get_reg(xedd, opTre_name); |
| 520 | // const xed_reg_enum_t baseReg1 = xed_decoded_inst_get_base_reg(xedd, 0); |
| 521 | // const xed_reg_enum_t baseReg2 = xed_decoded_inst_get_base_reg(xedd, 1); |
| 522 | const xed_reg_enum_t segReg1 = xed_decoded_inst_get_seg_reg (xedd, 0); |
| 523 | // const xed_reg_enum_t segReg2 = xed_decoded_inst_get_seg_reg (xedd, 1); |
| 524 | |
| 525 | const uint64_t immediateOne = xed_decoded_inst_get_unsigned_immediate(xedd); |
| 526 | const int64_t branchDestination = xed_decoded_inst_get_branch_displacement(xedd) + addr + instLen; |
| 527 | |
| 528 | auto LiftAsIntrinsic = [& il, xi, xedd, addr, xedd_iForm] () mutable { |
| 529 | |
| 530 | typedef struct |
| 531 | { |
| 532 | uint32_t index; |
| 533 | size_t width; |
| 534 | } MemoryOperandWriteInfo; |
| 535 | |
| 536 | vector<RegisterOrFlag> outputs = {}; |
| 537 | vector<ExprId> parameters = {}; |
| 538 | size_t noperands = xed_inst_noperands(xi); |
| 539 | vector<MemoryOperandWriteInfo> memoryOperandWrites = {}; |
| 540 | size_t numTempRegUsed = 0; |
| 541 | for (uint32_t i = 0; i < noperands; i++) |
| 542 | { |
| 543 | const xed_operand_t* op = xed_inst_operand(xi, i); |
| 544 | xed_operand_enum_t op_name = xed_operand_name(op); |
| 545 | if (xed_operand_written(op)) |
| 546 | { |
| 547 | switch(op_name) |
| 548 | { |
no test coverage detected