Rename ConstantSDNode::getValue to getZExtValue, for consistency
[oota-llvm.git] / lib / Target / PIC16 / PIC16InstrInfo.td
1 //===- PIC16InstrInfo.td - PIC16 Register 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 //===----------------------------------------------------------------------===//
11 // Instruction format superclass
12 //===----------------------------------------------------------------------===//
13
14 include "PIC16InstrFormats.td"
15
16 //===----------------------------------------------------------------------===//
17 // PIC16 profiles and nodes
18 //===----------------------------------------------------------------------===//
19
20 //===----------------------------------------------------------------------===//
21 // PIC16 addressing mode. 
22 //===----------------------------------------------------------------------===//
23 // It matches address of globals as well as the stack slots
24 // that are created for locals and temporaries. This addressing mode
25 // converts the GlobalAddress and FrameIndex nodes to TargetGlobalAddress
26 // and TargetFrameIndex nodes.
27 def diraddrmode : ComplexPattern<i16, 2, "SelectDirectAM", [frameindex], []>;
28 def dirloadmode : ComplexPattern<i16, 2, "LoadNothing", [frameindex], []>;
29 def indirloadmode : ComplexPattern<i16, 2, "LoadFSR", [frameindex], []>;
30
31
32 // Address operand.
33 def mem : Operand<i16> {
34   let PrintMethod = "printAddrModeOperand";
35   let MIOperandInfo = (ops i16imm, PTRRegs);
36 }
37
38 // Instruction operand types
39 def simm8      : Operand<i8>;
40
41
42 // These are target-independent nodes, but have target-specific formats.
43 def SDT_PIC16CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i8> ]>;
44 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PIC16CallSeq,
45                            [SDNPHasChain, SDNPOutFlag]>;
46 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_PIC16CallSeq,
47                            [SDNPHasChain, SDNPOutFlag]>;
48
49 def PIC16Wrapper  : SDNode<"PIC16ISD::Wrapper", SDTIntUnaryOp>;
50
51 // so_imm_XFORM - Return a so_imm value packed into the format described for
52 // so_imm def below.
53 def so_imm_XFORM : SDNodeXForm<imm, [{
54   return CurDAG->getTargetConstant((int8_t)N->getZExtValue(), MVT::i32);
55 }]>;
56
57 def so_imm : Operand<i8>,
58              PatLeaf<(imm), [{}]> {
59   let PrintMethod = "printSOImmOperand";
60 }
61
62
63
64 // PIC16 Address Mode! SDNode frameindex could possibily be a match 
65 // since load and store instructions from stack used it.
66 def addr : Operand<i16>;
67
68 // Arithmetic 2 register operands
69 class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
70              Operand Od> :
71   LiteralFormat< op,
72       (outs CPURegs:$dst),
73       (ins CPURegs:$b, Od:$c),
74       !strconcat(instr_asm, " $c"),
75       [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c))]>;
76
77 // Memory Load/Store. 
78 class LoadDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
79   ByteFormat< op,
80       (outs CPURegs:$dst),
81       (ins mem:$addr),
82       !strconcat(instr_asm, " $addr"),
83       [(set CPURegs:$dst, (OpNode diraddrmode:$addr))]>;
84
85 class LoadInDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
86   ByteFormat< op,
87       (outs PTRRegs:$dst),
88       (ins mem:$addr),
89       !strconcat(instr_asm, " $addr, $dst"),
90       [(set PTRRegs:$dst, (OpNode indirloadmode:$addr))]>;
91
92 class StoreDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
93   ByteFormat< op,
94       (outs),
95       (ins CPURegs:$src, mem:$addr),
96       !strconcat(instr_asm, " $addr"),
97       [(OpNode CPURegs:$src, diraddrmode:$addr)]>;
98
99 class StoreInDirect<bits<6> op, string instr_asm, PatFrag OpNode>:
100   ByteFormat< op,
101       (outs),
102       (ins CPURegs:$src, PTRRegs:$fsr),
103       !strconcat(instr_asm, " $fsr"),
104       [(OpNode CPURegs:$src, PTRRegs:$fsr)]>;
105
106 // Move.
107 class MovLit<bits<6> op, string instr_asm>:
108   LiteralFormat< op,
109       (outs CPURegs:$dst),
110       (ins i8imm:$src),
111       !strconcat(instr_asm, " $src"),
112       [(set CPURegs:$dst, imm:$src)]>;
113
114
115 // Arithmetic with memory store.
116 // Arithmetic instrunctions involving W and memory location.
117 // Since W is implicit, we only print the memory operand.
118 class Arith1M<bits<6> op, string instr_asm, SDNode OpNode>:
119   ByteFormat< op,
120       (outs),
121       (ins CPURegs:$b, mem:$dst),
122       !strconcat(instr_asm, " $dst"),
123       [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst),
124        (store (OpNode CPURegs:$b, (load diraddrmode:$dst)), diraddrmode:$dst)]>;
125
126 // Arithmetic with memory load.
127 // Arithmetic instrunctions involving W and memory location.
128 // Since W is implicit, we only print the memory operand.
129 class Arith1R<bits<6> op, string instr_asm, SDNode OpNode>:
130   ByteFormat< op,
131       (outs CPURegs:$dst),
132       (ins mem:$src1, CPURegs:$src2),
133       !strconcat(instr_asm, " $src1"),
134       [(set CPURegs:$dst, (OpNode (load diraddrmode:$src1), CPURegs:$src2))]>;
135
136 // Arithmetic with memory load.
137 // Arithmetic instrunctions involving W and memory location.
138 // Since W is implicit, we only print the memory operand.
139 class Arith2R<bits<6> op, string instr_asm, SDNode OpNode>:
140   ByteFormat< op,
141       (outs CPURegs:$dst),
142       (ins mem:$src1, CPURegs:$src2),
143       !strconcat(instr_asm, " $src1"),
144       [(set CPURegs:$dst, (OpNode CPURegs:$src2, (load diraddrmode:$src1)))]>;
145
146 //===----------------------------------------------------------------------===//
147 // Instruction definition
148 //===----------------------------------------------------------------------===//
149
150 //===----------------------------------------------------------------------===//
151 // PIC16I Instructions
152 //===----------------------------------------------------------------------===//
153
154 // Arithmetic
155
156 // ADDiu just accept 16-bit immediates but we handle this on Pat's.
157 // immZExt32 is used here so it can match GlobalAddress immediates.
158 // def ADDLW   : ArithI<0x09, "addlw", add, so_imm>;
159
160 let isReMaterializable = 1 in {
161 def MOVLW : MovLit<0x24, "movlw">;
162 }
163
164 // Load/Store
165 def LFSR1      : LoadInDirect        <0x4, "lfsr",  load>;
166
167 let isReMaterializable = 1 in {
168 def MOVF       : LoadDirect <0x23, "movf",  load>;
169 }
170
171 def MOVWF      : StoreDirect <0x2b, "movwf", store>;
172
173 def MOVFSRINC  : StoreInDirect <0x5, "movfsrinc", store>;
174
175 def RETURN     : ControlFormat<0x03, (outs), (ins), "return", []>;
176
177 def ADDWF      : Arith1M<0x01, "addwf", add>; 
178 def ADDFW      : Arith1R<0x02, "addfw", add>; 
179
180 def ADDWFE     : Arith1M<0x03, "addwfe", adde>; 
181 def ADDFWE     : Arith1R<0x04, "addfwe", adde>; 
182
183 def ADDWFC     : Arith1M<0x05, "addwfc", addc>; 
184 def ADDFWC     : Arith1R<0x06, "addfwc", addc>; 
185
186 def SUBWF      : Arith1M<0x07, "subwf", sub>; 
187 def SUBFW      : Arith1R<0x08, "subfw", sub>; 
188
189 def SUBWFE     : Arith1M<0x09, "subwfe", sube>; 
190 def SUBFWE     : Arith1R<0x0a, "subfwe", sube>; 
191
192 def SUBWFC     : Arith1M<0x0b, "subwfc", subc>; 
193 def SUBFWC     : Arith1R<0x0d, "subfwc", subc>; 
194
195 def SUBRFW     : Arith2R<0x08, "subfw", sub>; 
196
197 def SUBRFWE    : Arith2R<0x0a, "subfwe", sube>; 
198
199 def SUBRFWC    : Arith2R<0x0d, "subfwc", subc>; 
200
201 def brtarget   : Operand<OtherVT>;
202
203 class UncondJump< bits<4> op, string instr_asm>:
204   BitFormat< op,
205              (outs),
206              (ins brtarget:$target),
207              !strconcat(instr_asm, " $target"),
208              [(br bb:$target)]>;
209
210 def GOTO       : UncondJump<0x1, "goto">;
211
212 class LogicM<bits<6> op, string instr_asm, SDNode OpNode> :
213   ByteFormat< op,
214       (outs),
215       (ins CPURegs:$b, mem:$dst),
216       !strconcat(instr_asm, " $dst"),
217       [(store (OpNode (load diraddrmode:$dst), CPURegs:$b), diraddrmode:$dst)]>;
218
219 class LogicR<bits<6> op, string instr_asm, SDNode OpNode> :
220   ByteFormat< op,
221       (outs CPURegs:$dst),
222       (ins CPURegs:$b, mem:$c),
223       !strconcat(instr_asm, " $c"),
224       [(set CPURegs:$dst, (OpNode (load diraddrmode:$c), CPURegs:$b))]>;
225
226 class LogicI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od> :
227   LiteralFormat< op,
228       (outs CPURegs:$dst),
229       (ins CPURegs:$b, Od:$c),
230       !strconcat(instr_asm, " $c"),
231       [(set CPURegs:$dst, (OpNode CPURegs:$b, Od:$c ))]>;
232
233 def XORWF : LogicM<0x1,"xorwf",xor>; 
234 def XORFW : LogicR<0x1,"xorfw",xor>; 
235 def XORLW : LogicI<0x1,"xorlw",xor, so_imm>;
236
237 def ANDWF : LogicM<0x1,"andwf",and>; 
238 def ANDFW : LogicR<0x1,"andfw",and>; 
239 def ANDLW : LogicI<0x1,"andlw",and, so_imm>;
240
241 def IORWF : LogicM<0x1,"iorwf",or>; 
242 def IORFW : LogicR<0x1,"iorfw",or>; 
243 def IORLW : LogicI<0x1,"iorlw",or, so_imm>;
244
245
246 /* For comparison before branch */
247 def SDT_PIC16Cmp  : SDTypeProfile<1, 3, [SDTCisSameAs<0,1>]>;
248 def SDTIntBinOpPIC16 : SDTypeProfile<1, 2, [SDTCisSameAs<0,1>, 
249                                      SDTCisSameAs<1,2>, SDTCisInt<1>]>;
250
251 def PIC16Cmp : SDNode<"PIC16ISD::Cmp",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
252 def PIC16XORCC : SDNode<"PIC16ISD::XORCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
253 def PIC16SUBCC : SDNode<"PIC16ISD::SUBCC",SDTIntBinOpPIC16, [SDNPOutFlag]>; 
254
255 def XORFWCC : LogicR<0x1,"xorfw",PIC16XORCC>; 
256 def XORLWCC : LogicI<0x1,"xorlw",PIC16XORCC, so_imm>; 
257 def SUBFWCC : Arith1R<0x1,"subfw",PIC16SUBCC>; 
258 def SUBLWCC : ArithI<0x1,"sublw",PIC16SUBCC, so_imm>; 
259
260
261 /* For branch conditions */
262 def SDT_PIC16Branch  : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, 
263                                      SDTCisVT<1,i8>, SDTCisVT<2,i8>]>;
264
265 def PIC16Branch : SDNode<"PIC16ISD::Branch",SDT_PIC16Branch, 
266                          [SDNPHasChain, SDNPInFlag]>; 
267
268 def PIC16BTFSS  : SDNode<"PIC16ISD::BTFSS",SDT_PIC16Branch, 
269                          [SDNPHasChain, SDNPInFlag]>; 
270
271 def PIC16BTFSC  : SDNode<"PIC16ISD::BTFSC",SDT_PIC16Branch, 
272                          [SDNPHasChain, SDNPInFlag]>; 
273
274 class InstrBitTestCC<bits<4> op, string instr_asm,SDNode OpNode>:
275   BitFormat< op,
276              (outs),
277              (ins brtarget:$target ,so_imm:$i, STATUSRegs:$s ),
278                    !strconcat(instr_asm, " $s, $i, $target"),
279                    [(OpNode bb:$target, so_imm:$i, STATUSRegs:$s )]>;
280
281 def BTFSS : InstrBitTestCC<0x1,"btfss",PIC16BTFSS>;
282 def BTFSC : InstrBitTestCC<0x1,"btfsc",PIC16BTFSC>;
283
284
285 //===----------------------------------------------------------------------===//
286 // Pseudo instructions
287 //===----------------------------------------------------------------------===//
288
289 let Defs = [STKPTR], Uses = [STKPTR] in {
290 def ADJCALLSTACKDOWN : Pseudo<255, (outs), (ins i8imm:$amt),
291                                "!ADJCALLSTACKDOWN $amt",
292                                [(callseq_start imm:$amt)]>;
293 def ADJCALLSTACKUP : Pseudo<254, (outs), (ins i8imm:$amt),
294                             "!ADJCALLSTACKUP $amt",
295                             [(callseq_end imm:$amt)]>;
296 }
297
298
299 //===----------------------------------------------------------------------===//
300 //  Arbitrary patterns that map to one or more instructions
301 //===----------------------------------------------------------------------===//
302 def : Pat<(ret), (RETURN)>;