Added a more function PIC16 backend. However to get this working a patch in
[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 //===----------------------------------------------------------------------===//
79 // PIC16 Operand Definitions.
80 //===----------------------------------------------------------------------===//
81 def i8mem : Operand<i8>;
82
83
84
85 //===----------------------------------------------------------------------===//
86 // PIC16 Instructions.
87 //===----------------------------------------------------------------------===//
88 include "PIC16InstrFormats.td"
89
90 // Pseudo-instructions.
91 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
92                        "!ADJCALLSTACKDOWN $amt",
93                        [(PIC16callseq_start imm:$amt)]>;
94
95 def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
96                        "!ADJCALLSTACKUP $amt", 
97                        [(PIC16callseq_end imm:$amt)]>;
98
99 //-----------------------------------
100 // Vaious movlw insn patterns.
101 //-----------------------------------
102 let isReMaterializable = 1 in {
103 // Move 8-bit literal to W.
104 def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
105                       "movlw $src",
106                       [(set GPR:$dst, (i8 imm:$src))]>;
107
108 // Move a Lo(TGA) to W.
109 def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
110                       "movlw LOW(${src})",
111                       [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
112
113 // Move a Hi(TGA) to W.
114 def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
115                       "movlw HIGH(${src})",
116                       [(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>;
117 }
118
119 //-------------------
120 // FSR setting insns. 
121 //-------------------
122 // These insns are matched via a DAG replacement pattern.
123 def set_fsrlo:
124   ByteFormat<0, (outs FSR16:$fsr), 
125              (ins GPR:$val),
126              "movwf ${fsr}L",
127              []>;
128
129 let isTwoAddress = 1 in
130 def set_fsrhi:
131   ByteFormat<0, (outs FSR16:$dst), 
132              (ins FSR16:$src, GPR:$val),
133              "movwf ${dst}H",
134              []>;
135
136 def copy_fsr:
137   Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
138
139 //--------------------------
140 // Store to memory
141 //-------------------------
142 // Direct store.
143 def movwf : 
144   ByteFormat<0, (outs), 
145              (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
146              "movwf ${ptrlo} + ${offset}",
147              [(PIC16Store GPR:$val, tglobaladdr:$ptrlo, (i8 imm:$ptrhi), 
148                (i8 imm:$offset))]>;
149
150 def movwf_1 : 
151   ByteFormat<0, (outs), 
152              (ins GPR:$val, i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
153              "movwf ${ptrlo} + ${offset}",
154              [(PIC16Store GPR:$val, texternalsym:$ptrlo, (i8 imm:$ptrhi), 
155                (i8 imm:$offset))]>;
156
157 // Indirect store. Matched via a DAG replacement pattern.
158 def store_indirect : 
159   ByteFormat<0, (outs), 
160              (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
161              "movwi $offset[$fsr]",
162              []>;
163
164 //----------------------------
165 // Load from memory
166 //----------------------------
167 // Direct load.
168 def movf : 
169   ByteFormat<0, (outs GPR:$dst), 
170              (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
171              "movf ${ptrlo} + ${offset}, W",
172              [(set GPR:$dst, 
173                (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi),
174                (i8 imm:$offset)))]>;
175
176 def movf_1 : 
177   ByteFormat<0, (outs GPR:$dst), 
178              (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
179              "movf ${ptrlo} + ${offset}, W",
180              [(set GPR:$dst, 
181                (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi),
182                (i8 imm:$offset)))]>;
183
184 // Indirect load. Matched via a DAG replacement pattern.
185 def load_indirect : 
186   ByteFormat<0, (outs GPR:$dst), 
187              (ins FSR16:$fsr, i8imm:$offset),
188              "moviw $offset[$fsr]",
189              []>;
190
191 //-------------------------
192 // Various add/sub patterns.
193 //-------------------------
194 // W += [F] ; load from F and add the value to W. 
195 class ADDFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
196   ByteFormat<OpCode, (outs GPR:$dst),
197              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
198               !strconcat(OpcStr, " $ptrlo + $offset, W"),
199              [(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
200                                              (i8 imm:$ptrhi),
201                                              (i8 imm:$offset))))]>;
202 // let isTwoAddress = 1 in {
203 def addfw_1: ADDFW<0, "addwf", add>;
204 def addfw_2: ADDFW<0, "addwf", addc>;
205 def addfwc: ADDFW<0, "addwfc", adde>;  // With Carry.
206 // }
207
208 // [F] += W ; add the value of  W to [F]. 
209 class ADDWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
210   ByteFormat<OpCode, (outs),
211              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
212               !strconcat(OpcStr, " $ptrlo + $offset"),
213              [(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
214                                              (i8 imm:$ptrhi),
215                                              (i8 imm:$offset))),
216                                              diraddr:$ptrlo, 
217                                              (i8 imm:$ptrhi), (i8 imm:$offset)
218                                              )]>;
219 def addwf_1: ADDWF<0, "addwf", add>;
220 def addwf_2: ADDWF<0, "addwf", addc>;
221 def addwfc: ADDWF<0, "addwfc", adde>;  // With Carry.
222
223 // W -= [F] ; load from F and sub the value from W.
224 class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
225   ByteFormat<OpCode, (outs GPR:$dst),
226              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
227               !strconcat(OpcStr, " $ptrlo + $offset, W"),
228              [(set GPR:$dst, (OpNode (PIC16Load diraddr:$ptrlo,
229                                       (i8 imm:$ptrhi), (i8 imm:$offset)),
230                                       GPR:$src))]>;
231 //let isTwoAddress = 1 in {
232 def subfw_1: SUBFW<0, "subwf", sub>;
233 def subfw_2: SUBFW<0, "subwf", subc>;
234 def subfwb: SUBFW<0, "subwfb", sube>;  // With Borrow.
235 //}
236
237 // [F] -= W ; 
238 class SUBWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
239   ByteFormat<OpCode, (outs),
240              (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
241               !strconcat(OpcStr, " $ptrlo + $offset"),
242              [(PIC16Store (OpNode (PIC16Load diraddr:$ptrlo,
243                                       (i8 imm:$ptrhi), (i8 imm:$offset)),
244                                       GPR:$src), diraddr:$ptrlo,
245                                       (i8 imm:$ptrhi), (i8 imm:$offset))]>;
246
247 def subwf_1: SUBWF<0, "subwf", sub>;
248 def subwf_2: SUBWF<0, "subwf", subc>;
249 def subwfb: SUBWF<0, "subwfb", sube>;  // With Borrow.
250
251 // addlw 
252 // W += C ; add literal to W. (Without carry). May Produce a carry.
253 class ADDLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
254   LiteralFormat<opcode, (outs GPR:$dst),
255                 (ins GPR:$src, i8imm:$literal),
256                 !strconcat(OpcStr, " $literal"),
257                 [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>;
258
259 // let isTwoAddress = 1 in {
260 def addlw_1 : ADDLW<0, "addlw", add>;
261 def addlw_2 : ADDLW<0, "addlw", addc>;
262 def addlwc : ADDLW<0, "addlwc", adde>; // With Carry. (Assembler macro).
263 //}
264
265 // sublw 
266 // W = C - W ; sub W from literal. (Without borrow).
267 class SUBLW<bits<6> opcode, SDNode OpNode> :
268   LiteralFormat<opcode, (outs GPR:$dst),
269                 (ins GPR:$src, i8imm:$literal),
270                 "addlw $literal",
271                 [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
272
273 //let isTwoAddress = 1 in {
274 def sublw_1 : SUBLW<0, sub>;
275 def sublw_2 : SUBLW<0, subc>;
276 //}
277
278 // Banksel.
279 let isReMaterializable = 1 in {
280 def banksel : 
281   Pseudo<(outs BSR:$dst),
282          (ins i8mem:$ptr),
283          "banksel $ptr",
284          [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>;
285 }
286
287 // Return insn.
288 def Return : 
289   ControlFormat<0, (outs), (ins), "return", [(ret)]>;
290                       
291 //===----------------------------------------------------------------------===//
292 // PIC16 Replacment Patterns.
293 //===----------------------------------------------------------------------===//
294
295 // Identify an indirect store and select insns for it.
296 def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
297            imm:$offset),
298           (store_indirect GPR:$val, 
299            (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
300            imm:$offset)>;
301
302 // Identify an indirect load and select insns for it.
303 def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr), 
304            imm:$offset),
305           (load_indirect  (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
306            imm:$offset)>;
307