| 334 | |
| 335 | |
| 336 | static void Load( |
| 337 | LowLevelILFunction& il, |
| 338 | bool sx, |
| 339 | size_t size, |
| 340 | InstructionOperand& dst, |
| 341 | InstructionOperand& src, |
| 342 | size_t addr) |
| 343 | { |
| 344 | ExprId value, memValue; |
| 345 | size_t dstSize = get_register_size(dst.reg); |
| 346 | value = ReadAddress(il, src, addr); |
| 347 | |
| 348 | switch (src.cls) |
| 349 | { |
| 350 | case MEM_PRE_IDX: |
| 351 | memValue = il.Load(size, ILREG(src)); |
| 352 | |
| 353 | if (size != dstSize) |
| 354 | { |
| 355 | if (sx) |
| 356 | memValue = il.SignExtend(dstSize, memValue); |
| 357 | else |
| 358 | memValue = il.ZeroExtend(dstSize, memValue); |
| 359 | } |
| 360 | |
| 361 | il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); |
| 362 | il.AddInstruction(SetRegisterOrBranch(il, dst.reg, memValue)); |
| 363 | break; |
| 364 | case MEM_POST_IDX: |
| 365 | memValue = il.Load(size, ILREG(src)); |
| 366 | |
| 367 | if (size != dstSize) |
| 368 | { |
| 369 | if (sx) |
| 370 | memValue = il.SignExtend(dstSize, memValue); |
| 371 | else |
| 372 | memValue = il.ZeroExtend(dstSize, memValue); |
| 373 | } |
| 374 | |
| 375 | if (dst.reg == REG_PC) |
| 376 | { |
| 377 | // don't update Rd, update Rs, jump to pre-updated Rs |
| 378 | il.AddInstruction(il.SetRegister(4, LLIL_TEMP(0), memValue)); |
| 379 | il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); |
| 380 | il.AddInstruction(il.Jump(il.Register(4, LLIL_TEMP(0)))); |
| 381 | } |
| 382 | else |
| 383 | { |
| 384 | // set Rd, update Rs, don't jump |
| 385 | il.AddInstruction(il.SetRegister(get_register_size(dst.reg), dst.reg, memValue)); |
| 386 | il.AddInstruction(SetRegisterOrBranch(il, src.reg, value)); |
| 387 | } |
| 388 | |
| 389 | break; |
| 390 | case MEM_IMM: |
| 391 | case LABEL: |
| 392 | memValue = il.Load(size, value); |
| 393 | |