brintos

brintos / llvm-project-archived public Read only

0
0
Text · 42.3 KiB · 56b71db Raw
1109 lines · plain
1//===-- M68kInstrArithmetic.td - Integer Arith Instrs ------*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file describes the integer arithmetic instructions in the M68k11/// architecture. Here is the current status of the file:12///13///  Machine:14///15///    ADD       [~]   ADDA      [~]   ADDI        [~]   ADDQ [ ]   ADDX [~]16///    CLR       [ ]   CMP       [~]   CMPA        [~]   CMPI [~]   CMPM [ ]17///    CMP2      [ ]   DIVS/DIVU [~]   DIVSL/DIVUL [ ]   EXT  [~]   EXTB [ ]18///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   NOT  [~]   SUB  [~]19///    SUBA      [~]   SUBI      [~]   SUBQ        [ ]   SUBX [~]20///21///  Map:22///23///   [ ] - was not touched at all24///   [!] - requires extarnal stuff implemented25///   [~] - functional implementation26///   [X] - complete implementation27///28//===----------------------------------------------------------------------===//29 30//===----------------------------------------------------------------------===//31// OPMODE Encoding32//===----------------------------------------------------------------------===//33class MxOpModeEncoding<bits<3> encoding> {34  bits<3> Value = encoding;35}36 37// op EA, Dn38def MxOpMode8_d_EA  : MxOpModeEncoding<0b000>;39def MxOpMode16_d_EA : MxOpModeEncoding<0b001>;40def MxOpMode32_d_EA : MxOpModeEncoding<0b010>;41 42// op Dn, EA43def MxOpMode8_EA_d  : MxOpModeEncoding<0b100>;44def MxOpMode16_EA_d : MxOpModeEncoding<0b101>;45def MxOpMode32_EA_d : MxOpModeEncoding<0b110>;46 47// op EA, An48def MxOpMode16_a_EA : MxOpModeEncoding<0b011>;49def MxOpMode32_a_EA : MxOpModeEncoding<0b111>;50 51 52//===----------------------------------------------------------------------===//53// Encoding54//===----------------------------------------------------------------------===//55 56let Defs = [CCR] in {57let Constraints = "$src = $dst" in {58 59/// Encoding for Normal forms60/// ----------------------------------------------------61///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  062/// ----------------------------------------------------63///             |         |         | EFFECTIVE ADDRESS64///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG65/// ----------------------------------------------------66 67// $reg, $ccr <- $reg op $reg68class MxBiArOp_R_RR_xEA<string MN, SDNode NODE, MxType DST_TYPE, MxType SRC_TYPE,69                        bits<4> CMD>70    : MxInst<(outs DST_TYPE.ROp:$dst), (ins DST_TYPE.ROp:$src, SRC_TYPE.ROp:$opd),71             MN#"."#DST_TYPE.Prefix#"\t$opd, $dst",72             [(set DST_TYPE.VT:$dst, CCR, (NODE DST_TYPE.VT:$src, SRC_TYPE.VT:$opd))]> {73  let Inst = (descend74    CMD, (operand "$dst", 3),75    !cast<MxOpModeEncoding>("MxOpMode"#DST_TYPE.Size#"_"#DST_TYPE.RLet#"_EA").Value,76    !cond(77      !eq(SRC_TYPE.RLet, "r") : (descend 0b00, (operand "$opd", 4)),78      !eq(SRC_TYPE.RLet, "d") : (descend 0b000, (operand "$opd", 3))79    )80  );81}82 83/// This Op is similar to the one above except it uses reversed opmode, some84/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for85/// register only operations.86/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)87/// but some opcodes support address register and some do not which creates this88/// mess.89class MxBiArOp_R_RR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>90    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),91             MN#"."#TYPE.Prefix#"\t$opd, $dst",92             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))]> {93  let Inst = (descend94    CMD, (operand "$opd", 3),95    !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,96    /*Destination can only be a data register*/97    /*MODE*/0b000,98    /*REGISTER*/(operand "$dst", 3));99}100 101let mayLoad = 1 in102class MxBiArOp_R_RM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,103                    bits<4> CMD, MxEncMemOp SRC_ENC>104    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),105             MN#"."#TYPE.Prefix#"\t$opd, $dst",106             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))]> {107  let Inst = (ascend108    (descend CMD, (operand "$dst", 3),109             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,110             SRC_ENC.EA),111    SRC_ENC.Supplement112  );113}114 115/// Encoding for Immediate forms116/// ---------------------------------------------------117///  F  E  D  C  B  A  9  8 | 7  6 | 5  4  3 | 2  1  0118/// ---------------------------------------------------119///                         |      | EFFECTIVE ADDRESS120///  x  x  x  x  x  x  x  x | SIZE |   MODE  |   REG121/// ---------------------------------------------------122///     16-BIT WORD DATA    |     8-BIT BYTE DATA123/// ---------------------------------------------------124///                 32-BIT LONG DATA125/// ---------------------------------------------------126/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with127/// normal version128 129// $reg <- $reg op $imm130class MxBiArOp_R_RI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>131    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),132             MN#"."#TYPE.Prefix#"\t$opd, $dst",133             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {134  let Inst = (ascend135    (descend CMD, (operand "$dst", 3),136             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,137             MxEncAddrMode_i<"opd", TYPE.Size>.EA),138    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement139  );140}141 142// Again, there are two ways to write an immediate to Dn register either dEA143// opmode or using *I encoding, and again some instructions also support address144// registers some do not.145class MxBiArOp_R_RI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>146    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),147             MN#"i."#TYPE.Prefix#"\t$opd, $dst",148             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {149  let Inst = (ascend150    (descend 0b0000, CMD,151             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,152             // The destination cannot be address register, so it's always153             // the MODE for data register direct mode.154             /*MODE*/0b000,155             /*REGISTER*/(operand "$dst", 3)),156    // Source (i.e. immediate value) encoding157    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement158  );159}160} // Constraints161 162let mayLoad = 1, mayStore = 1 in {163 164// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for165// MxAdd to survive the match and subsequent mismatch.166class MxBiArOp_MR<string MN, MxType TYPE,167                  MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>168    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd),169             MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {170  let Inst = (ascend171    (descend CMD, (operand "$opd", 3),172             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,173             DST_ENC.EA),174    DST_ENC.Supplement175  );176}177 178class MxBiArOp_MI<string MN, MxType TYPE,179                  MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>180    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd),181             MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {182  let Inst = (ascend183    (descend 0b0000, CMD,184             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,185             DST_ENC.EA),186    // Source (i.e. immediate value) encoding187    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement,188    // Destination encoding189    DST_ENC.Supplement190  );191}192} // mayLoad, mayStore193} // Defs = [CCR]194 195multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,196                       bits<4> CMD, bits<4> CMDI> {197 198  foreach SZ = [8, 16, 32] in {199    // op $mem, $reg200    def NAME#SZ#"dk"  : MxBiArOp_R_RM<MN, NODE,201                                      !cast<MxType>("MxType"#SZ#"d"),202                                      !cast<MxType>("MxType"#SZ).KOp,203                                      !cast<MxType>("MxType"#SZ).KPat,204                                      CMD, MxEncAddrMode_k<"opd">>;205 206    def NAME#SZ#"dq"  : MxBiArOp_R_RM<MN, NODE,207                                      !cast<MxType>("MxType"#SZ#"d"),208                                      !cast<MxType>("MxType"#SZ).QOp,209                                      !cast<MxType>("MxType"#SZ).QPat,210                                      CMD, MxEncAddrMode_q<"opd">>;211 212    def NAME#SZ#"dp"  : MxBiArOp_R_RM<MN, NODE,213                                      !cast<MxType>("MxType"#SZ#"d"),214                                      !cast<MxType>("MxType"#SZ).POp,215                                      !cast<MxType>("MxType"#SZ).PPat,216                                      CMD, MxEncAddrMode_p<"opd">>;217 218    def NAME#SZ#"df"  : MxBiArOp_R_RM<MN, NODE,219                                      !cast<MxType>("MxType"#SZ#"d"),220                                      !cast<MxType>("MxType"#SZ).FOp,221                                      !cast<MxType>("MxType"#SZ).FPat,222                                      CMD, MxEncAddrMode_f<"opd">>;223 224    def NAME#SZ#"dj"  : MxBiArOp_R_RM<MN, NODE,225                                      !cast<MxType>("MxType"#SZ#"d"),226                                      !cast<MxType>("MxType"#SZ).JOp,227                                      !cast<MxType>("MxType"#SZ).JPat,228                                      CMD, MxEncAddrMode_j<"opd">>;229    // op $imm, $reg230    def NAME#SZ#"di"  : MxBiArOp_R_RI_xEA<MN, NODE,231                                          !cast<MxType>("MxType"#SZ#"d"),232                                          CMD>;233    // op $reg, $mem234    def NAME#SZ#"pd"  : MxBiArOp_MR<MN,235                                    !cast<MxType>("MxType"#SZ#"d"),236                                    !cast<MxType>("MxType"#SZ).POp,237                                    CMD, MxEncAddrMode_p<"dst">>;238 239    def NAME#SZ#"fd"  : MxBiArOp_MR<MN,240                                    !cast<MxType>("MxType"#SZ#"d"),241                                    !cast<MxType>("MxType"#SZ).FOp,242                                    CMD, MxEncAddrMode_f<"dst">>;243 244    def NAME#SZ#"jd"  : MxBiArOp_MR<MN,245                                    !cast<MxType>("MxType"#SZ#"d"),246                                    !cast<MxType>("MxType"#SZ).JOp,247                                    CMD, MxEncAddrMode_j<"dst">>;248    // op $imm, $mem249    def NAME#SZ#"pi"  : MxBiArOp_MI<MN,250                                    !cast<MxType>("MxType"#SZ),251                                    !cast<MxType>("MxType"#SZ).POp,252                                    CMDI, MxEncAddrMode_p<"dst">>;253 254    def NAME#SZ#"fi"  : MxBiArOp_MI<MN,255                                    !cast<MxType>("MxType"#SZ),256                                    !cast<MxType>("MxType"#SZ).FOp,257                                    CMDI, MxEncAddrMode_f<"dst">>;258 259    def NAME#SZ#"ji"  : MxBiArOp_MI<MN,260                                    !cast<MxType>("MxType"#SZ),261                                    !cast<MxType>("MxType"#SZ).JOp,262                                    CMDI, MxEncAddrMode_j<"dst">>;263    // op $reg, $reg264    let isCommutable = isComm in265    def NAME#SZ#"dd" : MxBiArOp_R_RR_xEA<MN, NODE,266                                         !cast<MxType>("MxType"#SZ#"d"),267                                         !cast<MxType>("MxType"#SZ#"d"),268                                         CMD>;269  } // foreach SZ270 271  foreach SZ = [16, 32] in272  def NAME#SZ#"dr" : MxBiArOp_R_RR_xEA<MN, NODE,273                                       !cast<MxType>("MxType"#SZ#"d"),274                                       !cast<MxType>("MxType"#SZ#"r"),275                                       CMD>;276 277} // MxBiArOp_DF278 279 280// These special snowflakes allowed to match address registers but since *A281// operations do not produce CCR we should not match them against Mx nodes that282// produce it.283let Pattern = [(null_frag)] in284multiclass MxBiArOp_AF<string MN, SDNode NODE, bits<4> CMD> {285 286  def NAME#"32ak" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.KOp, MxType32.KPat,287                                  CMD, MxEncAddrMode_k<"opd">>;288  def NAME#"32aq" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.QOp, MxType32.QPat,289                                  CMD, MxEncAddrMode_q<"opd">>;290  def NAME#"32af" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.FOp, MxType32.FPat,291                                  CMD, MxEncAddrMode_f<"opd">>;292  def NAME#"32ap" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.POp, MxType32.PPat,293                                  CMD, MxEncAddrMode_p<"opd">>;294  def NAME#"32aj" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.JOp, MxType32.JPat,295                                  CMD, MxEncAddrMode_j<"opd">>;296  def NAME#"32ab" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.BOp, MxType32.BPat,297                                  CMD, MxEncAddrMode_abs<"opd", true>>;298  def NAME#"32ai" : MxBiArOp_R_RI_xEA<MN, NODE, MxType32a, CMD>;299 300  def NAME#"32ar" : MxBiArOp_R_RR_xEA<MN, NODE, MxType32a, MxType32r, CMD>;301 302} // MxBiArOp_AF303 304// NOTE These naturally produce CCR305 306//===----------------------------------------------------------------------===//307// Add/Sub308//===----------------------------------------------------------------------===//309 310defm ADD : MxBiArOp_DF<"add",  MxAdd, 1, 0xD, 0x6>;311defm ADD : MxBiArOp_AF<"adda", MxAdd, 0xD>;312defm SUB : MxBiArOp_DF<"sub",  MxSub, 0, 0x9, 0x4>;313defm SUB : MxBiArOp_AF<"suba", MxSub, 0x9>;314 315// This pattern is used to enable the instruction selector to select ADD32ab316// for global values that are allocated in thread-local storage, i.e.:317//   t8: i32 = ISD::ADD GLOBAL_OFFSET_TABLE, TargetGlobalTLSAddress:i32<ptr @myvar>318//     ====>319//   t8: i32,i8 = ADD32ab GLOBAL_OFFSET_TABLE, TargetGlobalTLSAddress:i32<ptr @myvar>320def : Pat<(add MxARD32:$src, tglobaltlsaddr:$opd), (ADD32ab MxARD32:$src, MxAL32:$opd)>;321 322let Uses = [CCR], Defs = [CCR] in {323let Constraints = "$src = $dst" in {324 325/// Encoding for Extended forms326/// ------------------------------------------------------327///  F  E  D  C | B  A  9 | 8 | 7  6 | 5  4 | 3 | 2  1  0328/// ------------------------------------------------------329///  x  x  x  x |  REG Rx | 1 | SIZE | 0  0 | M |  REG Ry330/// ------------------------------------------------------331/// Rx - destination332/// Ry - source333/// M  - address mode switch334 335// $reg, ccr <- $reg op $reg op ccr336class MxBiArOp_R_RRX<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>337    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),338             MN#"."#TYPE.Prefix#"\t$opd, $dst",339             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))]> {340  let Inst = (descend CMD,341    // Destination register342    (operand "$dst", 3),343    0b1,344    // SIZE345    !cond(!eq(TYPE.Size, 8): 0b00,346          !eq(TYPE.Size, 16): 0b01,347          !eq(TYPE.Size, 32): 0b10),348    0b00, /*R/M*/0b0,349    // Source register350    (operand "$opd", 3)351  );352}353} // Constraints354} // Uses, Defs355 356multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {357 358let isCommutable = isComm in {359  foreach SZ = [8, 16, 32] in360  def NAME#SZ#"dd"  : MxBiArOp_R_RRX<MN, NODE, !cast<MxType>("MxType"#SZ#"d"), CMD>;361} // isComm362 363} // MxBiArOp_RFF364 365// NOTE These consume and produce CCR366defm ADDX : MxBiArOp_RFF<"addx", MxAddX, 1, 0xD>;367defm SUBX : MxBiArOp_RFF<"subx", MxSubX, 0, 0x9>;368 369 370//===----------------------------------------------------------------------===//371// And/Xor/Or372//===----------------------------------------------------------------------===//373 374defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;375defm OR  : MxBiArOp_DF<"or",  MxOr,  1, 0x8, 0x0>;376 377multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {378  foreach SZ = [8, 16, 32] in {379    let isCommutable = 1 in380    def NAME#SZ#"dd"  : MxBiArOp_R_RR_EAd<MN, NODE,381                                          !cast<MxType>("MxType"#SZ#"d"),382                                          CMD>;383 384    def NAME#SZ#"di"  : MxBiArOp_R_RI<MN, NODE,385                                      !cast<MxType>("MxType"#SZ#"d"),386                                      CMDI>;387  } // foreach SZ388} // MxBiArOp_DF_EAd389 390defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;391 392 393//===----------------------------------------------------------------------===//394// CMP395//===----------------------------------------------------------------------===//396 397let Defs = [CCR] in {398class MxCmp_RR<MxType LHS_TYPE, MxType RHS_TYPE = LHS_TYPE>399    : MxInst<(outs), (ins LHS_TYPE.ROp:$lhs, RHS_TYPE.ROp:$rhs),400             "cmp."#RHS_TYPE.Prefix#"\t$lhs, $rhs",401             [(set CCR, (MxCmp LHS_TYPE.VT:$lhs, RHS_TYPE.VT:$rhs))]> {402  let Inst = (descend 0b1011,403    // REGISTER404    (operand "$rhs", 3),405    // OPMODE406    !cast<MxOpModeEncoding>("MxOpMode"#RHS_TYPE.Size#"_"#RHS_TYPE.RLet#"_EA").Value,407    // MODE without last bit408    0b00,409    // REGISTER prefixed by D/A bit410    (operand "$lhs", 4)411  );412}413 414class MxCmp_RI<MxType TYPE>415    : MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg),416             "cmpi."#TYPE.Prefix#"\t$imm, $reg",417             [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))]> {418  let Inst = (ascend419    (descend 0b00001100,420             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,421             // The destination cannot be address register, so it's always422             // the MODE for data register direct mode.423             /*MODE*/0b000,424             /*REGISTER*/(operand "$reg", 3)),425    // Source (i.e. immediate value) encoding426    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement427  );428}429 430let mayLoad = 1 in {431 432class MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,433               MxEncMemOp MEM_ENC>434    : MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem),435             "cmpi."#TYPE.Prefix#"\t$imm, $mem",436             [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))]> {437  let Inst = (ascend438    (descend 0b00001100,439             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,440             MEM_ENC.EA),441    // Source (i.e. immediate value) encoding442    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,443    // Destination (i.e. memory operand) encoding444    MEM_ENC.Supplement445  );446}447 448// FIXME: What about abs.W?449class MxCmp_BI<MxType TYPE>450    : MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs),451             "cmpi."#TYPE.Prefix#"\t$imm, $abs",452             [(set CCR, (MxCmp TYPE.IPat:$imm,453                               (load (i32 (MxWrapper tglobaladdr:$abs)))))]> {454  defvar AbsEncoding = MxEncAddrMode_abs<"abs", true>;455  let Inst = (ascend456    (descend 0b00001100,457             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,458             AbsEncoding.EA),459    // Source (i.e. immediate value) encoding460    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,461    // Destination (i.e. memory operand) encoding462    AbsEncoding.Supplement463  );464}465 466class MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,467               MxEncMemOp MEM_ENC>468    : MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem),469             "cmp."#TYPE.Prefix#"\t$mem, $reg",470             [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))]> {471  let Inst = (ascend472    (descend 0b1011,473      // REGISTER474      (operand "$reg", 3),475      // OPMODE476      !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_d_EA").Value,477      MEM_ENC.EA),478    MEM_ENC.Supplement479  );480}481} // let mayLoad = 1482 483} // let Defs = [CCR]484 485multiclass MMxCmp_RM<MxType TYPE> {486  def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncAddrMode_k<"mem">>;487  def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncAddrMode_q<"mem">>;488  def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncAddrMode_p<"mem">>;489  def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncAddrMode_f<"mem">>;490  def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncAddrMode_j<"mem">>;491}492 493multiclass MMxCmp_MI<MxType TYPE> {494  def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat,495                                          MxEncAddrMode_k<"mem">>;496  def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat,497                                          MxEncAddrMode_q<"mem">>;498  def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat,499                                          MxEncAddrMode_p<"mem">>;500  def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat,501                                          MxEncAddrMode_f<"mem">>;502  def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat,503                                          MxEncAddrMode_j<"mem">>;504}505 506foreach S = [8, 16, 32] in {507  def CMP#S#di : MxCmp_RI<!cast<MxType>("MxType"#S#"d")>;508  def CMP#S#bi : MxCmp_BI<!cast<MxType>("MxType"#S#"d")>;509} // foreach510 511def CMP8dd : MxCmp_RR<MxType8d>;512foreach S = [16, 32] in {513  def CMP#S#dr : MxCmp_RR<!cast<MxType>("MxType"#S#"r"),514                          !cast<MxType>("MxType"#S#"d")>;515}516 517// cmp mem, Dn518defm CMP8d  : MMxCmp_RM<MxType8d>;519defm CMP16d : MMxCmp_RM<MxType16d>;520defm CMP32d : MMxCmp_RM<MxType32d>;521 522// cmp #imm, mem523defm CMP8  : MMxCmp_MI<MxType8d>;524defm CMP16 : MMxCmp_MI<MxType16d>;525defm CMP32 : MMxCmp_MI<MxType32d>;526 527 528//===----------------------------------------------------------------------===//529// EXT530//===----------------------------------------------------------------------===//531 532/// ---------------------------------------------------533///  F  E  D  C  B  A  9 | 8  7  6 | 5  4  3 | 2  1  0534/// ---------------------------------------------------535///  0  1  0  0  1  0  0 |  OPMODE | 0  0  0 |   REG536/// ---------------------------------------------------537let Defs = [CCR] in538let Constraints = "$src = $dst" in539class MxExt<MxType TO, MxType FROM>540    : MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src),541             "ext."#TO.Prefix#"\t$src", []> {542  let Inst = (descend 0b0100100,543    // OPMODE544    !cond(545      // byte -> word546      !and(!eq(FROM.Size, 8), !eq(TO.Size, 16)): 0b010,547      // word -> long548      !and(!eq(FROM.Size, 16), !eq(TO.Size, 32)): 0b011,549      // byte -> long550      !and(!eq(FROM.Size, 8), !eq(TO.Size, 32)): 0b111551    ),552    0b000,553    // REGISTER554    (operand "$src", 3)555  );556}557 558def EXT16 : MxExt<MxType16d, MxType8d>;559def EXT32 : MxExt<MxType32d, MxType16d>;560 561def : Pat<(sext_inreg i16:$src, i8),  (EXT16 $src)>;562def : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>;563def : Pat<(sext_inreg i32:$src, i8),564          (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;565 566 567//===----------------------------------------------------------------------===//568// DIV/MUL569//===----------------------------------------------------------------------===//570 571/// Word operation:572/// ----------------------------------------------------573///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0574/// ----------------------------------------------------575///             |         |         | EFFECTIVE ADDRESS576///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG577/// ----------------------------------------------------578let Defs = [CCR] in {579let Constraints = "$src = $dst" in {580// $dreg <- $dreg op $dreg581class MxDiMuOp_DD<string MN, bits<4> CMD, bit SIGNED = false,582                  MxOperand DST, MxOperand OPD>583    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {584  let Inst = (descend CMD,585    // REGISTER586    (operand "$dst", 3),587    !if(SIGNED, 0b111, 0b011),588    /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)589  );590}591 592// $dreg <- $dreg op $dreg593class MxDiMuOp_DD_Long<string MN, SDNode NODE, bits<10> CMD, bit SIGNED = false>594    : MxInst<(outs MxDRD32:$dst), (ins MxDRD32:$src, MxDRD32:$opd), MN#"\t$opd, $dst",595             [(set i32:$dst, CCR, (NODE i32:$src, i32:$opd))]> {596  let Inst = (ascend597    (descend CMD,598      /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)),599    (descend 0b0,600      // REGISTER601      (operand "$dst", 3),602      !if(SIGNED, 0b1, 0b0),603      /*SIZE*/0b0, 0b0000000,604      // Dr REGISTER605      0b000)606  );607}608 609// $reg <- $reg op $imm610class MxDiMuOp_DI<string MN, bits<4> CMD, bit SIGNED = false,611                  MxOperand DST, MxOperand OPD>612    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {613  // FIXME: Support immediates with different widths.614  defvar ImmEnc = MxEncAddrMode_i<"opd", 16>;615  let Inst = (ascend616    (descend CMD,617      // REGISTER618      (operand "$dst", 3),619      !if(SIGNED, 0b111, 0b011), ImmEnc.EA),620    ImmEnc.Supplement621  );622}623} // let Constraints624} // Defs = [CCR]625 626multiclass MxDiMuOp<string MN, bits<4> CMD> {627  def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, /*SIGNED*/true, MxDRD32, MxDRD16>;628  def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, /*SIGNED*/false, MxDRD32, MxDRD16>;629 630  def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, /*SIGNED*/true, MxDRD32, Mxi16imm>;631  def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, /*SIGNED*/false, MxDRD32, Mxi16imm>;632}633 634defm DIV : MxDiMuOp<"div", 0x8>;635 636def SDIVd32d32 : MxDiMuOp_DD_Long<"divs.l", sdiv, 0x131, /*SIGNED*/true>;637def UDIVd32d32 : MxDiMuOp_DD_Long<"divu.l", udiv, 0x131, /*SIGNED*/false>;638 639// This is used to cast immediates to 16-bits for operations which don't640// support smaller immediate sizes.641def as_i16imm : SDNodeXForm<imm, [{642  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);643}]>;644 645// RR i8646def : Pat<(sdiv i8:$dst, i8:$opd),647          (EXTRACT_SUBREG648            (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)),649             MxSubRegIndex8Lo)>;650 651def : Pat<(udiv i8:$dst, i8:$opd),652          (EXTRACT_SUBREG653            (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)),654             MxSubRegIndex8Lo)>;655 656def : Pat<(srem i8:$dst, i8:$opd),657          (EXTRACT_SUBREG658            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8),659             MxSubRegIndex8Lo)>;660 661def : Pat<(urem i8:$dst, i8:$opd),662          (EXTRACT_SUBREG663            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8),664             MxSubRegIndex8Lo)>;665 666// RR i16667def : Pat<(sdiv i16:$dst, i16:$opd),668          (EXTRACT_SUBREG669            (SDIVd32d16 (MOVSXd32d16 $dst), $opd),670             MxSubRegIndex16Lo)>;671 672def : Pat<(udiv i16:$dst, i16:$opd),673          (EXTRACT_SUBREG674            (UDIVd32d16 (MOVZXd32d16 $dst), $opd),675             MxSubRegIndex16Lo)>;676 677def : Pat<(srem i16:$dst, i16:$opd),678          (EXTRACT_SUBREG679            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8),680             MxSubRegIndex16Lo)>;681 682def : Pat<(urem i16:$dst, i16:$opd),683          (EXTRACT_SUBREG684            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8),685             MxSubRegIndex16Lo)>;686 687// RI i8688def : Pat<(sdiv i8:$dst, Mxi8immSExt8:$opd),689          (EXTRACT_SUBREG690            (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)),691             MxSubRegIndex8Lo)>;692 693def : Pat<(udiv i8:$dst, Mxi8immSExt8:$opd),694          (EXTRACT_SUBREG695            (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)),696             MxSubRegIndex8Lo)>;697 698def : Pat<(srem i8:$dst, Mxi8immSExt8:$opd),699          (EXTRACT_SUBREG700            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 8), 8),701             MxSubRegIndex8Lo)>;702 703def : Pat<(urem i8:$dst, Mxi8immSExt8:$opd),704          (EXTRACT_SUBREG705            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 8), 8),706             MxSubRegIndex8Lo)>;707 708// RI i16709def : Pat<(sdiv i16:$dst, Mxi16immSExt16:$opd),710          (EXTRACT_SUBREG711            (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),712             MxSubRegIndex16Lo)>;713 714def : Pat<(udiv i16:$dst, Mxi16immSExt16:$opd),715          (EXTRACT_SUBREG716            (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),717             MxSubRegIndex16Lo)>;718 719def : Pat<(srem i16:$dst, Mxi16immSExt16:$opd),720          (EXTRACT_SUBREG721            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8),722             MxSubRegIndex16Lo)>;723 724def : Pat<(urem i16:$dst, Mxi16immSExt16:$opd),725          (EXTRACT_SUBREG726            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8),727             MxSubRegIndex16Lo)>;728 729 730defm MUL : MxDiMuOp<"mul", 0xC>;731 732def SMULd32d32 : MxDiMuOp_DD_Long<"muls.l", MxSMul, 0x130, /*SIGNED*/true>;733def UMULd32d32 : MxDiMuOp_DD_Long<"mulu.l", MxUMul, 0x130, /*SIGNED*/false>;734 735// RR736def : Pat<(mul i16:$dst, i16:$opd),737          (EXTRACT_SUBREG738            (SMULd32d16 (MOVXd32d16 $dst), $opd),739             MxSubRegIndex16Lo)>;740 741def : Pat<(mulhs i16:$dst, i16:$opd),742          (EXTRACT_SUBREG743            (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),744             MxSubRegIndex16Lo)>;745 746def : Pat<(mulhu i16:$dst, i16:$opd),747          (EXTRACT_SUBREG748            (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),749             MxSubRegIndex16Lo)>;750 751def : Pat<(mul i32:$dst, i32:$opd), (SMULd32d32 $dst, $opd)>;752 753 754// RI755def : Pat<(mul i16:$dst, Mxi16immSExt16:$opd),756          (EXTRACT_SUBREG757            (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),758             MxSubRegIndex16Lo)>;759 760def : Pat<(mulhs i16:$dst, Mxi16immSExt16:$opd),761          (EXTRACT_SUBREG762            (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),763             MxSubRegIndex16Lo)>;764 765def : Pat<(mulhu i16:$dst, Mxi16immSExt16:$opd),766          (EXTRACT_SUBREG767            (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),768             MxSubRegIndex16Lo)>;769 770 771//===----------------------------------------------------------------------===//772// NEG/NEGX/NOT773//===----------------------------------------------------------------------===//774 775/// ------------+------------+------+---------+---------776///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0777/// ------------+------------+------+-------------------778///             |            |      | EFFECTIVE ADDRESS779///  0  1  0  0 | x  x  x  x | SIZE |   MODE  |   REG780/// ------------+------------+------+---------+---------781let Defs = [CCR] in {782let Constraints = "$src = $dst" in {783 784class MxNeg_D<MxType TYPE>785    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),786             "neg."#TYPE.Prefix#"\t$dst",787             [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))]> {788  let Inst = (descend 0b01000100,789    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,790    //MODE without last bit791    0b00,792    //REGISTER prefixed by D/A bit793    (operand "$dst", 4)794  );795}796 797let Uses = [CCR] in {798class MxNegX_D<MxType TYPE>799    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),800             "negx."#TYPE.Prefix#"\t$dst",801             [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))]> {802  let Inst = (descend 0b01000000,803    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,804    //MODE without last bit805    0b00,806    //REGISTER prefixed by D/A bit807    (operand "$dst", 4)808  );809}810}811 812class MxNot_D<MxType TYPE>813    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),814             "not."#TYPE.Prefix#"\t$dst",815             [(set TYPE.VT:$dst, (not TYPE.VT:$src))]> {816  let Inst = (descend 0b01000110,817    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,818    //MODE without last bit819    0b00,820    //REGISTER prefixed by D/A bit821    (operand "$dst", 4)822  );823}824 825} // let Constraints826} // let Defs = [CCR]827 828foreach S = [8, 16, 32] in {829  def NEG#S#d  : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;830  def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;831  def NOT#S#d  : MxNot_D<!cast<MxType>("MxType"#S#"d")>;832}833 834def : Pat<(MxSub 0, i8 :$src), (NEG8d  MxDRD8 :$src)>;835def : Pat<(MxSub 0, i16:$src), (NEG16d MxDRD16:$src)>;836def : Pat<(MxSub 0, i32:$src), (NEG32d MxDRD32:$src)>;837// SExt of i1 values.838// Although we specify `ZeroOrNegativeOneBooleanContent` for boolean content,839// we're still adding an AND here as we don't know the origin of the i1 value.840def : Pat<(sext_inreg i8:$src,  i1), (NEG8d  (AND8di  MxDRD8:$src,  1))>;841def : Pat<(sext_inreg i16:$src, i1), (NEG16d (AND16di MxDRD16:$src, 1))>;842def : Pat<(sext_inreg i32:$src, i1), (NEG32d (AND32di MxDRD32:$src, 1))>;843 844//===----------------------------------------------------------------------===//845// no-CCR Patterns846//===----------------------------------------------------------------------===//847 848/// Basically the reason for this stuff is that add and addc share the same849/// operand types constraints for whatever reasons and I had to define a common850/// MxAdd and MxSub instructions that produce CCR and then pattern-map add and addc851/// to it.852/// NOTE On the other hand I see no reason why I cannot just drop explicit CCR853/// result. Anyway works for now, hopefully I will better understand how this stuff854/// is designed later855foreach N = ["add", "addc"] in {856 857  // add reg, reg858  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),859            (ADD8dd  MxDRD8 :$src, MxDRD8 :$opd)>;860  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),861            (ADD16dr MxXRD16:$src, MxDRD16:$opd)>;862  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),863            (ADD32dr MxXRD32:$src, MxDRD32:$opd)>;864 865  // add (An), reg866  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),867            (ADD8dj MxDRD8:$src, MxType8.JOp:$opd)>;868  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),869            (ADD16dj MxDRD16:$src, MxType16.JOp:$opd)>;870  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),871            (ADD32dj MxDRD32:$src, MxType32.JOp:$opd)>;872 873  // add (i,An), reg874  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),875            (ADD8dp MxDRD8:$src, MxType8.POp:$opd)>;876  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),877            (ADD16dp MxDRD16:$src, MxType16.POp:$opd)>;878  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),879            (ADD32dp MxDRD32:$src, MxType32.POp:$opd)>;880 881  // add (i,An,Xn), reg882  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),883            (ADD8df MxDRD8:$src, MxType8.FOp:$opd)>;884  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),885            (ADD16df MxDRD16:$src, MxType16.FOp:$opd)>;886  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),887            (ADD32df MxDRD32:$src, MxType32.FOp:$opd)>;888 889  // add reg, imm890  def : Pat<(!cast<SDNode>(N) i8: $src, Mxi8immSExt8:$opd),891            (ADD8di  MxDRD8 :$src, imm:$opd)>;892  def : Pat<(!cast<SDNode>(N) i16:$src, Mxi16immSExt16:$opd),893            (ADD16di MxDRD16:$src, imm:$opd)>;894 895  // LEAp is more complex and thus will be selected over normal ADD32ri but it cannot896  // be used with data registers, here by adding complexity to a simple ADD32ri insts897  // we make sure it will be selected over LEAp898  let AddedComplexity = 15 in {899  def : Pat<(!cast<SDNode>(N) i32:$src, Mxi32immSExt32:$opd),900            (ADD32di MxDRD32:$src, imm:$opd)>;901  } // AddedComplexity = 15902 903  // add imm, (An)904  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),905                   MxType8.JPat:$dst),906            (ADD8ji MxType8.JOp:$dst, imm:$opd)>;907  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),908                   MxType16.JPat:$dst),909            (ADD16ji MxType16.JOp:$dst, imm:$opd)>;910  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),911                   MxType32.JPat:$dst),912            (ADD32ji MxType32.JOp:$dst, imm:$opd)>;913 914} // foreach add, addc915 916def : Pat<(adde i8 :$src, i8 :$opd), (ADDX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;917def : Pat<(adde i16:$src, i16:$opd), (ADDX16dd MxDRD16:$src, MxDRD16:$opd)>;918def : Pat<(adde i32:$src, i32:$opd), (ADDX32dd MxDRD32:$src, MxDRD32:$opd)>;919 920 921 922foreach N = ["sub", "subc"] in {923 924  // sub reg, reg925  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),926            (SUB8dd  MxDRD8 :$src, MxDRD8 :$opd)>;927  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),928            (SUB16dd MxDRD16:$src, MxDRD16:$opd)>;929  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),930            (SUB32dd MxDRD32:$src, MxDRD32:$opd)>;931 932 933  // sub (An), reg934  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),935            (SUB8dj MxDRD8:$src, MxType8.JOp:$opd)>;936  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),937            (SUB16dj MxDRD16:$src, MxType16.JOp:$opd)>;938  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),939            (SUB32dj MxDRD32:$src, MxType32.JOp:$opd)>;940 941  // sub (i,An), reg942  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),943            (SUB8dp MxDRD8:$src, MxType8.POp:$opd)>;944  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),945            (SUB16dp MxDRD16:$src, MxType16.POp:$opd)>;946  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),947            (SUB32dp MxDRD32:$src, MxType32.POp:$opd)>;948 949  // sub (i,An,Xn), reg950  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),951            (SUB8df MxDRD8:$src, MxType8.FOp:$opd)>;952  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),953            (SUB16df MxDRD16:$src, MxType16.FOp:$opd)>;954  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),955            (SUB32df MxDRD32:$src, MxType32.FOp:$opd)>;956 957  // sub reg, imm958  def : Pat<(!cast<SDNode>(N) i8 :$src, Mxi8immSExt8 :$opd),959            (SUB8di  MxDRD8 :$src, imm:$opd)>;960  def : Pat<(!cast<SDNode>(N) i16:$src, Mxi16immSExt16:$opd),961            (SUB16di MxDRD16:$src, imm:$opd)>;962  def : Pat<(!cast<SDNode>(N) i32:$src, Mxi32immSExt32:$opd),963            (SUB32di MxDRD32:$src, imm:$opd)>;964 965  // sub imm, (An)966  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),967                   MxType8.JPat:$dst),968            (SUB8ji MxType8.JOp:$dst, imm:$opd)>;969  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),970                   MxType16.JPat:$dst),971            (SUB16ji MxType16.JOp:$dst, imm:$opd)>;972  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),973                   MxType32.JPat:$dst),974            (SUB32ji MxType32.JOp:$dst, imm:$opd)>;975 976} // foreach sub, subx977 978def : Pat<(sube i8 :$src, i8 :$opd), (SUBX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;979def : Pat<(sube i16:$src, i16:$opd), (SUBX16dd MxDRD16:$src, MxDRD16:$opd)>;980def : Pat<(sube i32:$src, i32:$opd), (SUBX32dd MxDRD32:$src, MxDRD32:$opd)>;981 982multiclass BitwisePat<string INST, SDNode OP> {983  // op reg, reg984  def : Pat<(OP i8 :$src, i8 :$opd),985            (!cast<MxInst>(INST#"8dd")  MxDRD8 :$src, MxDRD8 :$opd)>;986  def : Pat<(OP i16:$src, i16:$opd),987            (!cast<MxInst>(INST#"16dd") MxDRD16:$src, MxDRD16:$opd)>;988  def : Pat<(OP i32:$src, i32:$opd),989            (!cast<MxInst>(INST#"32dd") MxDRD32:$src, MxDRD32:$opd)>;990  // op reg, imm991  def : Pat<(OP i8: $src, Mxi8immSExt8 :$opd),992            (!cast<MxInst>(INST#"8di")  MxDRD8 :$src, imm:$opd)>;993  def : Pat<(OP i16:$src, Mxi16immSExt16:$opd),994            (!cast<MxInst>(INST#"16di") MxDRD16:$src, imm:$opd)>;995  def : Pat<(OP i32:$src, Mxi32immSExt32:$opd),996            (!cast<MxInst>(INST#"32di") MxDRD32:$src, imm:$opd)>;997}998 999defm : BitwisePat<"AND", and>;1000defm : BitwisePat<"OR",  or>;1001defm : BitwisePat<"XOR", xor>;1002 1003//===----------------------------------------------------------------------===//1004// Floating point arithmetic instruction1005//===----------------------------------------------------------------------===//1006 1007let Defs = [FPS] in1008class MxFArithBase_FF<dag outs, dag ins, string asm, string rounding,1009                      list<dag> patterns>1010    : MxInst<outs, ins, asm, patterns> {1011  let Uses = !if(!eq(rounding, ""), [FPC], []);1012 1013  let Predicates = !if(!eq(rounding, ""), [AtLeastM68881], [AtLeastM68040]);1014}1015 1016class MxFPOpModeSelector<string rounding, bits<7> single, bits<7> double,1017                         bits<7> extended> {1018  bits<7> Mode = !cond(!eq(rounding, "s"): single,1019                       !eq(rounding, "d"): double,1020                       !eq(rounding, ""): extended);1021}1022 1023//===----------------------------------------------------------------------===//1024// Unary floating point instruction1025//===----------------------------------------------------------------------===//1026 1027class MxFUnary_FF<MxOpBundle Opnd, string rounding,1028                  string mnemonic, bits<7> opmode>1029    : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src),1030                    "f"#rounding#mnemonic#".x\t$src, $dst", rounding, [(null_frag)]> {1031  let Inst = (ascend1032  (descend 0b1111,1033    /*COPROCESSOR ID*/0b001,1034    0b000,1035    /*MODE+REGISTER*/0b000000),1036  (descend 0b0, /* R/M */ 0b0, 0b0,1037    /*SOURCE SPECIFIER*/1038    (operand "$src", 3),1039    /*DESTINATION*/1040    (operand "$dst", 3),1041    /*OPMODE*/1042    opmode)1043  );1044}1045 1046multiclass MxFUnaryOp<string mnemonic, bits<7> single, bits<7> double,1047                      bits<7> extended> {1048  foreach rounding = ["", "s", "d"] in {1049    defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;1050 1051    def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"1052      : MxFUnary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;1053  1054    let isCodeGenOnly = 1 in1055    foreach size = [32, 64] in1056      def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"1057        : MxFUnary_FF<!cast<MxOpBundle>("MxOp"#size#"AddrMode_fpr"),1058                      rounding, mnemonic, opmode>;1059  }1060}1061 1062defm FABS : MxFUnaryOp<"abs", 0b1011000, 0b1011100, 0b0011000>;1063defm FNEG : MxFUnaryOp<"neg", 0b1011010, 0b1011110, 0b0011010>;1064 1065//===----------------------------------------------------------------------===//1066// Binary floating point instruction1067//===----------------------------------------------------------------------===//1068 1069let Constraints = "$src = $dst" in1070class MxFBinary_FF<MxOpBundle Opnd, string rounding,1071                   string mnemonic, bits<7> opmode>1072    : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src, Opnd.Op:$opd),1073                      "f"#rounding#mnemonic#".x\t$opd, $dst", rounding, [(null_frag)]> {1074  let Inst = (ascend1075  (descend 0b1111,1076    /*COPROCESSOR ID*/0b001,1077    0b000,1078    /*MODE+REGISTER*/0b000000),1079  (descend 0b0, /* R/M */ 0b0, 0b0,1080    /*SOURCE SPECIFIER*/1081    (operand "$opd", 3),1082    /*DESTINATION*/1083    (operand "$dst", 3),1084    /*OPMODE*/1085    opmode)1086  );1087}1088 1089multiclass MxFBinaryOp<string mnemonic, bits<7> single, bits<7> double,1090                      bits<7> extended> {1091  foreach rounding = ["", "s", "d"] in {1092    defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;1093 1094    def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"1095      : MxFBinary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;1096 1097    let isCodeGenOnly = 1 in1098    foreach size = [32, 64] in1099      def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"1100        : MxFBinary_FF<!cast<MxOpBundle>("MxOp"#size#"AddrMode_fpr"),1101                        rounding, mnemonic, opmode>;1102  }1103}1104 1105defm FADD : MxFBinaryOp<"add", 0b1100010, 0b1100110, 0b0100010>;1106defm FSUB : MxFBinaryOp<"sub", 0b1101000, 0b1101100, 0b0101000>;1107defm FMUL : MxFBinaryOp<"mul", 0b1100011, 0b1100111, 0b0100011>;1108defm FDIV : MxFBinaryOp<"div", 0b1100000, 0b1100100, 0b0100000>;1109