1 //===- PIC16InstrInfo.td - PIC16 Instruction defs -------------*- tblgen-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // PIC16 Specific Type Constraints.
16 //===----------------------------------------------------------------------===//
17 class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
18 class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
20 //===----------------------------------------------------------------------===//
21 // PIC16 Specific Type Profiles.
22 //===----------------------------------------------------------------------===//
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>]>;
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>]>;
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>,
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>]>;
44 //===----------------------------------------------------------------------===//
45 // PIC16 addressing modes matching via DAG.
46 //===----------------------------------------------------------------------===//
47 def diraddr : ComplexPattern<i8, 1, "SelectDirectAddr", [], []>;
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]>;
57 // Low 8-bits of GlobalAddress.
58 def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>;
60 // High 8-bits of GlobalAddress.
61 def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>;
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>;
69 // Node to generate Bank Select for a GlobalAddress.
70 def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>;
72 // Node to match a direct store operation.
73 def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>;
75 // Node to match a direct load operation.
76 def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
78 //===----------------------------------------------------------------------===//
79 // PIC16 Operand Definitions.
80 //===----------------------------------------------------------------------===//
81 def i8mem : Operand<i8>;
85 //===----------------------------------------------------------------------===//
86 // PIC16 Instructions.
87 //===----------------------------------------------------------------------===//
88 include "PIC16InstrFormats.td"
90 // Pseudo-instructions.
91 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
92 "!ADJCALLSTACKDOWN $amt",
93 [(PIC16callseq_start imm:$amt)]>;
95 def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
96 "!ADJCALLSTACKUP $amt",
97 [(PIC16callseq_end imm:$amt)]>;
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),
106 [(set GPR:$dst, (i8 imm:$src))]>;
108 // Move a Lo(TGA) to W.
109 def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
111 [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
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))]>;
119 //-------------------
120 // FSR setting insns.
121 //-------------------
122 // These insns are matched via a DAG replacement pattern.
124 ByteFormat<0, (outs FSR16:$fsr),
129 let isTwoAddress = 1 in
131 ByteFormat<0, (outs FSR16:$dst),
132 (ins FSR16:$src, GPR:$val),
137 Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
139 //--------------------------
141 //-------------------------
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),
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),
157 // Indirect store. Matched via a DAG replacement pattern.
159 ByteFormat<0, (outs),
160 (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
161 "movwi $offset[$fsr]",
164 //----------------------------
166 //----------------------------
169 ByteFormat<0, (outs GPR:$dst),
170 (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
171 "movf ${ptrlo} + ${offset}, W",
173 (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi),
174 (i8 imm:$offset)))]>;
177 ByteFormat<0, (outs GPR:$dst),
178 (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
179 "movf ${ptrlo} + ${offset}, W",
181 (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi),
182 (i8 imm:$offset)))]>;
184 // Indirect load. Matched via a DAG replacement pattern.
186 ByteFormat<0, (outs GPR:$dst),
187 (ins FSR16:$fsr, i8imm:$offset),
188 "moviw $offset[$fsr]",
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,
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.
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,
217 (i8 imm:$ptrhi), (i8 imm:$offset)
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.
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)),
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.
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))]>;
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.
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)))]>;
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).
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),
271 [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
273 //let isTwoAddress = 1 in {
274 def sublw_1 : SUBLW<0, sub>;
275 def sublw_2 : SUBLW<0, subc>;
279 let isReMaterializable = 1 in {
281 Pseudo<(outs BSR:$dst),
284 [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>;
289 ControlFormat<0, (outs), (ins), "return", [(ret)]>;
291 //===----------------------------------------------------------------------===//
292 // PIC16 Replacment Patterns.
293 //===----------------------------------------------------------------------===//
295 // Identify an indirect store and select insns for it.
296 def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
298 (store_indirect GPR:$val,
299 (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
302 // Identify an indirect load and select insns for it.
303 def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
305 (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),