PageRenderTime 150ms CodeModel.GetById 17ms app.highlight 122ms RepoModel.GetById 1ms app.codeStats 0ms

/3rd_party/llvm/lib/Target/X86/X86InstrArithmetic.td

https://code.google.com/p/softart/
Unknown | 1395 lines | 1248 code | 147 blank | 0 comment | 0 complexity | e7802e0f7cd11df209074edc0307cabd MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, JSON, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, LGPL-3.0, BSD-2-Clause

Large files files are truncated, but you can click here to view the full file

   1//===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//
   2//
   3//                     The LLVM Compiler Infrastructure
   4//
   5// This file is distributed under the University of Illinois Open Source
   6// License. See LICENSE.TXT for details.
   7//
   8//===----------------------------------------------------------------------===//
   9//
  10// This file describes the integer arithmetic instructions in the X86
  11// architecture.
  12//
  13//===----------------------------------------------------------------------===//
  14
  15//===----------------------------------------------------------------------===//
  16// LEA - Load Effective Address
  17let SchedRW = [WriteLEA] in {
  18let neverHasSideEffects = 1 in
  19def LEA16r   : I<0x8D, MRMSrcMem,
  20                 (outs GR16:$dst), (ins i32mem:$src),
  21                 "lea{w}\t{$src|$dst}, {$dst|$src}", [], IIC_LEA_16>, OpSize;
  22let isReMaterializable = 1 in
  23def LEA32r   : I<0x8D, MRMSrcMem,
  24                 (outs GR32:$dst), (ins i32mem:$src),
  25                 "lea{l}\t{$src|$dst}, {$dst|$src}",
  26                 [(set GR32:$dst, lea32addr:$src)], IIC_LEA>,
  27                 Requires<[In32BitMode]>;
  28
  29def LEA64_32r : I<0x8D, MRMSrcMem,
  30                  (outs GR32:$dst), (ins lea64_32mem:$src),
  31                  "lea{l}\t{$src|$dst}, {$dst|$src}",
  32                  [(set GR32:$dst, lea64_32addr:$src)], IIC_LEA>,
  33                  Requires<[In64BitMode]>;
  34
  35let isReMaterializable = 1 in
  36def LEA64r   : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
  37                  "lea{q}\t{$src|$dst}, {$dst|$src}",
  38                  [(set GR64:$dst, lea64addr:$src)], IIC_LEA>;
  39} // SchedRW
  40
  41//===----------------------------------------------------------------------===//
  42//  Fixed-Register Multiplication and Division Instructions.
  43//
  44
  45// SchedModel info for instruction that loads one value and gets the second
  46// (and possibly third) value from a register.
  47// This is used for instructions that put the memory operands before other
  48// uses.
  49class SchedLoadReg<SchedWrite SW> : Sched<[SW,
  50  // Memory operand.
  51  ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
  52  // Register reads (implicit or explicit).
  53  ReadAfterLd, ReadAfterLd]>;
  54
  55// Extra precision multiplication
  56
  57// AL is really implied by AX, but the registers in Defs must match the
  58// SDNode results (i8, i32).
  59// AL,AH = AL*GR8
  60let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  61def MUL8r  : I<0xF6, MRM4r, (outs),  (ins GR8:$src), "mul{b}\t$src",
  62               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
  63               // This probably ought to be moved to a def : Pat<> if the
  64               // syntax can be accepted.
  65               [(set AL, (mul AL, GR8:$src)),
  66                (implicit EFLAGS)], IIC_MUL8>, Sched<[WriteIMul]>;
  67// AX,DX = AX*GR16
  68let Defs = [AX,DX,EFLAGS], Uses = [AX], neverHasSideEffects = 1 in
  69def MUL16r : I<0xF7, MRM4r, (outs),  (ins GR16:$src),
  70               "mul{w}\t$src",
  71               [], IIC_MUL16_REG>, OpSize, Sched<[WriteIMul]>;
  72// EAX,EDX = EAX*GR32
  73let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], neverHasSideEffects = 1 in
  74def MUL32r : I<0xF7, MRM4r, (outs),  (ins GR32:$src),
  75               "mul{l}\t$src",
  76               [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/],
  77               IIC_MUL32_REG>, Sched<[WriteIMul]>;
  78// RAX,RDX = RAX*GR64
  79let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in
  80def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
  81                "mul{q}\t$src",
  82                [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/],
  83                IIC_MUL64>, Sched<[WriteIMul]>;
  84// AL,AH = AL*[mem8]
  85let Defs = [AL,EFLAGS,AX], Uses = [AL] in
  86def MUL8m  : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
  87               "mul{b}\t$src",
  88               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
  89               // This probably ought to be moved to a def : Pat<> if the
  90               // syntax can be accepted.
  91               [(set AL, (mul AL, (loadi8 addr:$src))),
  92                (implicit EFLAGS)], IIC_MUL8>, SchedLoadReg<WriteIMulLd>;
  93// AX,DX = AX*[mem16]
  94let mayLoad = 1, neverHasSideEffects = 1 in {
  95let Defs = [AX,DX,EFLAGS], Uses = [AX] in
  96def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
  97               "mul{w}\t$src",
  98               [], IIC_MUL16_MEM>, OpSize, SchedLoadReg<WriteIMulLd>;
  99// EAX,EDX = EAX*[mem32]
 100let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
 101def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
 102              "mul{l}\t$src",
 103              [], IIC_MUL32_MEM>, SchedLoadReg<WriteIMulLd>;
 104// RAX,RDX = RAX*[mem64]
 105let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
 106def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
 107                "mul{q}\t$src", [], IIC_MUL64>, SchedLoadReg<WriteIMulLd>;
 108}
 109
 110let neverHasSideEffects = 1 in {
 111// AL,AH = AL*GR8
 112let Defs = [AL,EFLAGS,AX], Uses = [AL] in
 113def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", [],
 114              IIC_IMUL8>, Sched<[WriteIMul]>;
 115// AX,DX = AX*GR16
 116let Defs = [AX,DX,EFLAGS], Uses = [AX] in
 117def IMUL16r : I<0xF7, MRM5r, (outs),  (ins GR16:$src), "imul{w}\t$src", [],
 118              IIC_IMUL16_RR>, OpSize, Sched<[WriteIMul]>;
 119// EAX,EDX = EAX*GR32
 120let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
 121def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", [],
 122              IIC_IMUL32_RR>, Sched<[WriteIMul]>;
 123// RAX,RDX = RAX*GR64
 124let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
 125def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
 126              IIC_IMUL64_RR>, Sched<[WriteIMul]>;
 127
 128let mayLoad = 1 in {
 129// AL,AH = AL*[mem8]
 130let Defs = [AL,EFLAGS,AX], Uses = [AL] in
 131def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
 132                "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
 133// AX,DX = AX*[mem16]
 134let Defs = [AX,DX,EFLAGS], Uses = [AX] in
 135def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
 136                "imul{w}\t$src", [], IIC_IMUL16_MEM>, OpSize,
 137              SchedLoadReg<WriteIMulLd>;
 138// EAX,EDX = EAX*[mem32]
 139let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
 140def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
 141                "imul{l}\t$src", [], IIC_IMUL32_MEM>, SchedLoadReg<WriteIMulLd>;
 142// RAX,RDX = RAX*[mem64]
 143let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
 144def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
 145                 "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>;
 146}
 147} // neverHasSideEffects
 148
 149
 150let Defs = [EFLAGS] in {
 151let Constraints = "$src1 = $dst" in {
 152
 153let isCommutable = 1, SchedRW = [WriteIMul] in {
 154// X = IMUL Y, Z --> X = IMUL Z, Y
 155// Register-Register Signed Integer Multiply
 156def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
 157                 "imul{w}\t{$src2, $dst|$dst, $src2}",
 158                 [(set GR16:$dst, EFLAGS,
 159                       (X86smul_flag GR16:$src1, GR16:$src2))], IIC_IMUL16_RR>,
 160                       TB, OpSize;
 161def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
 162                 "imul{l}\t{$src2, $dst|$dst, $src2}",
 163                 [(set GR32:$dst, EFLAGS,
 164                       (X86smul_flag GR32:$src1, GR32:$src2))], IIC_IMUL32_RR>,
 165                 TB;
 166def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
 167                                   (ins GR64:$src1, GR64:$src2),
 168                  "imul{q}\t{$src2, $dst|$dst, $src2}",
 169                  [(set GR64:$dst, EFLAGS,
 170                        (X86smul_flag GR64:$src1, GR64:$src2))], IIC_IMUL64_RR>,
 171                 TB;
 172} // isCommutable, SchedRW
 173
 174// Register-Memory Signed Integer Multiply
 175let SchedRW = [WriteIMulLd, ReadAfterLd] in {
 176def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
 177                                  (ins GR16:$src1, i16mem:$src2),
 178                 "imul{w}\t{$src2, $dst|$dst, $src2}",
 179                 [(set GR16:$dst, EFLAGS,
 180                       (X86smul_flag GR16:$src1, (load addr:$src2)))],
 181                       IIC_IMUL16_RM>,
 182               TB, OpSize;
 183def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
 184                 (ins GR32:$src1, i32mem:$src2),
 185                 "imul{l}\t{$src2, $dst|$dst, $src2}",
 186                 [(set GR32:$dst, EFLAGS,
 187                       (X86smul_flag GR32:$src1, (load addr:$src2)))],
 188                       IIC_IMUL32_RM>,
 189               TB;
 190def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
 191                                   (ins GR64:$src1, i64mem:$src2),
 192                  "imul{q}\t{$src2, $dst|$dst, $src2}",
 193                  [(set GR64:$dst, EFLAGS,
 194                        (X86smul_flag GR64:$src1, (load addr:$src2)))],
 195                        IIC_IMUL64_RM>,
 196               TB;
 197} // SchedRW
 198} // Constraints = "$src1 = $dst"
 199
 200} // Defs = [EFLAGS]
 201
 202// Surprisingly enough, these are not two address instructions!
 203let Defs = [EFLAGS] in {
 204let SchedRW = [WriteIMul] in {
 205// Register-Integer Signed Integer Multiply
 206def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // GR16 = GR16*I16
 207                      (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
 208                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 209                      [(set GR16:$dst, EFLAGS,
 210                            (X86smul_flag GR16:$src1, imm:$src2))],
 211                            IIC_IMUL16_RRI>, OpSize;
 212def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // GR16 = GR16*I8
 213                     (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
 214                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 215                     [(set GR16:$dst, EFLAGS,
 216                           (X86smul_flag GR16:$src1, i16immSExt8:$src2))],
 217                           IIC_IMUL16_RRI>,
 218                 OpSize;
 219def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // GR32 = GR32*I32
 220                      (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
 221                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 222                      [(set GR32:$dst, EFLAGS,
 223                            (X86smul_flag GR32:$src1, imm:$src2))],
 224                            IIC_IMUL32_RRI>;
 225def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // GR32 = GR32*I8
 226                     (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
 227                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 228                     [(set GR32:$dst, EFLAGS,
 229                           (X86smul_flag GR32:$src1, i32immSExt8:$src2))],
 230                           IIC_IMUL32_RRI>;
 231def IMUL64rri32 : RIi32<0x69, MRMSrcReg,                    // GR64 = GR64*I32
 232                        (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
 233                        "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 234                       [(set GR64:$dst, EFLAGS,
 235                             (X86smul_flag GR64:$src1, i64immSExt32:$src2))],
 236                             IIC_IMUL64_RRI>;
 237def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64 = GR64*I8
 238                      (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
 239                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 240                      [(set GR64:$dst, EFLAGS,
 241                            (X86smul_flag GR64:$src1, i64immSExt8:$src2))],
 242                            IIC_IMUL64_RRI>;
 243} // SchedRW
 244
 245// Memory-Integer Signed Integer Multiply
 246let SchedRW = [WriteIMulLd] in {
 247def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                     // GR16 = [mem16]*I16
 248                      (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
 249                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 250                      [(set GR16:$dst, EFLAGS,
 251                            (X86smul_flag (load addr:$src1), imm:$src2))],
 252                            IIC_IMUL16_RMI>,
 253                 OpSize;
 254def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR16 = [mem16]*I8
 255                     (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
 256                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 257                     [(set GR16:$dst, EFLAGS,
 258                           (X86smul_flag (load addr:$src1),
 259                                         i16immSExt8:$src2))], IIC_IMUL16_RMI>,
 260                                         OpSize;
 261def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                     // GR32 = [mem32]*I32
 262                      (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
 263                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 264                      [(set GR32:$dst, EFLAGS,
 265                            (X86smul_flag (load addr:$src1), imm:$src2))],
 266                            IIC_IMUL32_RMI>;
 267def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR32 = [mem32]*I8
 268                     (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
 269                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 270                     [(set GR32:$dst, EFLAGS,
 271                           (X86smul_flag (load addr:$src1),
 272                                         i32immSExt8:$src2))],
 273                                         IIC_IMUL32_RMI>;
 274def IMUL64rmi32 : RIi32<0x69, MRMSrcMem,                   // GR64 = [mem64]*I32
 275                        (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
 276                        "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 277                        [(set GR64:$dst, EFLAGS,
 278                              (X86smul_flag (load addr:$src1),
 279                                            i64immSExt32:$src2))],
 280                                            IIC_IMUL64_RMI>;
 281def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64 = [mem64]*I8
 282                      (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
 283                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
 284                      [(set GR64:$dst, EFLAGS,
 285                            (X86smul_flag (load addr:$src1),
 286                                          i64immSExt8:$src2))],
 287                                          IIC_IMUL64_RMI>;
 288} // SchedRW
 289} // Defs = [EFLAGS]
 290
 291
 292
 293
 294// unsigned division/remainder
 295let hasSideEffects = 1 in { // so that we don't speculatively execute
 296let SchedRW = [WriteIDiv] in {
 297let Defs = [AL,AH,EFLAGS], Uses = [AX] in
 298def DIV8r  : I<0xF6, MRM6r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
 299               "div{b}\t$src", [], IIC_DIV8_REG>;
 300let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
 301def DIV16r : I<0xF7, MRM6r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
 302               "div{w}\t$src", [], IIC_DIV16>, OpSize;
 303let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 304def DIV32r : I<0xF7, MRM6r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
 305               "div{l}\t$src", [], IIC_DIV32>;
 306// RDX:RAX/r64 = RAX,RDX
 307let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
 308def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
 309                "div{q}\t$src", [], IIC_DIV64>;
 310} // SchedRW
 311
 312let mayLoad = 1 in {
 313let Defs = [AL,AH,EFLAGS], Uses = [AX] in
 314def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
 315               "div{b}\t$src", [], IIC_DIV8_MEM>,
 316             SchedLoadReg<WriteIDivLd>;
 317let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
 318def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
 319               "div{w}\t$src", [], IIC_DIV16>, OpSize,
 320             SchedLoadReg<WriteIDivLd>;
 321let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
 322def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
 323               "div{l}\t$src", [], IIC_DIV32>,
 324             SchedLoadReg<WriteIDivLd>;
 325// RDX:RAX/[mem64] = RAX,RDX
 326let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
 327def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
 328                "div{q}\t$src", [], IIC_DIV64>,
 329             SchedLoadReg<WriteIDivLd>;
 330}
 331
 332// Signed division/remainder.
 333let SchedRW = [WriteIDiv] in {
 334let Defs = [AL,AH,EFLAGS], Uses = [AX] in
 335def IDIV8r : I<0xF6, MRM7r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
 336               "idiv{b}\t$src", [], IIC_IDIV8>;
 337let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
 338def IDIV16r: I<0xF7, MRM7r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
 339               "idiv{w}\t$src", [], IIC_IDIV16>, OpSize;
 340let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 341def IDIV32r: I<0xF7, MRM7r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
 342               "idiv{l}\t$src", [], IIC_IDIV32>;
 343// RDX:RAX/r64 = RAX,RDX
 344let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
 345def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
 346                "idiv{q}\t$src", [], IIC_IDIV64>;
 347} // SchedRW
 348
 349let mayLoad = 1 in {
 350let Defs = [AL,AH,EFLAGS], Uses = [AX] in
 351def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
 352               "idiv{b}\t$src", [], IIC_IDIV8>,
 353             SchedLoadReg<WriteIDivLd>;
 354let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
 355def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
 356               "idiv{w}\t$src", [], IIC_IDIV16>, OpSize,
 357             SchedLoadReg<WriteIDivLd>;
 358let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
 359def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
 360               "idiv{l}\t$src", [], IIC_IDIV32>,
 361             SchedLoadReg<WriteIDivLd>;
 362let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
 363def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
 364                "idiv{q}\t$src", [], IIC_IDIV64>,
 365             SchedLoadReg<WriteIDivLd>;
 366}
 367} // hasSideEffects = 0
 368
 369//===----------------------------------------------------------------------===//
 370//  Two address Instructions.
 371//
 372
 373// unary instructions
 374let CodeSize = 2 in {
 375let Defs = [EFLAGS] in {
 376let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
 377def NEG8r  : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
 378               "neg{b}\t$dst",
 379               [(set GR8:$dst, (ineg GR8:$src1)),
 380                (implicit EFLAGS)], IIC_UNARY_REG>;
 381def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
 382               "neg{w}\t$dst",
 383               [(set GR16:$dst, (ineg GR16:$src1)),
 384                (implicit EFLAGS)], IIC_UNARY_REG>, OpSize;
 385def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
 386               "neg{l}\t$dst",
 387               [(set GR32:$dst, (ineg GR32:$src1)),
 388                (implicit EFLAGS)], IIC_UNARY_REG>;
 389def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
 390                [(set GR64:$dst, (ineg GR64:$src1)),
 391                 (implicit EFLAGS)], IIC_UNARY_REG>;
 392} // Constraints = "$src1 = $dst", SchedRW
 393
 394// Read-modify-write negate.
 395let SchedRW = [WriteALULd, WriteRMW] in {
 396def NEG8m  : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
 397               "neg{b}\t$dst",
 398               [(store (ineg (loadi8 addr:$dst)), addr:$dst),
 399                (implicit EFLAGS)], IIC_UNARY_MEM>;
 400def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
 401               "neg{w}\t$dst",
 402               [(store (ineg (loadi16 addr:$dst)), addr:$dst),
 403                (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize;
 404def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
 405               "neg{l}\t$dst",
 406               [(store (ineg (loadi32 addr:$dst)), addr:$dst),
 407                (implicit EFLAGS)], IIC_UNARY_MEM>;
 408def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
 409                [(store (ineg (loadi64 addr:$dst)), addr:$dst),
 410                 (implicit EFLAGS)], IIC_UNARY_MEM>;
 411} // SchedRW
 412} // Defs = [EFLAGS]
 413
 414
 415// Note: NOT does not set EFLAGS!
 416
 417let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
 418// Match xor -1 to not. Favors these over a move imm + xor to save code size.
 419let AddedComplexity = 15 in {
 420def NOT8r  : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
 421               "not{b}\t$dst",
 422               [(set GR8:$dst, (not GR8:$src1))], IIC_UNARY_REG>;
 423def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
 424               "not{w}\t$dst",
 425               [(set GR16:$dst, (not GR16:$src1))], IIC_UNARY_REG>, OpSize;
 426def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
 427               "not{l}\t$dst",
 428               [(set GR32:$dst, (not GR32:$src1))], IIC_UNARY_REG>;
 429def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
 430                [(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
 431}
 432} // Constraints = "$src1 = $dst", SchedRW
 433
 434let SchedRW = [WriteALULd, WriteRMW] in {
 435def NOT8m  : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
 436               "not{b}\t$dst",
 437               [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
 438def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
 439               "not{w}\t$dst",
 440               [(store (not (loadi16 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
 441               OpSize;
 442def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
 443               "not{l}\t$dst",
 444               [(store (not (loadi32 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
 445def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
 446                [(store (not (loadi64 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
 447} // SchedRW
 448} // CodeSize
 449
 450// TODO: inc/dec is slow for P4, but fast for Pentium-M.
 451let Defs = [EFLAGS] in {
 452let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
 453let CodeSize = 2 in
 454def INC8r  : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
 455               "inc{b}\t$dst",
 456               [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))],
 457               IIC_UNARY_REG>;
 458
 459let isConvertibleToThreeAddress = 1, CodeSize = 1 in {  // Can xform into LEA.
 460def INC16r : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
 461               "inc{w}\t$dst",
 462               [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))], IIC_UNARY_REG>,
 463             OpSize, Requires<[In32BitMode]>;
 464def INC32r : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
 465               "inc{l}\t$dst",
 466               [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
 467               IIC_UNARY_REG>,
 468             Requires<[In32BitMode]>;
 469def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
 470                [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
 471                IIC_UNARY_REG>;
 472} // isConvertibleToThreeAddress = 1, CodeSize = 1
 473
 474
 475// In 64-bit mode, single byte INC and DEC cannot be encoded.
 476let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
 477// Can transform into LEA.
 478def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
 479                  "inc{w}\t$dst",
 480                  [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))],
 481                  IIC_UNARY_REG>,
 482                OpSize, Requires<[In64BitMode]>;
 483def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
 484                  "inc{l}\t$dst",
 485                  [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
 486                  IIC_UNARY_REG>,
 487                Requires<[In64BitMode]>;
 488def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
 489                  "dec{w}\t$dst",
 490                  [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
 491                  IIC_UNARY_REG>,
 492                OpSize, Requires<[In64BitMode]>;
 493def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
 494                  "dec{l}\t$dst",
 495                  [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
 496                  IIC_UNARY_REG>,
 497                Requires<[In64BitMode]>;
 498} // isConvertibleToThreeAddress = 1, CodeSize = 2
 499
 500let isCodeGenOnly = 1, CodeSize = 2 in {
 501def INC32_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
 502                  "inc{w}\t$dst", [], IIC_UNARY_REG>,
 503                OpSize, Requires<[In32BitMode]>;
 504def INC32_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
 505                  "inc{l}\t$dst", [], IIC_UNARY_REG>,
 506                Requires<[In32BitMode]>;
 507def DEC32_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
 508                  "dec{w}\t$dst", [], IIC_UNARY_REG>,
 509                OpSize, Requires<[In32BitMode]>;
 510def DEC32_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
 511                  "dec{l}\t$dst", [], IIC_UNARY_REG>,
 512                Requires<[In32BitMode]>;
 513} // isCodeGenOnly = 1, CodeSize = 2
 514
 515} // Constraints = "$src1 = $dst", SchedRW
 516
 517let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
 518  def INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
 519               [(store (add (loadi8 addr:$dst), 1), addr:$dst),
 520                (implicit EFLAGS)], IIC_UNARY_MEM>;
 521  def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
 522               [(store (add (loadi16 addr:$dst), 1), addr:$dst),
 523                (implicit EFLAGS)], IIC_UNARY_MEM>,
 524               OpSize, Requires<[In32BitMode]>;
 525  def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
 526               [(store (add (loadi32 addr:$dst), 1), addr:$dst),
 527                (implicit EFLAGS)], IIC_UNARY_MEM>,
 528               Requires<[In32BitMode]>;
 529  def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
 530                  [(store (add (loadi64 addr:$dst), 1), addr:$dst),
 531                   (implicit EFLAGS)], IIC_UNARY_MEM>;
 532
 533// These are duplicates of their 32-bit counterparts. Only needed so X86 knows
 534// how to unfold them.
 535// FIXME: What is this for??
 536def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
 537                  [(store (add (loadi16 addr:$dst), 1), addr:$dst),
 538                    (implicit EFLAGS)], IIC_UNARY_MEM>,
 539                OpSize, Requires<[In64BitMode]>;
 540def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
 541                  [(store (add (loadi32 addr:$dst), 1), addr:$dst),
 542                    (implicit EFLAGS)], IIC_UNARY_MEM>,
 543                Requires<[In64BitMode]>;
 544def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
 545                  [(store (add (loadi16 addr:$dst), -1), addr:$dst),
 546                    (implicit EFLAGS)], IIC_UNARY_MEM>,
 547                OpSize, Requires<[In64BitMode]>;
 548def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
 549                  [(store (add (loadi32 addr:$dst), -1), addr:$dst),
 550                    (implicit EFLAGS)], IIC_UNARY_MEM>,
 551                Requires<[In64BitMode]>;
 552} // CodeSize = 2, SchedRW
 553
 554let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
 555let CodeSize = 2 in
 556def DEC8r  : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
 557               "dec{b}\t$dst",
 558               [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
 559               IIC_UNARY_REG>;
 560let isConvertibleToThreeAddress = 1, CodeSize = 1 in {   // Can xform into LEA.
 561def DEC16r : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
 562               "dec{w}\t$dst",
 563               [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
 564               IIC_UNARY_REG>,
 565             OpSize, Requires<[In32BitMode]>;
 566def DEC32r : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
 567               "dec{l}\t$dst",
 568               [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
 569               IIC_UNARY_REG>,
 570             Requires<[In32BitMode]>;
 571def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
 572                [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
 573                IIC_UNARY_REG>;
 574} // CodeSize = 2
 575} // Constraints = "$src1 = $dst", SchedRW
 576
 577
 578let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
 579  def DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
 580               [(store (add (loadi8 addr:$dst), -1), addr:$dst),
 581                (implicit EFLAGS)], IIC_UNARY_MEM>;
 582  def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
 583               [(store (add (loadi16 addr:$dst), -1), addr:$dst),
 584                (implicit EFLAGS)], IIC_UNARY_MEM>,
 585               OpSize, Requires<[In32BitMode]>;
 586  def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
 587               [(store (add (loadi32 addr:$dst), -1), addr:$dst),
 588                (implicit EFLAGS)], IIC_UNARY_MEM>,
 589               Requires<[In32BitMode]>;
 590  def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
 591                  [(store (add (loadi64 addr:$dst), -1), addr:$dst),
 592                   (implicit EFLAGS)], IIC_UNARY_MEM>;
 593} // CodeSize = 2, SchedRW
 594} // Defs = [EFLAGS]
 595
 596/// X86TypeInfo - This is a bunch of information that describes relevant X86
 597/// information about value types.  For example, it can tell you what the
 598/// register class and preferred load to use.
 599class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
 600                  PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
 601                  Operand immoperand, SDPatternOperator immoperator,
 602                  Operand imm8operand, SDPatternOperator imm8operator,
 603                  bit hasOddOpcode, bit hasOpSizePrefix, bit hasREX_WPrefix> {
 604  /// VT - This is the value type itself.
 605  ValueType VT = vt;
 606
 607  /// InstrSuffix - This is the suffix used on instructions with this type.  For
 608  /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
 609  string InstrSuffix = instrsuffix;
 610
 611  /// RegClass - This is the register class associated with this type.  For
 612  /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
 613  RegisterClass RegClass = regclass;
 614
 615  /// LoadNode - This is the load node associated with this type.  For
 616  /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
 617  PatFrag LoadNode = loadnode;
 618
 619  /// MemOperand - This is the memory operand associated with this type.  For
 620  /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
 621  X86MemOperand MemOperand = memoperand;
 622
 623  /// ImmEncoding - This is the encoding of an immediate of this type.  For
 624  /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32.  Note that i64 -> Imm32
 625  /// since the immediate fields of i64 instructions is a 32-bit sign extended
 626  /// value.
 627  ImmType ImmEncoding = immkind;
 628
 629  /// ImmOperand - This is the operand kind of an immediate of this type.  For
 630  /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm.  Note that i64 ->
 631  /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
 632  /// extended value.
 633  Operand ImmOperand = immoperand;
 634
 635  /// ImmOperator - This is the operator that should be used to match an
 636  /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
 637  SDPatternOperator ImmOperator = immoperator;
 638
 639  /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
 640  /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
 641  /// only used for instructions that have a sign-extended imm8 field form.
 642  Operand Imm8Operand = imm8operand;
 643
 644  /// Imm8Operator - This is the operator that should be used to match an 8-bit
 645  /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
 646  SDPatternOperator Imm8Operator = imm8operator;
 647
 648  /// HasOddOpcode - This bit is true if the instruction should have an odd (as
 649  /// opposed to even) opcode.  Operations on i8 are usually even, operations on
 650  /// other datatypes are odd.
 651  bit HasOddOpcode = hasOddOpcode;
 652
 653  /// HasOpSizePrefix - This bit is set to true if the instruction should have
 654  /// the 0x66 operand size prefix.  This is set for i16 types.
 655  bit HasOpSizePrefix = hasOpSizePrefix;
 656
 657  /// HasREX_WPrefix - This bit is set to true if the instruction should have
 658  /// the 0x40 REX prefix.  This is set for i64 types.
 659  bit HasREX_WPrefix = hasREX_WPrefix;
 660}
 661
 662def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
 663
 664
 665def Xi8  : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
 666                       Imm8 , i8imm ,    imm,          i8imm   , invalid_node,
 667                       0, 0, 0>;
 668def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
 669                       Imm16, i16imm,    imm,          i16i8imm, i16immSExt8,
 670                       1, 1, 0>;
 671def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
 672                       Imm32, i32imm,    imm,          i32i8imm, i32immSExt8,
 673                       1, 0, 0>;
 674def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
 675                       Imm32, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8,
 676                       1, 0, 1>;
 677
 678/// ITy - This instruction base class takes the type info for the instruction.
 679/// Using this, it:
 680/// 1. Concatenates together the instruction mnemonic with the appropriate
 681///    suffix letter, a tab, and the arguments.
 682/// 2. Infers whether the instruction should have a 0x66 prefix byte.
 683/// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
 684/// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
 685///    or 1 (for i16,i32,i64 operations).
 686class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
 687          string mnemonic, string args, list<dag> pattern,
 688          InstrItinClass itin = IIC_BIN_NONMEM>
 689  : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
 690       opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
 691      f, outs, ins,
 692      !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
 693      itin> {
 694
 695  // Infer instruction prefixes from type info.
 696  let hasOpSizePrefix = typeinfo.HasOpSizePrefix;
 697  let hasREX_WPrefix  = typeinfo.HasREX_WPrefix;
 698}
 699
 700// BinOpRR - Instructions like "add reg, reg, reg".
 701class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 702              dag outlist, list<dag> pattern, InstrItinClass itin,
 703              Format f = MRMDestReg>
 704  : ITy<opcode, f, typeinfo, outlist,
 705        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
 706        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
 707    Sched<[WriteALU]>;
 708
 709// BinOpRR_R - Instructions like "add reg, reg, reg", where the pattern has
 710// just a regclass (no eflags) as a result.
 711class BinOpRR_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 712                SDNode opnode>
 713  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 714            [(set typeinfo.RegClass:$dst,
 715                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
 716                  IIC_BIN_NONMEM>;
 717
 718// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
 719// just a EFLAGS as a result.
 720class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 721                SDPatternOperator opnode, Format f = MRMDestReg>
 722  : BinOpRR<opcode, mnemonic, typeinfo, (outs),
 723            [(set EFLAGS,
 724                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
 725            IIC_BIN_NONMEM, f>;
 726
 727// BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
 728// both a regclass and EFLAGS as a result.
 729class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 730                 SDNode opnode>
 731  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 732            [(set typeinfo.RegClass:$dst, EFLAGS,
 733                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
 734                  IIC_BIN_NONMEM>;
 735
 736// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
 737// both a regclass and EFLAGS as a result, and has EFLAGS as input.
 738class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 739                  SDNode opnode>
 740  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 741            [(set typeinfo.RegClass:$dst, EFLAGS,
 742                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
 743                          EFLAGS))], IIC_BIN_CARRY_NONMEM>;
 744
 745// BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
 746class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 747                 InstrItinClass itin = IIC_BIN_NONMEM>
 748  : ITy<opcode, MRMSrcReg, typeinfo,
 749        (outs typeinfo.RegClass:$dst),
 750        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
 751        mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
 752    Sched<[WriteALU]> {
 753  // The disassembler should know about this, but not the asmparser.
 754  let isCodeGenOnly = 1;
 755  let hasSideEffects = 0;
 756}
 757
 758// BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
 759class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
 760  : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
 761
 762// BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
 763class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
 764  : ITy<opcode, MRMSrcReg, typeinfo, (outs),
 765        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
 766        mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
 767    Sched<[WriteALU]> {
 768  // The disassembler should know about this, but not the asmparser.
 769  let isCodeGenOnly = 1;
 770  let hasSideEffects = 0;
 771}
 772
 773// BinOpRM - Instructions like "add reg, reg, [mem]".
 774class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 775              dag outlist, list<dag> pattern,
 776              InstrItinClass itin = IIC_BIN_MEM>
 777  : ITy<opcode, MRMSrcMem, typeinfo, outlist,
 778        (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
 779        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
 780    Sched<[WriteALULd, ReadAfterLd]>;
 781
 782// BinOpRM_R - Instructions like "add reg, reg, [mem]".
 783class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 784              SDNode opnode>
 785  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 786            [(set typeinfo.RegClass:$dst,
 787            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
 788
 789// BinOpRM_F - Instructions like "cmp reg, [mem]".
 790class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 791              SDPatternOperator opnode>
 792  : BinOpRM<opcode, mnemonic, typeinfo, (outs),
 793            [(set EFLAGS,
 794            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
 795
 796// BinOpRM_RF - Instructions like "add reg, reg, [mem]".
 797class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 798                 SDNode opnode>
 799  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 800            [(set typeinfo.RegClass:$dst, EFLAGS,
 801            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
 802
 803// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
 804class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 805                 SDNode opnode>
 806  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
 807            [(set typeinfo.RegClass:$dst, EFLAGS,
 808            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
 809                    EFLAGS))], IIC_BIN_CARRY_MEM>;
 810
 811// BinOpRI - Instructions like "add reg, reg, imm".
 812class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 813              Format f, dag outlist, list<dag> pattern,
 814              InstrItinClass itin = IIC_BIN_NONMEM>
 815  : ITy<opcode, f, typeinfo, outlist,
 816        (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
 817        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
 818    Sched<[WriteALU]> {
 819  let ImmT = typeinfo.ImmEncoding;
 820}
 821
 822// BinOpRI_R - Instructions like "add reg, reg, imm".
 823class BinOpRI_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 824                SDNode opnode, Format f>
 825  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 826            [(set typeinfo.RegClass:$dst,
 827                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
 828
 829// BinOpRI_F - Instructions like "cmp reg, imm".
 830class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 831                SDPatternOperator opnode, Format f>
 832  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
 833            [(set EFLAGS,
 834                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
 835
 836// BinOpRI_RF - Instructions like "add reg, reg, imm".
 837class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 838                 SDNode opnode, Format f>
 839  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 840            [(set typeinfo.RegClass:$dst, EFLAGS,
 841                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
 842// BinOpRI_RFF - Instructions like "adc reg, reg, imm".
 843class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 844                 SDNode opnode, Format f>
 845  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 846            [(set typeinfo.RegClass:$dst, EFLAGS,
 847                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
 848                        EFLAGS))], IIC_BIN_CARRY_NONMEM>;
 849
 850// BinOpRI8 - Instructions like "add reg, reg, imm8".
 851class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 852               Format f, dag outlist, list<dag> pattern,
 853               InstrItinClass itin = IIC_BIN_NONMEM>
 854  : ITy<opcode, f, typeinfo, outlist,
 855        (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
 856        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
 857    Sched<[WriteALU]> {
 858  let ImmT = Imm8; // Always 8-bit immediate.
 859}
 860
 861// BinOpRI8_R - Instructions like "add reg, reg, imm8".
 862class BinOpRI8_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 863                  SDNode opnode, Format f>
 864  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 865             [(set typeinfo.RegClass:$dst,
 866               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
 867
 868// BinOpRI8_F - Instructions like "cmp reg, imm8".
 869class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 870                  SDNode opnode, Format f>
 871  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
 872             [(set EFLAGS,
 873               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
 874
 875// BinOpRI8_RF - Instructions like "add reg, reg, imm8".
 876class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 877                  SDNode opnode, Format f>
 878  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 879             [(set typeinfo.RegClass:$dst, EFLAGS,
 880               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
 881
 882// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
 883class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 884                   SDNode opnode, Format f>
 885  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
 886             [(set typeinfo.RegClass:$dst, EFLAGS,
 887               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
 888                       EFLAGS))], IIC_BIN_CARRY_NONMEM>;
 889
 890// BinOpMR - Instructions like "add [mem], reg".
 891class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 892              list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
 893  : ITy<opcode, MRMDestMem, typeinfo,
 894        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
 895        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
 896    Sched<[WriteALULd, WriteRMW]>;
 897
 898// BinOpMR_RMW - Instructions like "add [mem], reg".
 899class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 900                  SDNode opnode>
 901  : BinOpMR<opcode, mnemonic, typeinfo,
 902          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
 903           (implicit EFLAGS)]>;
 904
 905// BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
 906class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 907                    SDNode opnode>
 908  : BinOpMR<opcode, mnemonic, typeinfo,
 909          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
 910                  addr:$dst),
 911           (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
 912
 913// BinOpMR_F - Instructions like "cmp [mem], reg".
 914class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 915                  SDNode opnode>
 916  : BinOpMR<opcode, mnemonic, typeinfo,
 917            [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
 918
 919// BinOpMI - Instructions like "add [mem], imm".
 920class BinOpMI<string mnemonic, X86TypeInfo typeinfo,
 921              Format f, list<dag> pattern, bits<8> opcode = 0x80,
 922              InstrItinClass itin = IIC_BIN_MEM>
 923  : ITy<opcode, f, typeinfo,
 924        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
 925        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
 926    Sched<[WriteALULd, WriteRMW]> {
 927  let ImmT = typeinfo.ImmEncoding;
 928}
 929
 930// BinOpMI_RMW - Instructions like "add [mem], imm".
 931class BinOpMI_RMW<string mnemonic, X86TypeInfo typeinfo,
 932                  SDNode opnode, Format f>
 933  : BinOpMI<mnemonic, typeinfo, f,
 934            [(store (opnode (typeinfo.VT (load addr:$dst)),
 935                            typeinfo.ImmOperator:$src), addr:$dst),
 936             (implicit EFLAGS)]>;
 937// BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
 938class BinOpMI_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
 939                  SDNode opnode, Format f>
 940  : BinOpMI<mnemonic, typeinfo, f,
 941            [(store (opnode (typeinfo.VT (load addr:$dst)),
 942                            typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
 943             (implicit EFLAGS)], 0x80, IIC_BIN_CARRY_MEM>;
 944
 945// BinOpMI_F - Instructions like "cmp [mem], imm".
 946class BinOpMI_F<string mnemonic, X86TypeInfo typeinfo,
 947                SDPatternOperator opnode, Format f, bits<8> opcode = 0x80>
 948  : BinOpMI<mnemonic, typeinfo, f,
 949            [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
 950                                               typeinfo.ImmOperator:$src))],
 951            opcode>;
 952
 953// BinOpMI8 - Instructions like "add [mem], imm8".
 954class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
 955               Format f, list<dag> pattern,
 956               InstrItinClass itin = IIC_BIN_MEM>
 957  : ITy<0x82, f, typeinfo,
 958        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
 959        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
 960    Sched<[WriteALULd, WriteRMW]> {
 961  let ImmT = Imm8; // Always 8-bit immediate.
 962}
 963
 964// BinOpMI8_RMW - Instructions like "add [mem], imm8".
 965class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
 966                   SDNode opnode, Format f>
 967  : BinOpMI8<mnemonic, typeinfo, f,
 968             [(store (opnode (load addr:$dst),
 969                             typeinfo.Imm8Operator:$src), addr:$dst),
 970              (implicit EFLAGS)]>;
 971
 972// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
 973class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
 974                   SDNode opnode, Format f>
 975  : BinOpMI8<mnemonic, typeinfo, f,
 976             [(store (opnode (load addr:$dst),
 977                             typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
 978              (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
 979
 980// BinOpMI8_F - Instructions like "cmp [mem], imm8".
 981class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
 982                 SDNode opnode, Format f>
 983  : BinOpMI8<mnemonic, typeinfo, f,
 984             [(set EFLAGS, (opnode (load addr:$dst),
 985                                   typeinfo.Imm8Operator:$src))]>;
 986
 987// BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
 988class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
 989              Register areg, string operands,
 990              InstrItinClass itin = IIC_BIN_NONMEM>
 991  : ITy<opcode, RawFrm, typeinfo,
 992        (outs), (ins typeinfo.ImmOperand:$src),
 993        mnemonic, operands, [], itin>, Sched<[WriteALU]> {
 994  let ImmT = typeinfo.ImmEncoding;
 995  let Uses = [areg];
 996  let Defs = [areg, EFLAGS];
 997  let hasSideEffects = 0;
 998}
 999
1000// BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
1001// and use EFLAGS.
1002class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
1003                Register areg, string operands>
1004  : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
1005            IIC_BIN_CARRY_NONMEM> {
1006  let Uses = [areg, EFLAGS];
1007}
1008
1009/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
1010/// defined with "(set GPR:$dst, EFLAGS, (...".
1011///
1012/// It would be nice to get rid of the second and third argument here, but
1013/// tblgen can't handle dependent type references aggressively enough: PR8330
1014multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1015                         string mnemonic, Format RegMRM, Format MemMRM,
1016                         SDNode opnodeflag, SDNode opnode,
1017                         bit CommutableRR, bit ConvertibleToThreeAddress> {
1018  let Defs = [EFLAGS] in {
1019    let Constraints = "$src1 = $dst" in {
1020      let isCommutable = CommutableRR,
1021          isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1022        def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
1023        def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
1024        def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
1025        def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
1026      } // isCommutable
1027
1028      def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
1029      def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
1030      def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
1031      def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
1032
1033      def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
1034      def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
1035      def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
1036      def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
1037
1038      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1039        // NOTE: These are order specific, we want the ri8 forms to be listed
1040        // first so that they are slightly preferred to the ri forms.
1041        def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
1042        def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
1043        def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
1044
1045

Large files files are truncated, but you can click here to view the full file