Skip to content
X86InstrInfo.td 225 KiB
Newer Older
          (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
                          x86_subreg_8bit)>,
      Requires<[In32BitMode]>;

// h-register tricks
def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))),
          (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
                          x86_subreg_8bit_hi)>,
      Requires<[In32BitMode]>;
def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))),
          (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
                          x86_subreg_8bit_hi)>,
      Requires<[In32BitMode]>;
def : Pat<(srl_su GR16:$src, (i8 8)),
          (EXTRACT_SUBREG
            (MOVZX32rr8
              (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
                              x86_subreg_8bit_hi)),
            x86_subreg_16bit)>,
      Requires<[In32BitMode]>;
def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
          (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
                                      x86_subreg_8bit_hi))>,
      Requires<[In32BitMode]>;
def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))),
          (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
                                      x86_subreg_8bit_hi))>,
      Requires<[In32BitMode]>;
def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
          (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
                                      x86_subreg_8bit_hi))>,
// (shl x, 1) ==> (add x, x)
def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr  GR8 :$src1, GR8 :$src1)>;
def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>;
def : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>;
Evan Cheng's avatar
Evan Cheng committed

// (shl x (and y, 31)) ==> (shl x, y)
def : Pat<(shl GR8:$src1, (and CL:$amt, 31)),
          (SHL8rCL GR8:$src1)>;
def : Pat<(shl GR16:$src1, (and CL:$amt, 31)),
          (SHL16rCL GR16:$src1)>;
def : Pat<(shl GR32:$src1, (and CL:$amt, 31)),
          (SHL32rCL GR32:$src1)>;
