1//===-- VOPInstructions.td - Vector Instruction Defintions ----------------===//
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// dummies for outer let
11class LetDummies {
12  bit isCommutable;
13  bit isConvertibleToThreeAddress;
14  bit isMoveImm;
15  bit isReMaterializable;
16  bit isAsCheapAsAMove;
17  bit VOPAsmPrefer32Bit;
18  Predicate SubtargetPredicate;
19  string Constraints;
20  string DisableEncoding;
21  list<SchedReadWrite> SchedRW;
22  list<Register> Uses;
23  list<Register> Defs;
24}
25
26class VOP <string opName> {
27  string OpName = opName;
28}
29
30class VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> :
31    InstSI <outs, ins, asm, pattern> {
32
33  let mayLoad = 0;
34  let mayStore = 0;
35  let hasSideEffects = 0;
36  let UseNamedOperandTable = 1;
37  let VALU = 1;
38  let Uses = [EXEC];
39}
40
41class VOP3Common <dag outs, dag ins, string asm = "",
42                  list<dag> pattern = [], bit HasMods = 0,
43                  bit VOP3Only = 0> :
44  VOPAnyCommon <outs, ins, asm, pattern> {
45
46  // Using complex patterns gives VOP3 patterns a very high complexity rating,
47  // but standalone patterns are almost always preferred, so we need to adjust the
48  // priority lower.  The goal is to use a high number to reduce complexity to
49  // zero (or less than zero).
50  let AddedComplexity = -1000;
51
52  let VOP3 = 1;
53
54  let AsmVariantName = AMDGPUAsmVariants.VOP3;
55  let AsmMatchConverter = !if(!eq(HasMods,1), "cvtVOP3", "");
56
57  let isCodeGenOnly = 0;
58
59  int Size = 8;
60
61  // Because SGPRs may be allowed if there are multiple operands, we
62  // need a post-isel hook to insert copies in order to avoid
63  // violating constant bus requirements.
64  let hasPostISelHook = 1;
65}
66
67class VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [],
68                   bit VOP3Only = 0, bit isVOP3P = 0, bit isVop3OpSel = 0> :
69  InstSI <P.Outs64,
70          !if(isVop3OpSel,
71              P.InsVOP3OpSel,
72              !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)),
73          "",
74          pattern>,
75  VOP <opName>,
76  SIMCInstr<opName#"_e64", SIEncodingFamily.NONE>,
77  MnemonicAlias<opName#"_e64", opName> {
78
79  let isPseudo = 1;
80  let isCodeGenOnly = 1;
81  let UseNamedOperandTable = 1;
82  let VOP3_OPSEL = isVop3OpSel;
83
84  string Mnemonic = opName;
85  string AsmOperands = !if(isVop3OpSel,
86                           P.AsmVOP3OpSel,
87                           !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64));
88
89  let Size = 8;
90  let mayLoad = 0;
91  let mayStore = 0;
92  let hasSideEffects = 0;
93  let SubtargetPredicate = isGCN;
94
95  // Because SGPRs may be allowed if there are multiple operands, we
96  // need a post-isel hook to insert copies in order to avoid
97  // violating constant bus requirements.
98  let hasPostISelHook = 1;
99
100  // Using complex patterns gives VOP3 patterns a very high complexity rating,
101  // but standalone patterns are almost always preferred, so we need to adjust the
102  // priority lower.  The goal is to use a high number to reduce complexity to
103  // zero (or less than zero).
104  let AddedComplexity = -1000;
105
106  let VOP3 = 1;
107  let VALU = 1;
108  let FPClamp = P.HasFPClamp;
109  let IntClamp = P.HasIntClamp;
110  let ClampLo = P.HasClampLo;
111  let ClampHi = P.HasClampHi;
112
113  let Uses = [EXEC];
114
115  let AsmVariantName = AMDGPUAsmVariants.VOP3;
116  let AsmMatchConverter =
117    !if(!and(P.IsPacked, isVOP3P),
118        "cvtVOP3P",
119        !if(isVOP3P, "cvtVOP3P_NotPacked",
120          !if(!or(P.HasModifiers, !or(P.HasOMod, P.HasIntClamp)),
121              "cvtVOP3",
122              "")));
123
124  VOPProfile Pfl = P;
125}
126
127class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> :
128  VOP3_Pseudo<opName, P, pattern, 1, 1> {
129  let VOP3P = 1;
130}
131
132class VOP3_Real <VOP3_Pseudo ps, int EncodingFamily> :
133  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
134  SIMCInstr <ps.PseudoInstr, EncodingFamily> {
135
136  let isPseudo = 0;
137  let isCodeGenOnly = 0;
138  let UseNamedOperandTable = 1;
139
140  let Constraints     = ps.Constraints;
141  let DisableEncoding = ps.DisableEncoding;
142
143  // copy relevant pseudo op flags
144  let SubtargetPredicate = ps.SubtargetPredicate;
145  let AsmMatchConverter  = ps.AsmMatchConverter;
146  let AsmVariantName     = ps.AsmVariantName;
147  let Constraints        = ps.Constraints;
148  let DisableEncoding    = ps.DisableEncoding;
149  let TSFlags            = ps.TSFlags;
150  let UseNamedOperandTable = ps.UseNamedOperandTable;
151  let Uses                 = ps.Uses;
152
153  VOPProfile Pfl = ps.Pfl;
154}
155
156// XXX - Is there any reason to distingusih this from regular VOP3
157// here?
158class VOP3P_Real<VOP3P_Pseudo ps, int EncodingFamily> :
159  VOP3_Real<ps, EncodingFamily>;
160
161class VOP3a<VOPProfile P> : Enc64 {
162  bits<4> src0_modifiers;
163  bits<9> src0;
164  bits<3> src1_modifiers;
165  bits<9> src1;
166  bits<3> src2_modifiers;
167  bits<9> src2;
168  bits<1> clamp;
169  bits<2> omod;
170
171  let Inst{8}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
172  let Inst{9}     = !if(P.HasSrc1Mods, src1_modifiers{1}, 0);
173  let Inst{10}    = !if(P.HasSrc2Mods, src2_modifiers{1}, 0);
174
175  let Inst{31-26} = 0x34; //encoding
176  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
177  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
178  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
179  let Inst{60-59} = !if(P.HasOMod, omod, 0);
180  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
181  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
182  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
183}
184
185class VOP3a_si <bits<9> op, VOPProfile P> : VOP3a<P> {
186  let Inst{25-17} = op;
187  let Inst{11}    = !if(P.HasClamp, clamp{0}, 0);
188}
189
190class VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> {
191  let Inst{25-16} = op;
192  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
193}
194
195class VOP3e_si <bits<9> op, VOPProfile P> : VOP3a_si <op, P> {
196  bits<8> vdst;
197  let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);
198}
199
200class VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> {
201  bits<8> vdst;
202  let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0);
203}
204
205class VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
206  let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0);
207  let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0);
208  let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0);
209  let Inst{14} = !if(P.HasDst,  src0_modifiers{3}, 0);
210}
211
212// NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa
213class VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> {
214  bits<2> attrchan;
215  bits<6> attr;
216  bits<1> high;
217
218  let Inst{8}     = 0; // No modifiers for src0
219  let Inst{61}    = 0;
220
221  let Inst{9}     = !if(P.HasSrc0Mods, src0_modifiers{1}, 0);
222  let Inst{62}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
223
224  let Inst{37-32} = attr;
225  let Inst{39-38} = attrchan;
226  let Inst{40}    = !if(P.HasHigh, high, 0);
227
228  let Inst{49-41} = src0;
229}
230
231class VOP3be <VOPProfile P> : Enc64 {
232  bits<8> vdst;
233  bits<2> src0_modifiers;
234  bits<9> src0;
235  bits<2> src1_modifiers;
236  bits<9> src1;
237  bits<2> src2_modifiers;
238  bits<9> src2;
239  bits<7> sdst;
240  bits<2> omod;
241
242  let Inst{7-0}   = vdst;
243  let Inst{14-8}  = sdst;
244  let Inst{31-26} = 0x34; //encoding
245  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
246  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
247  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
248  let Inst{60-59} = !if(P.HasOMod, omod, 0);
249  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0);
250  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0);
251  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0);
252}
253
254class VOP3Pe <bits<10> op, VOPProfile P> : Enc64 {
255  bits<8> vdst;
256  // neg, neg_hi, op_sel put in srcN_modifiers
257  bits<4> src0_modifiers;
258  bits<9> src0;
259  bits<4> src1_modifiers;
260  bits<9> src1;
261  bits<4> src2_modifiers;
262  bits<9> src2;
263  bits<1> clamp;
264
265  let Inst{7-0} = vdst;
266  let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0
267  let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1
268  let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2
269
270  let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0)
271  let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1)
272  let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2)
273
274  let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, 0); // op_sel_hi(2)
275
276  let Inst{15} = !if(P.HasClamp, clamp{0}, 0);
277
278  let Inst{25-16} = op;
279  let Inst{31-26} = 0x34; //encoding
280  let Inst{40-32} = !if(P.HasSrc0, src0, 0);
281  let Inst{49-41} = !if(P.HasSrc1, src1, 0);
282  let Inst{58-50} = !if(P.HasSrc2, src2, 0);
283  let Inst{59}    = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, 0); // op_sel_hi(0)
284  let Inst{60}    = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, 0); // op_sel_hi(1)
285  let Inst{61}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo)
286  let Inst{62}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo)
287  let Inst{63}    = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo)
288}
289
290class VOP3be_si <bits<9> op, VOPProfile P> : VOP3be<P> {
291  let Inst{25-17} = op;
292}
293
294class VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> {
295  bits<1> clamp;
296  let Inst{25-16} = op;
297  let Inst{15}    = !if(P.HasClamp, clamp{0}, 0);
298}
299
300def SDWA {
301  // sdwa_sel
302  int BYTE_0 = 0;
303  int BYTE_1 = 1;
304  int BYTE_2 = 2;
305  int BYTE_3 = 3;
306  int WORD_0 = 4;
307  int WORD_1 = 5;
308  int DWORD = 6;
309
310  // dst_unused
311  int UNUSED_PAD = 0;
312  int UNUSED_SEXT = 1;
313  int UNUSED_PRESERVE = 2;
314}
315
316class VOP_SDWAe<VOPProfile P> : Enc64 {
317  bits<8> src0;
318  bits<3> src0_sel;
319  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
320  bits<3> src1_sel;
321  bits<2> src1_modifiers;
322  bits<3> dst_sel;
323  bits<2> dst_unused;
324  bits<1> clamp;
325
326  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
327  let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, SDWA.DWORD);
328  let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, SDWA.UNUSED_PRESERVE);
329  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
330  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, SDWA.DWORD);
331  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
332  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
333  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, SDWA.DWORD);
334  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
335  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
336}
337
338// GFX9 adds two features to SDWA:
339// 1.	Add 3 fields to the SDWA microcode word: S0, S1 and OMOD.
340//    a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather
341//       than VGPRs (at most 1 can be an SGPR);
342//    b. OMOD is the standard output modifier (result *2, *4, /2)
343// 2.	Add a new version of the SDWA microcode word for VOPC: SDWAB. This
344//    replaces OMOD and the dest fields with SD and SDST (SGPR destination)
345//    field.
346//    a. When SD=1, the SDST is used as the destination for the compare result;
347//    b. When SD=0, VCC is used.
348//
349// In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA
350
351// gfx9 SDWA basic encoding
352class VOP_SDWA9e<VOPProfile P> : Enc64 {
353  bits<9> src0; // {src0_sgpr{0}, src0{7-0}}
354  bits<3> src0_sel;
355  bits<2> src0_modifiers; // float: {abs,neg}, int {sext}
356  bits<3> src1_sel;
357  bits<2> src1_modifiers;
358  bits<1> src1_sgpr;
359
360  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
361  let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, SDWA.DWORD);
362  let Inst{51}    = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0);
363  let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0);
364  let Inst{55}    = !if(P.HasSrc0, src0{8}, 0);
365  let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, SDWA.DWORD);
366  let Inst{59}    = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0);
367  let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0);
368  let Inst{63}    = 0; // src1_sgpr - should be specified in subclass
369}
370
371// gfx9 SDWA-A
372class VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> {
373  bits<3> dst_sel;
374  bits<2> dst_unused;
375  bits<1> clamp;
376  bits<2> omod;
377
378  let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, SDWA.DWORD);
379  let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, SDWA.UNUSED_PRESERVE);
380  let Inst{45}    = !if(P.HasSDWAClamp, clamp{0}, 0);
381  let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0);
382}
383
384// gfx9 SDWA-B
385class VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> {
386  bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}}
387
388  let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, 0);
389  let Inst{47} = !if(P.EmitDst, sdst{7}, 0);
390}
391
392class VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> :
393  InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>,
394  VOP <opName>,
395  SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE>,
396  MnemonicAlias <opName#"_sdwa", opName> {
397
398  let isPseudo = 1;
399  let isCodeGenOnly = 1;
400  let UseNamedOperandTable = 1;
401
402  string Mnemonic = opName;
403  string AsmOperands = P.AsmSDWA;
404  string AsmOperands9 = P.AsmSDWA9;
405
406  let Size = 8;
407  let mayLoad = 0;
408  let mayStore = 0;
409  let hasSideEffects = 0;
410
411  let VALU = 1;
412  let SDWA = 1;
413  let Uses = [EXEC];
414
415  let SubtargetPredicate = !if(P.HasExt, HasSDWA, DisableInst);
416  let AssemblerPredicate = !if(P.HasExt, HasSDWA, DisableInst);
417  let AsmVariantName = !if(P.HasExt, AMDGPUAsmVariants.SDWA,
418                                     AMDGPUAsmVariants.Disable);
419  let DecoderNamespace = "SDWA";
420
421  VOPProfile Pfl = P;
422}
423
424class VOP_SDWA_Real <VOP_SDWA_Pseudo ps> :
425  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>,
426  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> {
427
428  let isPseudo = 0;
429  let isCodeGenOnly = 0;
430
431  let Defs = ps.Defs;
432  let Uses = ps.Uses;
433  let SchedRW = ps.SchedRW;
434  let hasSideEffects = ps.hasSideEffects;
435
436  let Constraints     = ps.Constraints;
437  let DisableEncoding = ps.DisableEncoding;
438
439  // Copy relevant pseudo op flags
440  let SubtargetPredicate   = ps.SubtargetPredicate;
441  let AssemblerPredicate   = ps.AssemblerPredicate;
442  let AsmMatchConverter    = ps.AsmMatchConverter;
443  let AsmVariantName       = ps.AsmVariantName;
444  let UseNamedOperandTable = ps.UseNamedOperandTable;
445  let DecoderNamespace     = ps.DecoderNamespace;
446  let Constraints          = ps.Constraints;
447  let DisableEncoding      = ps.DisableEncoding;
448  let TSFlags              = ps.TSFlags;
449}
450
451class VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
452  InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []>,
453  SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9> {
454
455  let isPseudo = 0;
456  let isCodeGenOnly = 0;
457
458  let Defs = ps.Defs;
459  let Uses = ps.Uses;
460  let SchedRW = ps.SchedRW;
461  let hasSideEffects = ps.hasSideEffects;
462
463  let Constraints     = ps.Constraints;
464  let DisableEncoding = ps.DisableEncoding;
465
466  let SubtargetPredicate = !if(ps.Pfl.HasSDWA9, HasSDWA9, DisableInst);
467  let AssemblerPredicate = !if(ps.Pfl.HasSDWA9, HasSDWA9, DisableInst);
468  let AsmVariantName = !if(ps.Pfl.HasSDWA9, AMDGPUAsmVariants.SDWA9,
469                                            AMDGPUAsmVariants.Disable);
470  let DecoderNamespace = "SDWA9";
471
472  // Copy relevant pseudo op flags
473  let AsmMatchConverter    = ps.AsmMatchConverter;
474  let UseNamedOperandTable = ps.UseNamedOperandTable;
475  let Constraints          = ps.Constraints;
476  let DisableEncoding      = ps.DisableEncoding;
477  let TSFlags              = ps.TSFlags;
478}
479
480class VOP_DPPe<VOPProfile P> : Enc64 {
481  bits<2> src0_modifiers;
482  bits<8> src0;
483  bits<2> src1_modifiers;
484  bits<9> dpp_ctrl;
485  bits<1> bound_ctrl;
486  bits<4> bank_mask;
487  bits<4> row_mask;
488
489  let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0);
490  let Inst{48-40} = dpp_ctrl;
491  let Inst{51}    = bound_ctrl;
492  let Inst{52}    = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg
493  let Inst{53}    = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs
494  let Inst{54}    = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg
495  let Inst{55}    = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs
496  let Inst{59-56} = bank_mask;
497  let Inst{63-60} = row_mask;
498}
499
500class VOP_DPP <string OpName, VOPProfile P> :
501  InstSI <P.OutsDPP, P.InsDPP, OpName#P.AsmDPP, []>,
502  VOP_DPPe<P> {
503
504  let mayLoad = 0;
505  let mayStore = 0;
506  let hasSideEffects = 0;
507  let UseNamedOperandTable = 1;
508
509  let VALU = 1;
510  let DPP = 1;
511  let Size = 8;
512
513  let AsmMatchConverter = !if(!eq(P.HasModifiers,1), "cvtDPP", "");
514  let SubtargetPredicate = HasDPP;
515  let AssemblerPredicate = !if(P.HasExt, HasDPP, DisableInst);
516  let AsmVariantName = !if(P.HasExt, AMDGPUAsmVariants.DPP,
517                                     AMDGPUAsmVariants.Disable);
518  let Constraints = !if(P.NumSrcArgs, "$old = $vdst", "");
519  let DisableEncoding = !if(P.NumSrcArgs, "$old", "");
520  let DecoderNamespace = "DPP";
521}
522
523include "VOPCInstructions.td"
524include "VOP1Instructions.td"
525include "VOP2Instructions.td"
526include "VOP3Instructions.td"
527include "VOP3PInstructions.td"
528