Rename getABITypeSize to getTypePaddedSize, as
[oota-llvm.git] / lib / Target / PIC16 / PIC16InstrInfo.td
1 //===- PIC16InstrInfo.td - PIC16 Instruction 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 // This file describes the ARM instructions in TableGen format.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------------------------------------------===//
15 // PIC16 Specific Type Constraints.
16 //===----------------------------------------------------------------------===//
17 class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
18 class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
19
20 //===----------------------------------------------------------------------===//
21 // PIC16 Specific Type Profiles.
22 //===----------------------------------------------------------------------===//
23
24 // Generic type profiles for i8/i16 unary/binary operations.
25 // Taking one i8 or i16 and producing void.
26 def SDTI8VoidOp : SDTypeProfile<0, 1, [SDTCisI8<0>]>;
27 def SDTI16VoidOp : SDTypeProfile<0, 1, [SDTCisI16<0>]>;
28
29 // Taking one value and producing an output of same type.
30 def SDTI8UnaryOp : SDTypeProfile<1, 1, [SDTCisI8<0>, SDTCisI8<1>]>;
31 def SDTI16UnaryOp : SDTypeProfile<1, 1, [SDTCisI16<0>, SDTCisI16<1>]>;
32
33 // Taking two values and producing an output of same type.
34 def SDTI8BinOp : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>]>;
35 def SDTI16BinOp : SDTypeProfile<1, 2, [SDTCisI16<0>, SDTCisI16<1>, 
36                                        SDTCisI16<2>]>;
37
38 // Node specific type profiles.
39 def SDT_PIC16Load : SDTypeProfile<1, 3, [SDTCisI8<0>, SDTCisI8<1>, 
40                                           SDTCisI8<2>, SDTCisI8<3>]>;
41 def SDT_PIC16Store : SDTypeProfile<0, 4, [SDTCisI8<0>, SDTCisI8<1>, 
42                                           SDTCisI8<2>, SDTCisI8<3>]>;
43
44 //===----------------------------------------------------------------------===//
45 // PIC16 addressing modes matching via DAG.
46 //===----------------------------------------------------------------------===//
47 def diraddr : ComplexPattern<i8, 1, "SelectDirectAddr", [], []>;
48
49 //===----------------------------------------------------------------------===//
50 // PIC16 Specific Node Definitions.
51 //===----------------------------------------------------------------------===//
52 def PIC16callseq_start : SDNode<"ISD::CALLSEQ_START", SDTI8VoidOp,
53                                 [SDNPHasChain, SDNPOutFlag]>;
54 def PIC16callseq_end   : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp, 
55                                 [SDNPHasChain, SDNPOutFlag]>;
56
57 // Low 8-bits of GlobalAddress.
58 def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>;  
59
60 // High 8-bits of GlobalAddress.
61 def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>;
62
63 // The MTHI and MTLO nodes are used only to match them in the incoming 
64 // DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions.
65 // These nodes are not used for defining any instructions.
66 def MTLO : SDNode<"PIC16ISD::MTLO", SDTI8UnaryOp>;
67 def MTHI : SDNode<"PIC16ISD::MTHI", SDTI8UnaryOp>;
68
69 // Node to generate Bank Select for a GlobalAddress.
70 def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>;
71
72 // Node to match a direct store operation.
73 def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>;
74
75 // Node to match a direct load operation.
76 def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
77
78 // Nodes to match bitwise operatios.
79 def OR : SDNode<"ISD::OR", SDTI8BinOp>;
80 def XOR : SDNode<"ISD::XOR", SDTI8BinOp>;
81 def AND : SDNode<"ISD::AND", SDTI8BinOp>; 
82 //===----------------------------------------------------------------------===//
83 // PIC16 Operand Definitions.
84 //===----------------------------------------------------------------------===//
85 def i8mem : Operand<i8>;
86
87 include "PIC16InstrFormats.td"
88
89 //===----------------------------------------------------------------------===//
90 // PIC16 Common Classes.
91 //===----------------------------------------------------------------------===//
92
93 // W = W Op F : Load the value from F and do Op to W
94 class BinOpFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
95   ByteFormat<OpCode, (outs GPR:$dst),
96              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
97               !strconcat(OpcStr, " $ptrlo + $offset, W"),
98              [(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
99                                              (i8 imm:$ptrhi),
100                                              (i8 imm:$offset))))]>;
101 // F = F Op W : Load the value from F, do op with W and store in F
102 class BinOpWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
103   ByteFormat<OpCode, (outs),
104              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
105               !strconcat(OpcStr, " $ptrlo + $offset"),
106              [(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
107                                              (i8 imm:$ptrhi),
108                                              (i8 imm:$offset))),
109                                              diraddr:$ptrlo,
110                                              (i8 imm:$ptrhi), (i8 imm:$offset)
111                                              )]>;
112
113 //===----------------------------------------------------------------------===//
114 // PIC16 Instructions.
115 //===----------------------------------------------------------------------===//
116
117 // Pseudo-instructions.
118 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
119                        "!ADJCALLSTACKDOWN $amt",
120                        [(PIC16callseq_start imm:$amt)]>;
121
122 def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
123                        "!ADJCALLSTACKUP $amt", 
124                        [(PIC16callseq_end imm:$amt)]>;
125
126 //-----------------------------------
127 // Vaious movlw insn patterns.
128 //-----------------------------------
129 let isReMaterializable = 1 in {
130 // Move 8-bit literal to W.
131 def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
132                       "movlw $src",
133                       [(set GPR:$dst, (i8 imm:$src))]>;
134
135 // Move a Lo(TGA) to W.
136 def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
137                       "movlw LOW(${src})",
138                       [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
139
140 // Move a Hi(TGA) to W.
141 def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
142                       "movlw HIGH(${src})",
143                       [(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>;
144 }
145
146 //-------------------
147 // FSR setting insns. 
148 //-------------------
149 // These insns are matched via a DAG replacement pattern.
150 def set_fsrlo:
151   ByteFormat<0, (outs FSR16:$fsr), 
152              (ins GPR:$val),
153              "movwf ${fsr}L",
154              []>;
155
156 let isTwoAddress = 1 in
157 def set_fsrhi:
158   ByteFormat<0, (outs FSR16:$dst), 
159              (ins FSR16:$src, GPR:$val),
160              "movwf ${dst}H",
161              []>;
162
163 def copy_fsr:
164   Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
165
166 //--------------------------
167 // Store to memory
168 //-------------------------
169 // Direct store.
170 def movwf : 
171   ByteFormat<0, (outs), 
172              (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
173              "movwf ${ptrlo} + ${offset}",
174              [(PIC16Store GPR:$val, tglobaladdr:$ptrlo, (i8 imm:$ptrhi), 
175                (i8 imm:$offset))]>;
176
177 def movwf_1 : 
178   ByteFormat<0, (outs), 
179              (ins GPR:$val, i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
180              "movwf ${ptrlo} + ${offset}",
181              [(PIC16Store GPR:$val, texternalsym:$ptrlo, (i8 imm:$ptrhi), 
182                (i8 imm:$offset))]>;
183
184 // Indirect store. Matched via a DAG replacement pattern.
185 def store_indirect : 
186   ByteFormat<0, (outs), 
187              (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
188              "movwi $offset[$fsr]",
189              []>;
190
191 //----------------------------
192 // Load from memory
193 //----------------------------
194 // Direct load.
195 def movf : 
196   ByteFormat<0, (outs GPR:$dst), 
197              (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
198              "movf ${ptrlo} + ${offset}, W",
199              [(set GPR:$dst, 
200                (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi),
201                (i8 imm:$offset)))]>;
202
203 def movf_1 : 
204   ByteFormat<0, (outs GPR:$dst), 
205              (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
206              "movf ${ptrlo} + ${offset}, W",
207              [(set GPR:$dst, 
208                (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi),
209                (i8 imm:$offset)))]>;
210
211 // Indirect load. Matched via a DAG replacement pattern.
212 def load_indirect : 
213   ByteFormat<0, (outs GPR:$dst), 
214              (ins FSR16:$fsr, i8imm:$offset),
215              "moviw $offset[$fsr]",
216              []>;
217
218 //-------------------------
219 // Bitwise operations patterns
220 //--------------------------
221 def OrFW :  BinOpFW<0, "iorwf", OR>;
222 def XOrFW : BinOpFW<0, "xorwf", XOR>;
223 def AndFW : BinOpFW<0, "andwf", AND>;
224
225 def OrWF :  BinOpWF<0, "iorwf", OR>;
226 def XOrWF : BinOpWF<0, "xorwf", XOR>;
227 def AndWF : BinOpWF<0, "andwf", AND>;
228
229 //-------------------------
230 // Various add/sub patterns.
231 //-------------------------
232
233 // let isTwoAddress = 1 in {
234 def addfw_1: BinOpFW<0, "addwf", add>;
235 def addfw_2: BinOpFW<0, "addwf", addc>;
236 def addfwc: BinOpFW<0, "addwfc", adde>;  // With Carry.
237 // }
238
239 def addwf_1: BinOpWF<0, "addwf", add>;
240 def addwf_2: BinOpWF<0, "addwf", addc>;
241 def addwfc: BinOpWF<0, "addwfc", adde>;  // With Carry.
242
243 // W -= [F] ; load from F and sub the value from W.
244 class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
245   ByteFormat<OpCode, (outs GPR:$dst),
246              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
247               !strconcat(OpcStr, " $ptrlo + $offset, W"),
248              [(set GPR:$dst, (OpNode (PIC16Load diraddr:$ptrlo,
249                                       (i8 imm:$ptrhi), (i8 imm:$offset)),
250                                       GPR:$src))]>;
251 //let isTwoAddress = 1 in {
252 def subfw_1: SUBFW<0, "subwf", sub>;
253 def subfw_2: SUBFW<0, "subwf", subc>;
254 def subfwb: SUBFW<0, "subwfb", sube>;  // With Borrow.
255 //}
256
257 // [F] -= W ; 
258 class SUBWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
259   ByteFormat<OpCode, (outs),
260              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
261               !strconcat(OpcStr, " $ptrlo + $offset"),
262              [(PIC16Store (OpNode (PIC16Load diraddr:$ptrlo,
263                                       (i8 imm:$ptrhi), (i8 imm:$offset)),
264                                       GPR:$src), diraddr:$ptrlo,
265                                       (i8 imm:$ptrhi), (i8 imm:$offset))]>;
266
267 def subwf_1: SUBWF<0, "subwf", sub>;
268 def subwf_2: SUBWF<0, "subwf", subc>;
269 def subwfb: SUBWF<0, "subwfb", sube>;  // With Borrow.
270
271 // addlw 
272 // W += C ; add literal to W. (Without carry). May Produce a carry.
273 class ADDLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
274   LiteralFormat<opcode, (outs GPR:$dst),
275                 (ins GPR:$src, i8imm:$literal),
276                 !strconcat(OpcStr, " $literal"),
277                 [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>;
278
279 // let isTwoAddress = 1 in {
280 def addlw_1 : ADDLW<0, "addlw", add>;
281 def addlw_2 : ADDLW<0, "addlw", addc>;
282 def addlwc : ADDLW<0, "addlwc", adde>; // With Carry. (Assembler macro).
283 //}
284
285 // sublw 
286 // W = C - W ; sub W from literal. (Without borrow).
287 class SUBLW<bits<6> opcode, SDNode OpNode> :
288   LiteralFormat<opcode, (outs GPR:$dst),
289                 (ins GPR:$src, i8imm:$literal),
290                 "addlw $literal",
291                 [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
292
293 //let isTwoAddress = 1 in {
294 def sublw_1 : SUBLW<0, sub>;
295 def sublw_2 : SUBLW<0, subc>;
296 //}
297
298 // Banksel.
299 let isReMaterializable = 1 in {
300 def banksel : 
301   Pseudo<(outs BSR:$dst),
302          (ins i8mem:$ptr),
303          "banksel $ptr",
304          [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>;
305 }
306
307 // Return insn.
308 def Return : 
309   ControlFormat<0, (outs), (ins), "return", [(ret)]>;
310                       
311 //===----------------------------------------------------------------------===//
312 // PIC16 Replacment Patterns.
313 //===----------------------------------------------------------------------===//
314
315 // Identify an indirect store and select insns for it.
316 def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
317            imm:$offset),
318           (store_indirect GPR:$val, 
319            (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
320            imm:$offset)>;
321
322 // Identify an indirect load and select insns for it.
323 def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
324            imm:$offset),
325           (load_indirect  (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
326            imm:$offset)>;
327