[llvm-commits] [llvm] r60915 - in /llvm/trunk/lib: CodeGen/SelectionDAG/DAGCombiner.cpp Target/X86/X86ISelLowering.cpp Target/X86/X86ISelLowering.h Target/X86/X86Instr64bit.td Target/X86/X86InstrInfo.td

Evan Cheng evan.cheng at apple.com
Thu Dec 11 23:05:24 PST 2008


Do we really need different instructions? How us ADD32rr different  
from ADDvfo32er? Both implicitly define EFLAGS.

Evan

On Dec 11, 2008, at 4:56 PM, Bill Wendling <isanbard at gmail.com> wrote:

> Author: void
> Date: Thu Dec 11 18:56:36 2008
> New Revision: 60915
>
> URL: http://llvm.org/viewvc/llvm-project?rev=60915&view=rev
> Log:
> Redo the arithmetic with overflow architecture. I was changing the  
> semantics of
> ISD::ADD to emit an implicit EFLAGS. This was horribly broken.  
> Instead, replace
> the intrinsic with an ISD::SADDO node. Then custom lower that into an
> X86ISD::ADD node with a associated SETCC that checks the correct  
> condition code
> (overflow or carry). Then that gets lowered into the correct  
> X86::ADDOvf
> instruction.
>
> Similar for SUB and MUL instructions.
>
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>    llvm/trunk/lib/Target/X86/X86ISelLowering.h
>    llvm/trunk/lib/Target/X86/X86Instr64bit.td
>    llvm/trunk/lib/Target/X86/X86InstrInfo.td
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=60915&r1=60914&r2=60915&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Dec 11  
> 18:56:36 2008
> @@ -967,11 +967,6 @@
>     if (FoldedVOp.getNode()) return FoldedVOp;
>   }
>
> -  if (N->getNumValues() != 1)
> -    // FIXME: DAG combiner cannot handle arithmetic operators which  
> produce
> -    // multiple results.
> -    return SDValue();
> -
>   // fold (add x, undef) -> undef
>   if (N0.getOpcode() == ISD::UNDEF)
>     return N0;
> @@ -1167,11 +1162,6 @@
>     if (FoldedVOp.getNode()) return FoldedVOp;
>   }
>
> -  if (N->getNumValues() != 1)
> -    // FIXME: DAG combiner cannot handle arithmetic operators which  
> produce
> -    // multiple results.
> -    return SDValue();
> -
>   // fold (sub x, x) -> 0
>   if (N0 == N1)
>     return DAG.getConstant(0, N->getValueType(0));
> @@ -1230,11 +1220,6 @@
>     if (FoldedVOp.getNode()) return FoldedVOp;
>   }
>
> -  if (N->getNumValues() != 1)
> -    // FIXME: DAG combiner cannot handle arithmetic operators which  
> produce
> -    // multiple results.
> -    return SDValue();
> -
>   // fold (mul x, undef) -> 0
>   if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
>     return DAG.getConstant(0, VT);
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60915&r1=60914&r2=60915&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Dec 11  
> 18:56:36 2008
> @@ -5210,9 +5210,9 @@
>
>   if (Cond.getOpcode() == ISD::SETCC)
>     Cond = LowerSETCC(Cond, DAG);
> -  else if (Cond.getOpcode() == ISD::SADDO || Cond.getOpcode() ==  
> ISD::UADDO ||
> -           Cond.getOpcode() == ISD::SSUBO || Cond.getOpcode() ==  
> ISD::USUBO ||
> -           Cond.getOpcode() == ISD::SMULO || Cond.getOpcode() ==  
> ISD::UMULO)
> +  else if (Cond.getOpcode() == X86ISD::ADD ||
> +           Cond.getOpcode() == X86ISD::SUB ||
> +           Cond.getOpcode() == X86ISD::MUL)
>     Cond = LowerXALUO(Cond, DAG);
>
>   // If condition flag is set by a X86ISD::CMP, then use it as the  
> condition
> @@ -6142,27 +6142,27 @@
>   switch (Op.getOpcode()) {
>   default: assert(0 && "Unknown ovf instruction!");
>   case ISD::SADDO:
> -    BaseOp = ISD::ADD;
> +    BaseOp = X86ISD::ADD;
>     Cond = X86::COND_O;
>     break;
>   case ISD::UADDO:
> -    BaseOp = ISD::ADD;
> +    BaseOp = X86ISD::ADD;
>     Cond = X86::COND_C;
>     break;
>   case ISD::SSUBO:
> -    BaseOp = ISD::SUB;
> +    BaseOp = X86ISD::SUB;
>     Cond = X86::COND_O;
>     break;
>   case ISD::USUBO:
> -    BaseOp = ISD::SUB;
> +    BaseOp = X86ISD::SUB;
>     Cond = X86::COND_C;
>     break;
>   case ISD::SMULO:
> -    BaseOp = ISD::MUL;
> +    BaseOp = X86ISD::MUL;
>     Cond = X86::COND_O;
>     break;
>   case ISD::UMULO:
> -    BaseOp = ISD::MUL;
> +    BaseOp = X86ISD::MUL;
>     Cond = X86::COND_C;
>     break;
>   }
> @@ -6488,6 +6488,9 @@
>   case X86ISD::PCMPGTW:            return "X86ISD::PCMPGTW";
>   case X86ISD::PCMPGTD:            return "X86ISD::PCMPGTD";
>   case X86ISD::PCMPGTQ:            return "X86ISD::PCMPGTQ";
> +  case X86ISD::ADD:                return "X86ISD::ADD";
> +  case X86ISD::SUB:                return "X86ISD::SUB";
> +  case X86ISD::MUL:                return "X86ISD::MUL";
>   }
> }
>
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=60915&r1=60914&r2=60915&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Dec 11 18:56:36  
> 2008
> @@ -227,7 +227,11 @@
>
>       // PCMP* - Vector integer comparisons.
>       PCMPEQB, PCMPEQW, PCMPEQD, PCMPEQQ,
> -      PCMPGTB, PCMPGTW, PCMPGTD, PCMPGTQ
> +      PCMPGTB, PCMPGTW, PCMPGTD, PCMPGTQ,
> +
> +      // ADD, SUB, MUL - Arithmetic operations with overflow/carry
> +      // intrinsics.
> +      ADD, SUB, MUL
>     };
>   }
>
>
> Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=60915&r1=60914&r2=60915&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
> +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Thu Dec 11 18:56:36  
> 2008
> @@ -312,39 +312,76 @@
> let isTwoAddress = 1 in {
> let isConvertibleToThreeAddress = 1 in {
> let isCommutable = 1 in
> -def ADD64rr  : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
> -                  "add{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
> -                   (implicit EFLAGS)]>;
> +// Register-Register Addition
> +def ADD64rr    : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
> +                    "add{q}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>;
>
> -def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i32imm:$src2),
> -                      "add{q}\t{$src2, $dst|$dst, $src2}",
> -                      [(set GR64:$dst, (add GR64:$src1,  
> i64immSExt32:$src2)),
> -                       (implicit EFLAGS)]>;
> -def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1,  
> i64i8imm:$src2),
> +// Register-Register Addition with Overflow
> +def ADDOvf64rr : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
>                     "add{q}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR64:$dst, (add GR64:$src1,  
> i64immSExt8:$src2)),
> +                    [(set GR64:$dst, (X86add_ovf GR64:$src1,  
> GR64:$src2)),
>                      (implicit EFLAGS)]>;
> +
> +// Register-Integer Addition
> +def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i32imm:$src2),
> +                      "add{q}\t{$src2, $dst|$dst, $src2}",
> +                      [(set GR64:$dst, (add GR64:$src1,  
> i64immSExt32:$src2))]>;
> +def ADD64ri8  : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i8imm:$src2),
> +                     "add{q}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR64:$dst, (add GR64:$src1,  
> i64immSExt8:$src2))]>;
> +
> +// Register-Integer Addition with Overflow
> +def ADDOvf64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i32imm:$src2),
> +                         "add{q}\t{$src2, $dst|$dst, $src2}",
> +                         [(set GR64:$dst, (X86add_ovf GR64:$src1,  
> i64immSExt32:$src2)),
> +                          (implicit EFLAGS)]>;
> +def ADDOvf64ri8  : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i8imm:$src2),
> +                        "add{q}\t{$src2, $dst|$dst, $src2}",
> +                        [(set GR64:$dst, (X86add_ovf GR64:$src1,  
> i64immSExt8:$src2)),
> +                         (implicit EFLAGS)]>;
> } // isConvertibleToThreeAddress
>
> -def ADD64rm  : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
> -                  "add{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(set GR64:$dst, (add GR64:$src1, (load addr: 
> $src2))),
> -                   (implicit EFLAGS)]>;
> +// Register-Memory Addition
> +def ADD64rm     : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
> +                     "add{q}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR64:$dst, (add GR64:$src1, (load addr: 
> $src2)))]>;
> +
> +// Register-Memory Addition with Overflow
> +def ADDOvf64rm  : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
> +                     "add{q}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR64:$dst, (X86add_ovf GR64:$src1, (load  
> addr:$src2))),
> +                      (implicit EFLAGS)]>;
> } // isTwoAddress
>
> +// Memory-Register Addition
> def ADD64mr  : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst,  
> GR64:$src2),
>                   "add{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (add (load addr:$dst), GR64:$src2), addr: 
> $dst),
> -                   (implicit EFLAGS)]>;
> +                  [(store (add (load addr:$dst), GR64:$src2), addr: 
> $dst)]>;
> def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst,  
> i64i32imm :$src2),
>                       "add{q}\t{$src2, $dst|$dst, $src2}",
> -               [(store (add (load addr:$dst), i64immSExt32:$src2),  
> addr:$dst),
> -                (implicit EFLAGS)]>;
> +               [(store (add (load addr:$dst), i64immSExt32:$src2),  
> addr:$dst)]>;
> def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm : 
> $src2),
>                     "add{q}\t{$src2, $dst|$dst, $src2}",
> -                [(store (add (load addr:$dst), i64immSExt8:$src2),  
> addr:$dst),
> -                 (implicit EFLAGS)]>;
> +                [(store (add (load addr:$dst), i64immSExt8:$src2),  
> addr:$dst)]>;
> +
> +// Memory-Register Addition with Overflow
> +def ADDOvf64mr   : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst,  
> GR64:$src2),
> +                      "add{q}\t{$src2, $dst|$dst, $src2}",
> +                      [(store (X86add_ovf (load addr:$dst),  
> GR64:$src2),
> +                              addr:$dst),
> +                       (implicit EFLAGS)]>;
> +def ADDOvf64mi32 : RIi32<0x81, MRM0m, (outs),(ins i64mem:$dst,  
> i64i32imm:$src2),
> +                         "add{q}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86add_ovf (load addr:$dst),
> +                                             i64immSExt32:$src2),
> +                                 addr:$dst),
> +                          (implicit EFLAGS)]>;
> +def ADDOvf64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst,  
> i64i8imm :$src2),
> +                       "add{q}\t{$src2, $dst|$dst, $src2}",
> +                       [(store (X86add_ovf (load addr:$dst),  
> i64immSExt8:$src2),
> +                               addr:$dst),
> +                        (implicit EFLAGS)]>;
>
> let Uses = [EFLAGS] in {
> let isTwoAddress = 1 in {
> @@ -377,38 +414,86 @@
> } // Uses = [EFLAGS]
>
> let isTwoAddress = 1 in {
> +// Register-Register Subtraction
> def SUB64rr  : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
>                   "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(set GR64:$dst, (sub GR64:$src1, GR64:$src2)),
> -                   (implicit EFLAGS)]>;
> +                  [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
> +
> +// Register-Register Subtraction with Overflow
> +def SUBOvf64rr : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
> +                    "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR64:$dst, (X86sub_ovf GR64:$src1,  
> GR64:$src2)),
> +                     (implicit EFLAGS)]>;
>
> +// Register-Memory Subtraction
> def SUB64rm  : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
>                   "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(set GR64:$dst, (sub GR64:$src1, (load addr: 
> $src2))),
> -                   (implicit EFLAGS)]>;
> +                  [(set GR64:$dst, (sub GR64:$src1, (load addr: 
> $src2)))]>;
> +
> +// Register-Memory Subtraction with Overflow
> +def SUBOvf64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
> +                    "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR64:$dst, (X86sub_ovf GR64:$src1, (load  
> addr:$src2))),
> +                     (implicit EFLAGS)]>;
>
> -def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst), (ins  
> GR64:$src1, i64i32imm:$src2),
> +// Register-Integer Subtraction
> +def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
> +                                   (ins GR64:$src1, i64i32imm:$src2),
>                       "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                      [(set GR64:$dst, (sub GR64:$src1,  
> i64immSExt32:$src2)),
> -                   (implicit EFLAGS)]>;
> -def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst), (ins GR64:$src1,  
> i64i8imm:$src2),
> +                      [(set GR64:$dst, (sub GR64:$src1,  
> i64immSExt32:$src2))]>;
> +def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
> +                                 (ins GR64:$src1, i64i8imm:$src2),
>                     "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR64:$dst, (sub GR64:$src1,  
> i64immSExt8:$src2)),
> -                   (implicit EFLAGS)]>;
> +                    [(set GR64:$dst, (sub GR64:$src1,  
> i64immSExt8:$src2))]>;
> +
> +// Register-Integer Subtraction with Overflow
> +def SUBOvf64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
> +                                      (ins GR64:$src1, i64i32imm: 
> $src2),
> +                         "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                         [(set GR64:$dst, (X86sub_ovf GR64:$src1,
> +                                                       
> i64immSExt32:$src2)),
> +                          (implicit EFLAGS)]>;
> +def SUBOvf64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
> +                                    (ins GR64:$src1, i64i8imm:$src2),
> +                       "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR64:$dst, (X86sub_ovf GR64:$src1,
> +                                                     
> i64immSExt8:$src2)),
> +                        (implicit EFLAGS)]>;
> } // isTwoAddress
>
> +// Memory-Register Subtraction
> def SUB64mr  : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst,  
> GR64:$src2),
>                   "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (sub (load addr:$dst), GR64:$src2), addr: 
> $dst),
> -                   (implicit EFLAGS)]>;
> -def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst,  
> i64i32imm:$src2),
> +                  [(store (sub (load addr:$dst), GR64:$src2), addr: 
> $dst)]>;
> +
> +// Memory-Register Subtraction with Overflow
> +def SUBOvf64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst,  
> GR64:$src2),
> +                    "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                    [(store (X86sub_ovf (load addr:$dst),  
> GR64:$src2),
> +                            addr:$dst),
> +                     (implicit EFLAGS)]>;
> +
> +// Memory-Integer Subtraction
> +def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst,  
> i64i32imm:$src2),
>                       "sub{q}\t{$src2, $dst|$dst, $src2}",
> -               [(store (sub (load addr:$dst), i64immSExt32:$src2),  
> addr:$dst),
> -                   (implicit EFLAGS)]>;
> +                      [(store (sub (load addr:$dst),  
> i64immSExt32:$src2),
> +                              addr:$dst)]>;
> def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm : 
> $src2),
>                     "sub{q}\t{$src2, $dst|$dst, $src2}",
> -                [(store (sub (load addr:$dst), i64immSExt8:$src2),  
> addr:$dst),
> -                   (implicit EFLAGS)]>;
> +                    [(store (sub (load addr:$dst),  
> i64immSExt8:$src2),
> +                            addr:$dst)]>;
> +
> +// Memory-Integer Subtraction with Overflow
> +def SUBOvf64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem: 
> $dst,i64i32imm:$src2),
> +                         "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86sub_ovf (load addr:$dst),
> +                                             i64immSExt32:$src2),  
> addr:$dst),
> +                          (implicit EFLAGS)]>;
> +def SUBOvf64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst,  
> i64i8imm :$src2),
> +                       "sub{q}\t{$src2, $dst|$dst, $src2}",
> +                       [(store (X86sub_ovf (load addr:$dst),  
> i64immSExt8:$src2),
> +                               addr:$dst),
> +                        (implicit EFLAGS)]>;
>
> let Uses = [EFLAGS] in {
> let isTwoAddress = 1 in {
> @@ -459,38 +544,85 @@
> let Defs = [EFLAGS] in {
> let isTwoAddress = 1 in {
> let isCommutable = 1 in
> -def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst), (ins  
> GR64:$src1, GR64:$src2),
> +// Register-Register Integer Multiplication
> +def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
> +                                   (ins GR64:$src1, GR64:$src2),
>                   "imul{q}\t{$src2, $dst|$dst, $src2}",
> -                  [(set GR64:$dst, (mul GR64:$src1, GR64:$src2)),
> -                   (implicit EFLAGS)]>, TB;
> +                  [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>,  
> TB;
>
> -def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst), (ins  
> GR64:$src1, i64mem:$src2),
> +// Register-Register Multiplication with Overflow
> +def IMULOvf64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
> +                                      (ins GR64:$src1, GR64:$src2),
> +                     "imul{q}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR64:$dst, (X86mul_ovf GR64:$src1,  
> GR64:$src2)),
> +                      (implicit EFLAGS)]>, TB;
> +
> +// Register-Memory Integer Multiplication
> +def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
> +                                   (ins GR64:$src1, i64mem:$src2),
>                   "imul{q}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR64:$dst, (mul GR64:$src1, (load addr: 
> $src2))),
> -                  (implicit EFLAGS)]>, TB;
> +                  [(set GR64:$dst, (mul GR64:$src1, (load addr: 
> $src2)))]>, TB;
> +
> +// Register-Memory Integer Multiplication with Overflow
> +def IMULOvf64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
> +                                      (ins GR64:$src1, i64mem:$src2),
> +                     "imul{q}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR64:$dst, (X86mul_ovf GR64:$src1,
> +                                                  (load addr: 
> $src2))),
> +                      (implicit EFLAGS)]>, TB;
> } // isTwoAddress
>
> // Suprisingly enough, these are not two address instructions!
> +
> +// Register-Integer Integer Multiplication
> def IMUL64rri32 : RIi32<0x69, MRMSrcReg,                    // GR64  
> = GR64*I32
>                         (outs GR64:$dst), (ins GR64:$src1, i64i32imm: 
> $src2),
>                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                       [(set GR64:$dst, (mul GR64:$src1,  
> i64immSExt32:$src2)),
> -                        (implicit EFLAGS)]>;
> +                       [(set GR64:$dst, (mul GR64:$src1,  
> i64immSExt32:$src2))]>;
> def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64  
> = GR64*I8
>                       (outs GR64:$dst), (ins GR64:$src1, i64i8imm: 
> $src2),
>                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                      [(set GR64:$dst, (mul GR64:$src1,  
> i64immSExt8:$src2)),
> -                       (implicit EFLAGS)]>;
> +                      [(set GR64:$dst, (mul GR64:$src1,  
> i64immSExt8:$src2))]>;
> +
> +// Register-Integer Integer Multiplication with Overflow
> +def IMULOvf64rri32 : RIi32<0x69, MRMSrcReg,                 // GR64  
> = GR64*I32
> +                           (outs GR64:$dst), (ins GR64:$src1,  
> i64i32imm:$src2),
> +                           "imul{q}\t{$src2, $src1, $dst|$dst,  
> $src1, $src2}",
> +                           [(set GR64:$dst, (X86mul_ovf GR64:$src1,
> +                                                         
> i64immSExt32:$src2)),
> +                            (implicit EFLAGS)]>;
> +def IMULOvf64rri8 : RIi8<0x6B, MRMSrcReg,                   // GR64  
> = GR64*I8
> +                         (outs GR64:$dst), (ins GR64:$src1,  
> i64i8imm:$src2),
> +                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                         [(set GR64:$dst, (X86mul_ovf GR64:$src1,
> +                                                       
> i64immSExt8:$src2)),
> +                          (implicit EFLAGS)]>;
> +
> +// Memory-Integer Integer Multiplication
> def IMUL64rmi32 : RIi32<0x69, MRMSrcMem,                   // GR64 =  
> [mem64]*I32
>                         (outs GR64:$dst), (ins i64mem:$src1,  
> i64i32imm:$src2),
>                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                [(set GR64:$dst, (mul (load addr:$src1),  
> i64immSExt32:$src2)),
> -                 (implicit EFLAGS)]>;
> +                        [(set GR64:$dst, (mul (load addr:$src1),
> +                                              i64immSExt32:$src2))]>;
> def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64  
> = [mem64]*I8
>                       (outs GR64:$dst), (ins i64mem:$src1, i64i8imm:  
> $src2),
>                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                 [(set GR64:$dst, (mul (load addr:$src1),  
> i64immSExt8:$src2)),
> -                  (implicit EFLAGS)]>;
> +                      [(set GR64:$dst, (mul (load addr:$src1),
> +                                            i64immSExt8:$src2))]>;
> +
> +// Memory-Integer Integer Multiplication with Overflow
> +def IMULOvf64rmi32 : RIi32<0x69, MRMSrcMem,                   //  
> GR64 = [mem64]*I32
> +                           (outs GR64:$dst), (ins i64mem:$src1,  
> i64i32imm:$src2),
> +                           "imul{q}\t{$src2, $src1, $dst|$dst,  
> $src1, $src2}",
> +                           [(set GR64:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                         
> i64immSExt32:$src2)),
> +                            (implicit EFLAGS)]>;
> +def IMULOvf64rmi8 : RIi8<0x6B, MRMSrcMem,                      //  
> GR64 = [mem64]*I8
> +                         (outs GR64:$dst), (ins i64mem:$src1,  
> i64i8imm: $src2),
> +                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                         [(set GR64:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                       
> i64immSExt8:$src2)),
> +                          (implicit EFLAGS)]>;
> } // Defs = [EFLAGS]
>
> // Unsigned division / remainder
>
> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=60915&r1=60914&r2=60915&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Dec 11 18:56:36 2008
> @@ -27,6 +27,10 @@
>                                   [SDTCisSameAs<0, 1>,  
> SDTCisSameAs<1, 2>,
>                                    SDTCisVT<3, i8>, SDTCisVT<4,  
> i32>]>;
>
> +def SDTArithOvf : SDTypeProfile<1, 2,
> +                                [SDTCisSameAs<0, 1>,  
> SDTCisSameAs<0, 2>,
> +                                 SDTCisInt<0>]>;
> +
> def SDTX86BrCond  : SDTypeProfile<0, 3,
>                                   [SDTCisVT<0, OtherVT>,
>                                    SDTCisVT<1, i8>, SDTCisVT<2,  
> i32>]>;
> @@ -140,6 +144,10 @@
> def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
>                         [SDNPHasChain,  SDNPOptInFlag]>;
>
> +def X86add_ovf : SDNode<"X86ISD::ADD", SDTArithOvf>;
> +def X86sub_ovf : SDNode<"X86ISD::SUB", SDTArithOvf>;
> +def X86mul_ovf : SDNode<"X86ISD::MUL", SDTArithOvf>;
> +
> // 
> === 
> --- 
> ------------------------------------------------------------------- 
> ===//
> // X86 Operand Definitions.
> //
> @@ -1923,104 +1931,202 @@
> // Arithmetic.
> let Defs = [EFLAGS] in {
> let isCommutable = 1 in {   // X = ADD Y, Z   --> X = ADD Z, Y
> -def ADD8rr   : I<0x00, MRMDestReg, (outs GR8 :$dst),
> -                                   (ins GR8 :$src1, GR8 :$src2),
> -                 "add{b}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
> -                  (implicit EFLAGS)]>;
> +// Register-Register Addition
> +def ADD8rr    : I<0x00, MRMDestReg, (outs GR8 :$dst),
> +                                    (ins GR8 :$src1, GR8 :$src2),
> +                  "add{b}\t{$src2, $dst|$dst, $src2}",
> +                  [(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>;
> +
> +// Register-Register Addition with Overflow
> +def ADDOvf8rr : I<0x00, MRMDestReg, (outs GR8 :$dst),
> +                                    (ins GR8 :$src1, GR8 :$src2),
> +                  "add{b}\t{$src2, $dst|$dst, $src2}",
> +                  [(set GR8:$dst, (X86add_ovf GR8:$src1, GR8:$src2)),
> +                   (implicit EFLAGS)]>;
> +
> let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
> +// Register-Register Addition
> def ADD16rr  : I<0x01, MRMDestReg, (outs GR16:$dst),
>                                    (ins GR16:$src1, GR16:$src2),
>                  "add{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
> -                  (implicit EFLAGS)]>, OpSize;
> +                 [(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>,  
> OpSize;
> def ADD32rr  : I<0x01, MRMDestReg, (outs GR32:$dst),
>                                    (ins GR32:$src1, GR32:$src2),
>                  "add{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
> -                  (implicit EFLAGS)]>;
> +                 [(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
> +
> +// Register-Register Addition with Overflow
> +def ADDOvf16rr : I<0x01, MRMDestReg, (outs GR16:$dst),
> +                                     (ins GR16:$src1, GR16:$src2),
> +                   "add{w}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR16:$dst, (X86add_ovf GR16:$src1,  
> GR16:$src2)),
> +                    (implicit EFLAGS)]>, OpSize;
> +def ADDOvf32rr : I<0x01, MRMDestReg, (outs GR32:$dst),
> +                                     (ins GR32:$src1, GR32:$src2),
> +                   "add{l}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR32:$dst, (X86add_ovf GR32:$src1,  
> GR32:$src2)),
> +                    (implicit EFLAGS)]>;
> } // end isConvertibleToThreeAddress
> } // end isCommutable
> +
> +// Register-Memory Addition
> def ADD8rm   : I<0x02, MRMSrcMem, (outs GR8 :$dst),
>                                   (ins GR8 :$src1, i8mem :$src2),
>                  "add{b}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
> -                  (implicit EFLAGS)]>;
> +                 [(set GR8:$dst, (add GR8:$src1, (load addr: 
> $src2)))]>;
> def ADD16rm  : I<0x03, MRMSrcMem, (outs GR16:$dst),
>                                   (ins GR16:$src1, i16mem:$src2),
>                  "add{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (add GR16:$src1, (load addr: 
> $src2))),
> -                  (implicit EFLAGS)]>, OpSize;
> +                 [(set GR16:$dst, (add GR16:$src1, (load addr: 
> $src2)))]>,OpSize;
> def ADD32rm  : I<0x03, MRMSrcMem, (outs GR32:$dst),
>                                   (ins GR32:$src1, i32mem:$src2),
>                  "add{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (add GR32:$src1, (load addr: 
> $src2))),
> -                  (implicit EFLAGS)]>;
> +                 [(set GR32:$dst, (add GR32:$src1, (load addr: 
> $src2)))]>;
>
> -def ADD8ri   : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1,  
> i8imm:$src2),
> +// Register-Memory Addition with Overflow
> +def ADDOvf8rm  : I<0x02, MRMSrcMem, (outs GR8 :$dst),
> +                                    (ins GR8 :$src1, i8mem :$src2),
>                    "add{b}\t{$src2, $dst|$dst, $src2}",
> -                   [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
> +                   [(set GR8:$dst, (X86add_ovf GR8:$src1, (load  
> addr:$src2))),
> +                    (implicit EFLAGS)]>;
> +def ADDOvf16rm : I<0x03, MRMSrcMem, (outs GR16:$dst),
> +                                    (ins GR16:$src1, i16mem:$src2),
> +                   "add{w}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR16:$dst, (X86add_ovf GR16:$src1, (load  
> addr:$src2))),
> +                    (implicit EFLAGS)]>, OpSize;
> +def ADDOvf32rm : I<0x03, MRMSrcMem, (outs GR32:$dst),
> +                                    (ins GR32:$src1, i32mem:$src2),
> +                   "add{l}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR32:$dst, (X86add_ovf GR32:$src1, (load  
> addr:$src2))),
>                     (implicit EFLAGS)]>;
>
> +// Register-Integer Addition
> +def ADD8ri    : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1,  
> i8imm:$src2),
> +                    "add{b}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR8:$dst, (add GR8:$src1, imm:$src2))]>;
> +
> +// Register-Integer Addition with Overflow
> +def ADDOvf8ri  : Ii8<0x80, MRM0r, (outs GR8:$dst), (ins GR8:$src1,  
> i8imm:$src2),
> +                     "add{b}\t{$src2, $dst|$dst, $src2}",
> +                     [(set GR8:$dst, (X86add_ovf GR8:$src1, imm: 
> $src2)),
> +                      (implicit EFLAGS)]>;
> +
> let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
> +// Register-Integer Addition
> def ADD16ri  : Ii16<0x81, MRM0r, (outs GR16:$dst),
>                                  (ins GR16:$src1, i16imm:$src2),
>                     "add{w}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
> -                     (implicit EFLAGS)]>, OpSize;
> +                    [(set GR16:$dst, (add GR16:$src1, imm: 
> $src2))]>, OpSize;
> def ADD32ri  : Ii32<0x81, MRM0r, (outs GR32:$dst),
>                                  (ins GR32:$src1, i32imm:$src2),
>                     "add{l}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
> -                     (implicit EFLAGS)]>;
> +                    [(set GR32:$dst, (add GR32:$src1, imm:$src2))]>;
> def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst),
>                                 (ins GR16:$src1, i16i8imm:$src2),
>                    "add{w}\t{$src2, $dst|$dst, $src2}",
> -                [(set GR16:$dst, (add GR16:$src1,  
> i16immSExt8:$src2)),
> -                 (implicit EFLAGS)]>, OpSize;
> +                [(set GR16:$dst, (add GR16:$src1,  
> i16immSExt8:$src2))]>, OpSize;
> def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst),
>                                 (ins GR32:$src1, i32i8imm:$src2),
>                    "add{l}\t{$src2, $dst|$dst, $src2}",
> -                [(set GR32:$dst, (add GR32:$src1,  
> i32immSExt8:$src2)),
> -                 (implicit EFLAGS)]>;
> +                [(set GR32:$dst, (add GR32:$src1,  
> i32immSExt8:$src2))]>;
> +
> +// Register-Integer Addition with Overflow
> +def ADDOvf16ri  : Ii16<0x81, MRM0r, (outs GR16:$dst),
> +                                    (ins GR16:$src1, i16imm:$src2),
> +                       "add{w}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR16:$dst, (X86add_ovf GR16:$src1, imm: 
> $src2)),
> +                        (implicit EFLAGS)]>, OpSize;
> +def ADDOvf32ri  : Ii32<0x81, MRM0r, (outs GR32:$dst),
> +                                    (ins GR32:$src1, i32imm:$src2),
> +                       "add{l}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR32:$dst, (X86add_ovf GR32:$src1, imm: 
> $src2)),
> +                        (implicit EFLAGS)]>;
> +def ADDOvf16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst),
> +                                   (ins GR16:$src1, i16i8imm:$src2),
> +                      "add{w}\t{$src2, $dst|$dst, $src2}",
> +                      [(set GR16:$dst, (X86add_ovf GR16:$src1,
> +                                                    
> i16immSExt8:$src2)),
> +                       (implicit EFLAGS)]>, OpSize;
> +def ADDOvf32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst),
> +                                   (ins GR32:$src1, i32i8imm:$src2),
> +                      "add{l}\t{$src2, $dst|$dst, $src2}",
> +                      [(set GR32:$dst, (X86add_ovf GR32:$src1,
> +                                        i32immSExt8:$src2)),
> +                       (implicit EFLAGS)]>;
> }
>
> let isTwoAddress = 0 in {
> +  // Memory-Register Addition
>   def ADD8mr   : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst, GR8 : 
> $src2),
>                    "add{b}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (add (load addr:$dst), GR8:$src2), addr: 
> $dst),
> -                    (implicit EFLAGS)]>;
> +                   [(store (add (load addr:$dst), GR8:$src2), addr: 
> $dst)]>;
>   def ADD16mr  : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst,  
> GR16:$src2),
>                    "add{w}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (add (load addr:$dst), GR16:$src2), addr: 
> $dst),
> -                    (implicit EFLAGS)]>,
> -                 OpSize;
> +                   [(store (add (load addr:$dst), GR16:$src2), addr: 
> $dst)]>,
> +                   OpSize;
>   def ADD32mr  : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst,  
> GR32:$src2),
>                    "add{l}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (add (load addr:$dst), GR32:$src2), addr: 
> $dst),
> -                    (implicit EFLAGS)]>;
> +                   [(store (add (load addr:$dst), GR32:$src2), addr: 
> $dst)]>;
>   def ADD8mi   : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst, i8imm : 
> $src2),
>                      "add{b}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (add (loadi8 addr:$dst), imm:$src2),  
> addr:$dst),
> -                    (implicit EFLAGS)]>;
> +                   [(store (add (loadi8 addr:$dst), imm:$src2),  
> addr:$dst)]>;
>   def ADD16mi  : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm: 
> $src2),
>                       "add{w}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (add (loadi16 addr:$dst), imm:$src2),  
> addr:$dst),
> -                   (implicit EFLAGS)]>,
> -                 OpSize;
> +                  [(store (add (loadi16 addr:$dst), imm:$src2),  
> addr:$dst)]>,
> +                  OpSize;
>   def ADD32mi  : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm: 
> $src2),
>                       "add{l}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (add (loadi32 addr:$dst), imm:$src2),  
> addr:$dst),
> -                   (implicit EFLAGS)]>;
> +                  [(store (add (loadi32 addr:$dst), imm:$src2),  
> addr:$dst)]>;
>   def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst,  
> i16i8imm :$src2),
>                      "add{w}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (add (load addr:$dst),  
> i16immSExt8:$src2), addr:$dst),
> -                   (implicit EFLAGS)]>,
> -                 OpSize;
> +                  [(store (add (load addr:$dst), i16immSExt8:$src2),
> +                               addr:$dst)]>, OpSize;
>   def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst,  
> i32i8imm :$src2),
>                      "add{l}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (add (load addr:$dst),  
> i32immSExt8:$src2), addr:$dst),
> -                   (implicit EFLAGS)]>;
> +                  [(store (add (load addr:$dst), i32immSExt8:$src2),
> +                               addr:$dst)]>;
> +
> +  // Memory-Register Addition with Overflow
> +  def ADDOvf8mr   : I<0x00, MRMDestMem, (outs), (ins i8mem :$dst,  
> GR8 :$src2),
> +                      "add{b}\t{$src2, $dst|$dst, $src2}",
> +                      [(store (X86add_ovf (load addr:$dst),  
> GR8:$src2),
> +                                          addr:$dst),
> +                       (implicit EFLAGS)]>;
> +  def ADDOvf16mr  : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst,  
> GR16:$src2),
> +                      "add{w}\t{$src2, $dst|$dst, $src2}",
> +                      [(store (X86add_ovf (load addr:$dst),  
> GR16:$src2),
> +                                          addr:$dst),
> +                       (implicit EFLAGS)]>, OpSize;
> +  def ADDOvf32mr  : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst,  
> GR32:$src2),
> +                      "add{l}\t{$src2, $dst|$dst, $src2}",
> +                      [(store (X86add_ovf (load addr:$dst),  
> GR32:$src2),
> +                                          addr:$dst),
> +                       (implicit EFLAGS)]>;
> +  def ADDOvf8mi   : Ii8<0x80, MRM0m, (outs), (ins i8mem :$dst,  
> i8imm :$src2),
> +                        "add{b}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86add_ovf (loadi8 addr:$dst), imm: 
> $src2),
> +                                            addr:$dst),
> +                        (implicit EFLAGS)]>;
> +  def ADDOvf16mi  : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst,  
> i16imm:$src2),
> +                         "add{w}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86add_ovf (loadi16 addr:$dst),  
> imm:$src2),
> +                                             addr:$dst),
> +                          (implicit EFLAGS)]>, OpSize;
> +  def ADDOvf32mi  : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst,  
> i32imm:$src2),
> +                         "add{l}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86add_ovf (loadi32 addr:$dst),  
> imm:$src2),
> +                                             addr:$dst),
> +                          (implicit EFLAGS)]>;
> +  def ADDOvf16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst,  
> i16i8imm :$src2),
> +                        "add{w}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86add_ovf (load addr: 
> $dst),i16immSExt8:$src2),
> +                                            addr:$dst),
> +                         (implicit EFLAGS)]>, OpSize;
> +  def ADDOvf32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst,  
> i32i8imm :$src2),
> +                        "add{l}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86add_ovf (load addr: 
> $dst),i32immSExt8:$src2),
> +                                            addr:$dst),
> +                         (implicit EFLAGS)]>;
> }
>
> let Uses = [EFLAGS] in {
> @@ -2052,84 +2158,193 @@
> }
> } // Uses = [EFLAGS]
>
> -def SUB8rr   : I<0x28, MRMDestReg, (outs GR8 :$dst), (ins GR8 : 
> $src1, GR8 :$src2),
> -                 "sub{b}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
> -                  (implicit EFLAGS)]>;
> -def SUB16rr  : I<0x29, MRMDestReg, (outs GR16:$dst), (ins  
> GR16:$src1, GR16:$src2),
> -                 "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
> -                  (implicit EFLAGS)]>, OpSize;
> -def SUB32rr  : I<0x29, MRMDestReg, (outs GR32:$dst), (ins  
> GR32:$src1, GR32:$src2),
> -                 "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (sub GR32:$src1, GR32:$src2)),
> -                  (implicit EFLAGS)]>;
> -def SUB8rm   : I<0x2A, MRMSrcMem, (outs GR8 :$dst), (ins GR8 : 
> $src1, i8mem :$src2),
> -                 "sub{b}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
> -                  (implicit EFLAGS)]>;
> -def SUB16rm  : I<0x2B, MRMSrcMem, (outs GR16:$dst), (ins  
> GR16:$src1, i16mem:$src2),
> -                 "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (sub GR16:$src1, (load addr: 
> $src2))),
> -                  (implicit EFLAGS)]>, OpSize;
> -def SUB32rm  : I<0x2B, MRMSrcMem, (outs GR32:$dst), (ins  
> GR32:$src1, i32mem:$src2),
> -                 "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (sub GR32:$src1, (load addr: 
> $src2))),
> -                  (implicit EFLAGS)]>;
> +// Register-Register Subtraction
> +def SUB8rr  : I<0x28, MRMDestReg, (outs GR8:$dst), (ins GR8:$src1,  
> GR8:$src2),
> +                "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR8:$dst, (sub GR8:$src1, GR8:$src2))]>;
> +def SUB16rr : I<0x29, MRMDestReg, (outs GR16:$dst), (ins  
> GR16:$src1,GR16:$src2),
> +                "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR16:$dst, (sub GR16:$src1, GR16:$src2))]>,  
> OpSize;
> +def SUB32rr : I<0x29, MRMDestReg, (outs GR32:$dst), (ins  
> GR32:$src1,GR32:$src2),
> +                "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
> +
> +// Register-Register Subtraction with Overflow
> +def SUBOvf8rr  : I<0x28, MRMDestReg, (outs GR8:$dst),
> +                                     (ins GR8:$src1, GR8:$src2),
> +                   "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR8:$dst, (X86sub_ovf GR8:$src1,  
> GR8:$src2)),
> +                    (implicit EFLAGS)]>;
> +def SUBOvf16rr : I<0x29, MRMDestReg, (outs GR16:$dst),
> +                                     (ins GR16:$src1, GR16:$src2),
> +                   "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR16:$dst, (X86sub_ovf GR16:$src1,  
> GR16:$src2)),
> +                    (implicit EFLAGS)]>, OpSize;
> +def SUBOvf32rr : I<0x29, MRMDestReg, (outs GR32:$dst),
> +                                     (ins GR32:$src1, GR32:$src2),
> +                   "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR32:$dst, (X86sub_ovf GR32:$src1,  
> GR32:$src2)),
> +                    (implicit EFLAGS)]>;
>
> -def SUB8ri   : Ii8 <0x80, MRM5r, (outs GR8:$dst), (ins GR8:$src1,  
> i8imm:$src2),
> +// Register-Memory Subtraction
> +def SUB8rm  : I<0x2A, MRMSrcMem, (outs GR8 :$dst),
> +                                 (ins GR8 :$src1, i8mem :$src2),
> +                "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR8:$dst, (sub GR8:$src1, (load addr: 
> $src2)))]>;
> +def SUB16rm : I<0x2B, MRMSrcMem, (outs GR16:$dst),
> +                                 (ins GR16:$src1, i16mem:$src2),
> +                "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR16:$dst, (sub GR16:$src1, (load addr: 
> $src2)))]>, OpSize;
> +def SUB32rm : I<0x2B, MRMSrcMem, (outs GR32:$dst),
> +                                 (ins GR32:$src1, i32mem:$src2),
> +                "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                [(set GR32:$dst, (sub GR32:$src1, (load addr: 
> $src2)))]>;
> +
> +// Register-Memory Subtraction with Overflow
> +def SUBOvf8rm  : I<0x2A, MRMSrcMem, (outs GR8:$dst),
> +                                    (ins GR8:$src1, i8mem:$src2),
>                     "sub{b}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
> +                    [(set GR8:$dst, (X86sub_ovf GR8:$src1, (load  
> addr:$src2))),
> +                     (implicit EFLAGS)]>;
> +def SUBOvf16rm : I<0x2B, MRMSrcMem, (outs GR16:$dst),
> +                                    (ins GR16:$src1, i16mem:$src2),
> +                   "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR16:$dst, (X86sub_ovf GR16:$src1, (load  
> addr:$src2))),
> +                    (implicit EFLAGS)]>, OpSize;
> +def SUBOvf32rm : I<0x2B, MRMSrcMem, (outs GR32:$dst),
> +                                    (ins GR32:$src1, i32mem:$src2),
> +                   "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                   [(set GR32:$dst, (X86sub_ovf GR32:$src1, (load  
> addr:$src2))),
>                     (implicit EFLAGS)]>;
> -def SUB16ri  : Ii16<0x81, MRM5r, (outs GR16:$dst), (ins GR16:$src1,  
> i16imm:$src2),
> +
> +// Register-Integer Subtraction
> +def SUB8ri   : Ii8 <0x80, MRM5r, (outs GR8:$dst),
> +                                 (ins GR8:$src1, i8imm:$src2),
> +                    "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR8:$dst, (sub GR8:$src1, imm:$src2))]>;
> +def SUB16ri  : Ii16<0x81, MRM5r, (outs GR16:$dst),
> +                                 (ins GR16:$src1, i16imm:$src2),
>                     "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
> -                    (implicit EFLAGS)]>, OpSize;
> -def SUB32ri  : Ii32<0x81, MRM5r, (outs GR32:$dst), (ins GR32:$src1,  
> i32imm:$src2),
> +                    [(set GR16:$dst, (sub GR16:$src1, imm: 
> $src2))]>, OpSize;
> +def SUB32ri  : Ii32<0x81, MRM5r, (outs GR32:$dst),
> +                                 (ins GR32:$src1, i32imm:$src2),
>                     "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                    [(set GR32:$dst, (sub GR32:$src1, imm:$src2)),
> -                    (implicit EFLAGS)]>;
> -def SUB16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst), (ins GR16:$src1,  
> i16i8imm:$src2),
> +                    [(set GR32:$dst, (sub GR32:$src1, imm:$src2))]>;
> +def SUB16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst),
> +                                (ins GR16:$src1, i16i8imm:$src2),
>                    "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                   [(set GR16:$dst, (sub GR16:$src1,  
> i16immSExt8:$src2)),
> -                   (implicit EFLAGS)]>, OpSize;
> -def SUB32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst), (ins GR32:$src1,  
> i32i8imm:$src2),
> +                   [(set GR16:$dst, (sub GR16:$src1,  
> i16immSExt8:$src2))]>,
> +                   OpSize;
> +def SUB32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst),
> +                                (ins GR32:$src1, i32i8imm:$src2),
>                    "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                   [(set GR32:$dst, (sub GR32:$src1,  
> i32immSExt8:$src2)),
> -                   (implicit EFLAGS)]>;
> +                   [(set GR32:$dst, (sub GR32:$src1,  
> i32immSExt8:$src2))]>;
> +
> +// Register-Integer Subtraction with Overflow
> +def SUBOvf8ri   : Ii8 <0x80, MRM5r, (outs GR8:$dst),
> +                                    (ins GR8:$src1, i8imm:$src2),
> +                       "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR8:$dst, (X86sub_ovf GR8:$src1, imm: 
> $src2)),
> +                        (implicit EFLAGS)]>;
> +def SUBOvf16ri  : Ii16<0x81, MRM5r, (outs GR16:$dst),
> +                                    (ins GR16:$src1, i16imm:$src2),
> +                       "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR16:$dst, (X86sub_ovf GR16:$src1, imm: 
> $src2)),
> +                        (implicit EFLAGS)]>, OpSize;
> +def SUBOvf32ri  : Ii32<0x81, MRM5r, (outs GR32:$dst),
> +                                    (ins GR32:$src1, i32imm:$src2),
> +                       "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                       [(set GR32:$dst, (X86sub_ovf GR32:$src1, imm: 
> $src2)),
> +                        (implicit EFLAGS)]>;
> +def SUBOvf16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst),
> +                                   (ins GR16:$src1, i16i8imm:$src2),
> +                      "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                      [(set GR16:$dst, (X86sub_ovf GR16:$src1,
> +                                                    
> i16immSExt8:$src2)),
> +                       (implicit EFLAGS)]>, OpSize;
> +def SUBOvf32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst),
> +                                   (ins GR32:$src1, i32i8imm:$src2),
> +                      "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                      [(set GR32:$dst, (X86sub_ovf GR32:$src1,
> +                                                    
> i32immSExt8:$src2)),
> +                       (implicit EFLAGS)]>;
> +
> let isTwoAddress = 0 in {
> +  // Memory-Register Subtraction
>   def SUB8mr   : I<0x28, MRMDestMem, (outs), (ins i8mem :$dst, GR8 : 
> $src2),
>                    "sub{b}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (sub (load addr:$dst), GR8:$src2), addr: 
> $dst),
> -                   (implicit EFLAGS)]>;
> +                   [(store (sub (load addr:$dst), GR8:$src2), addr: 
> $dst)]>;
>   def SUB16mr  : I<0x29, MRMDestMem, (outs), (ins i16mem:$dst,  
> GR16:$src2),
>                    "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (sub (load addr:$dst), GR16:$src2), addr: 
> $dst),
> -                   (implicit EFLAGS)]>, OpSize;
> +                   [(store (sub (load addr:$dst), GR16:$src2), addr: 
> $dst)]>,
> +                   OpSize;
>   def SUB32mr  : I<0x29, MRMDestMem, (outs), (ins i32mem:$dst,  
> GR32:$src2),
>                    "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (sub (load addr:$dst), GR32:$src2), addr: 
> $dst),
> -                   (implicit EFLAGS)]>;
> +                   [(store (sub (load addr:$dst), GR32:$src2), addr: 
> $dst)]>;
> +
> +  // Memory-Register Subtraction with Overflow
> +  def SUBOvf8mr  : I<0x28, MRMDestMem, (outs), (ins i8mem :$dst,  
> GR8 :$src2),
> +                     "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                     [(store (X86sub_ovf (load addr:$dst),  
> GR8:$src2),
> +                                         addr:$dst),
> +                      (implicit EFLAGS)]>;
> +  def SUBOvf16mr : I<0x29, MRMDestMem, (outs), (ins i16mem:$dst,  
> GR16:$src2),
> +                     "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                     [(store (X86sub_ovf (load addr:$dst),  
> GR16:$src2),
> +                                         addr:$dst),
> +                      (implicit EFLAGS)]>, OpSize;
> +  def SUBOvf32mr : I<0x29, MRMDestMem, (outs), (ins i32mem:$dst,  
> GR32:$src2),
> +                     "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                     [(store (X86sub_ovf (load addr:$dst),  
> GR32:$src2),
> +                                         addr:$dst),
> +                      (implicit EFLAGS)]>;
> +
> +  // Memory-Integer Subtraction
>   def SUB8mi   : Ii8<0x80, MRM5m, (outs), (ins i8mem :$dst, i8imm: 
> $src2),
>                      "sub{b}\t{$src2, $dst|$dst, $src2}",
> -                   [(store (sub (loadi8 addr:$dst), imm:$src2),  
> addr:$dst),
> -                   (implicit EFLAGS)]>;
> +                     [(store (sub (loadi8 addr:$dst), imm:$src2),  
> addr:$dst)]>;
>   def SUB16mi  : Ii16<0x81, MRM5m, (outs), (ins i16mem:$dst, i16imm: 
> $src2),
>                       "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (sub (loadi16 addr:$dst), imm:$src2),  
> addr:$dst),
> -                  (implicit EFLAGS)]>, OpSize;
> +                      [(store (sub (loadi16 addr:$dst), imm: 
> $src2),addr:$dst)]>,
> +                      OpSize;
>   def SUB32mi  : Ii32<0x81, MRM5m, (outs), (ins i32mem:$dst, i32imm: 
> $src2),
>                       "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                  [(store (sub (loadi32 addr:$dst), imm:$src2),  
> addr:$dst),
> -                  (implicit EFLAGS)]>;
> +                      [(store (sub (loadi32 addr:$dst), imm: 
> $src2),addr:$dst)]>;
>   def SUB16mi8 : Ii8<0x83, MRM5m, (outs), (ins i16mem:$dst,  
> i16i8imm :$src2),
>                      "sub{w}\t{$src2, $dst|$dst, $src2}",
> -                [(store (sub (load addr:$dst), i16immSExt8:$src2),  
> addr:$dst),
> -                  (implicit EFLAGS)]>, OpSize;
> -  def SUB32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst,  
> i32i8imm :$src2),
> +                     [(store (sub (load addr:$dst),  
> i16immSExt8:$src2),
> +                             addr:$dst)]>, OpSize;
> +  def SUB32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst,  
> i32i8imm :$src2),
>                      "sub{l}\t{$src2, $dst|$dst, $src2}",
> -                [(store (sub (load addr:$dst), i32immSExt8:$src2),  
> addr:$dst),
> -                (implicit EFLAGS)]>;
> +                     [(store (sub (load addr:$dst),  
> i32immSExt8:$src2),
> +                             addr:$dst)]>;
> +
> +  // Memory-Integer Subtraction with Overflow
> +  def SUBOvf8mi   : Ii8<0x80, MRM5m, (outs), (ins i8mem :$dst,  
> i8imm:$src2),
> +                        "sub{b}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86sub_ovf (loadi8 addr:$dst), imm: 
> $src2),
> +                                addr:$dst),
> +                         (implicit EFLAGS)]>;
> +  def SUBOvf16mi  : Ii16<0x81, MRM5m, (outs), (ins i16mem:$dst,  
> i16imm:$src2),
> +                         "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86sub_ovf (loadi16 addr:$dst),  
> imm:$src2),
> +                                 addr:$dst),
> +                          (implicit EFLAGS)]>, OpSize;
> +  def SUBOvf32mi  : Ii32<0x81, MRM5m, (outs), (ins i32mem:$dst,  
> i32imm:$src2),
> +                         "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                         [(store (X86sub_ovf (loadi32 addr:$dst),  
> imm:$src2),
> +                                             addr:$dst),
> +                          (implicit EFLAGS)]>;
> +  def SUBOvf16mi8 : Ii8<0x83, MRM5m, (outs), (ins i16mem:$dst,  
> i16i8imm :$src2),
> +                        "sub{w}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86sub_ovf (load addr: 
> $dst),i16immSExt8:$src2),
> +                                            addr:$dst),
> +                         (implicit EFLAGS)]>, OpSize;
> +  def SUBOvf32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst,  
> i32i8imm :$src2),
> +                        "sub{l}\t{$src2, $dst|$dst, $src2}",
> +                        [(store (X86sub_ovf (load addr: 
> $dst),i32immSExt8:$src2),
> +                                            addr:$dst),
> +                         (implicit EFLAGS)]>;
> }
>
> let Uses = [EFLAGS] in {
> @@ -2165,70 +2380,143 @@
>
> let Defs = [EFLAGS] in {
> let isCommutable = 1 in {  // X = IMUL Y, Z --> X = IMUL Z, Y
> -def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins  
> GR16:$src1, GR16:$src2),
> +// Register-Register Integer Multiply
> +def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins  
> GR16:$src1,GR16:$src2),
>                  "imul{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (mul GR16:$src1, GR16:$src2)),
> -                 (implicit EFLAGS)]>, TB, OpSize;
> -def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins  
> GR32:$src1, GR32:$src2),
> +                 [(set GR16:$dst, (mul GR16:$src1, GR16:$src2))]>,  
> TB, OpSize;
> +def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins  
> GR32:$src1,GR32:$src2),
>                  "imul{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (mul GR32:$src1, GR32:$src2)),
> -                 (implicit EFLAGS)]>, TB;
> +                 [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>,  
> TB;
> +
> +// Register-Register Integer Multiply
> +def IMULOvf16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst),
> +                                     (ins GR16:$src1, GR16:$src2),
> +                    "imul{w}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR16:$dst, (X86mul_ovf GR16:$src1,  
> GR16:$src2)),
> +                     (implicit EFLAGS)]>, TB, OpSize;
> +def IMULOvf32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst),
> +                                     (ins GR32:$src1, GR32:$src2),
> +                    "imul{l}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR32:$dst, (X86mul_ovf GR32:$src1,  
> GR32:$src2)),
> +                     (implicit EFLAGS)]>, TB;
> }
> -def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst), (ins  
> GR16:$src1, i16mem:$src2),
> +
> +// Register-Memory Integer Multiply
> +def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
> +                                  (ins GR16:$src1, i16mem:$src2),
>                  "imul{w}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR16:$dst, (mul GR16:$src1, (load addr: 
> $src2))),
> -                 (implicit EFLAGS)]>,
> +                 [(set GR16:$dst, (mul GR16:$src1, (load addr: 
> $src2)))]>,
>                  TB, OpSize;
> def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1,  
> i32mem:$src2),
>                  "imul{l}\t{$src2, $dst|$dst, $src2}",
> -                 [(set GR32:$dst, (mul GR32:$src1, (load addr: 
> $src2))),
> -                 (implicit EFLAGS)]>, TB;
> +                 [(set GR32:$dst, (mul GR32:$src1, (load addr: 
> $src2)))]>, TB;
> +
> +// Register-Memory Integer Multiply with Overflow
> +def IMULOvf16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
> +                                     (ins GR16:$src1, i16mem:$src2),
> +                    "imul{w}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR16:$dst, (X86mul_ovf GR16:$src1,(load  
> addr:$src2))),
> +                     (implicit EFLAGS)]>,
> +                    TB, OpSize;
> +def IMULOvf32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
> +                                     (ins GR32:$src1, i32mem:$src2),
> +                    "imul{l}\t{$src2, $dst|$dst, $src2}",
> +                    [(set GR32:$dst, (X86mul_ovf GR32:$src1,(load  
> addr:$src2))),
> +                     (implicit EFLAGS)]>, TB;
> } // Defs = [EFLAGS]
> } // end Two Address instructions
>
> // Suprisingly enough, these are not two address instructions!
> let Defs = [EFLAGS] in {
> +// Register-Integer Integer Multiply
> def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // GR16  
> = GR16*I16
>                       (outs GR16:$dst), (ins GR16:$src1, i16imm: 
> $src2),
>                       "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                      [(set GR16:$dst, (mul GR16:$src1, imm:$src2)),
> -                      (implicit EFLAGS)]>, OpSize;
> +                      [(set GR16:$dst, (mul GR16:$src1, imm: 
> $src2))]>, OpSize;
> def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // GR32  
> = GR32*I32
>                       (outs GR32:$dst), (ins GR32:$src1, i32imm: 
> $src2),
>                       "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                      [(set GR32:$dst, (mul GR32:$src1, imm:$src2)),
> -                      (implicit EFLAGS)]>;
> +                      [(set GR32:$dst, (mul GR32:$src1, imm: 
> $src2))]>;
> def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // GR16  
> = GR16*I8
>                      (outs GR16:$dst), (ins GR16:$src1, i16i8imm: 
> $src2),
>                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                     [(set GR16:$dst, (mul GR16:$src1,  
> i16immSExt8:$src2)),
> -                     (implicit EFLAGS)]>, OpSize;
> +                     [(set GR16:$dst, (mul GR16:$src1,  
> i16immSExt8:$src2))]>,
> +                     OpSize;
> def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // GR32  
> = GR32*I8
>                      (outs GR32:$dst), (ins GR32:$src1, i32i8imm: 
> $src2),
>                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                     [(set GR32:$dst, (mul GR32:$src1,  
> i32immSExt8:$src2)),
> -                     (implicit EFLAGS)]>;
> +                     [(set GR32:$dst, (mul GR32:$src1,  
> i32immSExt8:$src2))]>;
>
> +// Register-Integer Integer Multiply with Overflow
> +def IMULOvf16rri  : Ii16<0x69, MRMSrcReg,                   // GR16  
> = GR16*I16
> +                        (outs GR16:$dst), (ins GR16:$src1, i16imm: 
> $src2),
> +                        "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR16:$dst, (X86mul_ovf GR16:$src1,  
> imm:$src2)),
> +                         (implicit EFLAGS)]>, OpSize;
> +def IMULOvf32rri  : Ii32<0x69, MRMSrcReg,                   // GR32  
> = GR32*I32
> +                        (outs GR32:$dst), (ins GR32:$src1, i32imm: 
> $src2),
> +                        "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR32:$dst, (X86mul_ovf GR32:$src1,  
> imm:$src2)),
> +                         (implicit EFLAGS)]>;
> +def IMULOvf16rri8 : Ii8<0x6B, MRMSrcReg,                    // GR16  
> = GR16*I8
> +                       (outs GR16:$dst), (ins GR16:$src1, i16i8imm: 
> $src2),
> +                       "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                       [(set GR16:$dst, (X86mul_ovf GR16:$src1,
> +                                         i16immSExt8:$src2)),
> +                        (implicit EFLAGS)]>, OpSize;
> +def IMULOvf32rri8 : Ii8<0x6B, MRMSrcReg,                    // GR32  
> = GR32*I8
> +                       (outs GR32:$dst), (ins GR32:$src1, i32i8imm: 
> $src2),
> +                       "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                       [(set GR32:$dst, (X86mul_ovf GR32:$src1,
> +                                         i32immSExt8:$src2)),
> +                        (implicit EFLAGS)]>;
> +
> +// Memory-Integer Integer Multiply
> def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                      // GR16  
> = [mem16]*I16
>                       (outs GR16:$dst), (ins i16mem:$src1, i16imm: 
> $src2),
>                       "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                      [(set GR16:$dst, (mul (load addr:$src1), imm: 
> $src2)),
> -                      (implicit EFLAGS)]>, OpSize;
> +                      [(set GR16:$dst, (mul (load addr:$src1), imm: 
> $src2))]>,
> +                      OpSize;
> def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                      // GR32  
> = [mem32]*I32
>                       (outs GR32:$dst), (ins i32mem:$src1, i32imm: 
> $src2),
>                       "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                      [(set GR32:$dst, (mul (load addr:$src1), imm: 
> $src2)),
> -                      (implicit EFLAGS)]>;
> +                      [(set GR32:$dst, (mul (load addr:$src1), imm: 
> $src2))]>;
> def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR16  
> = [mem16]*I8
>                      (outs GR16:$dst), (ins i16mem:$src1, i16i8imm : 
> $src2),
>                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                  [(set GR16:$dst, (mul (load addr:$src1),  
> i16immSExt8:$src2)),
> -                  (implicit EFLAGS)]>, OpSize;
> +                     [(set GR16:$dst, (mul (load addr:$src1),
> +                                       i16immSExt8:$src2))]>, OpSize;
> def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR32  
> = [mem32]*I8
>                      (outs GR32:$dst), (ins i32mem:$src1, i32i8imm:  
> $src2),
>                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> -                  [(set GR32:$dst, (mul (load addr:$src1),  
> i32immSExt8:$src2)),
> -                  (implicit EFLAGS)]>;
> +                     [(set GR32:$dst, (mul (load addr:$src1),
> +                                           i32immSExt8:$src2))]>;
> +
> +// Memory-Integer Integer Multiply with Overflow
> +def IMULOvf16rmi  : Ii16<0x69, MRMSrcMem,                   // GR16  
> = [mem16]*I16
> +                        (outs GR16:$dst), (ins i16mem:$src1, i16imm: 
> $src2),
> +                        "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR16:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                     imm:$src2)),
> +                         (implicit EFLAGS)]>, OpSize;
> +def IMULOvf32rmi  : Ii32<0x69, MRMSrcMem,                   // GR32  
> = [mem32]*I32
> +                        (outs GR32:$dst), (ins i32mem:$src1, i32imm: 
> $src2),
> +                        "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR32:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                     imm:$src2)),
> +                         (implicit EFLAGS)]>;
> +def IMULOvf16rmi8 : Ii8<0x6B, MRMSrcMem,                    // GR16  
> = [mem16]*I8
> +                        (outs GR16:$dst), (ins i16mem:$src1,  
> i16i8imm :$src2),
> +                        "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR16:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                      
> i16immSExt8:$src2)),
> +                         (implicit EFLAGS)]>, OpSize;
> +def IMULOvf32rmi8 : Ii8<0x6B, MRMSrcMem,                    // GR32  
> = [mem32]*I8
> +                        (outs GR32:$dst), (ins i32mem:$src1,  
> i32i8imm: $src2),
> +                        "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR32:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                      
> i32immSExt8:$src2)),
> +                         (implicit EFLAGS)]>;
> } // Defs = [EFLAGS]
>
> // 
> === 
> --- 
> ------------------------------------------------------------------- 
> ===//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> def IMULOvf16rmi8 : Ii8<0x6B, MRMSrcMem,                    // GR16  
> = [mem16]*I8
> +                        (outs GR16:$dst), (ins i16mem:$src1,  
> i16i8imm :$src2),
> +                        "imul{w}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR16:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                      
> i16immSExt8:$src2)),
> +                         (implicit EFLAGS)]>, OpSize;
> +def IMULOvf32rmi8 : Ii8<0x6B, MRMSrcMem,                    // GR32  
> = [mem32]*I8
> +                        (outs GR32:$dst), (ins i32mem:$src1,  
> i32i8imm: $src2),
> +                        "imul{l}\t{$src2, $src1, $dst|$dst, $src1,  
> $src2}",
> +                        [(set GR32:$dst, (X86mul_ovf (load addr: 
> $src1),
> +                                                      
> i32immSExt8:$src2)),
> +                         (implicit EFLAGS)]>;
> } // Defs = [EFLAGS]
>
> // 
> === 
> --- 
> ------------------------------------------------------------------- 
> ===//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list