Question regarding the x86 SBB instruction.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Question regarding the x86 SBB instruction.

James Courtier-Dutton-4
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding the x86 SBB instruction.

Duncan Sands
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
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding the x86 SBB instruction.

Michael Gottesman
In reply to this post by James Courtier-Dutton-4
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 <[hidden email]> 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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding the x86 SBB instruction.

Michael Gottesman
(i.e. how said intrinsics are codegened as the IR level)

On Jun 28, 2013, at 3:14 PM, Michael Gottesman <[hidden email]> 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 <[hidden email]> 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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev