| 680 | } |
| 681 | |
| 682 | static void LoadStoreOperandPairSize(LowLevelILFunction& il, bool load, size_t load_size, InstructionOperand& operand1, |
| 683 | InstructionOperand& operand2, InstructionOperand& operand3) |
| 684 | { |
| 685 | /* do pre-indexing */ |
| 686 | ExprId tmp = GetILOperandPreIndex(il, operand3); |
| 687 | if (tmp) |
| 688 | il.AddInstruction(tmp); |
| 689 | |
| 690 | /* compute addresses */ |
| 691 | OperandClass oclass = (operand3.operandClass == MEM_PRE_IDX) ? MEM_REG : operand3.operandClass; |
| 692 | ExprId addr0 = GetILOperandEffectiveAddress(il, operand3, 8, oclass, 0); |
| 693 | ExprId addr1 = GetILOperandEffectiveAddress(il, operand3, 8, oclass, load_size); |
| 694 | |
| 695 | /* load/store */ |
| 696 | if (load) |
| 697 | { |
| 698 | // We lift this instruction differently if operand1 and operand3 are equal as to not break outlining in the common case, |
| 699 | // since outlining does not seem to handle intermediate stores to temporary registers |
| 700 | // TODO: unify lifting once outlining handles intermediate temporary stores |
| 701 | if (REG_O(operand1) != REG_O(operand3)) |
| 702 | { |
| 703 | // {op} X, Y, [Z] |
| 704 | il.AddInstruction(ILSETREG_O(operand1, il.Load(load_size, addr0))); |
| 705 | il.AddInstruction(ILSETREG_O(operand2, il.Load(load_size, addr1))); |
| 706 | } |
| 707 | else |
| 708 | { |
| 709 | // {op} X, Y, [X] |
| 710 | // Prevent clobbering of source during write to operand1 by storing source in a temporary register |
| 711 | il.AddInstruction(il.SetRegister(REGSZ_O(operand1), LLIL_TEMP(0), addr1)); |
| 712 | il.AddInstruction(ILSETREG_O(operand1, il.Load(load_size, addr0))); |
| 713 | il.AddInstruction(ILSETREG_O(operand2, il.Load(load_size, il.Register(load_size, LLIL_TEMP(0))))); |
| 714 | } |
| 715 | } |
| 716 | else |
| 717 | { |
| 718 | il.AddInstruction(il.Store(load_size, addr0, ILREG_O(operand1))); |
| 719 | il.AddInstruction(il.Store(load_size, addr1, ILREG_O(operand2))); |
| 720 | } |
| 721 | |
| 722 | /* do post-indexing */ |
| 723 | tmp = GetILOperandPostIndex(il, operand3); |
| 724 | if (tmp) |
| 725 | il.AddInstruction(tmp); |
| 726 | } |
| 727 | |
| 728 | |
| 729 | static void LoadStoreOperandPair(LowLevelILFunction& il, bool load, InstructionOperand& operand1, |
no test coverage detected