Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 1 | //===- PIC16InstrInfo.td - PIC16 Register defs ----------------*- tblgen-*-===// |
| 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 | //===----------------------------------------------------------------------===// |
| 11 | // Instruction format superclass |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | include "PIC16InstrFormats.td" |
| 15 | |
| 16 | //===----------------------------------------------------------------------===// |
| 17 | // PIC16 profiles and nodes |
| 18 | //===----------------------------------------------------------------------===// |
| 19 | |
| 20 | //===----------------------------------------------------------------------===// |
| 21 | // PIC16 addressing mode. |
| 22 | //===----------------------------------------------------------------------===// |
| 23 | // It matches address of globals as well as the stack slots |
| 24 | // that are created for locals and temporaries. This addressing mode |
| 25 | // converts the GlobalAddress and FrameIndex nodes to TargetGlobalAddress |
| 26 | // and TargetFrameIndex nodes. |
| 27 | def diraddrmode : ComplexPattern<i16, 2, "SelectDirectAM", [frameindex], []>; |
| 28 | def dirloadmode : ComplexPattern<i16, 2, "LoadNothing", [frameindex], []>; |
| 29 | def indirloadmode : ComplexPattern<i16, 2, "LoadFSR", [frameindex], []>; |
| 30 | |
| 31 | |
| 32 | // Address operand. |
| 33 | def mem : Operand<i16> { |
| 34 | let PrintMethod = "printAddrModeOperand"; |
| 35 | let MIOperandInfo = (ops i16imm, PTRRegs); |
| 36 | } |
| 37 | |
| 38 | // Instruction operand types |
| 39 | def simm8 : Operand<i8>; |
| 40 | |
| 41 | |
| 42 | // These are target-independent nodes, but have target-specific formats. |
| 43 | def SDT_PIC16CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i8> ]>; |
| 44 | def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PIC16CallSeq, |
| 45 | [SDNPHasChain, SDNPOutFlag]>; |
| 46 | def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PIC16CallSeq, |
| 47 | [SDNPHasChain, SDNPOutFlag]>; |
| 48 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 49 | def PIC16Wrapper : SDNode<"PIC16ISD::Wrapper", SDTIntUnaryOp>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 50 | |
| 51 | // so_imm_XFORM - Return a so_imm value packed into the format described for |
| 52 | // so_imm def below. |
| 53 | def so_imm_XFORM : SDNodeXForm<imm, [{ |
Dan Gohman | faeb4a3 | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 54 | return CurDAG->getTargetConstant((int8_t)N->getZExtValue(), MVT::i32); |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 55 | }]>; |
| 56 | |
| 57 | def so_imm : Operand<i8>, |
| 58 | PatLeaf<(imm), [{}]> { |
| 59 | let PrintMethod = "printSOImmOperand"; |
| 60 | } |
| 61 | |
| 62 | |
| 63 | |
| 64 | // PIC16 Address Mode! SDNode frameindex could possibily be a match |
| 65 | // since load and store instructions from stack used it. |
| 66 | def addr : Operand<i16>; |
| 67 | |
| 68 | // Arithmetic 2 register operands |
| 69 | class ArithI<bits<6> op, string instr_asm, SDNode OpNode, |
| 70 | Operand Od> : |
| 71 | LiteralFormat< op, |
| 72 | (outs CPURegs:$dst), |
| 73 | (ins CPURegs:$b, Od:$c), |
| 74 | !strconcat(instr_asm, " $c"), |
| 75 | [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c))]>; |
| 76 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 77 | // Memory Load/Store. |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 78 | class LoadDirect<bits<6> op, string instr_asm, PatFrag OpNode>: |
| 79 | ByteFormat< op, |
| 80 | (outs CPURegs:$dst), |
| 81 | (ins mem:$addr), |
| 82 | !strconcat(instr_asm, " $addr"), |
| 83 | [(set CPURegs:$dst, (OpNode diraddrmode:$addr))]>; |
| 84 | |
| 85 | class LoadInDirect<bits<6> op, string instr_asm, PatFrag OpNode>: |
| 86 | ByteFormat< op, |
| 87 | (outs PTRRegs:$dst), |
| 88 | (ins mem:$addr), |
| 89 | !strconcat(instr_asm, " $addr, $dst"), |
| 90 | [(set PTRRegs:$dst, (OpNode indirloadmode:$addr))]>; |
| 91 | |
| 92 | class StoreDirect<bits<6> op, string instr_asm, PatFrag OpNode>: |
| 93 | ByteFormat< op, |
| 94 | (outs), |
| 95 | (ins CPURegs:$src, mem:$addr), |
| 96 | !strconcat(instr_asm, " $addr"), |
| 97 | [(OpNode CPURegs:$src, diraddrmode:$addr)]>; |
| 98 | |
| 99 | class StoreInDirect<bits<6> op, string instr_asm, PatFrag OpNode>: |
| 100 | ByteFormat< op, |
| 101 | (outs), |
| 102 | (ins CPURegs:$src, PTRRegs:$fsr), |
| 103 | !strconcat(instr_asm, " $fsr"), |
| 104 | [(OpNode CPURegs:$src, PTRRegs:$fsr)]>; |
| 105 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 106 | // Move. |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 107 | class MovLit<bits<6> op, string instr_asm>: |
| 108 | LiteralFormat< op, |
| 109 | (outs CPURegs:$dst), |
| 110 | (ins i8imm:$src), |
| 111 | !strconcat(instr_asm, " $src"), |
| 112 | [(set CPURegs:$dst, imm:$src)]>; |
| 113 | |
| 114 | |
| 115 | // Arithmetic with memory store. |
| 116 | // Arithmetic instrunctions involving W and memory location. |
| 117 | // Since W is implicit, we only print the memory operand. |
| 118 | class Arith1M<bits<6> op, string instr_asm, SDNode OpNode>: |
| 119 | ByteFormat< op, |
| 120 | (outs), |
| 121 | (ins CPURegs:$b, mem:$dst), |
| 122 | !strconcat(instr_asm, " $dst"), |
| 123 | [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst), |
| 124 | (store (OpNode CPURegs:$b, (load diraddrmode:$dst)), diraddrmode:$dst)]>; |
| 125 | |
| 126 | // Arithmetic with memory load. |
| 127 | // Arithmetic instrunctions involving W and memory location. |
| 128 | // Since W is implicit, we only print the memory operand. |
| 129 | class Arith1R<bits<6> op, string instr_asm, SDNode OpNode>: |
| 130 | ByteFormat< op, |
| 131 | (outs CPURegs:$dst), |
| 132 | (ins mem:$src1, CPURegs:$src2), |
| 133 | !strconcat(instr_asm, " $src1"), |
| 134 | [(set CPURegs:$dst, (OpNode (load diraddrmode:$src1), CPURegs:$src2))]>; |
| 135 | |
| 136 | // Arithmetic with memory load. |
| 137 | // Arithmetic instrunctions involving W and memory location. |
| 138 | // Since W is implicit, we only print the memory operand. |
| 139 | class Arith2R<bits<6> op, string instr_asm, SDNode OpNode>: |
| 140 | ByteFormat< op, |
| 141 | (outs CPURegs:$dst), |
| 142 | (ins mem:$src1, CPURegs:$src2), |
| 143 | !strconcat(instr_asm, " $src1"), |
| 144 | [(set CPURegs:$dst, (OpNode CPURegs:$src2, (load diraddrmode:$src1)))]>; |
| 145 | |
| 146 | //===----------------------------------------------------------------------===// |
| 147 | // Instruction definition |
| 148 | //===----------------------------------------------------------------------===// |
| 149 | |
| 150 | //===----------------------------------------------------------------------===// |
| 151 | // PIC16I Instructions |
| 152 | //===----------------------------------------------------------------------===// |
| 153 | |
| 154 | // Arithmetic |
| 155 | |
| 156 | // ADDiu just accept 16-bit immediates but we handle this on Pat's. |
| 157 | // immZExt32 is used here so it can match GlobalAddress immediates. |
| 158 | // def ADDLW : ArithI<0x09, "addlw", add, so_imm>; |
| 159 | |
| 160 | let isReMaterializable = 1 in { |
| 161 | def MOVLW : MovLit<0x24, "movlw">; |
| 162 | } |
| 163 | |
| 164 | // Load/Store |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 165 | def LFSR1 : LoadInDirect <0x4, "lfsr", load>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 166 | |
| 167 | let isReMaterializable = 1 in { |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 168 | def MOVF : LoadDirect <0x23, "movf", load>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 169 | } |
| 170 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 171 | def MOVWF : StoreDirect <0x2b, "movwf", store>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 172 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 173 | def MOVFSRINC : StoreInDirect <0x5, "movfsrinc", store>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 174 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 175 | def RETURN : ControlFormat<0x03, (outs), (ins), "return", []>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 176 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 177 | def ADDWF : Arith1M<0x01, "addwf", add>; |
| 178 | def ADDFW : Arith1R<0x02, "addfw", add>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 179 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 180 | def ADDWFE : Arith1M<0x03, "addwfe", adde>; |
| 181 | def ADDFWE : Arith1R<0x04, "addfwe", adde>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 182 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 183 | def ADDWFC : Arith1M<0x05, "addwfc", addc>; |
| 184 | def ADDFWC : Arith1R<0x06, "addfwc", addc>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 185 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 186 | def SUBWF : Arith1M<0x07, "subwf", sub>; |
| 187 | def SUBFW : Arith1R<0x08, "subfw", sub>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 188 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 189 | def SUBWFE : Arith1M<0x09, "subwfe", sube>; |
| 190 | def SUBFWE : Arith1R<0x0a, "subfwe", sube>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 191 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 192 | def SUBWFC : Arith1M<0x0b, "subwfc", subc>; |
| 193 | def SUBFWC : Arith1R<0x0d, "subfwc", subc>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 194 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 195 | def SUBRFW : Arith2R<0x08, "subfw", sub>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 196 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 197 | def SUBRFWE : Arith2R<0x0a, "subfwe", sube>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 198 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 199 | def SUBRFWC : Arith2R<0x0d, "subfwc", subc>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 200 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 201 | def brtarget : Operand<OtherVT>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 202 | |
| 203 | class UncondJump< bits<4> op, string instr_asm>: |
| 204 | BitFormat< op, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 205 | (outs), |
| 206 | (ins brtarget:$target), |
| 207 | !strconcat(instr_asm, " $target"), |
| 208 | [(br bb:$target)]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 209 | |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 210 | def GOTO : UncondJump<0x1, "goto">; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 211 | |
| 212 | class LogicM<bits<6> op, string instr_asm, SDNode OpNode> : |
| 213 | ByteFormat< op, |
| 214 | (outs), |
| 215 | (ins CPURegs:$b, mem:$dst), |
| 216 | !strconcat(instr_asm, " $dst"), |
| 217 | [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst)]>; |
| 218 | |
| 219 | class LogicR<bits<6> op, string instr_asm, SDNode OpNode> : |
| 220 | ByteFormat< op, |
| 221 | (outs CPURegs:$dst), |
| 222 | (ins CPURegs:$b, mem:$c), |
| 223 | !strconcat(instr_asm, " $c"), |
| 224 | [(set CPURegs:$dst, (OpNode (load diraddrmode:$c), CPURegs:$b))]>; |
| 225 | |
| 226 | class LogicI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od> : |
| 227 | LiteralFormat< op, |
| 228 | (outs CPURegs:$dst), |
| 229 | (ins CPURegs:$b, Od:$c), |
| 230 | !strconcat(instr_asm, " $c"), |
| 231 | [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c ))]>; |
| 232 | |
| 233 | def XORWF : LogicM<0x1,"xorwf",xor>; |
| 234 | def XORFW : LogicR<0x1,"xorfw",xor>; |
| 235 | def XORLW : LogicI<0x1,"xorlw",xor, so_imm>; |
| 236 | |
| 237 | def ANDWF : LogicM<0x1,"andwf",and>; |
| 238 | def ANDFW : LogicR<0x1,"andfw",and>; |
| 239 | def ANDLW : LogicI<0x1,"andlw",and, so_imm>; |
| 240 | |
| 241 | def IORWF : LogicM<0x1,"iorwf",or>; |
| 242 | def IORFW : LogicR<0x1,"iorfw",or>; |
| 243 | def IORLW : LogicI<0x1,"iorlw",or, so_imm>; |
| 244 | |
| 245 | |
| 246 | /* For comparison before branch */ |
| 247 | def SDT_PIC16Cmp : SDTypeProfile<1, 3, [SDTCisSameAs<0,1>]>; |
| 248 | def SDTIntBinOpPIC16 : SDTypeProfile<1, 2, [SDTCisSameAs<0,1>, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 249 | SDTCisSameAs<1,2>, SDTCisInt<1>]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 250 | |
| 251 | def PIC16Cmp : SDNode<"PIC16ISD::Cmp",SDTIntBinOpPIC16, [SDNPOutFlag]>; |
| 252 | def PIC16XORCC : SDNode<"PIC16ISD::XORCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; |
| 253 | def PIC16SUBCC : SDNode<"PIC16ISD::SUBCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; |
| 254 | |
| 255 | def XORFWCC : LogicR<0x1,"xorfw",PIC16XORCC>; |
| 256 | def XORLWCC : LogicI<0x1,"xorlw",PIC16XORCC, so_imm>; |
| 257 | def SUBFWCC : Arith1R<0x1,"subfw",PIC16SUBCC>; |
| 258 | def SUBLWCC : ArithI<0x1,"sublw",PIC16SUBCC, so_imm>; |
| 259 | |
| 260 | |
| 261 | /* For branch conditions */ |
| 262 | def SDT_PIC16Branch : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 263 | SDTCisVT<1,i8>, SDTCisVT<2,i8>]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 264 | |
| 265 | def PIC16Branch : SDNode<"PIC16ISD::Branch",SDT_PIC16Branch, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 266 | [SDNPHasChain, SDNPInFlag]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 267 | |
| 268 | def PIC16BTFSS : SDNode<"PIC16ISD::BTFSS",SDT_PIC16Branch, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 269 | [SDNPHasChain, SDNPInFlag]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 270 | |
| 271 | def PIC16BTFSC : SDNode<"PIC16ISD::BTFSC",SDT_PIC16Branch, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 272 | [SDNPHasChain, SDNPInFlag]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 273 | |
| 274 | class InstrBitTestCC<bits<4> op, string instr_asm,SDNode OpNode>: |
| 275 | BitFormat< op, |
Sanjiv Gupta | 1f7b12b | 2008-05-14 11:31:39 +0000 | [diff] [blame] | 276 | (outs), |
| 277 | (ins brtarget:$target ,so_imm:$i, STATUSRegs:$s ), |
| 278 | !strconcat(instr_asm, " $s, $i, $target"), |
| 279 | [(OpNode bb:$target, so_imm:$i, STATUSRegs:$s )]>; |
Sanjiv Gupta | 09bb420 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 280 | |
| 281 | def BTFSS : InstrBitTestCC<0x1,"btfss",PIC16BTFSS>; |
| 282 | def BTFSC : InstrBitTestCC<0x1,"btfsc",PIC16BTFSC>; |
| 283 | |
| 284 | |
| 285 | //===----------------------------------------------------------------------===// |
| 286 | // Pseudo instructions |
| 287 | //===----------------------------------------------------------------------===// |
| 288 | |
| 289 | let Defs = [STKPTR], Uses = [STKPTR] in { |
| 290 | def ADJCALLSTACKDOWN : Pseudo<255, (outs), (ins i8imm:$amt), |
| 291 | "!ADJCALLSTACKDOWN $amt", |
| 292 | [(callseq_start imm:$amt)]>; |
| 293 | def ADJCALLSTACKUP : Pseudo<254, (outs), (ins i8imm:$amt), |
| 294 | "!ADJCALLSTACKUP $amt", |
| 295 | [(callseq_end imm:$amt)]>; |
| 296 | } |
| 297 | |
| 298 | |
| 299 | //===----------------------------------------------------------------------===// |
| 300 | // Arbitrary patterns that map to one or more instructions |
| 301 | //===----------------------------------------------------------------------===// |
| 302 | def : Pat<(ret), (RETURN)>; |