def : Pat<(store (shl (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHL8mCL addr:$dst)>;
def : Pat<(store (shl (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHL16mCL addr:$dst)>;
def : Pat<(store (shl (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHL32mCL addr:$dst)>;

def : Pat<(srl GR8:$src1, (and CL:$amt, 31)),
          (SHR8rCL GR8:$src1)>;
def : Pat<(srl GR16:$src1, (and CL:$amt, 31)),
          (SHR16rCL GR16:$src1)>;
def : Pat<(srl GR32:$src1, (and CL:$amt, 31)),
          (SHR32rCL GR32:$src1)>;
def : Pat<(store (srl (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHR8mCL addr:$dst)>;
def : Pat<(store (srl (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHR16mCL addr:$dst)>;
def : Pat<(store (srl (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SHR32mCL addr:$dst)>;

def : Pat<(sra GR8:$src1, (and CL:$amt, 31)),
          (SAR8rCL GR8:$src1)>;
def : Pat<(sra GR16:$src1, (and CL:$amt, 31)),
          (SAR16rCL GR16:$src1)>;
def : Pat<(sra GR32:$src1, (and CL:$amt, 31)),
          (SAR32rCL GR32:$src1)>;
def : Pat<(store (sra (loadi8 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SAR8mCL addr:$dst)>;
def : Pat<(store (sra (loadi16 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SAR16mCL addr:$dst)>;
def : Pat<(store (sra (loadi32 addr:$dst), (and CL:$amt, 31)), addr:$dst),
          (SAR32mCL addr:$dst)>;

Evan Cheng's avatar
Evan Cheng committed
// (or (x >> c) | (y << (32 - c))) ==> (shrd32 x, y, c)
def : Pat<(or (srl GR32:$src1, CL:$amt),
              (shl GR32:$src2, (sub 32, CL:$amt))),
          (SHRD32rrCL GR32:$src1, GR32:$src2)>;
Evan Cheng's avatar
Evan Cheng committed

def : Pat<(store (or (srl (loadi32 addr:$dst), CL:$amt),
                     (shl GR32:$src2, (sub 32, CL:$amt))), addr:$dst),
          (SHRD32mrCL addr:$dst, GR32:$src2)>;
def : Pat<(or (srl GR32:$src1, (i8 (trunc ECX:$amt))),
              (shl GR32:$src2, (i8 (trunc (sub 32, ECX:$amt))))),
          (SHRD32rrCL GR32:$src1, GR32:$src2)>;

def : Pat<(store (or (srl (loadi32 addr:$dst), (i8 (trunc ECX:$amt))),
                     (shl GR32:$src2, (i8 (trunc (sub 32, ECX:$amt))))),
                 addr:$dst),
          (SHRD32mrCL addr:$dst, GR32:$src2)>;

def : Pat<(shrd GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm:$amt2)),
          (SHRD32rri8 GR32:$src1, GR32:$src2, (i8 imm:$amt1))>;

def : Pat<(store (shrd (loadi32 addr:$dst), (i8 imm:$amt1),
                       GR32:$src2, (i8 imm:$amt2)), addr:$dst),
          (SHRD32mri8 addr:$dst, GR32:$src2, (i8 imm:$amt1))>;

Evan Cheng's avatar
Evan Cheng committed
// (or (x << c) | (y >> (32 - c))) ==> (shld32 x, y, c)
def : Pat<(or (shl GR32:$src1, CL:$amt),
              (srl GR32:$src2, (sub 32, CL:$amt))),
          (SHLD32rrCL GR32:$src1, GR32:$src2)>;
def : Pat<(store (or (shl (loadi32 addr:$dst), CL:$amt),
                     (srl GR32:$src2, (sub 32, CL:$amt))), addr:$dst),
          (SHLD32mrCL addr:$dst, GR32:$src2)>;
def : Pat<(or (shl GR32:$src1, (i8 (trunc ECX:$amt))),
              (srl GR32:$src2, (i8 (trunc (sub 32, ECX:$amt))))),
          (SHLD32rrCL GR32:$src1, GR32:$src2)>;

def : Pat<(store (or (shl (loadi32 addr:$dst), (i8 (trunc ECX:$amt))),
                     (srl GR32:$src2, (i8 (trunc (sub 32, ECX:$amt))))),
                 addr:$dst),
          (SHLD32mrCL addr:$dst, GR32:$src2)>;

def : Pat<(shld GR32:$src1, (i8 imm:$amt1), GR32:$src2, (i8 imm:$amt2)),
          (SHLD32rri8 GR32:$src1, GR32:$src2, (i8 imm:$amt1))>;

def : Pat<(store (shld (loadi32 addr:$dst), (i8 imm:$amt1),
                       GR32:$src2, (i8 imm:$amt2)), addr:$dst),
          (SHLD32mri8 addr:$dst, GR32:$src2, (i8 imm:$amt1))>;

Evan Cheng's avatar
Evan Cheng committed
// (or (x >> c) | (y << (16 - c))) ==> (shrd16 x, y, c)
def : Pat<(or (srl GR16:$src1, CL:$amt),
              (shl GR16:$src2, (sub 16, CL:$amt))),
          (SHRD16rrCL GR16:$src1, GR16:$src2)>;
def : Pat<(store (or (srl (loadi16 addr:$dst), CL:$amt),
                     (shl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
          (SHRD16mrCL addr:$dst, GR16:$src2)>;
def : Pat<(or (srl GR16:$src1, (i8 (trunc CX:$amt))),
              (shl GR16:$src2, (i8 (trunc (sub 16, CX:$amt))))),
          (SHRD16rrCL GR16:$src1, GR16:$src2)>;

def : Pat<(store (or (srl (loadi16 addr:$dst), (i8 (trunc CX:$amt))),
                     (shl GR16:$src2, (i8 (trunc (sub 16, CX:$amt))))),
                 addr:$dst),
          (SHRD16mrCL addr:$dst, GR16:$src2)>;

def : Pat<(shrd GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm:$amt2)),
          (SHRD16rri8 GR16:$src1, GR16:$src2, (i8 imm:$amt1))>;

def : Pat<(store (shrd (loadi16 addr:$dst), (i8 imm:$amt1),
                       GR16:$src2, (i8 imm:$amt2)), addr:$dst),
          (SHRD16mri8 addr:$dst, GR16:$src2, (i8 imm:$amt1))>;

Evan Cheng's avatar
Evan Cheng committed
// (or (x << c) | (y >> (16 - c))) ==> (shld16 x, y, c)
def : Pat<(or (shl GR16:$src1, CL:$amt),
              (srl GR16:$src2, (sub 16, CL:$amt))),
          (SHLD16rrCL GR16:$src1, GR16:$src2)>;

def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt),
                     (srl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
          (SHLD16mrCL addr:$dst, GR16:$src2)>;
def : Pat<(or (shl GR16:$src1, (i8 (trunc CX:$amt))),
              (srl GR16:$src2, (i8 (trunc (sub 16, CX:$amt))))),
          (SHLD16rrCL GR16:$src1, GR16:$src2)>;

def : Pat<(store (or (shl (loadi16 addr:$dst), (i8 (trunc CX:$amt))),
                     (srl GR16:$src2, (i8 (trunc (sub 16, CX:$amt))))),
                 addr:$dst),
          (SHLD16mrCL addr:$dst, GR16:$src2)>;

def : Pat<(shld GR16:$src1, (i8 imm:$amt1), GR16:$src2, (i8 imm:$amt2)),
          (SHLD16rri8 GR16:$src1, GR16:$src2, (i8 imm:$amt1))>;

def : Pat<(store (shld (loadi16 addr:$dst), (i8 imm:$amt1),
                       GR16:$src2, (i8 imm:$amt2)), addr:$dst),
          (SHLD16mri8 addr:$dst, GR16:$src2, (i8 imm:$amt1))>;

//===----------------------------------------------------------------------===//
// EFLAGS-defining Patterns
//===----------------------------------------------------------------------===//

// Register-Register Addition with EFLAGS result
def : Pat<(parallel (X86add_flag GR8:$src1, GR8:$src2),
                    (implicit EFLAGS)),
          (ADD8rr GR8:$src1, GR8:$src2)>;
def : Pat<(parallel (X86add_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (ADD16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86add_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (ADD32rr GR32:$src1, GR32:$src2)>;

// Register-Memory Addition with EFLAGS result
def : Pat<(parallel (X86add_flag GR8:$src1, (loadi8 addr:$src2)),
                    (implicit EFLAGS)),
          (ADD8rm GR8:$src1, addr:$src2)>;
def : Pat<(parallel (X86add_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (ADD16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86add_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (ADD32rm GR32:$src1, addr:$src2)>;

// Register-Integer Addition with EFLAGS result
def : Pat<(parallel (X86add_flag GR8:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (ADD8ri GR8:$src1, imm:$src2)>;
def : Pat<(parallel (X86add_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (ADD16ri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86add_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (ADD32ri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86add_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86add_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Register Addition with EFLAGS result
def : Pat<(parallel (store (X86add_flag (loadi8 addr:$dst), GR8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD8mr addr:$dst, GR8:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), GR16:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD16mr addr:$dst, GR16:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), GR32:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD32mr addr:$dst, GR32:$src2)>;

// Memory-Integer Addition with EFLAGS result
def : Pat<(parallel (store (X86add_flag (loadi8 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD8mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD16mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD32mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi16 addr:$dst), i16immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD16mi8 addr:$dst, i16immSExt8:$src2)>;
def : Pat<(parallel (store (X86add_flag (loadi32 addr:$dst), i32immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (ADD32mi8 addr:$dst, i32immSExt8:$src2)>;

// Register-Register Subtraction with EFLAGS result
def : Pat<(parallel (X86sub_flag GR8:$src1, GR8:$src2),
                    (implicit EFLAGS)),
          (SUB8rr GR8:$src1, GR8:$src2)>;
def : Pat<(parallel (X86sub_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (SUB16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86sub_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (SUB32rr GR32:$src1, GR32:$src2)>;

// Register-Memory Subtraction with EFLAGS result
def : Pat<(parallel (X86sub_flag GR8:$src1, (loadi8 addr:$src2)),
                    (implicit EFLAGS)),
          (SUB8rm GR8:$src1, addr:$src2)>;
def : Pat<(parallel (X86sub_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (SUB16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86sub_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (SUB32rm GR32:$src1, addr:$src2)>;

// Register-Integer Subtraction with EFLAGS result
def : Pat<(parallel (X86sub_flag GR8:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (SUB8ri GR8:$src1, imm:$src2)>;
def : Pat<(parallel (X86sub_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (SUB16ri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86sub_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (SUB32ri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86sub_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (SUB16ri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86sub_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Register Subtraction with EFLAGS result
def : Pat<(parallel (store (X86sub_flag (loadi8 addr:$dst), GR8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB8mr addr:$dst, GR8:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), GR16:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB16mr addr:$dst, GR16:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), GR32:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB32mr addr:$dst, GR32:$src2)>;

// Memory-Integer Subtraction with EFLAGS result
def : Pat<(parallel (store (X86sub_flag (loadi8 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB8mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB16mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB32mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi16 addr:$dst), i16immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB16mi8 addr:$dst, i16immSExt8:$src2)>;
def : Pat<(parallel (store (X86sub_flag (loadi32 addr:$dst), i32immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (SUB32mi8 addr:$dst, i32immSExt8:$src2)>;


// Register-Register Signed Integer Multiply with EFLAGS result
def : Pat<(parallel (X86smul_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (IMUL16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86smul_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (IMUL32rr GR32:$src1, GR32:$src2)>;

// Register-Memory Signed Integer Multiply with EFLAGS result
def : Pat<(parallel (X86smul_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (IMUL16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86smul_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (IMUL32rm GR32:$src1, addr:$src2)>;

// Register-Integer Signed Integer Multiply with EFLAGS result
def : Pat<(parallel (X86smul_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (IMUL16rri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86smul_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (IMUL32rri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86smul_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (IMUL16rri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86smul_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (IMUL32rri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Integer Signed Integer Multiply with EFLAGS result
def : Pat<(parallel (X86smul_flag (loadi16 addr:$src1), imm:$src2),
                    (implicit EFLAGS)),
          (IMUL16rmi addr:$src1, imm:$src2)>;
def : Pat<(parallel (X86smul_flag (loadi32 addr:$src1), imm:$src2),
                    (implicit EFLAGS)),
          (IMUL32rmi addr:$src1, imm:$src2)>;
def : Pat<(parallel (X86smul_flag (loadi16 addr:$src1), i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (IMUL16rmi8 addr:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86smul_flag (loadi32 addr:$src1), i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>;

// Optimize multiply by 2 with EFLAGS result.
let AddedComplexity = 2 in {
def : Pat<(parallel (X86smul_flag GR16:$src1, 2),
                    (implicit EFLAGS)),
          (ADD16rr GR16:$src1, GR16:$src1)>;

def : Pat<(parallel (X86smul_flag GR32:$src1, 2),
                    (implicit EFLAGS)),
          (ADD32rr GR32:$src1, GR32:$src1)>;
}

// INC and DEC with EFLAGS result. Note that these do not set CF.
def : Pat<(parallel (X86inc_flag GR8:$src), (implicit EFLAGS)),
          (INC8r GR8:$src)>;
def : Pat<(parallel (store (i8 (X86inc_flag (loadi8 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (INC8m addr:$dst)>;
def : Pat<(parallel (X86dec_flag GR8:$src), (implicit EFLAGS)),
          (DEC8r GR8:$src)>;
def : Pat<(parallel (store (i8 (X86dec_flag (loadi8 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (DEC8m addr:$dst)>;

def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)),
          (INC16r GR16:$src)>, Requires<[In32BitMode]>;
def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (INC16m addr:$dst)>, Requires<[In32BitMode]>;
def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)),
          (DEC16r GR16:$src)>, Requires<[In32BitMode]>;
def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (DEC16m addr:$dst)>, Requires<[In32BitMode]>;

def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)),
          (INC32r GR32:$src)>, Requires<[In32BitMode]>;
def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (INC32m addr:$dst)>, Requires<[In32BitMode]>;
def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)),
          (DEC32r GR32:$src)>, Requires<[In32BitMode]>;
def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst),
                    (implicit EFLAGS)),
          (DEC32m addr:$dst)>, Requires<[In32BitMode]>;
// Register-Register Or with EFLAGS result
def : Pat<(parallel (X86or_flag GR8:$src1, GR8:$src2),
                    (implicit EFLAGS)),
          (OR8rr GR8:$src1, GR8:$src2)>;
def : Pat<(parallel (X86or_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (OR16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86or_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (OR32rr GR32:$src1, GR32:$src2)>;

// Register-Memory Or with EFLAGS result
def : Pat<(parallel (X86or_flag GR8:$src1, (loadi8 addr:$src2)),
                    (implicit EFLAGS)),
          (OR8rm GR8:$src1, addr:$src2)>;
def : Pat<(parallel (X86or_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (OR16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86or_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (OR32rm GR32:$src1, addr:$src2)>;

// Register-Integer Or with EFLAGS result
def : Pat<(parallel (X86or_flag GR8:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (OR8ri GR8:$src1, imm:$src2)>;
def : Pat<(parallel (X86or_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (OR16ri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86or_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (OR32ri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86or_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (OR16ri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86or_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (OR32ri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Register Or with EFLAGS result
def : Pat<(parallel (store (X86or_flag (loadi8 addr:$dst), GR8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR8mr addr:$dst, GR8:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), GR16:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR16mr addr:$dst, GR16:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), GR32:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR32mr addr:$dst, GR32:$src2)>;

// Memory-Integer Or with EFLAGS result
def : Pat<(parallel (store (X86or_flag (loadi8 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR8mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR16mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR32mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi16 addr:$dst), i16immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR16mi8 addr:$dst, i16immSExt8:$src2)>;
def : Pat<(parallel (store (X86or_flag (loadi32 addr:$dst), i32immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (OR32mi8 addr:$dst, i32immSExt8:$src2)>;

// Register-Register XOr with EFLAGS result
def : Pat<(parallel (X86xor_flag GR8:$src1, GR8:$src2),
                    (implicit EFLAGS)),
          (XOR8rr GR8:$src1, GR8:$src2)>;
def : Pat<(parallel (X86xor_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (XOR16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86xor_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (XOR32rr GR32:$src1, GR32:$src2)>;

// Register-Memory XOr with EFLAGS result
def : Pat<(parallel (X86xor_flag GR8:$src1, (loadi8 addr:$src2)),
                    (implicit EFLAGS)),
          (XOR8rm GR8:$src1, addr:$src2)>;
def : Pat<(parallel (X86xor_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (XOR16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86xor_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (XOR32rm GR32:$src1, addr:$src2)>;

// Register-Integer XOr with EFLAGS result
def : Pat<(parallel (X86xor_flag GR8:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (XOR8ri GR8:$src1, imm:$src2)>;
def : Pat<(parallel (X86xor_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (XOR16ri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86xor_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (XOR32ri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86xor_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (XOR16ri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86xor_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Register XOr with EFLAGS result
def : Pat<(parallel (store (X86xor_flag (loadi8 addr:$dst), GR8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR8mr addr:$dst, GR8:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), GR16:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR16mr addr:$dst, GR16:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), GR32:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR32mr addr:$dst, GR32:$src2)>;

// Memory-Integer XOr with EFLAGS result
def : Pat<(parallel (store (X86xor_flag (loadi8 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR8mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR16mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR32mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi16 addr:$dst), i16immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR16mi8 addr:$dst, i16immSExt8:$src2)>;
def : Pat<(parallel (store (X86xor_flag (loadi32 addr:$dst), i32immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (XOR32mi8 addr:$dst, i32immSExt8:$src2)>;

// Register-Register And with EFLAGS result
def : Pat<(parallel (X86and_flag GR8:$src1, GR8:$src2),
                    (implicit EFLAGS)),
          (AND8rr GR8:$src1, GR8:$src2)>;
def : Pat<(parallel (X86and_flag GR16:$src1, GR16:$src2),
                    (implicit EFLAGS)),
          (AND16rr GR16:$src1, GR16:$src2)>;
def : Pat<(parallel (X86and_flag GR32:$src1, GR32:$src2),
                    (implicit EFLAGS)),
          (AND32rr GR32:$src1, GR32:$src2)>;

// Register-Memory And with EFLAGS result
def : Pat<(parallel (X86and_flag GR8:$src1, (loadi8 addr:$src2)),
                    (implicit EFLAGS)),
          (AND8rm GR8:$src1, addr:$src2)>;
def : Pat<(parallel (X86and_flag GR16:$src1, (loadi16 addr:$src2)),
                    (implicit EFLAGS)),
          (AND16rm GR16:$src1, addr:$src2)>;
def : Pat<(parallel (X86and_flag GR32:$src1, (loadi32 addr:$src2)),
                    (implicit EFLAGS)),
          (AND32rm GR32:$src1, addr:$src2)>;

// Register-Integer And with EFLAGS result
def : Pat<(parallel (X86and_flag GR8:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (AND8ri GR8:$src1, imm:$src2)>;
def : Pat<(parallel (X86and_flag GR16:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (AND16ri GR16:$src1, imm:$src2)>;
def : Pat<(parallel (X86and_flag GR32:$src1, imm:$src2),
                    (implicit EFLAGS)),
          (AND32ri GR32:$src1, imm:$src2)>;
def : Pat<(parallel (X86and_flag GR16:$src1, i16immSExt8:$src2),
                    (implicit EFLAGS)),
          (AND16ri8 GR16:$src1, i16immSExt8:$src2)>;
def : Pat<(parallel (X86and_flag GR32:$src1, i32immSExt8:$src2),
                    (implicit EFLAGS)),
          (AND32ri8 GR32:$src1, i32immSExt8:$src2)>;

// Memory-Register And with EFLAGS result
def : Pat<(parallel (store (X86and_flag (loadi8 addr:$dst), GR8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND8mr addr:$dst, GR8:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), GR16:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND16mr addr:$dst, GR16:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), GR32:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND32mr addr:$dst, GR32:$src2)>;

// Memory-Integer And with EFLAGS result
def : Pat<(parallel (store (X86and_flag (loadi8 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND8mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND16mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), imm:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND32mi addr:$dst, imm:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi16 addr:$dst), i16immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND16mi8 addr:$dst, i16immSExt8:$src2)>;
def : Pat<(parallel (store (X86and_flag (loadi32 addr:$dst), i32immSExt8:$src2),
                           addr:$dst),
                    (implicit EFLAGS)),
          (AND32mi8 addr:$dst, i32immSExt8:$src2)>;

// -disable-16bit support.
def : Pat<(truncstorei16 (i32 imm:$src), addr:$dst),
          (MOV16mi addr:$dst, imm:$src)>;
def : Pat<(truncstorei16 GR32:$src, addr:$dst),
          (MOV16mr addr:$dst, (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>;
def : Pat<(i32 (sextloadi16 addr:$dst)),
          (MOVSX32rm16 addr:$dst)>;
def : Pat<(i32 (zextloadi16 addr:$dst)),
          (MOVZX32rm16 addr:$dst)>;
def : Pat<(i32 (extloadi16 addr:$dst)),
          (MOVZX32rm16 addr:$dst)>;

//===----------------------------------------------------------------------===//
// Floating Point Stack Support
//===----------------------------------------------------------------------===//

include "X86InstrFPStack.td"

//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//

include "X86Instr64bit.td"

//===----------------------------------------------------------------------===//
// XMM Floating point support (requires SSE / SSE2)
//===----------------------------------------------------------------------===//

Evan Cheng's avatar
Evan Cheng committed

//===----------------------------------------------------------------------===//
// MMX and XMM Packed Integer support (requires MMX, SSE, and SSE2)
Evan Cheng's avatar
Evan Cheng committed
//===----------------------------------------------------------------------===//