blob: 250ca0a373f21a2a296f630071d829d55dd2c636 [file] [log] [blame]
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +00001//===- PIC16InstrInfo.td - PIC16 Instruction defs -------------*- tblgen-*-===//
Sanjiv Gupta09bb4202008-05-13 09:02:57 +00002//
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//===----------------------------------------------------------------------===//
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +00009//
Sanjiv Guptab2d77212009-01-30 09:01:44 +000010// This file describes the PIC16 instructions in TableGen format.
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000011//
Sanjiv Gupta09bb4202008-05-13 09:02:57 +000012//===----------------------------------------------------------------------===//
13
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000014//===----------------------------------------------------------------------===//
15// PIC16 Specific Type Constraints.
16//===----------------------------------------------------------------------===//
17class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
18class 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.
26def SDTI8VoidOp : SDTypeProfile<0, 1, [SDTCisI8<0>]>;
27def SDTI16VoidOp : SDTypeProfile<0, 1, [SDTCisI16<0>]>;
28
29// Taking one value and producing an output of same type.
30def SDTI8UnaryOp : SDTypeProfile<1, 1, [SDTCisI8<0>, SDTCisI8<1>]>;
31def SDTI16UnaryOp : SDTypeProfile<1, 1, [SDTCisI16<0>, SDTCisI16<1>]>;
32
33// Taking two values and producing an output of same type.
34def SDTI8BinOp : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>]>;
35def SDTI16BinOp : SDTypeProfile<1, 2, [SDTCisI16<0>, SDTCisI16<1>,
36 SDTCisI16<2>]>;
37
38// Node specific type profiles.
39def SDT_PIC16Load : SDTypeProfile<1, 3, [SDTCisI8<0>, SDTCisI8<1>,
40 SDTCisI8<2>, SDTCisI8<3>]>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000041
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000042def SDT_PIC16Store : SDTypeProfile<0, 4, [SDTCisI8<0>, SDTCisI8<1>,
43 SDTCisI8<2>, SDTCisI8<3>]>;
44
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +000045def SDT_PIC16Connect : SDTypeProfile<1, 2, [SDTCisI8<0>, SDTCisI8<1>,
46 SDTCisI8<2>]>;
47
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000048// PIC16ISD::CALL type prorile
49def SDT_PIC16call : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +000050def SDT_PIC16callw : SDTypeProfile<1, -1, [SDTCisInt<0>]>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000051
52// PIC16ISD::BRCOND
53def SDT_PIC16Brcond: SDTypeProfile<0, 2,
54 [SDTCisVT<0, OtherVT>, SDTCisI8<1>]>;
55
56// PIC16ISD::BRCOND
57def SDT_PIC16Selecticc: SDTypeProfile<1, 3,
58 [SDTCisI8<0>, SDTCisI8<1>, SDTCisI8<2>,
59 SDTCisI8<3>]>;
60
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000061//===----------------------------------------------------------------------===//
62// PIC16 addressing modes matching via DAG.
63//===----------------------------------------------------------------------===//
64def diraddr : ComplexPattern<i8, 1, "SelectDirectAddr", [], []>;
65
66//===----------------------------------------------------------------------===//
67// PIC16 Specific Node Definitions.
68//===----------------------------------------------------------------------===//
69def PIC16callseq_start : SDNode<"ISD::CALLSEQ_START", SDTI8VoidOp,
70 [SDNPHasChain, SDNPOutFlag]>;
71def PIC16callseq_end : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp,
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000072 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000073
74// Low 8-bits of GlobalAddress.
Sanjiv Guptaa8792002009-04-14 02:49:52 +000075def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8BinOp>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000076
77// High 8-bits of GlobalAddress.
Sanjiv Guptaa8792002009-04-14 02:49:52 +000078def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8BinOp>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000079
80// The MTHI and MTLO nodes are used only to match them in the incoming
81// DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions.
82// These nodes are not used for defining any instructions.
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +000083def MTLO : SDNode<"PIC16ISD::MTLO", SDTI8UnaryOp>;
84def MTHI : SDNode<"PIC16ISD::MTHI", SDTI8UnaryOp>;
85def MTPCLATH : SDNode<"PIC16ISD::MTPCLATH", SDTI8UnaryOp>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000086
87// Node to generate Bank Select for a GlobalAddress.
88def Banksel : SDNode<"PIC16ISD::Banksel", SDTI8UnaryOp>;
89
90// Node to match a direct store operation.
91def PIC16Store : SDNode<"PIC16ISD::PIC16Store", SDT_PIC16Store, [SDNPHasChain]>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000092def PIC16StWF : SDNode<"PIC16ISD::PIC16StWF", SDT_PIC16Store,
93 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +000094
95// Node to match a direct load operation.
Sanjiv Guptae48b2ee2009-04-02 17:42:00 +000096def PIC16Load : SDNode<"PIC16ISD::PIC16Load", SDT_PIC16Load, [SDNPHasChain]>;
97def PIC16LdArg : SDNode<"PIC16ISD::PIC16LdArg", SDT_PIC16Load, [SDNPHasChain]>;
98def PIC16LdWF : SDNode<"PIC16ISD::PIC16LdWF", SDT_PIC16Load,
Sanjiv Gupta4affaea2009-01-13 19:18:47 +000099 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000100def PIC16Connect: SDNode<"PIC16ISD::PIC16Connect", SDT_PIC16Connect, []>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000101
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000102// Node to match PIC16 call
103def PIC16call : SDNode<"PIC16ISD::CALL", SDT_PIC16call,
104 [SDNPHasChain , SDNPOptInFlag, SDNPOutFlag]>;
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000105def PIC16callw : SDNode<"PIC16ISD::CALLW", SDT_PIC16callw,
106 [SDNPHasChain , SDNPOptInFlag, SDNPOutFlag]>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000107
108// Node to match a comparison instruction.
109def PIC16Subcc : SDNode<"PIC16ISD::SUBCC", SDTI8BinOp, [SDNPOutFlag]>;
110
111// Node to match a conditional branch.
112def PIC16Brcond : SDNode<"PIC16ISD::BRCOND", SDT_PIC16Brcond,
113 [SDNPHasChain, SDNPInFlag]>;
114
115def PIC16Selecticc : SDNode<"PIC16ISD::SELECT_ICC", SDT_PIC16Selecticc,
116 [SDNPInFlag]>;
117
Dan Gohman9178de12009-08-05 01:29:28 +0000118def PIC16ret : SDNode<"PIC16ISD::RET", SDTNone, [SDNPHasChain]>;
119
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000120//===----------------------------------------------------------------------===//
121// PIC16 Operand Definitions.
122//===----------------------------------------------------------------------===//
123def i8mem : Operand<i8>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000124def brtarget: Operand<OtherVT>;
125
126// Operand for printing out a condition code.
127let PrintMethod = "printCCOperand" in
128 def CCOp : Operand<i8>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000129
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000130include "PIC16InstrFormats.td"
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000131
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000132//===----------------------------------------------------------------------===//
133// PIC16 Common Classes.
134//===----------------------------------------------------------------------===//
135
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000136// W = W Op F : Load the value from F and do Op to W.
Sanjiv Gupta0ba7dab2009-05-12 04:30:38 +0000137let isTwoAddress = 1, mayLoad = 1 in
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000138class BinOpFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
139 ByteFormat<OpCode, (outs GPR:$dst),
140 (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
141 !strconcat(OpcStr, " $ptrlo + $offset, W"),
142 [(set GPR:$dst, (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
143 (i8 imm:$ptrhi),
144 (i8 imm:$offset))))]>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000145
146// F = F Op W : Load the value from F, do op with W and store in F.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000147// This insn class is not marked as TwoAddress because the reg is
148// being used as a source operand only. (Remember a TwoAddress insn
149// needs a copyRegToReg.)
Sanjiv Gupta0ba7dab2009-05-12 04:30:38 +0000150let mayStore = 1 in
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000151class BinOpWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
152 ByteFormat<OpCode, (outs),
153 (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
154 !strconcat(OpcStr, " $ptrlo + $offset"),
155 [(PIC16Store (OpNode GPR:$src, (PIC16Load diraddr:$ptrlo,
156 (i8 imm:$ptrhi),
157 (i8 imm:$offset))),
158 diraddr:$ptrlo,
159 (i8 imm:$ptrhi), (i8 imm:$offset)
160 )]>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000161
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000162// W = W Op L : Do Op of L with W and place result in W.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000163let isTwoAddress = 1 in
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000164class BinOpLW<bits<6> opcode, string OpcStr, SDNode OpNode> :
165 LiteralFormat<opcode, (outs GPR:$dst),
166 (ins GPR:$src, i8imm:$literal),
167 !strconcat(OpcStr, " $literal"),
168 [(set GPR:$dst, (OpNode GPR:$src, (i8 imm:$literal)))]>;
169
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000170//===----------------------------------------------------------------------===//
171// PIC16 Instructions.
172//===----------------------------------------------------------------------===//
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000173
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000174// Pseudo-instructions.
175def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i8imm:$amt),
176 "!ADJCALLSTACKDOWN $amt",
177 [(PIC16callseq_start imm:$amt)]>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000178
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000179def ADJCALLSTACKUP : Pseudo<(outs), (ins i8imm:$amt),
180 "!ADJCALLSTACKUP $amt",
181 [(PIC16callseq_end imm:$amt)]>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000182
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000183//-----------------------------------
184// Vaious movlw insn patterns.
185//-----------------------------------
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000186let isReMaterializable = 1 in {
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000187// Move 8-bit literal to W.
188def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
189 "movlw $src",
190 [(set GPR:$dst, (i8 imm:$src))]>;
191
192// Move a Lo(TGA) to W.
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000193def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
Sanjiv Gupta6f8dca82009-06-03 15:31:12 +0000194 "movlw LOW(${src} + ${src2})",
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000195 [(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>;
196
197// Move a Lo(TES) to W.
198def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
Sanjiv Gupta6f8dca82009-06-03 15:31:12 +0000199 "movlw LOW(${src} + ${src2})",
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000200 [(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000201
202// Move a Hi(TGA) to W.
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000203def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
Sanjiv Gupta6f8dca82009-06-03 15:31:12 +0000204 "movlw HIGH(${src} + ${src2})",
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000205 [(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>;
206
207// Move a Hi(TES) to W.
208def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
Sanjiv Gupta6f8dca82009-06-03 15:31:12 +0000209 "movlw HIGH(${src} + ${src2})",
Sanjiv Guptaa8792002009-04-14 02:49:52 +0000210 [(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000211}
212
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000213//-------------------
214// FSR setting insns.
215//-------------------
216// These insns are matched via a DAG replacement pattern.
217def set_fsrlo:
218 ByteFormat<0, (outs FSR16:$fsr),
219 (ins GPR:$val),
220 "movwf ${fsr}L",
221 []>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000222
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000223let isTwoAddress = 1 in
224def set_fsrhi:
225 ByteFormat<0, (outs FSR16:$dst),
226 (ins FSR16:$src, GPR:$val),
227 "movwf ${dst}H",
228 []>;
229
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000230def set_pclath:
231 ByteFormat<0, (outs PCLATHR:$dst),
232 (ins GPR:$val),
233 "movwf ${dst}",
234 [(set PCLATHR:$dst , (MTPCLATH GPR:$val))]>;
235
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000236//----------------------------
237// copyRegToReg
238// copyRegToReg insns. These are dummy. They should always be deleted
239// by the optimizer and never be present in the final generated code.
240// if they are, then we have to write correct macros for these insns.
241//----------------------------
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000242def copy_fsr:
243 Pseudo<(outs FSR16:$dst), (ins FSR16:$src), "copy_fsr $dst, $src", []>;
244
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000245def copy_w:
246 Pseudo<(outs GPR:$dst), (ins GPR:$src), "copy_w $dst, $src", []>;
247
Sanjiv Guptaab5e8d92009-04-10 15:10:14 +0000248class SAVE_FSR<string OpcStr>:
249 Pseudo<(outs),
250 (ins FSR16:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
251 !strconcat(OpcStr, " $ptrlo, $offset"),
252 []>;
253
254def save_fsr0: SAVE_FSR<"save_fsr0">;
255def save_fsr1: SAVE_FSR<"save_fsr1">;
256
257class RESTORE_FSR<string OpcStr>:
258 Pseudo<(outs FSR16:$dst),
259 (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
260 !strconcat(OpcStr, " $ptrlo, $offset"),
261 []>;
262
263def restore_fsr0: RESTORE_FSR<"restore_fsr0">;
264def restore_fsr1: RESTORE_FSR<"restore_fsr1">;
265
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000266//--------------------------
267// Store to memory
268//-------------------------
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000269
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000270// Direct store.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000271// Input operands are: val = W, ptrlo = GA, offset = offset, ptrhi = banksel.
Sanjiv Gupta0ba7dab2009-05-12 04:30:38 +0000272let mayStore = 1 in
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000273class MOVWF_INSN<bits<6> OpCode, SDNode OpNodeDest, SDNode Op>:
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000274 ByteFormat<0, (outs),
275 (ins GPR:$val, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
276 "movwf ${ptrlo} + ${offset}",
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000277 [(Op GPR:$val, OpNodeDest:$ptrlo, (i8 imm:$ptrhi),
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000278 (i8 imm:$offset))]>;
279
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000280// Store W to a Global Address.
281def movwf : MOVWF_INSN<0, tglobaladdr, PIC16Store>;
282
283// Store W to an External Symobol.
284def movwf_1 : MOVWF_INSN<0, texternalsym, PIC16Store>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000285
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000286// Store with InFlag and OutFlag
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000287// This is same as movwf_1 but has a flag. A flag is required to
288// order the stores while passing the params to function.
289def movwf_2 : MOVWF_INSN<0, texternalsym, PIC16StWF>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000290
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000291// Indirect store. Matched via a DAG replacement pattern.
292def store_indirect :
293 ByteFormat<0, (outs),
294 (ins GPR:$val, FSR16:$fsr, i8imm:$offset),
295 "movwi $offset[$fsr]",
296 []>;
297
298//----------------------------
299// Load from memory
300//----------------------------
301// Direct load.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000302// Input Operands are: ptrlo = GA, offset = offset, ptrhi = banksel.
303// Output: dst = W
Sanjiv Gupta018bde12009-07-03 07:58:59 +0000304let Defs = [STATUS], mayLoad = 1 in
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000305class MOVF_INSN<bits<6> OpCode, SDNode OpNodeSrc, SDNode Op>:
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000306 ByteFormat<0, (outs GPR:$dst),
307 (ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
308 "movf ${ptrlo} + ${offset}, W",
309 [(set GPR:$dst,
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000310 (Op OpNodeSrc:$ptrlo, (i8 imm:$ptrhi),
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000311 (i8 imm:$offset)))]>;
312
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000313// Load from a GA.
314def movf : MOVF_INSN<0, tglobaladdr, PIC16Load>;
315
316// Load from an ES.
317def movf_1 : MOVF_INSN<0, texternalsym, PIC16Load>;
Sanjiv Guptae48b2ee2009-04-02 17:42:00 +0000318def movf_1_1 : MOVF_INSN<0, texternalsym, PIC16LdArg>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000319
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000320// Load with InFlag and OutFlag
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000321// This is same as movf_1 but has a flag. A flag is required to
322// order the loads while copying the return value of a function.
323def movf_2 : MOVF_INSN<0, texternalsym, PIC16LdWF>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000324
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000325// Indirect load. Matched via a DAG replacement pattern.
326def load_indirect :
327 ByteFormat<0, (outs GPR:$dst),
328 (ins FSR16:$fsr, i8imm:$offset),
329 "moviw $offset[$fsr]",
330 []>;
331
332//-------------------------
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000333// Bitwise operations patterns
334//--------------------------
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000335// W = W op [F]
336let Defs = [STATUS] in {
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000337def OrFW : BinOpFW<0, "iorwf", or>;
338def XOrFW : BinOpFW<0, "xorwf", xor>;
339def AndFW : BinOpFW<0, "andwf", and>;
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000340
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000341// F = W op [F]
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000342def OrWF : BinOpWF<0, "iorwf", or>;
343def XOrWF : BinOpWF<0, "xorwf", xor>;
344def AndWF : BinOpWF<0, "andwf", and>;
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000345
346//-------------------------
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000347// Various add/sub patterns.
348//-------------------------
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000349
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000350// W = W + [F]
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000351def addfw_1: BinOpFW<0, "addwf", add>;
352def addfw_2: BinOpFW<0, "addwf", addc>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000353
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000354let Uses = [STATUS] in
355def addfwc: BinOpFW<0, "addwfc", adde>; // With Carry.
356
357// F = W + [F]
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000358def addwf_1: BinOpWF<0, "addwf", add>;
359def addwf_2: BinOpWF<0, "addwf", addc>;
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000360let Uses = [STATUS] in
Sanjiv Guptaecfffdb2008-11-26 10:53:50 +0000361def addwfc: BinOpWF<0, "addwfc", adde>; // With Carry.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000362}
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000363
364// W -= [F] ; load from F and sub the value from W.
Sanjiv Gupta0ba7dab2009-05-12 04:30:38 +0000365let isTwoAddress = 1, mayLoad = 1 in
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000366class SUBFW<bits<6> OpCode, string OpcStr, SDNode OpNode>:
367 ByteFormat<OpCode, (outs GPR:$dst),
368 (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
369 !strconcat(OpcStr, " $ptrlo + $offset, W"),
370 [(set GPR:$dst, (OpNode (PIC16Load diraddr:$ptrlo,
371 (i8 imm:$ptrhi), (i8 imm:$offset)),
372 GPR:$src))]>;
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000373let Defs = [STATUS] in {
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000374def subfw_1: SUBFW<0, "subwf", sub>;
375def subfw_2: SUBFW<0, "subwf", subc>;
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000376
377let Uses = [STATUS] in
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000378def subfwb: SUBFW<0, "subwfb", sube>; // With Borrow.
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000379
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000380}
Sanjiv Gupta12adb6a2009-07-08 05:40:05 +0000381let Defs = [STATUS], isTerminator = 1 in
382def subfw_cc: SUBFW<0, "subwf", PIC16Subcc>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000383
384// [F] -= W ;
Sanjiv Gupta0ba7dab2009-05-12 04:30:38 +0000385let mayStore = 1 in
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000386class SUBWF<bits<6> OpCode, string OpcStr, SDNode OpNode>:
387 ByteFormat<OpCode, (outs),
388 (ins GPR:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
389 !strconcat(OpcStr, " $ptrlo + $offset"),
390 [(PIC16Store (OpNode (PIC16Load diraddr:$ptrlo,
391 (i8 imm:$ptrhi), (i8 imm:$offset)),
392 GPR:$src), diraddr:$ptrlo,
393 (i8 imm:$ptrhi), (i8 imm:$offset))]>;
394
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000395let Defs = [STATUS] in {
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000396def subwf_1: SUBWF<0, "subwf", sub>;
397def subwf_2: SUBWF<0, "subwf", subc>;
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000398
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000399let Uses = [STATUS] in
400 def subwfb: SUBWF<0, "subwfb", sube>; // With Borrow.
401
402def subwf_cc: SUBWF<0, "subwf", PIC16Subcc>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000403}
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000404
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000405// addlw
406let Defs = [STATUS] in {
407def addlw_1 : BinOpLW<0, "addlw", add>;
408def addlw_2 : BinOpLW<0, "addlw", addc>;
409
410let Uses = [STATUS] in
411def addlwc : BinOpLW<0, "addlwc", adde>; // With Carry. (Assembler macro).
412
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000413// bitwise operations involving a literal and w.
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000414def andlw : BinOpLW<0, "andlw", and>;
415def xorlw : BinOpLW<0, "xorlw", xor>;
416def orlw : BinOpLW<0, "iorlw", or>;
417}
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000418
419// sublw
420// W = C - W ; sub W from literal. (Without borrow).
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000421let isTwoAddress = 1 in
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000422class SUBLW<bits<6> opcode, SDNode OpNode> :
423 LiteralFormat<opcode, (outs GPR:$dst),
424 (ins GPR:$src, i8imm:$literal),
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000425 "sublw $literal",
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000426 [(set GPR:$dst, (OpNode (i8 imm:$literal), GPR:$src))]>;
427
Sanjiv Guptaa5f3bc42009-03-10 10:35:34 +0000428let Defs = [STATUS] in {
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000429def sublw_1 : SUBLW<0, sub>;
430def sublw_2 : SUBLW<0, subc>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000431}
Sanjiv Gupta12adb6a2009-07-08 05:40:05 +0000432let Defs = [STATUS], isTerminator = 1 in
433def sublw_cc : SUBLW<0, PIC16Subcc>;
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000434
435// Call instruction.
Sanjiv Guptaab5e8d92009-04-10 15:10:14 +0000436let isCall = 1,
437 Defs = [W, FSR0, FSR1] in {
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000438 def CALL: LiteralFormat<0x1, (outs), (ins i8imm:$func),
Sanjiv Gupta769f3332009-04-22 12:02:36 +0000439 //"call ${func} + 2",
440 "call ${func}",
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000441 [(PIC16call diraddr:$func)]>;
442}
443
Sanjiv Guptaab5e8d92009-04-10 15:10:14 +0000444let isCall = 1,
445 Defs = [W, FSR0, FSR1] in {
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000446 def CALL_1: LiteralFormat<0x1, (outs), (ins GPR:$func, PCLATHR:$pc),
447 "callw",
448 [(PIC16call (PIC16Connect GPR:$func, PCLATHR:$pc))]>;
449}
450
Sanjiv Guptaab5e8d92009-04-10 15:10:14 +0000451let isCall = 1,
452 Defs = [FSR0, FSR1] in {
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000453 def CALLW: LiteralFormat<0x1, (outs GPR:$dest),
454 (ins GPR:$func, PCLATHR:$pc),
455 "callw",
456 [(set GPR:$dest, (PIC16callw (PIC16Connect GPR:$func, PCLATHR:$pc)))]>;
457}
458
Sanjiv Gupta902e91c2009-05-28 17:32:56 +0000459let Uses = [STATUS], isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000460def pic16brcond: ControlFormat<0x0, (outs), (ins brtarget:$dst, CCOp:$cc),
461 "b$cc $dst",
462 [(PIC16Brcond bb:$dst, imm:$cc)]>;
463
464// Unconditional branch.
Sanjiv Gupta902e91c2009-05-28 17:32:56 +0000465let isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in
Sanjiv Gupta4affaea2009-01-13 19:18:47 +0000466def br_uncond: ControlFormat<0x0, (outs), (ins brtarget:$dst),
467 "goto $dst",
468 [(br bb:$dst)]>;
469
470// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the
471// scheduler into a branch sequence.
472let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
473 def SELECT_CC_Int_ICC
474 : Pseudo<(outs GPR:$dst), (ins GPR:$T, GPR:$F, i8imm:$Cond),
475 "; SELECT_CC_Int_ICC PSEUDO!",
476 [(set GPR:$dst, (PIC16Selecticc GPR:$T, GPR:$F,
477 imm:$Cond))]>;
478}
479
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000480
481// Banksel.
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000482def banksel :
Sanjiv Guptabb4a5c72009-05-06 08:02:01 +0000483 Pseudo<(outs),
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000484 (ins i8mem:$ptr),
485 "banksel $ptr",
Sanjiv Guptabb4a5c72009-05-06 08:02:01 +0000486 []>;
487
488def pagesel :
489 Pseudo<(outs),
490 (ins i8mem:$ptr),
491 "movlp $ptr",
492 []>;
493
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000494
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000495// Return insn.
Sanjiv Gupta8506f892009-07-25 07:48:53 +0000496let isTerminator = 1, isBarrier = 1, isReturn = 1 in
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000497def Return :
Dan Gohman9178de12009-08-05 01:29:28 +0000498 ControlFormat<0, (outs), (ins), "return", [(PIC16ret)]>;
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000499
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000500//===----------------------------------------------------------------------===//
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000501// PIC16 Replacment Patterns.
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000502//===----------------------------------------------------------------------===//
503
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000504// Identify an indirect store and select insns for it.
505def : Pat<(PIC16Store GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
506 imm:$offset),
507 (store_indirect GPR:$val,
508 (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
509 imm:$offset)>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000510
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000511def : Pat<(PIC16StWF GPR:$val, (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
512 imm:$offset),
513 (store_indirect GPR:$val,
514 (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
515 imm:$offset)>;
516
Sanjiv Gupta085ae4f2008-11-19 11:00:54 +0000517// Identify an indirect load and select insns for it.
518def : Pat<(PIC16Load (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
519 imm:$offset),
520 (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
521 imm:$offset)>;
Sanjiv Gupta09bb4202008-05-13 09:02:57 +0000522
Sanjiv Gupta4a912ed2009-04-08 05:38:48 +0000523def : Pat<(PIC16LdWF (MTLO GPR:$loaddr), (MTHI GPR:$hiaddr),
524 imm:$offset),
525 (load_indirect (set_fsrhi (set_fsrlo GPR:$loaddr), GPR:$hiaddr),
526 imm:$offset)>;
527