James Courtier-Dutton
2013-Jun-28 12:51 UTC
[LLVMdev] Question regarding the x86 SBB instruction.
Hi, I have the x86 SBB instruction. how should I represent this in LLVM IR. (as part of a decompiler from binary to LLVM IR) Pre-conditions: %eax = 0xffffffff %edx = 0xffffffff %carry = 1 SBB %eax, %edx // %edx is the destination doing %edx = %edx - (%eax + carry) JC jump_destination1 // If the Carry flag is set, jump to jump_destination1 How do I represent this correctly in LLVM IR? In the above case, the carry flag should be set by the SBB because: %eax + carry == 0x100000000 (33 bits) or 0x0 (32 bits) %edx - (%eax + carry) == %edx with Carry set. If I use LLVM IR: %eax2 = ADD i32 %eax1, %carry (%eax2 == 0) [%edx2,%carry] = llvm.ssub.with.overflow.i32 %edx1, %eax2 (carry =0, but I want it to be 1) So, the problem only occurs with the edge case of %eax == 0xffffffff and carry == 1 Any ideas how I could make this work accurately in LLVM IR ? I could put an if round it: if ((%eax1 == 0xffffffff)) && (%carry1 == 1)) { %carry2 = 1 } else { %eax2 = ADD i32 %eax1, %carry [%edx2,%carry3] = llvm.ssub.with.overflow.i32 %edx1, %eax2 } %carry4 = phi (%carry2, %carry3) (true branch, else branch) %edx3 = phi (%edx1, %edx2) branch cond %carry4 jump_destination Any better ideas? James
Hi James, you could use the sadd_with_overflow intrinsic. Ciao, Duncan. On 28/06/13 14:51, James Courtier-Dutton wrote:> Hi, > > I have the x86 SBB instruction. how should I represent this in LLVM > IR. (as part of a decompiler from binary to LLVM IR) > > Pre-conditions: > %eax = 0xffffffff > %edx = 0xffffffff > %carry = 1 > > SBB %eax, %edx // %edx is the destination doing %edx = %edx - > (%eax + carry) > JC jump_destination1 // If the Carry flag is set, jump to jump_destination1 > > How do I represent this correctly in LLVM IR? > In the above case, the carry flag should be set by the SBB because: > %eax + carry == 0x100000000 (33 bits) or 0x0 (32 bits) > %edx - (%eax + carry) == %edx with Carry set. > > If I use LLVM IR: > %eax2 = ADD i32 %eax1, %carry (%eax2 == 0) > [%edx2,%carry] = llvm.ssub.with.overflow.i32 %edx1, %eax2 (carry => 0, but I want it to be 1) > > So, the problem only occurs with the edge case of %eax == 0xffffffff > and carry == 1 > > Any ideas how I could make this work accurately in LLVM IR ? > I could put an if round it: > if ((%eax1 == 0xffffffff)) && (%carry1 == 1)) { > %carry2 = 1 > } else { > %eax2 = ADD i32 %eax1, %carry > [%edx2,%carry3] = llvm.ssub.with.overflow.i32 %edx1, %eax2 > } > %carry4 = phi (%carry2, %carry3) (true branch, else branch) > %edx3 = phi (%edx1, %edx2) > branch cond %carry4 jump_destination > > Any better ideas? > > James > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Michael Gottesman
2013-Jun-28 22:14 UTC
[LLVMdev] Question regarding the x86 SBB instruction.
Look at the __builtin_addc* builtins in clang. I am currently working on an optimization which transforms said intrinsics into chains of ADCs/SBBs. Michael On Jun 28, 2013, at 5:51 AM, James Courtier-Dutton <james.dutton at gmail.com> wrote:> Hi, > > I have the x86 SBB instruction. how should I represent this in LLVM > IR. (as part of a decompiler from binary to LLVM IR) > > Pre-conditions: > %eax = 0xffffffff > %edx = 0xffffffff > %carry = 1 > > SBB %eax, %edx // %edx is the destination doing %edx = %edx - > (%eax + carry) > JC jump_destination1 // If the Carry flag is set, jump to jump_destination1 > > How do I represent this correctly in LLVM IR? > In the above case, the carry flag should be set by the SBB because: > %eax + carry == 0x100000000 (33 bits) or 0x0 (32 bits) > %edx - (%eax + carry) == %edx with Carry set. > > If I use LLVM IR: > %eax2 = ADD i32 %eax1, %carry (%eax2 == 0) > [%edx2,%carry] = llvm.ssub.with.overflow.i32 %edx1, %eax2 (carry => 0, but I want it to be 1) > > So, the problem only occurs with the edge case of %eax == 0xffffffff > and carry == 1 > > Any ideas how I could make this work accurately in LLVM IR ? > I could put an if round it: > if ((%eax1 == 0xffffffff)) && (%carry1 == 1)) { > %carry2 = 1 > } else { > %eax2 = ADD i32 %eax1, %carry > [%edx2,%carry3] = llvm.ssub.with.overflow.i32 %edx1, %eax2 > } > %carry4 = phi (%carry2, %carry3) (true branch, else branch) > %edx3 = phi (%edx1, %edx2) > branch cond %carry4 jump_destination > > Any better ideas? > > James > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130628/68977d9a/attachment.html>
Michael Gottesman
2013-Jun-28 22:15 UTC
[LLVMdev] Question regarding the x86 SBB instruction.
(i.e. how said intrinsics are codegened as the IR level) On Jun 28, 2013, at 3:14 PM, Michael Gottesman <mgottesman at apple.com> wrote:> Look at the __builtin_addc* builtins in clang. I am currently working on an optimization which transforms said intrinsics into chains of ADCs/SBBs. > > Michael > > On Jun 28, 2013, at 5:51 AM, James Courtier-Dutton <james.dutton at gmail.com> wrote: > >> Hi, >> >> I have the x86 SBB instruction. how should I represent this in LLVM >> IR. (as part of a decompiler from binary to LLVM IR) >> >> Pre-conditions: >> %eax = 0xffffffff >> %edx = 0xffffffff >> %carry = 1 >> >> SBB %eax, %edx // %edx is the destination doing %edx = %edx - >> (%eax + carry) >> JC jump_destination1 // If the Carry flag is set, jump to jump_destination1 >> >> How do I represent this correctly in LLVM IR? >> In the above case, the carry flag should be set by the SBB because: >> %eax + carry == 0x100000000 (33 bits) or 0x0 (32 bits) >> %edx - (%eax + carry) == %edx with Carry set. >> >> If I use LLVM IR: >> %eax2 = ADD i32 %eax1, %carry (%eax2 == 0) >> [%edx2,%carry] = llvm.ssub.with.overflow.i32 %edx1, %eax2 (carry =>> 0, but I want it to be 1) >> >> So, the problem only occurs with the edge case of %eax == 0xffffffff >> and carry == 1 >> >> Any ideas how I could make this work accurately in LLVM IR ? >> I could put an if round it: >> if ((%eax1 == 0xffffffff)) && (%carry1 == 1)) { >> %carry2 = 1 >> } else { >> %eax2 = ADD i32 %eax1, %carry >> [%edx2,%carry3] = llvm.ssub.with.overflow.i32 %edx1, %eax2 >> } >> %carry4 = phi (%carry2, %carry3) (true branch, else branch) >> %edx3 = phi (%edx1, %edx2) >> branch cond %carry4 jump_destination >> >> Any better ideas? >> >> James >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130628/1e791f0b/attachment.html>
Reasonably Related Threads
- [LLVMdev] Question regarding the x86 SBB instruction.
- [LLVMdev] help decompiling x86 ASM to LLVM IR
- Correct modelling of instructions with types smaller than the register class
- Correct modelling of instructions with types smaller than the register class
- [LLVMdev] help decompiling x86 ASM to LLVM IR