| Akira Hatanaka | 7d7ee0c | 2011-09-24 01:40:18 +0000 | [diff] [blame] | 1 | //===- Mips64InstrInfo.td - Mips64 Instruction Information -*- tablegen -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file describes Mips64 instructions. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | c117967 | 2011-09-28 17:50:27 +0000 | [diff] [blame] | 13 |  | 
|  | 14 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | 7769a77 | 2011-09-30 02:08:54 +0000 | [diff] [blame] | 15 | // Mips Operand, Complex Patterns and Transformations Definitions. | 
|  | 16 | //===----------------------------------------------------------------------===// | 
|  | 17 |  | 
|  | 18 | // Instruction operand types | 
| Akira Hatanaka | 61e256a | 2011-09-30 03:18:46 +0000 | [diff] [blame] | 19 | def shamt_64       : Operand<i64>; | 
| Akira Hatanaka | 7769a77 | 2011-09-30 02:08:54 +0000 | [diff] [blame] | 20 |  | 
|  | 21 | // Unsigned Operand | 
|  | 22 | def uimm16_64      : Operand<i64> { | 
|  | 23 | let PrintMethod = "printUnsignedImm"; | 
|  | 24 | } | 
|  | 25 |  | 
| Akira Hatanaka | 61e256a | 2011-09-30 03:18:46 +0000 | [diff] [blame] | 26 | // Transformation Function - get Imm - 32. | 
|  | 27 | def Subtract32 : SDNodeXForm<imm, [{ | 
| Akira Hatanaka | 4a04a56 | 2011-12-07 20:10:24 +0000 | [diff] [blame] | 28 | return getImm(N, (unsigned)N->getZExtValue() - 32); | 
| Akira Hatanaka | 61e256a | 2011-09-30 03:18:46 +0000 | [diff] [blame] | 29 | }]>; | 
|  | 30 |  | 
| Akira Hatanaka | 2a232d8 | 2011-12-19 19:44:09 +0000 | [diff] [blame] | 31 | // shamt must fit in 6 bits. | 
|  | 32 | def immZExt6 : ImmLeaf<i32, [{return Imm == (Imm & 0x3f);}]>; | 
| Akira Hatanaka | 61e256a | 2011-09-30 03:18:46 +0000 | [diff] [blame] | 33 |  | 
| Akira Hatanaka | 7769a77 | 2011-09-30 02:08:54 +0000 | [diff] [blame] | 34 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | 3603641 | 2011-09-29 20:37:56 +0000 | [diff] [blame] | 35 | // Instructions specific format | 
|  | 36 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 37 | let usesCustomInserter = 1 in { | 
|  | 38 | def ATOMIC_LOAD_ADD_I64  : Atomic2Ops<atomic_load_add_64, GPR64>; | 
|  | 39 | def ATOMIC_LOAD_SUB_I64  : Atomic2Ops<atomic_load_sub_64, GPR64>; | 
|  | 40 | def ATOMIC_LOAD_AND_I64  : Atomic2Ops<atomic_load_and_64, GPR64>; | 
|  | 41 | def ATOMIC_LOAD_OR_I64   : Atomic2Ops<atomic_load_or_64, GPR64>; | 
|  | 42 | def ATOMIC_LOAD_XOR_I64  : Atomic2Ops<atomic_load_xor_64, GPR64>; | 
|  | 43 | def ATOMIC_LOAD_NAND_I64 : Atomic2Ops<atomic_load_nand_64, GPR64>; | 
|  | 44 | def ATOMIC_SWAP_I64      : Atomic2Ops<atomic_swap_64, GPR64>; | 
|  | 45 | def ATOMIC_CMP_SWAP_I64  : AtomicCmpSwap<atomic_cmp_swap_64, GPR64>; | 
| Akira Hatanaka | 21cbc25 | 2011-11-11 04:14:30 +0000 | [diff] [blame] | 46 | } | 
|  | 47 |  | 
| Akira Hatanaka | 4254319 | 2013-04-30 23:22:09 +0000 | [diff] [blame] | 48 | /// Pseudo instructions for loading and storing accumulator registers. | 
| Akira Hatanaka | 21f3343 | 2013-08-01 23:14:16 +0000 | [diff] [blame] | 49 | let isPseudo = 1, isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 50 | def LOAD_ACC128  : Load<"", ACC128>; | 
|  | 51 | def STORE_ACC128 : Store<"", ACC128>; | 
| Akira Hatanaka | c8d8502 | 2013-03-30 00:54:52 +0000 | [diff] [blame] | 52 | } | 
|  | 53 |  | 
| Akira Hatanaka | 3603641 | 2011-09-29 20:37:56 +0000 | [diff] [blame] | 54 | //===----------------------------------------------------------------------===// | 
|  | 55 | // Instruction definition | 
|  | 56 | //===----------------------------------------------------------------------===// | 
| Akira Hatanaka | 71928e6 | 2012-04-17 18:03:21 +0000 | [diff] [blame] | 57 | let DecoderNamespace = "Mips64" in { | 
| Akira Hatanaka | 7769a77 | 2011-09-30 02:08:54 +0000 | [diff] [blame] | 58 | /// Arithmetic Instructions (ALU Immediate) | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 59 | def DADDi   : ArithLogicI<"daddi", simm16_64, GPR64Opnd>, ADDI_FM<0x18>; | 
|  | 60 | def DADDiu  : ArithLogicI<"daddiu", simm16_64, GPR64Opnd, IIArith, | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 61 | immSExt16, add>, | 
| Akira Hatanaka | ab1b715b | 2012-12-20 03:40:03 +0000 | [diff] [blame] | 62 | ADDI_FM<0x19>, IsAsCheapAsAMove; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 63 |  | 
|  | 64 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 65 | def SLTi64  : SetCC_I<"slti", setlt, simm16_64, immSExt16, GPR64Opnd>, | 
| Akira Hatanaka | e7f1acc | 2012-12-20 04:27:52 +0000 | [diff] [blame] | 66 | SLTI_FM<0xa>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 67 | def SLTiu64 : SetCC_I<"sltiu", setult, simm16_64, immSExt16, GPR64Opnd>, | 
| Akira Hatanaka | e7f1acc | 2012-12-20 04:27:52 +0000 | [diff] [blame] | 68 | SLTI_FM<0xb>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 69 | def ANDi64 : ArithLogicI<"andi", uimm16_64, GPR64Opnd, IILogic, immZExt16, | 
| Akira Hatanaka | d644568 | 2013-07-31 00:57:41 +0000 | [diff] [blame] | 70 | and>, | 
|  | 71 | ADDI_FM<0xc>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 72 | def ORi64   : ArithLogicI<"ori", uimm16_64, GPR64Opnd, IILogic, immZExt16, | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 73 | or>, | 
| Akira Hatanaka | ab1b715b | 2012-12-20 03:40:03 +0000 | [diff] [blame] | 74 | ADDI_FM<0xd>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 75 | def XORi64  : ArithLogicI<"xori", uimm16_64, GPR64Opnd, IILogic, immZExt16, | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 76 | xor>, | 
| Akira Hatanaka | ab1b715b | 2012-12-20 03:40:03 +0000 | [diff] [blame] | 77 | ADDI_FM<0xe>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 78 | def LUi64   : LoadUpper<"lui", GPR64Opnd, uimm16_64>, LUI_FM; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 79 | } | 
| Akira Hatanaka | 7769a77 | 2011-09-30 02:08:54 +0000 | [diff] [blame] | 80 |  | 
| Akira Hatanaka | 3603641 | 2011-09-29 20:37:56 +0000 | [diff] [blame] | 81 | /// Arithmetic Instructions (3-Operand, R-Type) | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 82 | def DADD   : ArithLogicR<"dadd", GPR64Opnd>, ADD_FM<0, 0x2c>; | 
|  | 83 | def DADDu  : ArithLogicR<"daddu", GPR64Opnd, 1, IIArith, add>, | 
| Jack Carter | 873c724 | 2013-01-12 01:03:14 +0000 | [diff] [blame] | 84 | ADD_FM<0, 0x2d>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 85 | def DSUBu  : ArithLogicR<"dsubu", GPR64Opnd, 0, IIArith, sub>, | 
| Jack Carter | 873c724 | 2013-01-12 01:03:14 +0000 | [diff] [blame] | 86 | ADD_FM<0, 0x2f>; | 
| Akira Hatanaka | e2a39e7 | 2013-08-06 22:35:29 +0000 | [diff] [blame] | 87 |  | 
|  | 88 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 89 | def SLT64  : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>; | 
|  | 90 | def SLTu64 : SetCC_R<"sltu", setult, GPR64Opnd>, ADD_FM<0, 0x2b>; | 
|  | 91 | def AND64  : ArithLogicR<"and", GPR64Opnd, 1, IIArith, and>, ADD_FM<0, 0x24>; | 
|  | 92 | def OR64   : ArithLogicR<"or", GPR64Opnd, 1, IIArith, or>, ADD_FM<0, 0x25>; | 
|  | 93 | def XOR64  : ArithLogicR<"xor", GPR64Opnd, 1, IIArith, xor>, ADD_FM<0, 0x26>; | 
|  | 94 | def NOR64  : LogicNOR<"nor", GPR64Opnd>, ADD_FM<0, 0x27>; | 
| Akira Hatanaka | e2a39e7 | 2013-08-06 22:35:29 +0000 | [diff] [blame] | 95 | } | 
| Akira Hatanaka | 61e256a | 2011-09-30 03:18:46 +0000 | [diff] [blame] | 96 |  | 
|  | 97 | /// Shift Instructions | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 98 | def DSLL   : shift_rotate_imm<"dsll", shamt, GPR64Opnd, shl, immZExt6>, | 
| Akira Hatanaka | f412e75 | 2013-01-04 19:25:46 +0000 | [diff] [blame] | 99 | SRA_FM<0x38, 0>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 100 | def DSRL   : shift_rotate_imm<"dsrl", shamt, GPR64Opnd, srl, immZExt6>, | 
| Akira Hatanaka | f412e75 | 2013-01-04 19:25:46 +0000 | [diff] [blame] | 101 | SRA_FM<0x3a, 0>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 102 | def DSRA   : shift_rotate_imm<"dsra", shamt, GPR64Opnd, sra, immZExt6>, | 
| Akira Hatanaka | f412e75 | 2013-01-04 19:25:46 +0000 | [diff] [blame] | 103 | SRA_FM<0x3b, 0>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 104 | def DSLLV  : shift_rotate_reg<"dsllv", GPR64Opnd, shl>, SRLV_FM<0x14, 0>; | 
|  | 105 | def DSRLV  : shift_rotate_reg<"dsrlv", GPR64Opnd, srl>, SRLV_FM<0x16, 0>; | 
|  | 106 | def DSRAV  : shift_rotate_reg<"dsrav", GPR64Opnd, sra>, SRLV_FM<0x17, 0>; | 
|  | 107 | def DSLL32 : shift_rotate_imm<"dsll32", shamt, GPR64Opnd>, SRA_FM<0x3c, 0>; | 
|  | 108 | def DSRL32 : shift_rotate_imm<"dsrl32", shamt, GPR64Opnd>, SRA_FM<0x3e, 0>; | 
|  | 109 | def DSRA32 : shift_rotate_imm<"dsra32", shamt, GPR64Opnd>, SRA_FM<0x3f, 0>; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 110 |  | 
| Akira Hatanaka | 7ba8a8d | 2011-09-30 18:51:46 +0000 | [diff] [blame] | 111 | // Rotate Instructions | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 112 | let Predicates = [HasMips64r2, HasStdEnc] in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 113 | def DROTR  : shift_rotate_imm<"drotr", shamt, GPR64Opnd, rotr, immZExt6>, | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 114 | SRA_FM<0x3a, 1>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 115 | def DROTRV : shift_rotate_reg<"drotrv", GPR64Opnd, rotr>, | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 116 | SRLV_FM<0x16, 1>; | 
| Akira Hatanaka | 7ba8a8d | 2011-09-30 18:51:46 +0000 | [diff] [blame] | 117 | } | 
|  | 118 |  | 
| Akira Hatanaka | be68f3c | 2011-10-11 00:27:28 +0000 | [diff] [blame] | 119 | /// Load and Store Instructions | 
| Jia Liu | f54f60f | 2012-02-28 07:46:26 +0000 | [diff] [blame] | 120 | ///  aligned | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 121 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 122 | def LB64  : Load<"lb", GPR64Opnd, sextloadi8, IILoad>, LW_FM<0x20>; | 
|  | 123 | def LBu64 : Load<"lbu", GPR64Opnd, zextloadi8, IILoad>, LW_FM<0x24>; | 
|  | 124 | def LH64  : Load<"lh", GPR64Opnd, sextloadi16, IILoad>, LW_FM<0x21>; | 
|  | 125 | def LHu64 : Load<"lhu", GPR64Opnd, zextloadi16, IILoad>, LW_FM<0x25>; | 
|  | 126 | def LW64  : Load<"lw", GPR64Opnd, sextloadi32, IILoad>, LW_FM<0x23>; | 
|  | 127 | def SB64  : Store<"sb", GPR64Opnd, truncstorei8, IIStore>, LW_FM<0x28>; | 
|  | 128 | def SH64  : Store<"sh", GPR64Opnd, truncstorei16, IIStore>, LW_FM<0x29>; | 
|  | 129 | def SW64  : Store<"sw", GPR64Opnd, truncstorei32, IIStore>, LW_FM<0x2b>; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 130 | } | 
|  | 131 |  | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 132 | def LWu   : Load<"lwu", GPR64Opnd, zextloadi32, IILoad>, LW_FM<0x27>; | 
|  | 133 | def LD    : Load<"ld", GPR64Opnd, load, IILoad>, LW_FM<0x37>; | 
|  | 134 | def SD    : Store<"sd", GPR64Opnd, store, IIStore>, LW_FM<0x3f>; | 
| Akira Hatanaka | be68f3c | 2011-10-11 00:27:28 +0000 | [diff] [blame] | 135 |  | 
| Akira Hatanaka | f11571d | 2012-06-02 00:04:19 +0000 | [diff] [blame] | 136 | /// load/store left/right | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 137 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 138 | def LWL64 : LoadLeftRight<"lwl", MipsLWL, GPR64Opnd>, LW_FM<0x22>; | 
|  | 139 | def LWR64 : LoadLeftRight<"lwr", MipsLWR, GPR64Opnd>, LW_FM<0x26>; | 
|  | 140 | def SWL64 : StoreLeftRight<"swl", MipsSWL, GPR64Opnd>, LW_FM<0x2a>; | 
|  | 141 | def SWR64 : StoreLeftRight<"swr", MipsSWR, GPR64Opnd>, LW_FM<0x2e>; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 142 | } | 
| Jack Carter | 873c724 | 2013-01-12 01:03:14 +0000 | [diff] [blame] | 143 |  | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 144 | def LDL   : LoadLeftRight<"ldl", MipsLDL, GPR64Opnd>, LW_FM<0x1a>; | 
|  | 145 | def LDR   : LoadLeftRight<"ldr", MipsLDR, GPR64Opnd>, LW_FM<0x1b>; | 
|  | 146 | def SDL   : StoreLeftRight<"sdl", MipsSDL, GPR64Opnd>, LW_FM<0x2c>; | 
|  | 147 | def SDR   : StoreLeftRight<"sdr", MipsSDR, GPR64Opnd>, LW_FM<0x2d>; | 
| Akira Hatanaka | f11571d | 2012-06-02 00:04:19 +0000 | [diff] [blame] | 148 |  | 
| Akira Hatanaka | 21cbc25 | 2011-11-11 04:14:30 +0000 | [diff] [blame] | 149 | /// Load-linked, Store-conditional | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 150 | def LLD : LLBase<"lld", GPR64Opnd>, LW_FM<0x34>; | 
|  | 151 | def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>; | 
| Akira Hatanaka | 21cbc25 | 2011-11-11 04:14:30 +0000 | [diff] [blame] | 152 |  | 
| Akira Hatanaka | 4b6ac98 | 2011-10-11 18:49:17 +0000 | [diff] [blame] | 153 | /// Jump and Branch Instructions | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 154 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 155 | def JR64   : IndirectBranch<GPR64Opnd>, MTLO_FM<8>; | 
|  | 156 | def BEQ64  : CBranch<"beq", seteq, GPR64Opnd>, BEQ_FM<4>; | 
|  | 157 | def BNE64  : CBranch<"bne", setne, GPR64Opnd>, BEQ_FM<5>; | 
|  | 158 | def BGEZ64 : CBranchZero<"bgez", setge, GPR64Opnd>, BGEZ_FM<1, 1>; | 
|  | 159 | def BGTZ64 : CBranchZero<"bgtz", setgt, GPR64Opnd>, BGEZ_FM<7, 0>; | 
|  | 160 | def BLEZ64 : CBranchZero<"blez", setle, GPR64Opnd>, BGEZ_FM<6, 0>; | 
|  | 161 | def BLTZ64 : CBranchZero<"bltz", setlt, GPR64Opnd>, BGEZ_FM<1, 0>; | 
|  | 162 | def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM; | 
|  | 163 | def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>; | 
|  | 164 | def TAILCALL64_R : JumpFR<GPR64Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall; | 
| Akira Hatanaka | 34a32c0 | 2013-08-06 22:20:40 +0000 | [diff] [blame] | 165 | } | 
|  | 166 |  | 
| Akira Hatanaka | a279d9b | 2011-10-03 20:01:11 +0000 | [diff] [blame] | 167 | /// Multiply and Divide Instructions. | 
| Akira Hatanaka | 8002a3f | 2013-08-14 00:47:08 +0000 | [diff] [blame] | 168 | def DMULT  : Mult<"dmult", IIImult, GPR64Opnd, [HI0_64, LO0_64]>, | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 169 | MULT_FM<0, 0x1c>; | 
| Akira Hatanaka | 8002a3f | 2013-08-14 00:47:08 +0000 | [diff] [blame] | 170 | def DMULTu : Mult<"dmultu", IIImult, GPR64Opnd, [HI0_64, LO0_64]>, | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 171 | MULT_FM<0, 0x1d>; | 
| Akira Hatanaka | 00fcf2e | 2013-08-08 21:54:26 +0000 | [diff] [blame] | 172 | def PseudoDMULT  : MultDivPseudo<DMULT, ACC128, GPR64Opnd, MipsMult, | 
| Akira Hatanaka | 1baf2ea | 2013-07-12 22:43:20 +0000 | [diff] [blame] | 173 | IIImult>; | 
| Akira Hatanaka | 00fcf2e | 2013-08-08 21:54:26 +0000 | [diff] [blame] | 174 | def PseudoDMULTu : MultDivPseudo<DMULTu, ACC128, GPR64Opnd, MipsMultu, | 
| Akira Hatanaka | 1baf2ea | 2013-07-12 22:43:20 +0000 | [diff] [blame] | 175 | IIImult>; | 
| Akira Hatanaka | 8002a3f | 2013-08-14 00:47:08 +0000 | [diff] [blame] | 176 | def DSDIV : Div<"ddiv", IIIdiv, GPR64Opnd, [HI0_64, LO0_64]>, MULT_FM<0, 0x1e>; | 
|  | 177 | def DUDIV : Div<"ddivu", IIIdiv, GPR64Opnd, [HI0_64, LO0_64]>, MULT_FM<0, 0x1f>; | 
| Akira Hatanaka | 00fcf2e | 2013-08-08 21:54:26 +0000 | [diff] [blame] | 178 | def PseudoDSDIV : MultDivPseudo<DSDIV, ACC128, GPR64Opnd, MipsDivRem, | 
| Akira Hatanaka | 1cb0242 | 2013-05-20 18:07:43 +0000 | [diff] [blame] | 179 | IIIdiv, 0, 1, 1>; | 
| Akira Hatanaka | 00fcf2e | 2013-08-08 21:54:26 +0000 | [diff] [blame] | 180 | def PseudoDUDIV : MultDivPseudo<DUDIV, ACC128, GPR64Opnd, MipsDivRemU, | 
| Akira Hatanaka | 1cb0242 | 2013-05-20 18:07:43 +0000 | [diff] [blame] | 181 | IIIdiv, 0, 1, 1>; | 
| Akira Hatanaka | a279d9b | 2011-10-03 20:01:11 +0000 | [diff] [blame] | 182 |  | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 183 | let isCodeGenOnly = 1 in { | 
| Akira Hatanaka | 8002a3f | 2013-08-14 00:47:08 +0000 | [diff] [blame] | 184 | def MTHI64 : MoveToLOHI<"mthi", GPR64Opnd, [HI0_64]>, MTLO_FM<0x11>; | 
|  | 185 | def MTLO64 : MoveToLOHI<"mtlo", GPR64Opnd, [LO0_64]>, MTLO_FM<0x13>; | 
|  | 186 | def MFHI64 : MoveFromLOHI<"mfhi", GPR64Opnd, [HI0_64]>, MFLO_FM<0x10>; | 
|  | 187 | def MFLO64 : MoveFromLOHI<"mflo", GPR64Opnd, [LO0_64]>, MFLO_FM<0x12>; | 
| Akira Hatanaka | cdcc745 | 2011-10-03 19:28:44 +0000 | [diff] [blame] | 188 |  | 
| Akira Hatanaka | 9f7ec15 | 2012-01-24 21:41:09 +0000 | [diff] [blame] | 189 | /// Sign Ext In Register Instructions. | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 190 | def SEB64 : SignExtInReg<"seb", i8, GPR64Opnd>, SEB_FM<0x10, 0x20>; | 
|  | 191 | def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd>, SEB_FM<0x18, 0x20>; | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 192 | } | 
| Akira Hatanaka | 9f7ec15 | 2012-01-24 21:41:09 +0000 | [diff] [blame] | 193 |  | 
| Akira Hatanaka | 48a72ca | 2011-10-03 21:16:50 +0000 | [diff] [blame] | 194 | /// Count Leading | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 195 | def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>; | 
|  | 196 | def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>; | 
| Akira Hatanaka | 48a72ca | 2011-10-03 21:16:50 +0000 | [diff] [blame] | 197 |  | 
| Akira Hatanaka | 4706ac9 | 2011-12-20 23:56:43 +0000 | [diff] [blame] | 198 | /// Double Word Swap Bytes/HalfWords | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 199 | def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>; | 
|  | 200 | def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>; | 
| Akira Hatanaka | 4706ac9 | 2011-12-20 23:56:43 +0000 | [diff] [blame] | 201 |  | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 202 | def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd>, LW_FM<0x19>; | 
| Akira Hatanaka | 6ac2fc4 | 2012-12-21 23:21:32 +0000 | [diff] [blame] | 203 |  | 
| Akira Hatanaka | c7e3998 | 2013-08-06 23:01:10 +0000 | [diff] [blame] | 204 | let isCodeGenOnly = 1 in | 
| Akira Hatanaka | 85ccf23 | 2013-08-08 21:37:32 +0000 | [diff] [blame] | 205 | def RDHWR64 : ReadHardware<GPR64Opnd, HWRegsOpnd>, RDHWR_FM; | 
| Akira Hatanaka | 4350c18 | 2011-12-07 23:31:26 +0000 | [diff] [blame] | 206 |  | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 207 | def DEXT : ExtBase<"dext", GPR64Opnd>, EXT_FM<3>; | 
| Jack Carter | cd6b0e1 | 2012-08-28 20:07:41 +0000 | [diff] [blame] | 208 | let Pattern = []<dag> in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 209 | def DEXTU : ExtBase<"dextu", GPR64Opnd>, EXT_FM<2>; | 
|  | 210 | def DEXTM : ExtBase<"dextm", GPR64Opnd>, EXT_FM<1>; | 
| Jack Carter | cd6b0e1 | 2012-08-28 20:07:41 +0000 | [diff] [blame] | 211 | } | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 212 | def DINS : InsBase<"dins", GPR64Opnd>, EXT_FM<7>; | 
| Jack Carter | b3f3b17 | 2012-08-31 18:06:48 +0000 | [diff] [blame] | 213 | let Pattern = []<dag> in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 214 | def DINSU : InsBase<"dinsu", GPR64Opnd>, EXT_FM<6>; | 
|  | 215 | def DINSM : InsBase<"dinsm", GPR64Opnd>, EXT_FM<5>; | 
| Jack Carter | b3f3b17 | 2012-08-31 18:06:48 +0000 | [diff] [blame] | 216 | } | 
| Akira Hatanaka | 20cee2e | 2011-12-05 21:26:34 +0000 | [diff] [blame] | 217 |  | 
| Jack Carter | f4946cf | 2012-08-07 00:35:22 +0000 | [diff] [blame] | 218 | let isCodeGenOnly = 1, rs = 0, shamt = 0 in { | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 219 | def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 220 | "dsll\t$rd, $rt, 32", [], IIArith>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 221 | def SLL64_32 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR32:$rt), | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 222 | "sll\t$rd, $rt, 0", [], IIArith>; | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 223 | def SLL64_64 : FR<0x0, 0x00, (outs GPR64:$rd), (ins GPR64:$rt), | 
| Akira Hatanaka | f8fff21 | 2013-07-31 00:55:34 +0000 | [diff] [blame] | 224 | "sll\t$rd, $rt, 0", [], IIArith>; | 
| Jack Carter | f4946cf | 2012-08-07 00:35:22 +0000 | [diff] [blame] | 225 | } | 
| Akira Hatanaka | 71928e6 | 2012-04-17 18:03:21 +0000 | [diff] [blame] | 226 | } | 
| Akira Hatanaka | 7ba8a8d | 2011-09-30 18:51:46 +0000 | [diff] [blame] | 227 | //===----------------------------------------------------------------------===// | 
|  | 228 | //  Arbitrary patterns that map to one or more instructions | 
|  | 229 | //===----------------------------------------------------------------------===// | 
|  | 230 |  | 
| Akira Hatanaka | f93b3f4 | 2011-11-14 19:06:14 +0000 | [diff] [blame] | 231 | // extended loads | 
| Akira Hatanaka | 6781fc1 | 2013-08-20 21:08:22 +0000 | [diff] [blame] | 232 | let Predicates = [HasStdEnc] in { | 
| Akira Hatanaka | d8ab16b | 2012-06-14 21:03:23 +0000 | [diff] [blame] | 233 | def : MipsPat<(i64 (extloadi1  addr:$src)), (LB64 addr:$src)>; | 
|  | 234 | def : MipsPat<(i64 (extloadi8  addr:$src)), (LB64 addr:$src)>; | 
| Akira Hatanaka | 3e7ba76 | 2012-09-15 01:52:08 +0000 | [diff] [blame] | 235 | def : MipsPat<(i64 (extloadi16 addr:$src)), (LH64 addr:$src)>; | 
|  | 236 | def : MipsPat<(i64 (extloadi32 addr:$src)), (LW64 addr:$src)>; | 
| Akira Hatanaka | f93b3f4 | 2011-11-14 19:06:14 +0000 | [diff] [blame] | 237 | } | 
| Akira Hatanaka | 09b23eb | 2011-10-11 00:55:05 +0000 | [diff] [blame] | 238 |  | 
|  | 239 | // hi/lo relocs | 
| Akira Hatanaka | d8ab16b | 2012-06-14 21:03:23 +0000 | [diff] [blame] | 240 | def : MipsPat<(MipsHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>; | 
|  | 241 | def : MipsPat<(MipsHi tblockaddress:$in), (LUi64 tblockaddress:$in)>; | 
|  | 242 | def : MipsPat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>; | 
|  | 243 | def : MipsPat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>; | 
|  | 244 | def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>; | 
| Akira Hatanaka | bb6e74a | 2012-11-21 20:40:38 +0000 | [diff] [blame] | 245 | def : MipsPat<(MipsHi texternalsym:$in), (LUi64 texternalsym:$in)>; | 
| Akira Hatanaka | 7b8547c | 2011-11-16 22:39:56 +0000 | [diff] [blame] | 246 |  | 
| Akira Hatanaka | d8ab16b | 2012-06-14 21:03:23 +0000 | [diff] [blame] | 247 | def : MipsPat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>; | 
|  | 248 | def : MipsPat<(MipsLo tblockaddress:$in), (DADDiu ZERO_64, tblockaddress:$in)>; | 
|  | 249 | def : MipsPat<(MipsLo tjumptable:$in), (DADDiu ZERO_64, tjumptable:$in)>; | 
|  | 250 | def : MipsPat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>; | 
|  | 251 | def : MipsPat<(MipsLo tglobaltlsaddr:$in), | 
|  | 252 | (DADDiu ZERO_64, tglobaltlsaddr:$in)>; | 
| Akira Hatanaka | bb6e74a | 2012-11-21 20:40:38 +0000 | [diff] [blame] | 253 | def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>; | 
| Akira Hatanaka | 7b8547c | 2011-11-16 22:39:56 +0000 | [diff] [blame] | 254 |  | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 255 | def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)), | 
|  | 256 | (DADDiu GPR64:$hi, tglobaladdr:$lo)>; | 
|  | 257 | def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)), | 
|  | 258 | (DADDiu GPR64:$hi, tblockaddress:$lo)>; | 
|  | 259 | def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)), | 
|  | 260 | (DADDiu GPR64:$hi, tjumptable:$lo)>; | 
|  | 261 | def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)), | 
|  | 262 | (DADDiu GPR64:$hi, tconstpool:$lo)>; | 
|  | 263 | def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)), | 
|  | 264 | (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>; | 
| Akira Hatanaka | f75add6 | 2011-10-11 18:53:46 +0000 | [diff] [blame] | 265 |  | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 266 | def : WrapperPat<tglobaladdr, DADDiu, GPR64>; | 
|  | 267 | def : WrapperPat<tconstpool, DADDiu, GPR64>; | 
|  | 268 | def : WrapperPat<texternalsym, DADDiu, GPR64>; | 
|  | 269 | def : WrapperPat<tblockaddress, DADDiu, GPR64>; | 
|  | 270 | def : WrapperPat<tjumptable, DADDiu, GPR64>; | 
|  | 271 | def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>; | 
| Akira Hatanaka | b2e05cb | 2011-12-07 22:11:43 +0000 | [diff] [blame] | 272 |  | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 273 | defm : BrcondPats<GPR64, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64, | 
| Akira Hatanaka | 7148bce | 2011-10-11 19:09:09 +0000 | [diff] [blame] | 274 | ZERO_64>; | 
|  | 275 |  | 
| Akira Hatanaka | 6871031 | 2013-05-21 17:13:47 +0000 | [diff] [blame] | 276 | def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst), | 
|  | 277 | (BLEZ64 i64:$lhs, bb:$dst)>; | 
|  | 278 | def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst), | 
|  | 279 | (BGEZ64 i64:$lhs, bb:$dst)>; | 
|  | 280 |  | 
| Akira Hatanaka | f75add6 | 2011-10-11 18:53:46 +0000 | [diff] [blame] | 281 | // setcc patterns | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 282 | defm : SeteqPats<GPR64, SLTiu64, XOR64, SLTu64, ZERO_64>; | 
|  | 283 | defm : SetlePats<GPR64, SLT64, SLTu64>; | 
|  | 284 | defm : SetgtPats<GPR64, SLT64, SLTu64>; | 
|  | 285 | defm : SetgePats<GPR64, SLT64, SLTu64>; | 
|  | 286 | defm : SetgeImmPats<GPR64, SLTi64, SLTiu64>; | 
| Akira Hatanaka | d5c1329 | 2011-11-07 18:57:41 +0000 | [diff] [blame] | 287 |  | 
|  | 288 | // truncate | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 289 | def : MipsPat<(i32 (trunc GPR64:$src)), | 
|  | 290 | (SLL (EXTRACT_SUBREG GPR64:$src, sub_32), 0)>, | 
| Akira Hatanaka | 8dd951b | 2013-08-20 23:21:55 +0000 | [diff] [blame] | 291 | Requires<[HasStdEnc]>; | 
| Jia Liu | f54f60f | 2012-02-28 07:46:26 +0000 | [diff] [blame] | 292 |  | 
| Akira Hatanaka | ae378af | 2011-12-07 23:14:41 +0000 | [diff] [blame] | 293 | // 32-to-64-bit extension | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 294 | def : MipsPat<(i64 (anyext GPR32:$src)), (SLL64_32 GPR32:$src)>; | 
|  | 295 | def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>; | 
|  | 296 | def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>; | 
| Akira Hatanaka | 4e21069 | 2011-12-20 22:06:20 +0000 | [diff] [blame] | 297 |  | 
| Akira Hatanaka | 494fdf1 | 2011-12-20 22:40:40 +0000 | [diff] [blame] | 298 | // Sign extend in register | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 299 | def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)), | 
|  | 300 | (SLL64_64 GPR64:$src)>; | 
| Akira Hatanaka | 494fdf1 | 2011-12-20 22:40:40 +0000 | [diff] [blame] | 301 |  | 
| Akira Hatanaka | d8ab16b | 2012-06-14 21:03:23 +0000 | [diff] [blame] | 302 | // bswap MipsPattern | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 303 | def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>; | 
| David Chisnall | 3705125 | 2012-10-09 16:27:43 +0000 | [diff] [blame] | 304 |  | 
| Akira Hatanaka | be8612f | 2013-03-30 01:36:35 +0000 | [diff] [blame] | 305 | // mflo/hi patterns. | 
| Akira Hatanaka | 00fcf2e | 2013-08-08 21:54:26 +0000 | [diff] [blame] | 306 | def : MipsPat<(i64 (ExtractLOHI ACC128:$ac, imm:$lohi_idx)), | 
|  | 307 | (EXTRACT_SUBREG ACC128:$ac, imm:$lohi_idx)>; | 
| Akira Hatanaka | be8612f | 2013-03-30 01:36:35 +0000 | [diff] [blame] | 308 |  | 
| David Chisnall | 3705125 | 2012-10-09 16:27:43 +0000 | [diff] [blame] | 309 | //===----------------------------------------------------------------------===// | 
|  | 310 | // Instruction aliases | 
|  | 311 | //===----------------------------------------------------------------------===// | 
| Jack Carter | 9c1a027 | 2013-02-05 08:32:10 +0000 | [diff] [blame] | 312 | def : InstAlias<"move $dst, $src", | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 313 | (DADDu GPR64Opnd:$dst,  GPR64Opnd:$src, ZERO_64), 1>, | 
| Jack Carter | 9c1a027 | 2013-02-05 08:32:10 +0000 | [diff] [blame] | 314 | Requires<[HasMips64]>; | 
| Jack Carter | 873c724 | 2013-01-12 01:03:14 +0000 | [diff] [blame] | 315 | def : InstAlias<"daddu $rs, $rt, $imm", | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 316 | (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm), | 
| Akira Hatanaka | e2a39e7 | 2013-08-06 22:35:29 +0000 | [diff] [blame] | 317 | 0>; | 
| Jack Carter | 873c724 | 2013-01-12 01:03:14 +0000 | [diff] [blame] | 318 | def : InstAlias<"dadd $rs, $rt, $imm", | 
| Akira Hatanaka | 13e6ccf | 2013-08-06 23:08:38 +0000 | [diff] [blame] | 319 | (DADDi GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm), | 
| Akira Hatanaka | e2a39e7 | 2013-08-06 22:35:29 +0000 | [diff] [blame] | 320 | 0>; | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 321 |  | 
| Jack Carter | 51785c4 | 2013-05-16 19:40:19 +0000 | [diff] [blame] | 322 | /// Move between CPU and coprocessor registers | 
| Akira Hatanaka | 37e9b0d | 2013-08-28 00:42:50 +0000 | [diff] [blame^] | 323 | let DecoderNamespace = "Mips64", Predicates = [HasMips64] in { | 
|  | 324 | def DMFC0 : MFC3OP<"dmfc0", GPR64Opnd>, MFC3OP_FM<0x10, 1>; | 
|  | 325 | def DMTC0 : MFC3OP<"dmtc0", GPR64Opnd>, MFC3OP_FM<0x10, 5>; | 
|  | 326 | def DMFC2 : MFC3OP<"dmfc2", GPR64Opnd>, MFC3OP_FM<0x12, 1>; | 
|  | 327 | def DMTC2 : MFC3OP<"dmtc2", GPR64Opnd>, MFC3OP_FM<0x12, 5>; | 
| David Chisnall | 6a00ab4 | 2012-10-11 10:21:34 +0000 | [diff] [blame] | 328 | } | 
| Jack Carter | 86c2c56 | 2013-01-18 20:15:06 +0000 | [diff] [blame] | 329 |  | 
| David Chisnall | 6a00ab4 | 2012-10-11 10:21:34 +0000 | [diff] [blame] | 330 | // Two operand (implicit 0 selector) versions: | 
| Akira Hatanaka | 37e9b0d | 2013-08-28 00:42:50 +0000 | [diff] [blame^] | 331 | def : InstAlias<"dmfc0 $rt, $rd", (DMFC0 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; | 
|  | 332 | def : InstAlias<"dmtc0 $rt, $rd", (DMTC0 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; | 
|  | 333 | def : InstAlias<"dmfc2 $rt, $rd", (DMFC2 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; | 
|  | 334 | def : InstAlias<"dmtc2 $rt, $rd", (DMTC2 GPR64Opnd:$rt, GPR64Opnd:$rd, 0), 0>; | 
| David Chisnall | 6a00ab4 | 2012-10-11 10:21:34 +0000 | [diff] [blame] | 335 |  |