| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 1 | //===- MipsInstrInfo.td - Mips Register defs --------------------*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 5 | // This file was developed by Bruno Cardoso Lopes and is distributed under the | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 6 | // University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 |  | 
|  | 10 | //===----------------------------------------------------------------------===// | 
|  | 11 | // Instruction format superclass | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | include "MipsInstrFormats.td" | 
|  | 15 |  | 
|  | 16 | //===----------------------------------------------------------------------===// | 
|  | 17 | // Mips profiles and nodes | 
|  | 18 | //===----------------------------------------------------------------------===// | 
|  | 19 |  | 
|  | 20 | // Call | 
|  | 21 | def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; | 
|  | 22 | def MipsJmpLink     : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain, | 
|  | 23 | SDNPOutFlag]>; | 
|  | 24 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 25 | // Hi and Lo nodes are created to let easy manipulation of 16-bit when | 
|  | 26 | // handling 32-bit immediates. They are used on MipsISelLowering to | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 27 | // lower stuff like GlobalAddress, ExternalSymbol, ... on static model | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 28 | // This two nodes have nothing to do with Mips Registers Hi and Lo. | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 29 | def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 30 | def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 31 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 32 | // Necessary to generate glued instructions when loading GlobalAddress | 
|  | 33 | // into registers. | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 34 | def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative, | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 35 | SDNPAssociative, SDNPOptInFlag]>; | 
|  | 36 |  | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 37 | // Used to Load Addresses on PIC code. | 
|  | 38 | def MipsLoadAddr: SDNode<"MipsISD::LoadAddr", SDTIntUnaryOp>; | 
|  | 39 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 40 | // Return | 
|  | 41 | def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; | 
|  | 42 | def MipsRet     : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 43 | SDNPOptInFlag]>; | 
|  | 44 |  | 
|  | 45 | // These are target-independent nodes, but have target-specific formats. | 
|  | 46 | def SDT_MipsCallSeq : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 47 | def callseq_start   : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq, | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 48 | [SDNPHasChain, SDNPOutFlag]>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 49 | def callseq_end     : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq, | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 50 | [SDNPHasChain, SDNPOutFlag]>; | 
|  | 51 |  | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 52 | //===----------------------------------------------------------------------===// | 
|  | 53 | // Mips Instruction Predicate Definitions. | 
|  | 54 | //===----------------------------------------------------------------------===// | 
|  | 55 | def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">; | 
|  | 56 |  | 
|  | 57 | //===----------------------------------------------------------------------===// | 
|  | 58 | // Mips Operand, Complex Patterns and Transformations Definitions. | 
|  | 59 | //===----------------------------------------------------------------------===// | 
|  | 60 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 61 | // Instruction operand types | 
|  | 62 | def brtarget    : Operand<OtherVT>; | 
|  | 63 | def calltarget  : Operand<i32>; | 
|  | 64 | def uimm16      : Operand<i32>; | 
|  | 65 | def simm16      : Operand<i32>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 66 | def shamt       : Operand<i32>; | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 67 | def addrlabel   : Operand<i32>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 68 |  | 
|  | 69 | // Address operand | 
|  | 70 | def mem : Operand<i32> { | 
|  | 71 | let PrintMethod = "printMemOperand"; | 
|  | 72 | let MIOperandInfo = (ops simm16, CPURegs); | 
|  | 73 | } | 
|  | 74 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 75 | // Transformation Function - get the lower 16 bits. | 
|  | 76 | def LO16 : SDNodeXForm<imm, [{ | 
|  | 77 | return getI32Imm((unsigned)N->getValue() & 0xFFFF); | 
|  | 78 | }]>; | 
|  | 79 |  | 
|  | 80 | // Transformation Function - get the higher 16 bits. | 
|  | 81 | def HI16 : SDNodeXForm<imm, [{ | 
|  | 82 | return getI32Imm((unsigned)N->getValue() >> 16); | 
|  | 83 | }]>; | 
|  | 84 |  | 
|  | 85 | // Node immediate fits as 16-bit sign extended on target immediate. | 
|  | 86 | // e.g. addi, andi | 
|  | 87 | def immSExt16  : PatLeaf<(imm), [{ | 
|  | 88 | if (N->getValueType(0) == MVT::i32) | 
|  | 89 | return (int32_t)N->getValue() == (short)N->getValue(); | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 90 | else | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 91 | return (int64_t)N->getValue() == (short)N->getValue(); | 
|  | 92 | }]>; | 
|  | 93 |  | 
|  | 94 | // Node immediate fits as 16-bit zero extended on target immediate. | 
|  | 95 | // The LO16 param means that only the lower 16 bits of the node | 
|  | 96 | // immediate are caught. | 
|  | 97 | // e.g. addiu, sltiu | 
|  | 98 | def immZExt16  : PatLeaf<(imm), [{ | 
| Bruno Cardoso Lopes | c5affec | 2007-07-11 22:47:02 +0000 | [diff] [blame] | 99 | if (N->getValueType(0) == MVT::i32) | 
|  | 100 | return (uint32_t)N->getValue() == (unsigned short)N->getValue(); | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 101 | else | 
| Bruno Cardoso Lopes | c5affec | 2007-07-11 22:47:02 +0000 | [diff] [blame] | 102 | return (uint64_t)N->getValue() == (unsigned short)N->getValue(); | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 103 | }], LO16>; | 
|  | 104 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 105 | // Node immediate fits as 32-bit zero extended on target immediate. | 
|  | 106 | //def immZExt32  : PatLeaf<(imm), [{ | 
|  | 107 | //  return (uint64_t)N->getValue() == (uint32_t)N->getValue(); | 
|  | 108 | //}], LO16>; | 
|  | 109 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 110 | // shamt field must fit in 5 bits. | 
|  | 111 | def immZExt5 : PatLeaf<(imm), [{ | 
|  | 112 | return N->getValue() == ((N->getValue()) & 0x1f) ; | 
|  | 113 | }]>; | 
|  | 114 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 115 | // Mips Address Mode! SDNode frameindex could possibily be a match | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 116 | // since load and store instructions from stack used it. | 
|  | 117 | def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>; | 
|  | 118 |  | 
|  | 119 | //===----------------------------------------------------------------------===// | 
|  | 120 | // Instructions specific format | 
|  | 121 | //===----------------------------------------------------------------------===// | 
|  | 122 |  | 
|  | 123 | // Arithmetic 3 register operands | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 124 | let isCommutable = 1 in | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 125 | class ArithR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode, | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 126 | InstrItinClass itin>: | 
|  | 127 | FR< op, | 
|  | 128 | func, | 
|  | 129 | (outs CPURegs:$dst), | 
|  | 130 | (ins CPURegs:$b, CPURegs:$c), | 
|  | 131 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 132 | [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 133 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 134 | let isCommutable = 1 in | 
|  | 135 | class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm>: | 
|  | 136 | FR< op, | 
|  | 137 | func, | 
|  | 138 | (outs CPURegs:$dst), | 
|  | 139 | (ins CPURegs:$b, CPURegs:$c), | 
|  | 140 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 141 | [], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 142 |  | 
|  | 143 | // Arithmetic 2 register operands | 
|  | 144 | let isCommutable = 1 in | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 145 | class ArithI<bits<6> op, string instr_asm, SDNode OpNode, | 
|  | 146 | Operand Od, PatLeaf imm_type> : | 
|  | 147 | FI< op, | 
|  | 148 | (outs CPURegs:$dst), | 
|  | 149 | (ins CPURegs:$b, Od:$c), | 
|  | 150 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 151 | [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 152 |  | 
|  | 153 | // Arithmetic Multiply ADD/SUB | 
|  | 154 | let rd=0 in | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 155 | class MArithR<bits<6> func, string instr_asm> : | 
|  | 156 | FR< 0x1c, | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 157 | func, | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 158 | (outs CPURegs:$rs), | 
|  | 159 | (ins CPURegs:$rt), | 
|  | 160 | !strconcat(instr_asm, " $rs, $rt"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 161 | [], IIImul>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 162 |  | 
|  | 163 | //  Logical | 
|  | 164 | class LogicR<bits<6> func, string instr_asm, SDNode OpNode>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 165 | FR< 0x00, | 
|  | 166 | func, | 
|  | 167 | (outs CPURegs:$dst), | 
|  | 168 | (ins CPURegs:$b, CPURegs:$c), | 
|  | 169 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 170 | [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 171 |  | 
|  | 172 | class LogicI<bits<6> op, string instr_asm, SDNode OpNode>: | 
|  | 173 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 174 | (outs CPURegs:$dst), | 
|  | 175 | (ins CPURegs:$b, uimm16:$c), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 176 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 177 | [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 178 |  | 
|  | 179 | class LogicNOR<bits<6> op, bits<6> func, string instr_asm>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 180 | FR< op, | 
|  | 181 | func, | 
|  | 182 | (outs CPURegs:$dst), | 
|  | 183 | (ins CPURegs:$b, CPURegs:$c), | 
|  | 184 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 185 | [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 186 |  | 
|  | 187 | // Shifts | 
|  | 188 | let rt = 0 in | 
|  | 189 | class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 190 | FR< 0x00, | 
|  | 191 | func, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 192 | (outs CPURegs:$dst), | 
|  | 193 | (ins CPURegs:$b, shamt:$c), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 194 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 195 | [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 196 |  | 
|  | 197 | class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 198 | FR< 0x00, | 
|  | 199 | func, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 200 | (outs CPURegs:$dst), | 
|  | 201 | (ins CPURegs:$b, CPURegs:$c), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 202 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 203 | [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 204 |  | 
|  | 205 | // Load Upper Imediate | 
|  | 206 | class LoadUpper<bits<6> op, string instr_asm>: | 
|  | 207 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 208 | (outs CPURegs:$dst), | 
|  | 209 | (ins uimm16:$imm), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 210 | !strconcat(instr_asm, " $dst, $imm"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 211 | [], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 212 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 213 | // Memory Load/Store | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 214 | let isLoad = 1, hasDelaySlot = 1 in | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 215 | class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>: | 
|  | 216 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 217 | (outs CPURegs:$dst), | 
|  | 218 | (ins mem:$addr), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 219 | !strconcat(instr_asm, " $dst, $addr"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 220 | [(set CPURegs:$dst, (OpNode addr:$addr))], IILoad>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 221 |  | 
|  | 222 | let isStore = 1 in | 
|  | 223 | class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>: | 
|  | 224 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 225 | (outs), | 
|  | 226 | (ins CPURegs:$dst, mem:$addr), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 227 | !strconcat(instr_asm, " $dst, $addr"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 228 | [(OpNode CPURegs:$dst, addr:$addr)], IIStore>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 229 |  | 
|  | 230 | // Conditional Branch | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 231 | let isBranch = 1, isTerminator=1, hasDelaySlot = 1 in { | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 232 | class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>: | 
|  | 233 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 234 | (outs), | 
|  | 235 | (ins CPURegs:$a, CPURegs:$b, brtarget:$offset), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 236 | !strconcat(instr_asm, " $a, $b, $offset"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 237 | [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)], | 
|  | 238 | IIBranch>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 239 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 240 |  | 
|  | 241 | class CBranchZero<bits<6> op, string instr_asm, PatFrag cond_op>: | 
|  | 242 | FI< op, | 
|  | 243 | (outs), | 
|  | 244 | (ins CPURegs:$src, brtarget:$offset), | 
|  | 245 | !strconcat(instr_asm, " $src, $offset"), | 
|  | 246 | [(brcond (cond_op CPURegs:$src, 0), bb:$offset)], | 
|  | 247 | IIBranch>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 248 | } | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 249 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 250 | // SetCC | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 251 | class SetCC_R<bits<6> op, bits<6> func, string instr_asm, | 
|  | 252 | PatFrag cond_op>: | 
|  | 253 | FR< op, | 
|  | 254 | func, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 255 | (outs CPURegs:$dst), | 
|  | 256 | (ins CPURegs:$b, CPURegs:$c), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 257 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 258 | [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))], | 
|  | 259 | IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 260 |  | 
|  | 261 | class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, | 
|  | 262 | Operand Od, PatLeaf imm_type>: | 
|  | 263 | FI< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 264 | (outs CPURegs:$dst), | 
|  | 265 | (ins CPURegs:$b, Od:$c), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 266 | !strconcat(instr_asm, " $dst, $b, $c"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 267 | [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))], | 
|  | 268 | IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 269 |  | 
|  | 270 | // Unconditional branch | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 271 | let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 272 | class JumpFJ<bits<6> op, string instr_asm>: | 
|  | 273 | FJ< op, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 274 | (outs), | 
|  | 275 | (ins brtarget:$target), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 276 | !strconcat(instr_asm, " $target"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 277 | [(br bb:$target)], IIBranch>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 278 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 279 | let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 280 | class JumpFR<bits<6> op, bits<6> func, string instr_asm>: | 
|  | 281 | FR< op, | 
|  | 282 | func, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 283 | (outs), | 
|  | 284 | (ins CPURegs:$target), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 285 | !strconcat(instr_asm, " $target"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 286 | [], IIBranch>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 287 |  | 
|  | 288 | // Jump and Link (Call) | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 289 | let isCall=1, hasDelaySlot=1, | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 290 | // All calls clobber the non-callee saved registers... | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 291 | Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 292 | T3, T4, T5, T6, T7, T8, T9, K0, K1] in { | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 293 | class JumpLink<bits<6> op, string instr_asm>: | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 294 | FJ< op, | 
|  | 295 | (outs), | 
|  | 296 | (ins calltarget:$target), | 
|  | 297 | !strconcat(instr_asm, " $target"), | 
|  | 298 | [(MipsJmpLink imm:$target)], IIBranch>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 299 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 300 | let rd=31 in | 
|  | 301 | class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm>: | 
|  | 302 | FR< op, | 
|  | 303 | func, | 
|  | 304 | (outs), | 
|  | 305 | (ins CPURegs:$rs), | 
|  | 306 | !strconcat(instr_asm, " $rs"), | 
|  | 307 | [(MipsJmpLink CPURegs:$rs)], IIBranch>; | 
|  | 308 |  | 
|  | 309 | class BranchLink<string instr_asm>: | 
|  | 310 | FI< 0x1, | 
|  | 311 | (outs), | 
|  | 312 | (ins CPURegs:$rs, brtarget:$target), | 
|  | 313 | !strconcat(instr_asm, " $rs, $target"), | 
|  | 314 | [], IIBranch>; | 
|  | 315 | } | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 316 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 317 | // Mul, Div | 
|  | 318 | class MulDiv<bits<6> func, string instr_asm, InstrItinClass itin>: | 
|  | 319 | FR< 0x00, | 
|  | 320 | func, | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 321 | (outs), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 322 | (ins CPURegs:$a, CPURegs:$b), | 
|  | 323 | !strconcat(instr_asm, " $a, $b"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 324 | [], itin>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 325 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 326 | // Move from Hi/Lo | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 327 | class MoveFromTo<bits<6> func, string instr_asm>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 328 | FR< 0x00, | 
|  | 329 | func, | 
|  | 330 | (outs CPURegs:$dst), | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 331 | (ins), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 332 | !strconcat(instr_asm, " $dst"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 333 | [], IIHiLo>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 334 |  | 
|  | 335 | // Count Leading Ones/Zeros in Word | 
|  | 336 | class CountLeading<bits<6> func, string instr_asm>: | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 337 | FR< 0x1c, | 
|  | 338 | func, | 
|  | 339 | (outs CPURegs:$dst), | 
|  | 340 | (ins CPURegs:$src), | 
|  | 341 | !strconcat(instr_asm, " $dst, $src"), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 342 | [], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 343 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 344 | class EffectiveAddress<string instr_asm> : | 
|  | 345 | FI<0x09, | 
|  | 346 | (outs CPURegs:$dst), | 
| Bruno Cardoso Lopes | 6d5ada2 | 2007-09-24 20:15:11 +0000 | [diff] [blame] | 347 | (ins mem:$addr), | 
|  | 348 | instr_asm, | 
|  | 349 | [(set CPURegs:$dst, addr:$addr)], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 350 |  | 
|  | 351 | //===----------------------------------------------------------------------===// | 
|  | 352 | // Pseudo instructions | 
|  | 353 | //===----------------------------------------------------------------------===// | 
|  | 354 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 355 | // As stack alignment is always done with addiu, we need a 16-bit immediate | 
| Evan Cheng | 3e18e50 | 2007-09-11 19:55:27 +0000 | [diff] [blame] | 356 | let Defs = [SP], Uses = [SP] in { | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 357 | def ADJCALLSTACKDOWN : PseudoInstMips<(outs), (ins uimm16:$amt), | 
|  | 358 | "!ADJCALLSTACKDOWN $amt", | 
|  | 359 | [(callseq_start imm:$amt)]>; | 
|  | 360 | def ADJCALLSTACKUP   : PseudoInstMips<(outs), (ins uimm16:$amt), | 
|  | 361 | "!ADJCALLSTACKUP $amt", | 
|  | 362 | [(callseq_end imm:$amt)]>; | 
| Evan Cheng | 3e18e50 | 2007-09-11 19:55:27 +0000 | [diff] [blame] | 363 | } | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 364 |  | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 365 | def IMPLICIT_DEF_CPURegs : PseudoInstMips<(outs CPURegs:$dst), (ins), | 
|  | 366 | "!IMPLICIT_DEF $dst", | 
|  | 367 | [(set CPURegs:$dst, (undef))]>; | 
|  | 368 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 369 | // When handling PIC code the assembler needs .cpload and .cprestore | 
|  | 370 | // directives. If the real instructions corresponding these directives | 
|  | 371 | // are used, we have the same behavior, but get also a bunch of warnings | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 372 | // from the assembler. | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 373 | def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg), | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 374 | ".set noreorder\n\t.cpload $reg\n\t.set reorder", []>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 375 | def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc), | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 376 | ".cprestore $loc", []>; | 
|  | 377 |  | 
|  | 378 | // Used on PIC code only, it loads the address of label into register reg. The | 
|  | 379 | // address is calculated from the global pointer ($gp) and is expanded by the | 
|  | 380 | // assembler into two instructions "lw" and "addiu". | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 381 | def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label), | 
| Bruno Cardoso Lopes | 5cef9cf | 2007-10-09 02:55:31 +0000 | [diff] [blame] | 382 | "la $dst, $label", []>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 383 |  | 
|  | 384 | //===----------------------------------------------------------------------===// | 
|  | 385 | // Instruction definition | 
|  | 386 | //===----------------------------------------------------------------------===// | 
|  | 387 |  | 
|  | 388 | //===----------------------------------------------------------------------===// | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 389 | // MipsI Instructions | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 390 | //===----------------------------------------------------------------------===// | 
|  | 391 |  | 
|  | 392 | // Arithmetic | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 393 |  | 
|  | 394 | // ADDiu just accept 16-bit immediates but we handle this on Pat's. | 
|  | 395 | // immZExt32 is used here so it can match GlobalAddress immediates. | 
|  | 396 | def ADDiu   : ArithI<0x09, "addiu", MipsAdd, uimm16, immZExt16>; | 
|  | 397 | def ADDi    : ArithI<0x08, "addi",  add, simm16, immSExt16>; | 
|  | 398 | def MUL     : ArithR<0x1c, 0x02, "mul", mul, IIImul>; | 
|  | 399 | def ADDu    : ArithR<0x00, 0x21, "addu", add, IIAlu>; | 
|  | 400 | def SUBu    : ArithR<0x00, 0x23, "subu", sub, IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 401 | def ADD     : ArithOverflowR<0x00, 0x20, "add">; | 
|  | 402 | def SUB     : ArithOverflowR<0x00, 0x22, "sub">; | 
|  | 403 | def MADD    : MArithR<0x00, "madd">; | 
|  | 404 | def MADDU   : MArithR<0x01, "maddu">; | 
|  | 405 | def MSUB    : MArithR<0x04, "msub">; | 
|  | 406 | def MSUBU   : MArithR<0x05, "msubu">; | 
|  | 407 |  | 
|  | 408 | // Logical | 
|  | 409 | def AND     : LogicR<0x24, "and", and>; | 
|  | 410 | def OR      : LogicR<0x25, "or",  or>; | 
|  | 411 | def XOR     : LogicR<0x26, "xor", xor>; | 
|  | 412 | def ANDi    : LogicI<0x0c, "andi", and>; | 
|  | 413 | def ORi     : LogicI<0x0d, "ori",  or>; | 
|  | 414 | def XORi    : LogicI<0x0e, "xori",  xor>; | 
|  | 415 | def NOR     : LogicNOR<0x00, 0x27, "nor">; | 
|  | 416 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 417 | // Shifts | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 418 | def SLL     : LogicR_shift_imm<0x00, "sll", shl>; | 
|  | 419 | def SRL     : LogicR_shift_imm<0x02, "srl", srl>; | 
|  | 420 | def SRA     : LogicR_shift_imm<0x03, "sra", sra>; | 
|  | 421 | def SLLV    : LogicR_shift_reg<0x04, "sllv", shl>; | 
|  | 422 | def SRLV    : LogicR_shift_reg<0x06, "srlv", srl>; | 
|  | 423 | def SRAV    : LogicR_shift_reg<0x07, "srav", sra>; | 
|  | 424 |  | 
|  | 425 | // Load Upper Immediate | 
|  | 426 | def LUi     : LoadUpper<0x0f, "lui">; | 
|  | 427 |  | 
|  | 428 | // Load/Store | 
|  | 429 | def LB      : LoadM<0x20, "lb",  sextloadi8>; | 
|  | 430 | def LBu     : LoadM<0x24, "lbu", zextloadi8>; | 
|  | 431 | def LH      : LoadM<0x21, "lh",  sextloadi16>; | 
|  | 432 | def LHu     : LoadM<0x25, "lhu", zextloadi16>; | 
|  | 433 | def LW      : LoadM<0x23, "lw",  load>; | 
|  | 434 | def SB      : StoreM<0x28, "sb", truncstorei8>; | 
|  | 435 | def SH      : StoreM<0x29, "sh", truncstorei16>; | 
|  | 436 | def SW      : StoreM<0x2b, "sw", store>; | 
|  | 437 |  | 
|  | 438 | // Conditional Branch | 
|  | 439 | def BEQ     : CBranch<0x04, "beq", seteq>; | 
|  | 440 | def BNE     : CBranch<0x05, "bne", setne>; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 441 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 442 | let rt=1 in | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 443 | def BGEZ    : CBranchZero<0x01, "bgez", setge>; | 
|  | 444 |  | 
|  | 445 | let rt=0 in { | 
|  | 446 | def BGTZ    : CBranchZero<0x07, "bgtz", setgt>; | 
|  | 447 | def BLEZ    : CBranchZero<0x07, "blez", setle>; | 
|  | 448 | def BLTZ    : CBranchZero<0x01, "bltz", setlt>; | 
|  | 449 | } | 
|  | 450 |  | 
|  | 451 | // Set Condition Code | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 452 | def SLT     : SetCC_R<0x00, 0x2a, "slt", setlt>; | 
|  | 453 | def SLTu    : SetCC_R<0x00, 0x2b, "sltu", setult>; | 
|  | 454 | def SLTi    : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>; | 
|  | 455 | def SLTiu   : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>; | 
|  | 456 |  | 
|  | 457 | // Unconditional jump | 
|  | 458 | def J       : JumpFJ<0x02, "j">; | 
|  | 459 | def JR      : JumpFR<0x00, 0x08, "jr">; | 
|  | 460 |  | 
|  | 461 | // Jump and Link (Call) | 
|  | 462 | def JAL     : JumpLink<0x03, "jal">; | 
|  | 463 | def JALR    : JumpLinkReg<0x00, 0x09, "jalr">; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 464 | def BGEZAL  : BranchLink<"bgezal">; | 
|  | 465 | def BLTZAL  : BranchLink<"bltzal">; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 466 |  | 
|  | 467 | // MulDiv and Move From Hi/Lo operations, have | 
|  | 468 | // their correpondent SDNodes created on ISelDAG. | 
|  | 469 | // Special Mul, Div operations | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 470 | def MULT    : MulDiv<0x18, "mult", IIImul>; | 
|  | 471 | def MULTu   : MulDiv<0x19, "multu", IIImul>; | 
|  | 472 | def DIV     : MulDiv<0x1a, "div", IIIdiv>; | 
|  | 473 | def DIVu    : MulDiv<0x1b, "divu", IIIdiv>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 474 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 475 | // Move From Hi/Lo | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 476 | def MFHI    : MoveFromTo<0x10, "mfhi">; | 
|  | 477 | def MFLO    : MoveFromTo<0x12, "mflo">; | 
|  | 478 | def MTHI    : MoveFromTo<0x11, "mthi">; | 
|  | 479 | def MTLO    : MoveFromTo<0x13, "mtlo">; | 
|  | 480 |  | 
|  | 481 | // Count Leading | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 482 | // CLO/CLZ are part of the newer MIPS32(tm) instruction | 
|  | 483 | // set and not older Mips I keep this for future use | 
|  | 484 | // though. | 
|  | 485 | //def CLO     : CountLeading<0x21, "clo">; | 
|  | 486 | //def CLZ     : CountLeading<0x20, "clz">; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 487 |  | 
|  | 488 | // No operation | 
|  | 489 | let addr=0 in | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 490 | def NOP     : FJ<0, (outs), (ins), "nop", [], IIAlu>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 491 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 492 | // Ret instruction - as mips does not have "ret" a | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 493 | // jr $ra must be generated. | 
| Evan Cheng | ac1591b | 2007-07-21 00:34:19 +0000 | [diff] [blame] | 494 | let isReturn=1, isTerminator=1, hasDelaySlot=1, | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 495 | isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 496 | { | 
| Evan Cheng | 94b5a80 | 2007-07-19 01:14:50 +0000 | [diff] [blame] | 497 | def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 498 | "jr $target", [(MipsRet CPURegs:$target)], IIBranch>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 499 | } | 
|  | 500 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 501 | // FrameIndexes are legalized when they are operands from load/store | 
| Bruno Cardoso Lopes | 6d5ada2 | 2007-09-24 20:15:11 +0000 | [diff] [blame] | 502 | // instructions. The same not happens for stack address copies, so an | 
|  | 503 | // add op with mem ComplexPattern is used and the stack address copy | 
|  | 504 | // can be matched. It's similar to Sparc LEA_ADDRi | 
|  | 505 | def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">; | 
|  | 506 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 507 | //===----------------------------------------------------------------------===// | 
|  | 508 | //  Arbitrary patterns that map to one or more instructions | 
|  | 509 | //===----------------------------------------------------------------------===// | 
|  | 510 |  | 
|  | 511 | // Small immediates | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 512 | def : Pat<(i32 immSExt16:$in), | 
| Bruno Cardoso Lopes | c5affec | 2007-07-11 22:47:02 +0000 | [diff] [blame] | 513 | (ADDiu ZERO, imm:$in)>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 514 | def : Pat<(i32 immZExt16:$in), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 515 | (ORi ZERO, imm:$in)>; | 
|  | 516 |  | 
|  | 517 | // Arbitrary immediates | 
|  | 518 | def : Pat<(i32 imm:$imm), | 
|  | 519 | (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>; | 
|  | 520 |  | 
|  | 521 | // Call | 
|  | 522 | def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)), | 
|  | 523 | (JAL tglobaladdr:$dst)>; | 
|  | 524 | def : Pat<(MipsJmpLink (i32 texternalsym:$dst)), | 
|  | 525 | (JAL texternalsym:$dst)>; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 526 | def : Pat<(MipsJmpLink CPURegs:$dst), | 
|  | 527 | (JALR CPURegs:$dst)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 528 |  | 
|  | 529 | // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable | 
|  | 530 | def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; | 
|  | 531 | def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 532 | def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)), | 
|  | 533 | (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 534 | def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 535 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 536 | // Mips does not have not, so we increase the operation | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 537 | def : Pat<(not CPURegs:$in), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 538 | (NOR CPURegs:$in, ZERO)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 539 |  | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 540 | // extended load and stores | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 541 | def : Pat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 542 | def : Pat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>; | 
|  | 543 | def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 544 | def : Pat<(truncstorei1 CPURegs:$src, addr:$addr), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 545 | (SB CPURegs:$src, addr:$addr)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 546 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 547 | /// | 
|  | 548 | /// brcond patterns | 
|  | 549 | /// | 
|  | 550 |  | 
|  | 551 | // direct match equal/notequal zero branches | 
|  | 552 | def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst), | 
| Bruno Cardoso Lopes | c5affec | 2007-07-11 22:47:02 +0000 | [diff] [blame] | 553 | (BNE CPURegs:$lhs, ZERO, bb:$dst)>; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 554 | def : Pat<(brcond (seteq CPURegs:$lhs, 0), bb:$dst), | 
|  | 555 | (BEQ CPURegs:$lhs, ZERO, bb:$dst)>; | 
| Bruno Cardoso Lopes | c5affec | 2007-07-11 22:47:02 +0000 | [diff] [blame] | 556 |  | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 557 | def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 558 | (BGEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 559 | def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 560 | (BGEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 561 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 562 | def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 563 | (BGTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 564 | def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 565 | (BGTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 566 |  | 
|  | 567 | def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 568 | (BLEZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 569 | def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 570 | (BLEZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 571 |  | 
|  | 572 | def : Pat<(brcond (setlt CPURegs:$lhs, immSExt16:$rhs), bb:$dst), | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 573 | (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; | 
| Bruno Cardoso Lopes | 35e43c4 | 2007-06-06 07:42:06 +0000 | [diff] [blame] | 574 | def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst), | 
|  | 575 | (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>; | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 576 | def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 577 | (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>; | 
|  | 578 | def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 579 | (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>; | 
|  | 580 |  | 
|  | 581 | def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 582 | (BLTZ (SUB CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 583 | def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst), | 
|  | 584 | (BLTZ (SUBu CPURegs:$lhs, CPURegs:$rhs), bb:$dst)>; | 
|  | 585 |  | 
|  | 586 | // generic brcond pattern | 
|  | 587 | def : Pat<(brcond CPURegs:$cond, bb:$dst), | 
|  | 588 | (BNE CPURegs:$cond, ZERO, bb:$dst)>; | 
|  | 589 |  | 
|  | 590 | /// | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 591 | /// setcc patterns, only matched when there | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 592 | /// is no brcond following a setcc operation | 
|  | 593 | /// | 
|  | 594 |  | 
|  | 595 | // setcc 2 register operands | 
|  | 596 | def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs), | 
|  | 597 | (XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>; | 
|  | 598 | def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs), | 
|  | 599 | (XORi (SLTu CPURegs:$rhs, CPURegs:$lhs), 1)>; | 
|  | 600 |  | 
|  | 601 | def : Pat<(setgt CPURegs:$lhs, CPURegs:$rhs), | 
|  | 602 | (SLT CPURegs:$rhs, CPURegs:$lhs)>; | 
|  | 603 | def : Pat<(setugt CPURegs:$lhs, CPURegs:$rhs), | 
|  | 604 | (SLTu CPURegs:$rhs, CPURegs:$lhs)>; | 
|  | 605 |  | 
|  | 606 | def : Pat<(setge CPURegs:$lhs, CPURegs:$rhs), | 
|  | 607 | (XORi (SLT CPURegs:$lhs, CPURegs:$rhs), 1)>; | 
|  | 608 | def : Pat<(setuge CPURegs:$lhs, CPURegs:$rhs), | 
|  | 609 | (XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>; | 
|  | 610 |  | 
|  | 611 | def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 612 | (OR (SLT CPURegs:$lhs, CPURegs:$rhs), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 613 | (SLT CPURegs:$rhs, CPURegs:$lhs))>; | 
|  | 614 |  | 
|  | 615 | def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs), | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 616 | (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs), | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 617 | (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>; | 
| Eric Christopher | 1806391 | 2007-10-26 04:00:13 +0000 | [diff] [blame] | 618 |  | 
| Bruno Cardoso Lopes | 9fbef51 | 2007-08-18 02:37:46 +0000 | [diff] [blame] | 619 | // setcc reg/imm operands | 
|  | 620 | def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs), | 
|  | 621 | (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>; | 
|  | 622 | def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs), | 
|  | 623 | (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>; |