xref: /llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td (revision 614a5780347ff0c8f82b8867660ea7fb4d9fdccb)
1bec7b166SMin-Yih Hsu//===-- M68kInstrArithmetic.td - Integer Arith Instrs ------*- tablegen -*-===//
2bec7b166SMin-Yih Hsu//
3bec7b166SMin-Yih Hsu// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bec7b166SMin-Yih Hsu// See https://llvm.org/LICENSE.txt for license information.
5bec7b166SMin-Yih Hsu// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bec7b166SMin-Yih Hsu//
7bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
8bec7b166SMin-Yih Hsu///
9bec7b166SMin-Yih Hsu/// \file
10bec7b166SMin-Yih Hsu/// This file describes the integer arithmetic instructions in the M68k
11bec7b166SMin-Yih Hsu/// architecture. Here is the current status of the file:
12bec7b166SMin-Yih Hsu///
13bec7b166SMin-Yih Hsu///  Machine:
14bec7b166SMin-Yih Hsu///
15bec7b166SMin-Yih Hsu///    ADD       [~]   ADDA      [~]   ADDI        [~]   ADDQ [ ]   ADDX [~]
16bec7b166SMin-Yih Hsu///    CLR       [ ]   CMP       [~]   CMPA        [~]   CMPI [~]   CMPM [ ]
17bec7b166SMin-Yih Hsu///    CMP2      [ ]   DIVS/DIVU [~]   DIVSL/DIVUL [ ]   EXT  [~]   EXTB [ ]
18*614a5780SPeter Lafreniere///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   NOT  [~]   SUB  [~]
19*614a5780SPeter Lafreniere///    SUBA      [~]   SUBI      [~]   SUBQ        [ ]   SUBX [~]
20bec7b166SMin-Yih Hsu///
21bec7b166SMin-Yih Hsu///  Map:
22bec7b166SMin-Yih Hsu///
23bec7b166SMin-Yih Hsu///   [ ] - was not touched at all
24bec7b166SMin-Yih Hsu///   [!] - requires extarnal stuff implemented
25bec7b166SMin-Yih Hsu///   [~] - functional implementation
26bec7b166SMin-Yih Hsu///   [X] - complete implementation
27bec7b166SMin-Yih Hsu///
28bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
29bec7b166SMin-Yih Hsu
30bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
3108f2b0dcSMin-Yih Hsu// OPMODE Encoding
3208f2b0dcSMin-Yih Hsu//===----------------------------------------------------------------------===//
3308f2b0dcSMin-Yih Hsuclass MxOpModeEncoding<bits<3> encoding> {
3408f2b0dcSMin-Yih Hsu  bits<3> Value = encoding;
3508f2b0dcSMin-Yih Hsu}
3608f2b0dcSMin-Yih Hsu
3708f2b0dcSMin-Yih Hsu// op EA, Dn
3808f2b0dcSMin-Yih Hsudef MxOpMode8_d_EA  : MxOpModeEncoding<0b000>;
3908f2b0dcSMin-Yih Hsudef MxOpMode16_d_EA : MxOpModeEncoding<0b001>;
4008f2b0dcSMin-Yih Hsudef MxOpMode32_d_EA : MxOpModeEncoding<0b010>;
4108f2b0dcSMin-Yih Hsu
4208f2b0dcSMin-Yih Hsu// op Dn, EA
4308f2b0dcSMin-Yih Hsudef MxOpMode8_EA_d  : MxOpModeEncoding<0b100>;
4408f2b0dcSMin-Yih Hsudef MxOpMode16_EA_d : MxOpModeEncoding<0b101>;
4508f2b0dcSMin-Yih Hsudef MxOpMode32_EA_d : MxOpModeEncoding<0b110>;
4608f2b0dcSMin-Yih Hsu
4708f2b0dcSMin-Yih Hsu// op EA, An
4808f2b0dcSMin-Yih Hsudef MxOpMode16_a_EA : MxOpModeEncoding<0b011>;
4908f2b0dcSMin-Yih Hsudef MxOpMode32_a_EA : MxOpModeEncoding<0b111>;
5008f2b0dcSMin-Yih Hsu
5108f2b0dcSMin-Yih Hsu
5208f2b0dcSMin-Yih Hsu//===----------------------------------------------------------------------===//
53bec7b166SMin-Yih Hsu// Encoding
54bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
55bec7b166SMin-Yih Hsu
5608f2b0dcSMin-Yih Hsulet Defs = [CCR] in {
5708f2b0dcSMin-Yih Hsulet Constraints = "$src = $dst" in {
5808f2b0dcSMin-Yih Hsu
59bec7b166SMin-Yih Hsu/// Encoding for Normal forms
60bec7b166SMin-Yih Hsu/// ----------------------------------------------------
61bec7b166SMin-Yih Hsu///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
62bec7b166SMin-Yih Hsu/// ----------------------------------------------------
63bec7b166SMin-Yih Hsu///             |         |         | EFFECTIVE ADDRESS
64bec7b166SMin-Yih Hsu///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
65bec7b166SMin-Yih Hsu/// ----------------------------------------------------
66bec7b166SMin-Yih Hsu
6708f2b0dcSMin-Yih Hsu// $reg, $ccr <- $reg op $reg
6808f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RR_xEA<string MN, SDNode NODE, MxType DST_TYPE, MxType SRC_TYPE,
6908f2b0dcSMin-Yih Hsu                        bits<4> CMD>
7008f2b0dcSMin-Yih Hsu    : MxInst<(outs DST_TYPE.ROp:$dst), (ins DST_TYPE.ROp:$src, SRC_TYPE.ROp:$opd),
7108f2b0dcSMin-Yih Hsu             MN#"."#DST_TYPE.Prefix#"\t$opd, $dst",
7208f2b0dcSMin-Yih Hsu             [(set DST_TYPE.VT:$dst, CCR, (NODE DST_TYPE.VT:$src, SRC_TYPE.VT:$opd))]> {
7308f2b0dcSMin-Yih Hsu  let Inst = (descend
7408f2b0dcSMin-Yih Hsu    CMD, (operand "$dst", 3),
7508f2b0dcSMin-Yih Hsu    !cast<MxOpModeEncoding>("MxOpMode"#DST_TYPE.Size#"_"#DST_TYPE.RLet#"_EA").Value,
76a5d618b3SSheng    !cond(
77a5d618b3SSheng      !eq(SRC_TYPE.RLet, "r") : (descend 0b00, (operand "$opd", 4)),
78a5d618b3SSheng      !eq(SRC_TYPE.RLet, "d") : (descend 0b000, (operand "$opd", 3))
79a5d618b3SSheng    )
8008f2b0dcSMin-Yih Hsu  );
8108f2b0dcSMin-Yih Hsu}
8208f2b0dcSMin-Yih Hsu
8308f2b0dcSMin-Yih Hsu/// This Op is similar to the one above except it uses reversed opmode, some
8408f2b0dcSMin-Yih Hsu/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for
8508f2b0dcSMin-Yih Hsu/// register only operations.
8608f2b0dcSMin-Yih Hsu/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)
8708f2b0dcSMin-Yih Hsu/// but some opcodes support address register and some do not which creates this
8808f2b0dcSMin-Yih Hsu/// mess.
8908f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
9008f2b0dcSMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
9108f2b0dcSMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst",
9208f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))]> {
9308f2b0dcSMin-Yih Hsu  let Inst = (descend
9408f2b0dcSMin-Yih Hsu    CMD, (operand "$opd", 3),
9508f2b0dcSMin-Yih Hsu    !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,
9608f2b0dcSMin-Yih Hsu    /*Destination can only be a data register*/
9708f2b0dcSMin-Yih Hsu    /*MODE*/0b000,
9808f2b0dcSMin-Yih Hsu    /*REGISTER*/(operand "$dst", 3));
9908f2b0dcSMin-Yih Hsu}
10008f2b0dcSMin-Yih Hsu
10108f2b0dcSMin-Yih Hsulet mayLoad = 1 in
10208f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,
10308f2b0dcSMin-Yih Hsu                    bits<4> CMD, MxEncMemOp SRC_ENC>
10408f2b0dcSMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),
10508f2b0dcSMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst",
10608f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))]> {
10708f2b0dcSMin-Yih Hsu  let Inst = (ascend
10808f2b0dcSMin-Yih Hsu    (descend CMD, (operand "$dst", 3),
10908f2b0dcSMin-Yih Hsu             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,
11008f2b0dcSMin-Yih Hsu             SRC_ENC.EA),
11108f2b0dcSMin-Yih Hsu    SRC_ENC.Supplement
11208f2b0dcSMin-Yih Hsu  );
11308f2b0dcSMin-Yih Hsu}
114bec7b166SMin-Yih Hsu
115bec7b166SMin-Yih Hsu/// Encoding for Immediate forms
116bec7b166SMin-Yih Hsu/// ---------------------------------------------------
117bec7b166SMin-Yih Hsu///  F  E  D  C  B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
118bec7b166SMin-Yih Hsu/// ---------------------------------------------------
119bec7b166SMin-Yih Hsu///                         |      | EFFECTIVE ADDRESS
120bec7b166SMin-Yih Hsu///  x  x  x  x  x  x  x  x | SIZE |   MODE  |   REG
121bec7b166SMin-Yih Hsu/// ---------------------------------------------------
122bec7b166SMin-Yih Hsu///     16-BIT WORD DATA    |     8-BIT BYTE DATA
123bec7b166SMin-Yih Hsu/// ---------------------------------------------------
124bec7b166SMin-Yih Hsu///                 32-BIT LONG DATA
125bec7b166SMin-Yih Hsu/// ---------------------------------------------------
126bec7b166SMin-Yih Hsu/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with
127bec7b166SMin-Yih Hsu/// normal version
128bec7b166SMin-Yih Hsu
129bec7b166SMin-Yih Hsu// $reg <- $reg op $imm
13008f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
131bec7b166SMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
132bec7b166SMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst",
13308f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {
13408f2b0dcSMin-Yih Hsu  let Inst = (ascend
13508f2b0dcSMin-Yih Hsu    (descend CMD, (operand "$dst", 3),
13608f2b0dcSMin-Yih Hsu             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,
13708f2b0dcSMin-Yih Hsu             MxEncAddrMode_i<"opd", TYPE.Size>.EA),
13808f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement
13908f2b0dcSMin-Yih Hsu  );
14008f2b0dcSMin-Yih Hsu}
141bec7b166SMin-Yih Hsu
142bec7b166SMin-Yih Hsu// Again, there are two ways to write an immediate to Dn register either dEA
1435fd28e4dSSheng// opmode or using *I encoding, and again some instructions also support address
144bec7b166SMin-Yih Hsu// registers some do not.
14508f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
146bec7b166SMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
147bec7b166SMin-Yih Hsu             MN#"i."#TYPE.Prefix#"\t$opd, $dst",
14808f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {
14908f2b0dcSMin-Yih Hsu  let Inst = (ascend
15008f2b0dcSMin-Yih Hsu    (descend 0b0000, CMD,
1511290d0ddSSheng             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
15208f2b0dcSMin-Yih Hsu             // The destination cannot be address register, so it's always
15308f2b0dcSMin-Yih Hsu             // the MODE for data register direct mode.
15408f2b0dcSMin-Yih Hsu             /*MODE*/0b000,
15508f2b0dcSMin-Yih Hsu             /*REGISTER*/(operand "$dst", 3)),
15608f2b0dcSMin-Yih Hsu    // Source (i.e. immediate value) encoding
15708f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement
15808f2b0dcSMin-Yih Hsu  );
15908f2b0dcSMin-Yih Hsu}
160bec7b166SMin-Yih Hsu} // Constraints
161bec7b166SMin-Yih Hsu
162bec7b166SMin-Yih Hsulet mayLoad = 1, mayStore = 1 in {
163bec7b166SMin-Yih Hsu
164bec7b166SMin-Yih Hsu// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for
165bec7b166SMin-Yih Hsu// MxAdd to survive the match and subsequent mismatch.
16608f2b0dcSMin-Yih Hsuclass MxBiArOp_MR<string MN, MxType TYPE,
16708f2b0dcSMin-Yih Hsu                  MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>
168bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd),
16908f2b0dcSMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {
17008f2b0dcSMin-Yih Hsu  let Inst = (ascend
17108f2b0dcSMin-Yih Hsu    (descend CMD, (operand "$opd", 3),
17208f2b0dcSMin-Yih Hsu             !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,
17308f2b0dcSMin-Yih Hsu             DST_ENC.EA),
17408f2b0dcSMin-Yih Hsu    DST_ENC.Supplement
17508f2b0dcSMin-Yih Hsu  );
17608f2b0dcSMin-Yih Hsu}
177bec7b166SMin-Yih Hsu
17808f2b0dcSMin-Yih Hsuclass MxBiArOp_MI<string MN, MxType TYPE,
17908f2b0dcSMin-Yih Hsu                  MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>
180bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd),
18108f2b0dcSMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {
18208f2b0dcSMin-Yih Hsu  let Inst = (ascend
18308f2b0dcSMin-Yih Hsu    (descend 0b0000, CMD,
1841290d0ddSSheng             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
18508f2b0dcSMin-Yih Hsu             DST_ENC.EA),
18608f2b0dcSMin-Yih Hsu    // Source (i.e. immediate value) encoding
18708f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"opd", TYPE.Size>.Supplement,
18808f2b0dcSMin-Yih Hsu    // Destination encoding
18908f2b0dcSMin-Yih Hsu    DST_ENC.Supplement
19008f2b0dcSMin-Yih Hsu  );
19108f2b0dcSMin-Yih Hsu}
192bec7b166SMin-Yih Hsu} // mayLoad, mayStore
193bec7b166SMin-Yih Hsu} // Defs = [CCR]
194bec7b166SMin-Yih Hsu
195bec7b166SMin-Yih Hsumulticlass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
196bec7b166SMin-Yih Hsu                       bits<4> CMD, bits<4> CMDI> {
197bec7b166SMin-Yih Hsu
19808f2b0dcSMin-Yih Hsu  foreach SZ = [8, 16, 32] in {
199bec7b166SMin-Yih Hsu    // op $mem, $reg
20008f2b0dcSMin-Yih Hsu    def NAME#SZ#"dk"  : MxBiArOp_R_RM<MN, NODE,
20108f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
20208f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).KOp,
20308f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).KPat,
20408f2b0dcSMin-Yih Hsu                                      CMD, MxEncAddrMode_k<"opd">>;
205bec7b166SMin-Yih Hsu
20608f2b0dcSMin-Yih Hsu    def NAME#SZ#"dq"  : MxBiArOp_R_RM<MN, NODE,
20708f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
20808f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).QOp,
20908f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).QPat,
21008f2b0dcSMin-Yih Hsu                                      CMD, MxEncAddrMode_q<"opd">>;
211bec7b166SMin-Yih Hsu
21208f2b0dcSMin-Yih Hsu    def NAME#SZ#"dp"  : MxBiArOp_R_RM<MN, NODE,
21308f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
21408f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).POp,
21508f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).PPat,
21608f2b0dcSMin-Yih Hsu                                      CMD, MxEncAddrMode_p<"opd">>;
217bec7b166SMin-Yih Hsu
21808f2b0dcSMin-Yih Hsu    def NAME#SZ#"df"  : MxBiArOp_R_RM<MN, NODE,
21908f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
22008f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).FOp,
22108f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).FPat,
22208f2b0dcSMin-Yih Hsu                                      CMD, MxEncAddrMode_f<"opd">>;
223bec7b166SMin-Yih Hsu
22408f2b0dcSMin-Yih Hsu    def NAME#SZ#"dj"  : MxBiArOp_R_RM<MN, NODE,
22508f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
22608f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).JOp,
22708f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ).JPat,
22808f2b0dcSMin-Yih Hsu                                      CMD, MxEncAddrMode_j<"opd">>;
229bec7b166SMin-Yih Hsu    // op $imm, $reg
23008f2b0dcSMin-Yih Hsu    def NAME#SZ#"di"  : MxBiArOp_R_RI_xEA<MN, NODE,
23108f2b0dcSMin-Yih Hsu                                          !cast<MxType>("MxType"#SZ#"d"),
23208f2b0dcSMin-Yih Hsu                                          CMD>;
233bec7b166SMin-Yih Hsu    // op $reg, $mem
23408f2b0dcSMin-Yih Hsu    def NAME#SZ#"pd"  : MxBiArOp_MR<MN,
23508f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ#"d"),
23608f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).POp,
23708f2b0dcSMin-Yih Hsu                                    CMD, MxEncAddrMode_p<"dst">>;
238bec7b166SMin-Yih Hsu
23908f2b0dcSMin-Yih Hsu    def NAME#SZ#"fd"  : MxBiArOp_MR<MN,
24008f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ#"d"),
24108f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).FOp,
24208f2b0dcSMin-Yih Hsu                                    CMD, MxEncAddrMode_f<"dst">>;
243bec7b166SMin-Yih Hsu
24408f2b0dcSMin-Yih Hsu    def NAME#SZ#"jd"  : MxBiArOp_MR<MN,
24508f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ#"d"),
24608f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).JOp,
24708f2b0dcSMin-Yih Hsu                                    CMD, MxEncAddrMode_j<"dst">>;
248bec7b166SMin-Yih Hsu    // op $imm, $mem
24908f2b0dcSMin-Yih Hsu    def NAME#SZ#"pi"  : MxBiArOp_MI<MN,
25008f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ),
25108f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).POp,
25208f2b0dcSMin-Yih Hsu                                    CMDI, MxEncAddrMode_p<"dst">>;
253bec7b166SMin-Yih Hsu
25408f2b0dcSMin-Yih Hsu    def NAME#SZ#"fi"  : MxBiArOp_MI<MN,
25508f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ),
25608f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).FOp,
25708f2b0dcSMin-Yih Hsu                                    CMDI, MxEncAddrMode_f<"dst">>;
258bec7b166SMin-Yih Hsu
25908f2b0dcSMin-Yih Hsu    def NAME#SZ#"ji"  : MxBiArOp_MI<MN,
26008f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ),
26108f2b0dcSMin-Yih Hsu                                    !cast<MxType>("MxType"#SZ).JOp,
26208f2b0dcSMin-Yih Hsu                                    CMDI, MxEncAddrMode_j<"dst">>;
26308f2b0dcSMin-Yih Hsu    // op $reg, $reg
26408f2b0dcSMin-Yih Hsu    let isCommutable = isComm in
26508f2b0dcSMin-Yih Hsu    def NAME#SZ#"dd" : MxBiArOp_R_RR_xEA<MN, NODE,
26608f2b0dcSMin-Yih Hsu                                         !cast<MxType>("MxType"#SZ#"d"),
26708f2b0dcSMin-Yih Hsu                                         !cast<MxType>("MxType"#SZ#"d"),
26808f2b0dcSMin-Yih Hsu                                         CMD>;
26908f2b0dcSMin-Yih Hsu  } // foreach SZ
270bec7b166SMin-Yih Hsu
27108f2b0dcSMin-Yih Hsu  foreach SZ = [16, 32] in
27208f2b0dcSMin-Yih Hsu  def NAME#SZ#"dr" : MxBiArOp_R_RR_xEA<MN, NODE,
27308f2b0dcSMin-Yih Hsu                                       !cast<MxType>("MxType"#SZ#"d"),
27408f2b0dcSMin-Yih Hsu                                       !cast<MxType>("MxType"#SZ#"r"),
27508f2b0dcSMin-Yih Hsu                                       CMD>;
276bec7b166SMin-Yih Hsu
277bec7b166SMin-Yih Hsu} // MxBiArOp_DF
278bec7b166SMin-Yih Hsu
279bec7b166SMin-Yih Hsu
280bec7b166SMin-Yih Hsu// These special snowflakes allowed to match address registers but since *A
281bec7b166SMin-Yih Hsu// operations do not produce CCR we should not match them against Mx nodes that
282bec7b166SMin-Yih Hsu// produce it.
283bec7b166SMin-Yih Hsulet Pattern = [(null_frag)] in
284c64ffa22SJim Linmulticlass MxBiArOp_AF<string MN, SDNode NODE, bits<4> CMD> {
285bec7b166SMin-Yih Hsu
28608f2b0dcSMin-Yih Hsu  def NAME#"32ak" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.KOp, MxType32.KPat,
28708f2b0dcSMin-Yih Hsu                                  CMD, MxEncAddrMode_k<"opd">>;
28808f2b0dcSMin-Yih Hsu  def NAME#"32aq" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.QOp, MxType32.QPat,
28908f2b0dcSMin-Yih Hsu                                  CMD, MxEncAddrMode_q<"opd">>;
29008f2b0dcSMin-Yih Hsu  def NAME#"32af" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.FOp, MxType32.FPat,
29108f2b0dcSMin-Yih Hsu                                  CMD, MxEncAddrMode_f<"opd">>;
29208f2b0dcSMin-Yih Hsu  def NAME#"32ap" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.POp, MxType32.PPat,
29308f2b0dcSMin-Yih Hsu                                  CMD, MxEncAddrMode_p<"opd">>;
29408f2b0dcSMin-Yih Hsu  def NAME#"32aj" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.JOp, MxType32.JPat,
29508f2b0dcSMin-Yih Hsu                                  CMD, MxEncAddrMode_j<"opd">>;
29640d89de4SSheng  def NAME#"32ab" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.BOp, MxType32.BPat,
29740d89de4SSheng                                  CMD, MxEncAddrMode_abs<"opd", true>>;
29808f2b0dcSMin-Yih Hsu  def NAME#"32ai" : MxBiArOp_R_RI_xEA<MN, NODE, MxType32a, CMD>;
299bec7b166SMin-Yih Hsu
30008f2b0dcSMin-Yih Hsu  def NAME#"32ar" : MxBiArOp_R_RR_xEA<MN, NODE, MxType32a, MxType32r, CMD>;
301bec7b166SMin-Yih Hsu
302bec7b166SMin-Yih Hsu} // MxBiArOp_AF
303bec7b166SMin-Yih Hsu
304bec7b166SMin-Yih Hsu// NOTE These naturally produce CCR
305bec7b166SMin-Yih Hsu
30608f2b0dcSMin-Yih Hsu//===----------------------------------------------------------------------===//
30708f2b0dcSMin-Yih Hsu// Add/Sub
30808f2b0dcSMin-Yih Hsu//===----------------------------------------------------------------------===//
30908f2b0dcSMin-Yih Hsu
310bec7b166SMin-Yih Hsudefm ADD : MxBiArOp_DF<"add",  MxAdd, 1, 0xD, 0x6>;
311c64ffa22SJim Lindefm ADD : MxBiArOp_AF<"adda", MxAdd, 0xD>;
312bec7b166SMin-Yih Hsudefm SUB : MxBiArOp_DF<"sub",  MxSub, 0, 0x9, 0x4>;
313c64ffa22SJim Lindefm SUB : MxBiArOp_AF<"suba", MxSub, 0x9>;
314bec7b166SMin-Yih Hsu
3154c2ec08eSSheng// This pattern is used to enable the instruction selector to select ADD32ab
3164c2ec08eSSheng// for global values that are allocated in thread-local storage, i.e.:
3174c2ec08eSSheng//   t8: i32 = ISD::ADD GLOBAL_OFFSET_TABLE, TargetGlobalTLSAddress:i32<ptr @myvar>
3184c2ec08eSSheng//     ====>
3194c2ec08eSSheng//   t8: i32,i8 = ADD32ab GLOBAL_OFFSET_TABLE, TargetGlobalTLSAddress:i32<ptr @myvar>
3204c2ec08eSShengdef : Pat<(add MxARD32:$src, tglobaltlsaddr:$opd), (ADD32ab MxARD32:$src, MxAL32:$opd)>;
321bec7b166SMin-Yih Hsu
322bec7b166SMin-Yih Hsulet Uses = [CCR], Defs = [CCR] in {
323bec7b166SMin-Yih Hsulet Constraints = "$src = $dst" in {
324bec7b166SMin-Yih Hsu
32508f2b0dcSMin-Yih Hsu/// Encoding for Extended forms
32608f2b0dcSMin-Yih Hsu/// ------------------------------------------------------
32708f2b0dcSMin-Yih Hsu///  F  E  D  C | B  A  9 | 8 | 7  6 | 5  4 | 3 | 2  1  0
32808f2b0dcSMin-Yih Hsu/// ------------------------------------------------------
32908f2b0dcSMin-Yih Hsu///  x  x  x  x |  REG Rx | 1 | SIZE | 0  0 | M |  REG Ry
33008f2b0dcSMin-Yih Hsu/// ------------------------------------------------------
33108f2b0dcSMin-Yih Hsu/// Rx - destination
33208f2b0dcSMin-Yih Hsu/// Ry - source
33308f2b0dcSMin-Yih Hsu/// M  - address mode switch
33408f2b0dcSMin-Yih Hsu
335bec7b166SMin-Yih Hsu// $reg, ccr <- $reg op $reg op ccr
33608f2b0dcSMin-Yih Hsuclass MxBiArOp_R_RRX<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
337bec7b166SMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
338bec7b166SMin-Yih Hsu             MN#"."#TYPE.Prefix#"\t$opd, $dst",
33908f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))]> {
34008f2b0dcSMin-Yih Hsu  let Inst = (descend CMD,
34108f2b0dcSMin-Yih Hsu    // Destination register
34208f2b0dcSMin-Yih Hsu    (operand "$dst", 3),
34308f2b0dcSMin-Yih Hsu    0b1,
34408f2b0dcSMin-Yih Hsu    // SIZE
34508f2b0dcSMin-Yih Hsu    !cond(!eq(TYPE.Size, 8): 0b00,
34608f2b0dcSMin-Yih Hsu          !eq(TYPE.Size, 16): 0b01,
34708f2b0dcSMin-Yih Hsu          !eq(TYPE.Size, 32): 0b10),
34808f2b0dcSMin-Yih Hsu    0b00, /*R/M*/0b0,
34908f2b0dcSMin-Yih Hsu    // Source register
35008f2b0dcSMin-Yih Hsu    (operand "$opd", 3)
35108f2b0dcSMin-Yih Hsu  );
35208f2b0dcSMin-Yih Hsu}
353bec7b166SMin-Yih Hsu} // Constraints
354bec7b166SMin-Yih Hsu} // Uses, Defs
355bec7b166SMin-Yih Hsu
356bec7b166SMin-Yih Hsumulticlass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {
357bec7b166SMin-Yih Hsu
358bec7b166SMin-Yih Hsulet isCommutable = isComm in {
35908f2b0dcSMin-Yih Hsu  foreach SZ = [8, 16, 32] in
36008f2b0dcSMin-Yih Hsu  def NAME#SZ#"dd"  : MxBiArOp_R_RRX<MN, NODE, !cast<MxType>("MxType"#SZ#"d"), CMD>;
361bec7b166SMin-Yih Hsu} // isComm
362bec7b166SMin-Yih Hsu
363bec7b166SMin-Yih Hsu} // MxBiArOp_RFF
364bec7b166SMin-Yih Hsu
365bec7b166SMin-Yih Hsu// NOTE These consume and produce CCR
366bec7b166SMin-Yih Hsudefm ADDX : MxBiArOp_RFF<"addx", MxAddX, 1, 0xD>;
367bec7b166SMin-Yih Hsudefm SUBX : MxBiArOp_RFF<"subx", MxSubX, 0, 0x9>;
368bec7b166SMin-Yih Hsu
369bec7b166SMin-Yih Hsu
370bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
371bec7b166SMin-Yih Hsu// And/Xor/Or
372bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
373bec7b166SMin-Yih Hsu
374bec7b166SMin-Yih Hsudefm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;
375bec7b166SMin-Yih Hsudefm OR  : MxBiArOp_DF<"or",  MxOr,  1, 0x8, 0x0>;
376bec7b166SMin-Yih Hsu
377bec7b166SMin-Yih Hsumulticlass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {
37808f2b0dcSMin-Yih Hsu  foreach SZ = [8, 16, 32] in {
37908f2b0dcSMin-Yih Hsu    let isCommutable = 1 in
38008f2b0dcSMin-Yih Hsu    def NAME#SZ#"dd"  : MxBiArOp_R_RR_EAd<MN, NODE,
38108f2b0dcSMin-Yih Hsu                                          !cast<MxType>("MxType"#SZ#"d"),
38208f2b0dcSMin-Yih Hsu                                          CMD>;
383bec7b166SMin-Yih Hsu
38408f2b0dcSMin-Yih Hsu    def NAME#SZ#"di"  : MxBiArOp_R_RI<MN, NODE,
38508f2b0dcSMin-Yih Hsu                                      !cast<MxType>("MxType"#SZ#"d"),
38608f2b0dcSMin-Yih Hsu                                      CMDI>;
38708f2b0dcSMin-Yih Hsu  } // foreach SZ
388bec7b166SMin-Yih Hsu} // MxBiArOp_DF_EAd
389bec7b166SMin-Yih Hsu
390bec7b166SMin-Yih Hsudefm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
391bec7b166SMin-Yih Hsu
392bec7b166SMin-Yih Hsu
393bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
394bec7b166SMin-Yih Hsu// CMP
395bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
396bec7b166SMin-Yih Hsu
397bec7b166SMin-Yih Hsulet Defs = [CCR] in {
39808f2b0dcSMin-Yih Hsuclass MxCmp_RR<MxType LHS_TYPE, MxType RHS_TYPE = LHS_TYPE>
399657bb726SMin-Yih Hsu    : MxInst<(outs), (ins LHS_TYPE.ROp:$lhs, RHS_TYPE.ROp:$rhs),
400657bb726SMin-Yih Hsu             "cmp."#RHS_TYPE.Prefix#"\t$lhs, $rhs",
40108f2b0dcSMin-Yih Hsu             [(set CCR, (MxCmp LHS_TYPE.VT:$lhs, RHS_TYPE.VT:$rhs))]> {
40208f2b0dcSMin-Yih Hsu  let Inst = (descend 0b1011,
40308f2b0dcSMin-Yih Hsu    // REGISTER
40408f2b0dcSMin-Yih Hsu    (operand "$rhs", 3),
40508f2b0dcSMin-Yih Hsu    // OPMODE
40608f2b0dcSMin-Yih Hsu    !cast<MxOpModeEncoding>("MxOpMode"#RHS_TYPE.Size#"_"#RHS_TYPE.RLet#"_EA").Value,
40708f2b0dcSMin-Yih Hsu    // MODE without last bit
40808f2b0dcSMin-Yih Hsu    0b00,
40908f2b0dcSMin-Yih Hsu    // REGISTER prefixed by D/A bit
41008f2b0dcSMin-Yih Hsu    (operand "$lhs", 4)
41108f2b0dcSMin-Yih Hsu  );
41208f2b0dcSMin-Yih Hsu}
413bec7b166SMin-Yih Hsu
414bec7b166SMin-Yih Hsuclass MxCmp_RI<MxType TYPE>
415bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg),
416bec7b166SMin-Yih Hsu             "cmpi."#TYPE.Prefix#"\t$imm, $reg",
41708f2b0dcSMin-Yih Hsu             [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))]> {
41808f2b0dcSMin-Yih Hsu  let Inst = (ascend
41908f2b0dcSMin-Yih Hsu    (descend 0b00001100,
4201290d0ddSSheng             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
42108f2b0dcSMin-Yih Hsu             // The destination cannot be address register, so it's always
42208f2b0dcSMin-Yih Hsu             // the MODE for data register direct mode.
42308f2b0dcSMin-Yih Hsu             /*MODE*/0b000,
42408f2b0dcSMin-Yih Hsu             /*REGISTER*/(operand "$reg", 3)),
42508f2b0dcSMin-Yih Hsu    // Source (i.e. immediate value) encoding
42608f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement
42708f2b0dcSMin-Yih Hsu  );
42808f2b0dcSMin-Yih Hsu}
429bec7b166SMin-Yih Hsu
430bec7b166SMin-Yih Hsulet mayLoad = 1 in {
431bec7b166SMin-Yih Hsu
432bec7b166SMin-Yih Hsuclass MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
43308f2b0dcSMin-Yih Hsu               MxEncMemOp MEM_ENC>
434bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem),
435bec7b166SMin-Yih Hsu             "cmpi."#TYPE.Prefix#"\t$imm, $mem",
43608f2b0dcSMin-Yih Hsu             [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))]> {
43708f2b0dcSMin-Yih Hsu  let Inst = (ascend
43808f2b0dcSMin-Yih Hsu    (descend 0b00001100,
4391290d0ddSSheng             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
44008f2b0dcSMin-Yih Hsu             MEM_ENC.EA),
44108f2b0dcSMin-Yih Hsu    // Source (i.e. immediate value) encoding
44208f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,
44308f2b0dcSMin-Yih Hsu    // Destination (i.e. memory operand) encoding
44408f2b0dcSMin-Yih Hsu    MEM_ENC.Supplement
44508f2b0dcSMin-Yih Hsu  );
44608f2b0dcSMin-Yih Hsu}
447bec7b166SMin-Yih Hsu
44808f2b0dcSMin-Yih Hsu// FIXME: What about abs.W?
449bec7b166SMin-Yih Hsuclass MxCmp_BI<MxType TYPE>
450bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs),
451bec7b166SMin-Yih Hsu             "cmpi."#TYPE.Prefix#"\t$imm, $abs",
452bec7b166SMin-Yih Hsu             [(set CCR, (MxCmp TYPE.IPat:$imm,
45308f2b0dcSMin-Yih Hsu                               (load (i32 (MxWrapper tglobaladdr:$abs)))))]> {
45408f2b0dcSMin-Yih Hsu  defvar AbsEncoding = MxEncAddrMode_abs<"abs", true>;
45508f2b0dcSMin-Yih Hsu  let Inst = (ascend
45608f2b0dcSMin-Yih Hsu    (descend 0b00001100,
4571290d0ddSSheng             !cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
45808f2b0dcSMin-Yih Hsu             AbsEncoding.EA),
45908f2b0dcSMin-Yih Hsu    // Source (i.e. immediate value) encoding
46008f2b0dcSMin-Yih Hsu    MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,
46108f2b0dcSMin-Yih Hsu    // Destination (i.e. memory operand) encoding
46208f2b0dcSMin-Yih Hsu    AbsEncoding.Supplement
46308f2b0dcSMin-Yih Hsu  );
46408f2b0dcSMin-Yih Hsu}
465bec7b166SMin-Yih Hsu
466bec7b166SMin-Yih Hsuclass MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
46708f2b0dcSMin-Yih Hsu               MxEncMemOp MEM_ENC>
468bec7b166SMin-Yih Hsu    : MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem),
469bec7b166SMin-Yih Hsu             "cmp."#TYPE.Prefix#"\t$mem, $reg",
47008f2b0dcSMin-Yih Hsu             [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))]> {
47108f2b0dcSMin-Yih Hsu  let Inst = (ascend
47208f2b0dcSMin-Yih Hsu    (descend 0b1011,
47308f2b0dcSMin-Yih Hsu      // REGISTER
47408f2b0dcSMin-Yih Hsu      (operand "$reg", 3),
47508f2b0dcSMin-Yih Hsu      // OPMODE
47608f2b0dcSMin-Yih Hsu      !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_d_EA").Value,
47708f2b0dcSMin-Yih Hsu      MEM_ENC.EA),
47808f2b0dcSMin-Yih Hsu    MEM_ENC.Supplement
47908f2b0dcSMin-Yih Hsu  );
48008f2b0dcSMin-Yih Hsu}
481bec7b166SMin-Yih Hsu} // let mayLoad = 1
482bec7b166SMin-Yih Hsu
483bec7b166SMin-Yih Hsu} // let Defs = [CCR]
484bec7b166SMin-Yih Hsu
485bec7b166SMin-Yih Hsumulticlass MMxCmp_RM<MxType TYPE> {
48608f2b0dcSMin-Yih Hsu  def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncAddrMode_k<"mem">>;
48708f2b0dcSMin-Yih Hsu  def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncAddrMode_q<"mem">>;
48808f2b0dcSMin-Yih Hsu  def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncAddrMode_p<"mem">>;
48908f2b0dcSMin-Yih Hsu  def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncAddrMode_f<"mem">>;
49008f2b0dcSMin-Yih Hsu  def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncAddrMode_j<"mem">>;
491bec7b166SMin-Yih Hsu}
492bec7b166SMin-Yih Hsu
493bec7b166SMin-Yih Hsumulticlass MMxCmp_MI<MxType TYPE> {
49408f2b0dcSMin-Yih Hsu  def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat,
49508f2b0dcSMin-Yih Hsu                                          MxEncAddrMode_k<"mem">>;
49608f2b0dcSMin-Yih Hsu  def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat,
49708f2b0dcSMin-Yih Hsu                                          MxEncAddrMode_q<"mem">>;
49808f2b0dcSMin-Yih Hsu  def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat,
49908f2b0dcSMin-Yih Hsu                                          MxEncAddrMode_p<"mem">>;
50008f2b0dcSMin-Yih Hsu  def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat,
50108f2b0dcSMin-Yih Hsu                                          MxEncAddrMode_f<"mem">>;
50208f2b0dcSMin-Yih Hsu  def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat,
50308f2b0dcSMin-Yih Hsu                                          MxEncAddrMode_j<"mem">>;
504bec7b166SMin-Yih Hsu}
505bec7b166SMin-Yih Hsu
506bec7b166SMin-Yih Hsuforeach S = [8, 16, 32] in {
507bec7b166SMin-Yih Hsu  def CMP#S#di : MxCmp_RI<!cast<MxType>("MxType"#S#"d")>;
508bec7b166SMin-Yih Hsu  def CMP#S#bi : MxCmp_BI<!cast<MxType>("MxType"#S#"d")>;
509bec7b166SMin-Yih Hsu} // foreach
510bec7b166SMin-Yih Hsu
511657bb726SMin-Yih Hsudef CMP8dd : MxCmp_RR<MxType8d>;
512657bb726SMin-Yih Hsuforeach S = [16, 32] in {
513657bb726SMin-Yih Hsu  def CMP#S#dr : MxCmp_RR<!cast<MxType>("MxType"#S#"r"),
514657bb726SMin-Yih Hsu                          !cast<MxType>("MxType"#S#"d")>;
515657bb726SMin-Yih Hsu}
516657bb726SMin-Yih Hsu
517bec7b166SMin-Yih Hsu// cmp mem, Dn
518bec7b166SMin-Yih Hsudefm CMP8d  : MMxCmp_RM<MxType8d>;
519bec7b166SMin-Yih Hsudefm CMP16d : MMxCmp_RM<MxType16d>;
520bec7b166SMin-Yih Hsudefm CMP32d : MMxCmp_RM<MxType32d>;
521bec7b166SMin-Yih Hsu
522bec7b166SMin-Yih Hsu// cmp #imm, mem
523bec7b166SMin-Yih Hsudefm CMP8  : MMxCmp_MI<MxType8d>;
524bec7b166SMin-Yih Hsudefm CMP16 : MMxCmp_MI<MxType16d>;
525bec7b166SMin-Yih Hsudefm CMP32 : MMxCmp_MI<MxType32d>;
526bec7b166SMin-Yih Hsu
527bec7b166SMin-Yih Hsu
528bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
529bec7b166SMin-Yih Hsu// EXT
530bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
531bec7b166SMin-Yih Hsu
532bec7b166SMin-Yih Hsu/// ---------------------------------------------------
533bec7b166SMin-Yih Hsu///  F  E  D  C  B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
534bec7b166SMin-Yih Hsu/// ---------------------------------------------------
535bec7b166SMin-Yih Hsu///  0  1  0  0  1  0  0 |  OPMODE | 0  0  0 |   REG
536bec7b166SMin-Yih Hsu/// ---------------------------------------------------
537bec7b166SMin-Yih Hsulet Defs = [CCR] in
538bec7b166SMin-Yih Hsulet Constraints = "$src = $dst" in
539bec7b166SMin-Yih Hsuclass MxExt<MxType TO, MxType FROM>
540bec7b166SMin-Yih Hsu    : MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src),
54108f2b0dcSMin-Yih Hsu             "ext."#TO.Prefix#"\t$src", []> {
54208f2b0dcSMin-Yih Hsu  let Inst = (descend 0b0100100,
54308f2b0dcSMin-Yih Hsu    // OPMODE
54408f2b0dcSMin-Yih Hsu    !cond(
54508f2b0dcSMin-Yih Hsu      // byte -> word
54608f2b0dcSMin-Yih Hsu      !and(!eq(FROM.Size, 8), !eq(TO.Size, 16)): 0b010,
54708f2b0dcSMin-Yih Hsu      // word -> long
54808f2b0dcSMin-Yih Hsu      !and(!eq(FROM.Size, 16), !eq(TO.Size, 32)): 0b011,
54908f2b0dcSMin-Yih Hsu      // byte -> long
55008f2b0dcSMin-Yih Hsu      !and(!eq(FROM.Size, 8), !eq(TO.Size, 32)): 0b111
55108f2b0dcSMin-Yih Hsu    ),
55208f2b0dcSMin-Yih Hsu    0b000,
55308f2b0dcSMin-Yih Hsu    // REGISTER
55408f2b0dcSMin-Yih Hsu    (operand "$src", 3)
55508f2b0dcSMin-Yih Hsu  );
55608f2b0dcSMin-Yih Hsu}
557bec7b166SMin-Yih Hsu
558bec7b166SMin-Yih Hsudef EXT16 : MxExt<MxType16d, MxType8d>;
559bec7b166SMin-Yih Hsudef EXT32 : MxExt<MxType32d, MxType16d>;
560bec7b166SMin-Yih Hsu
561bec7b166SMin-Yih Hsudef : Pat<(sext_inreg i16:$src, i8),  (EXT16 $src)>;
562bec7b166SMin-Yih Hsudef : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>;
563bec7b166SMin-Yih Hsudef : Pat<(sext_inreg i32:$src, i8),
564bec7b166SMin-Yih Hsu          (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;
565bec7b166SMin-Yih Hsu
566bec7b166SMin-Yih Hsu
567bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
568bec7b166SMin-Yih Hsu// DIV/MUL
569bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
570bec7b166SMin-Yih Hsu
571bec7b166SMin-Yih Hsu/// Word operation:
572bec7b166SMin-Yih Hsu/// ----------------------------------------------------
573bec7b166SMin-Yih Hsu///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
574bec7b166SMin-Yih Hsu/// ----------------------------------------------------
575bec7b166SMin-Yih Hsu///             |         |         | EFFECTIVE ADDRESS
576bec7b166SMin-Yih Hsu///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
577bec7b166SMin-Yih Hsu/// ----------------------------------------------------
578bec7b166SMin-Yih Hsulet Defs = [CCR] in {
579bec7b166SMin-Yih Hsulet Constraints = "$src = $dst" in {
58008f2b0dcSMin-Yih Hsu// $dreg <- $dreg op $dreg
58108f2b0dcSMin-Yih Hsuclass MxDiMuOp_DD<string MN, bits<4> CMD, bit SIGNED = false,
582bec7b166SMin-Yih Hsu                  MxOperand DST, MxOperand OPD>
58308f2b0dcSMin-Yih Hsu    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {
58408f2b0dcSMin-Yih Hsu  let Inst = (descend CMD,
58508f2b0dcSMin-Yih Hsu    // REGISTER
58608f2b0dcSMin-Yih Hsu    (operand "$dst", 3),
58708f2b0dcSMin-Yih Hsu    !if(SIGNED, 0b111, 0b011),
58808f2b0dcSMin-Yih Hsu    /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)
58908f2b0dcSMin-Yih Hsu  );
59008f2b0dcSMin-Yih Hsu}
591bec7b166SMin-Yih Hsu
5926a4e72b2SIan Douglas Scott// $dreg <- $dreg op $dreg
593b80e1accSMin-Yih Hsuclass MxDiMuOp_DD_Long<string MN, SDNode NODE, bits<10> CMD, bit SIGNED = false>
594b80e1accSMin-Yih Hsu    : MxInst<(outs MxDRD32:$dst), (ins MxDRD32:$src, MxDRD32:$opd), MN#"\t$opd, $dst",
595b80e1accSMin-Yih Hsu             [(set i32:$dst, CCR, (NODE i32:$src, i32:$opd))]> {
5966a4e72b2SIan Douglas Scott  let Inst = (ascend
5976a4e72b2SIan Douglas Scott    (descend CMD,
5986a4e72b2SIan Douglas Scott      /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)),
5996a4e72b2SIan Douglas Scott    (descend 0b0,
6006a4e72b2SIan Douglas Scott      // REGISTER
6016a4e72b2SIan Douglas Scott      (operand "$dst", 3),
6026a4e72b2SIan Douglas Scott      !if(SIGNED, 0b1, 0b0),
6036a4e72b2SIan Douglas Scott      /*SIZE*/0b0, 0b0000000,
6046a4e72b2SIan Douglas Scott      // Dr REGISTER
6056a4e72b2SIan Douglas Scott      0b000)
6066a4e72b2SIan Douglas Scott  );
6076a4e72b2SIan Douglas Scott}
6086a4e72b2SIan Douglas Scott
609bec7b166SMin-Yih Hsu// $reg <- $reg op $imm
61008f2b0dcSMin-Yih Hsuclass MxDiMuOp_DI<string MN, bits<4> CMD, bit SIGNED = false,
611bec7b166SMin-Yih Hsu                  MxOperand DST, MxOperand OPD>
61208f2b0dcSMin-Yih Hsu    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {
61308f2b0dcSMin-Yih Hsu  // FIXME: Support immediates with different widths.
61408f2b0dcSMin-Yih Hsu  defvar ImmEnc = MxEncAddrMode_i<"opd", 16>;
61508f2b0dcSMin-Yih Hsu  let Inst = (ascend
61608f2b0dcSMin-Yih Hsu    (descend CMD,
61708f2b0dcSMin-Yih Hsu      // REGISTER
61808f2b0dcSMin-Yih Hsu      (operand "$dst", 3),
61908f2b0dcSMin-Yih Hsu      !if(SIGNED, 0b111, 0b011), ImmEnc.EA),
62008f2b0dcSMin-Yih Hsu    ImmEnc.Supplement
62108f2b0dcSMin-Yih Hsu  );
62208f2b0dcSMin-Yih Hsu}
623bec7b166SMin-Yih Hsu} // let Constraints
624bec7b166SMin-Yih Hsu} // Defs = [CCR]
625bec7b166SMin-Yih Hsu
6266f85075fSMin-Yih Hsumulticlass MxDiMuOp<string MN, bits<4> CMD> {
62708f2b0dcSMin-Yih Hsu  def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, /*SIGNED*/true, MxDRD32, MxDRD16>;
62808f2b0dcSMin-Yih Hsu  def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, /*SIGNED*/false, MxDRD32, MxDRD16>;
629bec7b166SMin-Yih Hsu
63008f2b0dcSMin-Yih Hsu  def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, /*SIGNED*/true, MxDRD32, Mxi16imm>;
63108f2b0dcSMin-Yih Hsu  def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, /*SIGNED*/false, MxDRD32, Mxi16imm>;
632bec7b166SMin-Yih Hsu}
633bec7b166SMin-Yih Hsu
634bec7b166SMin-Yih Hsudefm DIV : MxDiMuOp<"div", 0x8>;
635bec7b166SMin-Yih Hsu
636b80e1accSMin-Yih Hsudef SDIVd32d32 : MxDiMuOp_DD_Long<"divs.l", sdiv, 0x131, /*SIGNED*/true>;
637b80e1accSMin-Yih Hsudef UDIVd32d32 : MxDiMuOp_DD_Long<"divu.l", udiv, 0x131, /*SIGNED*/false>;
6386a4e72b2SIan Douglas Scott
639028d6250SRicky Taylor// This is used to cast immediates to 16-bits for operations which don't
640028d6250SRicky Taylor// support smaller immediate sizes.
641028d6250SRicky Taylordef as_i16imm : SDNodeXForm<imm, [{
642028d6250SRicky Taylor  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
643028d6250SRicky Taylor}]>;
644028d6250SRicky Taylor
645bec7b166SMin-Yih Hsu// RR i8
646bec7b166SMin-Yih Hsudef : Pat<(sdiv i8:$dst, i8:$opd),
647bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
648bec7b166SMin-Yih Hsu            (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)),
649bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
650bec7b166SMin-Yih Hsu
651bec7b166SMin-Yih Hsudef : Pat<(udiv i8:$dst, i8:$opd),
652bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
653bec7b166SMin-Yih Hsu            (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)),
654bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
655bec7b166SMin-Yih Hsu
656bec7b166SMin-Yih Hsudef : Pat<(srem i8:$dst, i8:$opd),
657bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
658bec7b166SMin-Yih Hsu            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8),
659bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
660bec7b166SMin-Yih Hsu
661bec7b166SMin-Yih Hsudef : Pat<(urem i8:$dst, i8:$opd),
662bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
663bec7b166SMin-Yih Hsu            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8),
664bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
665bec7b166SMin-Yih Hsu
666bec7b166SMin-Yih Hsu// RR i16
667bec7b166SMin-Yih Hsudef : Pat<(sdiv i16:$dst, i16:$opd),
668bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
669bec7b166SMin-Yih Hsu            (SDIVd32d16 (MOVSXd32d16 $dst), $opd),
670bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
671bec7b166SMin-Yih Hsu
672bec7b166SMin-Yih Hsudef : Pat<(udiv i16:$dst, i16:$opd),
673bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
674bec7b166SMin-Yih Hsu            (UDIVd32d16 (MOVZXd32d16 $dst), $opd),
675bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
676bec7b166SMin-Yih Hsu
677bec7b166SMin-Yih Hsudef : Pat<(srem i16:$dst, i16:$opd),
678bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
679bec7b166SMin-Yih Hsu            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8),
680bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
681bec7b166SMin-Yih Hsu
682bec7b166SMin-Yih Hsudef : Pat<(urem i16:$dst, i16:$opd),
683bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
684bec7b166SMin-Yih Hsu            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8),
685bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
686bec7b166SMin-Yih Hsu
687bec7b166SMin-Yih Hsu// RI i8
688f9d161f0SMin-Yih Hsudef : Pat<(sdiv i8:$dst, Mxi8immSExt8:$opd),
689bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
690028d6250SRicky Taylor            (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)),
691bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
692bec7b166SMin-Yih Hsu
693f9d161f0SMin-Yih Hsudef : Pat<(udiv i8:$dst, Mxi8immSExt8:$opd),
694bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
695028d6250SRicky Taylor            (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)),
696bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
697bec7b166SMin-Yih Hsu
698f9d161f0SMin-Yih Hsudef : Pat<(srem i8:$dst, Mxi8immSExt8:$opd),
699bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
700028d6250SRicky Taylor            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 8), 8),
701bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
702bec7b166SMin-Yih Hsu
703f9d161f0SMin-Yih Hsudef : Pat<(urem i8:$dst, Mxi8immSExt8:$opd),
704bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
705028d6250SRicky Taylor            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 8), 8),
706bec7b166SMin-Yih Hsu             MxSubRegIndex8Lo)>;
707bec7b166SMin-Yih Hsu
708bec7b166SMin-Yih Hsu// RI i16
709f9d161f0SMin-Yih Hsudef : Pat<(sdiv i16:$dst, Mxi16immSExt16:$opd),
710bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
711bec7b166SMin-Yih Hsu            (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),
712bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
713bec7b166SMin-Yih Hsu
714f9d161f0SMin-Yih Hsudef : Pat<(udiv i16:$dst, Mxi16immSExt16:$opd),
715bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
716bec7b166SMin-Yih Hsu            (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),
717bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
718bec7b166SMin-Yih Hsu
719f9d161f0SMin-Yih Hsudef : Pat<(srem i16:$dst, Mxi16immSExt16:$opd),
720bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
721bec7b166SMin-Yih Hsu            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8),
722bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
723bec7b166SMin-Yih Hsu
724f9d161f0SMin-Yih Hsudef : Pat<(urem i16:$dst, Mxi16immSExt16:$opd),
725bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
726bec7b166SMin-Yih Hsu            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8),
727bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
728bec7b166SMin-Yih Hsu
729bec7b166SMin-Yih Hsu
7306f85075fSMin-Yih Hsudefm MUL : MxDiMuOp<"mul", 0xC>;
731bec7b166SMin-Yih Hsu
732b80e1accSMin-Yih Hsudef SMULd32d32 : MxDiMuOp_DD_Long<"muls.l", MxSMul, 0x130, /*SIGNED*/true>;
733b80e1accSMin-Yih Hsudef UMULd32d32 : MxDiMuOp_DD_Long<"mulu.l", MxUMul, 0x130, /*SIGNED*/false>;
7346a4e72b2SIan Douglas Scott
735bec7b166SMin-Yih Hsu// RR
736bec7b166SMin-Yih Hsudef : Pat<(mul i16:$dst, i16:$opd),
737bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
738bec7b166SMin-Yih Hsu            (SMULd32d16 (MOVXd32d16 $dst), $opd),
739bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
740bec7b166SMin-Yih Hsu
741bec7b166SMin-Yih Hsudef : Pat<(mulhs i16:$dst, i16:$opd),
742bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
743bec7b166SMin-Yih Hsu            (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
744bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
745bec7b166SMin-Yih Hsu
746bec7b166SMin-Yih Hsudef : Pat<(mulhu i16:$dst, i16:$opd),
747bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
748bec7b166SMin-Yih Hsu            (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
749bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
750bec7b166SMin-Yih Hsu
7516a4e72b2SIan Douglas Scottdef : Pat<(mul i32:$dst, i32:$opd), (SMULd32d32 $dst, $opd)>;
7526a4e72b2SIan Douglas Scott
753bec7b166SMin-Yih Hsu
754bec7b166SMin-Yih Hsu// RI
755f9d161f0SMin-Yih Hsudef : Pat<(mul i16:$dst, Mxi16immSExt16:$opd),
756bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
757bec7b166SMin-Yih Hsu            (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),
758bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
759bec7b166SMin-Yih Hsu
760f9d161f0SMin-Yih Hsudef : Pat<(mulhs i16:$dst, Mxi16immSExt16:$opd),
761bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
762bec7b166SMin-Yih Hsu            (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
763bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
764bec7b166SMin-Yih Hsu
765f9d161f0SMin-Yih Hsudef : Pat<(mulhu i16:$dst, Mxi16immSExt16:$opd),
766bec7b166SMin-Yih Hsu          (EXTRACT_SUBREG
767bec7b166SMin-Yih Hsu            (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
768bec7b166SMin-Yih Hsu             MxSubRegIndex16Lo)>;
769bec7b166SMin-Yih Hsu
770bec7b166SMin-Yih Hsu
771bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
772*614a5780SPeter Lafreniere// NEG/NEGX/NOT
773bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
774bec7b166SMin-Yih Hsu
775bec7b166SMin-Yih Hsu/// ------------+------------+------+---------+---------
776bec7b166SMin-Yih Hsu///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
777bec7b166SMin-Yih Hsu/// ------------+------------+------+-------------------
778bec7b166SMin-Yih Hsu///             |            |      | EFFECTIVE ADDRESS
779bec7b166SMin-Yih Hsu///  0  1  0  0 | x  x  x  x | SIZE |   MODE  |   REG
780bec7b166SMin-Yih Hsu/// ------------+------------+------+---------+---------
781bec7b166SMin-Yih Hsulet Defs = [CCR] in {
782bec7b166SMin-Yih Hsulet Constraints = "$src = $dst" in {
783bec7b166SMin-Yih Hsu
784bec7b166SMin-Yih Hsuclass MxNeg_D<MxType TYPE>
785bec7b166SMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
786bec7b166SMin-Yih Hsu             "neg."#TYPE.Prefix#"\t$dst",
78708f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))]> {
78808f2b0dcSMin-Yih Hsu  let Inst = (descend 0b01000100,
7891290d0ddSSheng    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
79008f2b0dcSMin-Yih Hsu    //MODE without last bit
79108f2b0dcSMin-Yih Hsu    0b00,
79208f2b0dcSMin-Yih Hsu    //REGISTER prefixed by D/A bit
79308f2b0dcSMin-Yih Hsu    (operand "$dst", 4)
79408f2b0dcSMin-Yih Hsu  );
79508f2b0dcSMin-Yih Hsu}
796bec7b166SMin-Yih Hsu
797bec7b166SMin-Yih Hsulet Uses = [CCR] in {
798bec7b166SMin-Yih Hsuclass MxNegX_D<MxType TYPE>
799bec7b166SMin-Yih Hsu    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
800bec7b166SMin-Yih Hsu             "negx."#TYPE.Prefix#"\t$dst",
80108f2b0dcSMin-Yih Hsu             [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))]> {
80208f2b0dcSMin-Yih Hsu  let Inst = (descend 0b01000000,
8031290d0ddSSheng    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
80408f2b0dcSMin-Yih Hsu    //MODE without last bit
80508f2b0dcSMin-Yih Hsu    0b00,
80608f2b0dcSMin-Yih Hsu    //REGISTER prefixed by D/A bit
80708f2b0dcSMin-Yih Hsu    (operand "$dst", 4)
80808f2b0dcSMin-Yih Hsu  );
80908f2b0dcSMin-Yih Hsu}
810bec7b166SMin-Yih Hsu}
811bec7b166SMin-Yih Hsu
812*614a5780SPeter Lafreniereclass MxNot_D<MxType TYPE>
813*614a5780SPeter Lafreniere    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
814*614a5780SPeter Lafreniere             "not."#TYPE.Prefix#"\t$dst",
815*614a5780SPeter Lafreniere             [(set TYPE.VT:$dst, (not TYPE.VT:$src))]> {
816*614a5780SPeter Lafreniere  let Inst = (descend 0b01000110,
817*614a5780SPeter Lafreniere    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
818*614a5780SPeter Lafreniere    //MODE without last bit
819*614a5780SPeter Lafreniere    0b00,
820*614a5780SPeter Lafreniere    //REGISTER prefixed by D/A bit
821*614a5780SPeter Lafreniere    (operand "$dst", 4)
822*614a5780SPeter Lafreniere  );
823*614a5780SPeter Lafreniere}
824*614a5780SPeter Lafreniere
825bec7b166SMin-Yih Hsu} // let Constraints
826bec7b166SMin-Yih Hsu} // let Defs = [CCR]
827bec7b166SMin-Yih Hsu
828bec7b166SMin-Yih Hsuforeach S = [8, 16, 32] in {
829bec7b166SMin-Yih Hsu  def NEG#S#d  : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;
830bec7b166SMin-Yih Hsu  def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;
831*614a5780SPeter Lafreniere  def NOT#S#d  : MxNot_D<!cast<MxType>("MxType"#S#"d")>;
832bec7b166SMin-Yih Hsu}
833bec7b166SMin-Yih Hsu
834bec7b166SMin-Yih Hsudef : Pat<(MxSub 0, i8 :$src), (NEG8d  MxDRD8 :$src)>;
835bec7b166SMin-Yih Hsudef : Pat<(MxSub 0, i16:$src), (NEG16d MxDRD16:$src)>;
836bec7b166SMin-Yih Hsudef : Pat<(MxSub 0, i32:$src), (NEG32d MxDRD32:$src)>;
837876980a5SMin-Yih Hsu// SExt of i1 values.
838876980a5SMin-Yih Hsu// Although we specify `ZeroOrOneBooleanContent` for boolean content,
839876980a5SMin-Yih Hsu// we're still adding an AND here as we don't know the origin of the i1 value.
840876980a5SMin-Yih Hsudef : Pat<(sext_inreg i8:$src,  i1), (NEG8d  (AND8di  MxDRD8:$src,  1))>;
841876980a5SMin-Yih Hsudef : Pat<(sext_inreg i16:$src, i1), (NEG16d (AND16di MxDRD16:$src, 1))>;
842876980a5SMin-Yih Hsudef : Pat<(sext_inreg i32:$src, i1), (NEG32d (AND32di MxDRD32:$src, 1))>;
843bec7b166SMin-Yih Hsu
844bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
845bec7b166SMin-Yih Hsu// no-CCR Patterns
846bec7b166SMin-Yih Hsu//===----------------------------------------------------------------------===//
847bec7b166SMin-Yih Hsu
848bec7b166SMin-Yih Hsu/// Basically the reason for this stuff is that add and addc share the same
849bec7b166SMin-Yih Hsu/// operand types constraints for whatever reasons and I had to define a common
850bec7b166SMin-Yih Hsu/// MxAdd and MxSub instructions that produce CCR and then pattern-map add and addc
851bec7b166SMin-Yih Hsu/// to it.
852bec7b166SMin-Yih Hsu/// NOTE On the other hand I see no reason why I cannot just drop explicit CCR
853bec7b166SMin-Yih Hsu/// result. Anyway works for now, hopefully I will better understand how this stuff
854bec7b166SMin-Yih Hsu/// is designed later
855bec7b166SMin-Yih Hsuforeach N = ["add", "addc"] in {
856bec7b166SMin-Yih Hsu
857bec7b166SMin-Yih Hsu  // add reg, reg
858bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
859bec7b166SMin-Yih Hsu            (ADD8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
860bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
861657bb726SMin-Yih Hsu            (ADD16dr MxXRD16:$src, MxDRD16:$opd)>;
862bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
863657bb726SMin-Yih Hsu            (ADD32dr MxXRD32:$src, MxDRD32:$opd)>;
864bec7b166SMin-Yih Hsu
865bec7b166SMin-Yih Hsu  // add (An), reg
866bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
867bec7b166SMin-Yih Hsu            (ADD8dj MxDRD8:$src, MxType8.JOp:$opd)>;
868bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
869bec7b166SMin-Yih Hsu            (ADD16dj MxDRD16:$src, MxType16.JOp:$opd)>;
870bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
871657bb726SMin-Yih Hsu            (ADD32dj MxDRD32:$src, MxType32.JOp:$opd)>;
872bec7b166SMin-Yih Hsu
873bec7b166SMin-Yih Hsu  // add (i,An), reg
874bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
875bec7b166SMin-Yih Hsu            (ADD8dp MxDRD8:$src, MxType8.POp:$opd)>;
876bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
877bec7b166SMin-Yih Hsu            (ADD16dp MxDRD16:$src, MxType16.POp:$opd)>;
878bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
879657bb726SMin-Yih Hsu            (ADD32dp MxDRD32:$src, MxType32.POp:$opd)>;
880bec7b166SMin-Yih Hsu
881bec7b166SMin-Yih Hsu  // add (i,An,Xn), reg
882bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
883bec7b166SMin-Yih Hsu            (ADD8df MxDRD8:$src, MxType8.FOp:$opd)>;
884bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
885bec7b166SMin-Yih Hsu            (ADD16df MxDRD16:$src, MxType16.FOp:$opd)>;
886bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
887657bb726SMin-Yih Hsu            (ADD32df MxDRD32:$src, MxType32.FOp:$opd)>;
888bec7b166SMin-Yih Hsu
889bec7b166SMin-Yih Hsu  // add reg, imm
890f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i8: $src, Mxi8immSExt8:$opd),
891bec7b166SMin-Yih Hsu            (ADD8di  MxDRD8 :$src, imm:$opd)>;
892f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i16:$src, Mxi16immSExt16:$opd),
893bec7b166SMin-Yih Hsu            (ADD16di MxDRD16:$src, imm:$opd)>;
894bec7b166SMin-Yih Hsu
895bec7b166SMin-Yih Hsu  // LEAp is more complex and thus will be selected over normal ADD32ri but it cannot
896bec7b166SMin-Yih Hsu  // be used with data registers, here by adding complexity to a simple ADD32ri insts
897bec7b166SMin-Yih Hsu  // we make sure it will be selected over LEAp
898bec7b166SMin-Yih Hsu  let AddedComplexity = 15 in {
899f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i32:$src, Mxi32immSExt32:$opd),
900657bb726SMin-Yih Hsu            (ADD32di MxDRD32:$src, imm:$opd)>;
901bec7b166SMin-Yih Hsu  } // AddedComplexity = 15
902bec7b166SMin-Yih Hsu
903bec7b166SMin-Yih Hsu  // add imm, (An)
904bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
905bec7b166SMin-Yih Hsu                   MxType8.JPat:$dst),
906bec7b166SMin-Yih Hsu            (ADD8ji MxType8.JOp:$dst, imm:$opd)>;
907bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
908bec7b166SMin-Yih Hsu                   MxType16.JPat:$dst),
909bec7b166SMin-Yih Hsu            (ADD16ji MxType16.JOp:$dst, imm:$opd)>;
910bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
911bec7b166SMin-Yih Hsu                   MxType32.JPat:$dst),
912bec7b166SMin-Yih Hsu            (ADD32ji MxType32.JOp:$dst, imm:$opd)>;
913bec7b166SMin-Yih Hsu
914bec7b166SMin-Yih Hsu} // foreach add, addc
915bec7b166SMin-Yih Hsu
916bec7b166SMin-Yih Hsudef : Pat<(adde i8 :$src, i8 :$opd), (ADDX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
917bec7b166SMin-Yih Hsudef : Pat<(adde i16:$src, i16:$opd), (ADDX16dd MxDRD16:$src, MxDRD16:$opd)>;
918bec7b166SMin-Yih Hsudef : Pat<(adde i32:$src, i32:$opd), (ADDX32dd MxDRD32:$src, MxDRD32:$opd)>;
919bec7b166SMin-Yih Hsu
920bec7b166SMin-Yih Hsu
921bec7b166SMin-Yih Hsu
922bec7b166SMin-Yih Hsuforeach N = ["sub", "subc"] in {
923bec7b166SMin-Yih Hsu
924bec7b166SMin-Yih Hsu  // sub reg, reg
925bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
926bec7b166SMin-Yih Hsu            (SUB8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
927bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
928bec7b166SMin-Yih Hsu            (SUB16dd MxDRD16:$src, MxDRD16:$opd)>;
929bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
930657bb726SMin-Yih Hsu            (SUB32dd MxDRD32:$src, MxDRD32:$opd)>;
931bec7b166SMin-Yih Hsu
932bec7b166SMin-Yih Hsu
933bec7b166SMin-Yih Hsu  // sub (An), reg
934bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
935bec7b166SMin-Yih Hsu            (SUB8dj MxDRD8:$src, MxType8.JOp:$opd)>;
936bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
937bec7b166SMin-Yih Hsu            (SUB16dj MxDRD16:$src, MxType16.JOp:$opd)>;
938bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
939657bb726SMin-Yih Hsu            (SUB32dj MxDRD32:$src, MxType32.JOp:$opd)>;
940bec7b166SMin-Yih Hsu
941bec7b166SMin-Yih Hsu  // sub (i,An), reg
942bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
943bec7b166SMin-Yih Hsu            (SUB8dp MxDRD8:$src, MxType8.POp:$opd)>;
944bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
945bec7b166SMin-Yih Hsu            (SUB16dp MxDRD16:$src, MxType16.POp:$opd)>;
946bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
947657bb726SMin-Yih Hsu            (SUB32dp MxDRD32:$src, MxType32.POp:$opd)>;
948bec7b166SMin-Yih Hsu
949bec7b166SMin-Yih Hsu  // sub (i,An,Xn), reg
950bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
951bec7b166SMin-Yih Hsu            (SUB8df MxDRD8:$src, MxType8.FOp:$opd)>;
952bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
953bec7b166SMin-Yih Hsu            (SUB16df MxDRD16:$src, MxType16.FOp:$opd)>;
954bec7b166SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
955657bb726SMin-Yih Hsu            (SUB32df MxDRD32:$src, MxType32.FOp:$opd)>;
956bec7b166SMin-Yih Hsu
957bec7b166SMin-Yih Hsu  // sub reg, imm
958f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i8 :$src, Mxi8immSExt8 :$opd),
959bec7b166SMin-Yih Hsu            (SUB8di  MxDRD8 :$src, imm:$opd)>;
960f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i16:$src, Mxi16immSExt16:$opd),
961bec7b166SMin-Yih Hsu            (SUB16di MxDRD16:$src, imm:$opd)>;
962f9d161f0SMin-Yih Hsu  def : Pat<(!cast<SDNode>(N) i32:$src, Mxi32immSExt32:$opd),
963657bb726SMin-Yih Hsu            (SUB32di MxDRD32:$src, imm:$opd)>;
964bec7b166SMin-Yih Hsu
965bec7b166SMin-Yih Hsu  // sub imm, (An)
966bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
967bec7b166SMin-Yih Hsu                   MxType8.JPat:$dst),
968bec7b166SMin-Yih Hsu            (SUB8ji MxType8.JOp:$dst, imm:$opd)>;
969bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
970bec7b166SMin-Yih Hsu                   MxType16.JPat:$dst),
971bec7b166SMin-Yih Hsu            (SUB16ji MxType16.JOp:$dst, imm:$opd)>;
972bec7b166SMin-Yih Hsu  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
973bec7b166SMin-Yih Hsu                   MxType32.JPat:$dst),
974bec7b166SMin-Yih Hsu            (SUB32ji MxType32.JOp:$dst, imm:$opd)>;
975bec7b166SMin-Yih Hsu
976bec7b166SMin-Yih Hsu} // foreach sub, subx
977bec7b166SMin-Yih Hsu
978bec7b166SMin-Yih Hsudef : Pat<(sube i8 :$src, i8 :$opd), (SUBX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
979bec7b166SMin-Yih Hsudef : Pat<(sube i16:$src, i16:$opd), (SUBX16dd MxDRD16:$src, MxDRD16:$opd)>;
980bec7b166SMin-Yih Hsudef : Pat<(sube i32:$src, i32:$opd), (SUBX32dd MxDRD32:$src, MxDRD32:$opd)>;
981bec7b166SMin-Yih Hsu
9825cb5225cSJim Linmulticlass BitwisePat<string INST, SDNode OP> {
9835cb5225cSJim Lin  // op reg, reg
9845cb5225cSJim Lin  def : Pat<(OP i8 :$src, i8 :$opd),
9855cb5225cSJim Lin            (!cast<MxInst>(INST#"8dd")  MxDRD8 :$src, MxDRD8 :$opd)>;
9865cb5225cSJim Lin  def : Pat<(OP i16:$src, i16:$opd),
9875cb5225cSJim Lin            (!cast<MxInst>(INST#"16dd") MxDRD16:$src, MxDRD16:$opd)>;
9885cb5225cSJim Lin  def : Pat<(OP i32:$src, i32:$opd),
9895cb5225cSJim Lin            (!cast<MxInst>(INST#"32dd") MxDRD32:$src, MxDRD32:$opd)>;
9905cb5225cSJim Lin  // op reg, imm
991f9d161f0SMin-Yih Hsu  def : Pat<(OP i8: $src, Mxi8immSExt8 :$opd),
9925cb5225cSJim Lin            (!cast<MxInst>(INST#"8di")  MxDRD8 :$src, imm:$opd)>;
993f9d161f0SMin-Yih Hsu  def : Pat<(OP i16:$src, Mxi16immSExt16:$opd),
9945cb5225cSJim Lin            (!cast<MxInst>(INST#"16di") MxDRD16:$src, imm:$opd)>;
995f9d161f0SMin-Yih Hsu  def : Pat<(OP i32:$src, Mxi32immSExt32:$opd),
9965cb5225cSJim Lin            (!cast<MxInst>(INST#"32di") MxDRD32:$src, imm:$opd)>;
9975cb5225cSJim Lin}
998bec7b166SMin-Yih Hsu
9995cb5225cSJim Lindefm : BitwisePat<"AND", and>;
10005cb5225cSJim Lindefm : BitwisePat<"OR",  or>;
10015cb5225cSJim Lindefm : BitwisePat<"XOR", xor>;
10027943b994SSheng
10037943b994SSheng//===----------------------------------------------------------------------===//
10047943b994SSheng// Floating point arithmetic instruction
10057943b994SSheng//===----------------------------------------------------------------------===//
10067943b994SSheng
10077943b994SShenglet Defs = [FPS] in
10087943b994SShengclass MxFArithBase_FF<dag outs, dag ins, string asm, string rounding,
10097943b994SSheng                      list<dag> patterns>
10107943b994SSheng    : MxInst<outs, ins, asm, patterns> {
10117943b994SSheng  let Uses = !if(!eq(rounding, ""), [FPC], []);
10127943b994SSheng
10137943b994SSheng  let Predicates = !if(!eq(rounding, ""), [AtLeastM68881], [AtLeastM68040]);
10147943b994SSheng}
10157943b994SSheng
10167943b994SShengclass MxFPOpModeSelector<string rounding, bits<7> single, bits<7> double,
10177943b994SSheng                         bits<7> extended> {
10187943b994SSheng  bits<7> Mode = !cond(!eq(rounding, "s"): single,
10197943b994SSheng                       !eq(rounding, "d"): double,
10207943b994SSheng                       !eq(rounding, ""): extended);
10217943b994SSheng}
10227943b994SSheng
10237943b994SSheng//===----------------------------------------------------------------------===//
10247943b994SSheng// Unary floating point instruction
10257943b994SSheng//===----------------------------------------------------------------------===//
10267943b994SSheng
10277943b994SShengclass MxFUnary_FF<MxOpBundle Opnd, string rounding,
10287943b994SSheng                  string mnemonic, bits<7> opmode>
10297943b994SSheng    : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src),
10307943b994SSheng                    "f"#rounding#mnemonic#".x\t$src, $dst", rounding, [(null_frag)]> {
10317943b994SSheng  let Inst = (ascend
10327943b994SSheng  (descend 0b1111,
10337943b994SSheng    /*COPROCESSOR ID*/0b001,
10347943b994SSheng    0b000,
10357943b994SSheng    /*MODE+REGISTER*/0b000000),
10367943b994SSheng  (descend 0b0, /* R/M */ 0b0, 0b0,
10377943b994SSheng    /*SOURCE SPECIFIER*/
10387943b994SSheng    (operand "$src", 3),
10397943b994SSheng    /*DESTINATION*/
10407943b994SSheng    (operand "$dst", 3),
10417943b994SSheng    /*OPMODE*/
10427943b994SSheng    opmode)
10437943b994SSheng  );
10447943b994SSheng}
10457943b994SSheng
10467943b994SShengmulticlass MxFUnaryOp<string mnemonic, bits<7> single, bits<7> double,
10477943b994SSheng                      bits<7> extended> {
10487943b994SSheng  foreach rounding = ["", "s", "d"] in {
10497943b994SSheng    defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;
10507943b994SSheng
10517943b994SSheng    def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"
10527943b994SSheng      : MxFUnary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;
10537943b994SSheng
10547943b994SSheng    let isCodeGenOnly = 1 in
10557943b994SSheng    foreach size = [32, 64] in
10567943b994SSheng      def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"
10577943b994SSheng        : MxFUnary_FF<!cast<MxOpBundle>("MxOp"#size#"AddrMode_fpr"),
10587943b994SSheng                      rounding, mnemonic, opmode>;
10597943b994SSheng  }
10607943b994SSheng}
10617943b994SSheng
10627943b994SShengdefm FABS : MxFUnaryOp<"abs", 0b1011000, 0b1011100, 0b0011000>;
10637943b994SShengdefm FNEG : MxFUnaryOp<"neg", 0b1011010, 0b1011110, 0b0011010>;
10647943b994SSheng
10657943b994SSheng//===----------------------------------------------------------------------===//
10667943b994SSheng// Binary floating point instruction
10677943b994SSheng//===----------------------------------------------------------------------===//
10687943b994SSheng
10697943b994SShenglet Constraints = "$src = $dst" in
10707943b994SShengclass MxFBinary_FF<MxOpBundle Opnd, string rounding,
10717943b994SSheng                   string mnemonic, bits<7> opmode>
10727943b994SSheng    : MxFArithBase_FF<(outs Opnd.Op:$dst), (ins Opnd.Op:$src, Opnd.Op:$opd),
10737943b994SSheng                      "f"#rounding#mnemonic#".x\t$opd, $dst", rounding, [(null_frag)]> {
10747943b994SSheng  let Inst = (ascend
10757943b994SSheng  (descend 0b1111,
10767943b994SSheng    /*COPROCESSOR ID*/0b001,
10777943b994SSheng    0b000,
10787943b994SSheng    /*MODE+REGISTER*/0b000000),
10797943b994SSheng  (descend 0b0, /* R/M */ 0b0, 0b0,
10807943b994SSheng    /*SOURCE SPECIFIER*/
10817943b994SSheng    (operand "$opd", 3),
10827943b994SSheng    /*DESTINATION*/
10837943b994SSheng    (operand "$dst", 3),
10847943b994SSheng    /*OPMODE*/
10857943b994SSheng    opmode)
10867943b994SSheng  );
10877943b994SSheng}
10887943b994SSheng
10897943b994SShengmulticlass MxFBinaryOp<string mnemonic, bits<7> single, bits<7> double,
10907943b994SSheng                      bits<7> extended> {
10917943b994SSheng  foreach rounding = ["", "s", "d"] in {
10927943b994SSheng    defvar opmode = MxFPOpModeSelector<rounding, single, double, extended>.Mode;
10937943b994SSheng
10947943b994SSheng    def F # !toupper(rounding) # !substr(NAME, 1) # "80fp_fp"
10957943b994SSheng      : MxFBinary_FF<MxOp80AddrMode_fpr, rounding, mnemonic, opmode>;
10967943b994SSheng
10977943b994SSheng    let isCodeGenOnly = 1 in
10987943b994SSheng    foreach size = [32, 64] in
10997943b994SSheng      def F # !toupper(rounding) # !substr(NAME, 1) # size # "fp_fp"
11007943b994SSheng        : MxFBinary_FF<!cast<MxOpBundle>("MxOp"#size#"AddrMode_fpr"),
11017943b994SSheng                        rounding, mnemonic, opmode>;
11027943b994SSheng  }
11037943b994SSheng}
11047943b994SSheng
11057943b994SShengdefm FADD : MxFBinaryOp<"add", 0b1100010, 0b1100110, 0b0100010>;
11067943b994SShengdefm FSUB : MxFBinaryOp<"sub", 0b1101000, 0b1101100, 0b0101000>;
11077943b994SShengdefm FMUL : MxFBinaryOp<"mul", 0b1100011, 0b1100111, 0b0100011>;
11087943b994SShengdefm FDIV : MxFBinaryOp<"div", 0b1100000, 0b1100100, 0b0100000>;
1109