Returns an IL expression that reads (and only reads) from the operand. It accounts for, but does not generate IL that executes, pre and post indexing. The operand class can be overridden. An additional offset can be applied, convenient for calculating sequential loads and stores. */
| 304 | The operand class can be overridden. |
| 305 | An additional offset can be applied, convenient for calculating sequential loads and stores. */ |
| 306 | static ExprId GetILOperandEffectiveAddress(LowLevelILFunction& il, InstructionOperand& operand, |
| 307 | size_t addrSize, OperandClass oclass, size_t extra_offset) |
| 308 | { |
| 309 | ExprId addr = 0; |
| 310 | if (oclass == NONE) |
| 311 | oclass = operand.operandClass; |
| 312 | switch (oclass) |
| 313 | { |
| 314 | case MEM_REG: // ldr x0, [x1] |
| 315 | case MEM_POST_IDX: // ldr w0, [x1], #4 |
| 316 | addr = ILREG_O(operand); |
| 317 | if (extra_offset) |
| 318 | addr = il.Add(addrSize, addr, il.Const(addrSize, extra_offset)); |
| 319 | break; |
| 320 | case MEM_OFFSET: // ldr w0, [x1, #4] |
| 321 | case MEM_PRE_IDX: // ldr w0, [x1, #4]! |
| 322 | addr = il.Add(addrSize, ILREG_O(operand), il.Const(addrSize, operand.immediate + extra_offset)); |
| 323 | break; |
| 324 | case MEM_EXTENDED: |
| 325 | if (operand.shiftType == ShiftType_NONE) |
| 326 | { |
| 327 | addr = |
| 328 | il.Add(addrSize, ILREG_O(operand), il.Const(addrSize, operand.immediate + extra_offset)); |
| 329 | } |
| 330 | else if (operand.shiftType == ShiftType_LSL) |
| 331 | { |
| 332 | if (extra_offset) |
| 333 | { |
| 334 | addr = il.Add(addrSize, ILREG_O(operand), |
| 335 | il.Add(addrSize, |
| 336 | il.ShiftLeft(addrSize, il.Const(addrSize, operand.immediate), |
| 337 | il.Const(1, operand.shiftValue)), |
| 338 | il.Const(addrSize, extra_offset))); |
| 339 | } |
| 340 | else |
| 341 | { |
| 342 | addr = il.Add(addrSize, ILREG_O(operand), |
| 343 | il.ShiftLeft( |
| 344 | addrSize, il.Const(addrSize, operand.immediate), il.Const(1, operand.shiftValue))); |
| 345 | } |
| 346 | } |
| 347 | else |
| 348 | { |
| 349 | // printf("ERROR: dunno how to handle MEM_EXTENDED shiftType %d\n", operand.shiftType); |
| 350 | ABORT_LIFT; |
| 351 | } |
| 352 | break; |
| 353 | default: |
| 354 | // printf("ERROR: dunno how to handle operand class %d\n", oclass); |
| 355 | ABORT_LIFT; |
| 356 | } |
| 357 | return addr; |
| 358 | } |
| 359 | |
| 360 | |
| 361 | static size_t ReadILOperand(LowLevelILFunction& il, InstructionOperand& operand, size_t resultSize) |
no test coverage detected