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 // 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>;
87 include "PIC16InstrFormats.td"
89 //===----------------------------------------------------------------------===//
90 // PIC16 Common Classes.
91 //===----------------------------------------------------------------------===//
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,
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,
110 (i8 imm:$ptrhi), (i8 imm:$offset)
113 //===----------------------------------------------------------------------===//
114 // PIC16 Instructions.
115 //===----------------------------------------------------------------------===//
117 // Pseudo-instructions.
118 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
119 "!ADJCALLSTACKDOWN $amt",
120 [(PIC16callseq_start imm:$amt)]>;
122 def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
123 "!ADJCALLSTACKUP $amt",
124 [(PIC16callseq_end imm:$amt)]>;
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),
133 [(set GPR:$dst, (i8 imm:$src))]>;
135 // Move a Lo(TGA) to W.
136 def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
138 [(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
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))]>;
146 //-------------------
147 // FSR setting insns.
148 //-------------------
149 // These insns are matched via a DAG replacement pattern.
151 ByteFormat<0, (outs FSR16:$fsr),
156 let isTwoAddress = 1 in
158 ByteFormat<0, (outs FSR16:$dst),
159 (ins FSR16:$src, GPR:$val),
164 Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
166 //--------------------------
168 //-------------------------
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),
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),
184 // Indirect store. Matched via a DAG replacement pattern.
186 ByteFormat<0, (outs),
187 (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
188 "movwi $offset[$fsr]",
191 //----------------------------
193 //----------------------------
196 ByteFormat<0, (outs GPR:$dst),
197 (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
198 "movf ${ptrlo} + ${offset}, W",
200 (PIC16Load tglobaladdr:$ptrlo, (i8 imm:$ptrhi),
201 (i8 imm:$offset)))]>;
204 ByteFormat<0, (outs GPR:$dst),
205 (ins i8mem:$ptrlo, i8imm:$ptrhi, i8imm:$offset),
206 "movf ${ptrlo} + ${offset}, W",
208 (PIC16Load texternalsym:$ptrlo, (i8 imm:$ptrhi),
209 (i8 imm:$offset)))]>;
211 // Indirect load. Matched via a DAG replacement pattern.
213 ByteFormat<0, (outs GPR:$dst),
214 (ins FSR16:$fsr, i8imm:$offset),
215 "moviw $offset[$fsr]",
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>;
225 def OrWF : BinOpWF<0, "iorwf", OR>;
226 def XOrWF : BinOpWF<0, "xorwf", XOR>;
227 def AndWF : BinOpWF<0, "andwf", AND>;
229 //-------------------------
230 // Various add/sub patterns.
231 //-------------------------
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.
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.
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)),
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.
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))]>;
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.
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)))]>;
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).
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),
291 [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
293 //let isTwoAddress = 1 in {
294 def sublw_1 : SUBLW<0, sub>;
295 def sublw_2 : SUBLW<0, subc>;
299 let isReMaterializable = 1 in {
301 Pseudo<(outs BSR:$dst),
304 [(set BSR:$dst, (Banksel tglobaladdr:$ptr))]>;
309 ControlFormat<0, (outs), (ins), "return", [(ret)]>;
311 //===----------------------------------------------------------------------===//
312 // PIC16 Replacment Patterns.
313 //===----------------------------------------------------------------------===//
315 // Identify an indirect store and select insns for it.
316 def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
318 (store_indirect GPR:$val,
319 (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
322 // Identify an indirect load and select insns for it.
323 def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
325 (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),