1 //gcc a.c ../../../VEX/priv/tilegx_disasm.c   -I ../../../  -I ../../../VEX/priv/  -I ../../../VEX/pub/
2 
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include "tilegx_disasm.h"
8 
9 #undef DGB
10 
11 static unsigned char op_abnorm[TILEGX_OPC_NONE] = {
12   /* Black list */
13   [ TILEGX_OPC_BPT      ] = 1,
14   [ TILEGX_OPC_INFO     ] = 1,
15   [ TILEGX_OPC_INFOL    ] = 1,
16   [ TILEGX_OPC_DRAIN    ] = 1,
17   [ TILEGX_OPC_IRET     ] = 1,
18   [ TILEGX_OPC_SWINT0   ] = 1,
19   [ TILEGX_OPC_SWINT1   ] = 1,
20   [ TILEGX_OPC_SWINT2   ] = 1,
21   [ TILEGX_OPC_SWINT3   ] = 1,
22   [ TILEGX_OPC_LD4S_TLS ] = 1,
23   [ TILEGX_OPC_LD_TLS   ] = 1,
24   [ TILEGX_OPC_MFSPR    ] = 1,
25   [ TILEGX_OPC_MTSPR    ] = 1,
26   [ TILEGX_OPC_ILL      ] = 1,
27   [ TILEGX_OPC_NAP      ] = 1,
28 
29   /* mem load */
30   [ TILEGX_OPC_LD         ] = 2,
31   [ TILEGX_OPC_LD_ADD     ] = 2,
32   [ TILEGX_OPC_LD1S       ] = 2,
33   [ TILEGX_OPC_LD1S_ADD   ] = 2,
34   [ TILEGX_OPC_LD1U       ] = 2,
35   [ TILEGX_OPC_LD1U_ADD   ] = 2,
36   [ TILEGX_OPC_LD2S       ] = 2,
37   [ TILEGX_OPC_LD2S_ADD   ] = 2,
38   [ TILEGX_OPC_LD2U       ] = 2,
39   [ TILEGX_OPC_LD2U_ADD   ] = 2,
40   [ TILEGX_OPC_LD4S       ] = 2,
41   [ TILEGX_OPC_LD4S_ADD   ] = 2,
42   [ TILEGX_OPC_LD4U       ] = 2,
43   [ TILEGX_OPC_LD4U_ADD   ] = 2,
44   [ TILEGX_OPC_LDNA       ] = 2,
45   [ TILEGX_OPC_LDNA_ADD   ] = 2,
46   [ TILEGX_OPC_LDNT       ] = 2,
47   [ TILEGX_OPC_LDNT1S     ] = 2,
48   [ TILEGX_OPC_LDNT1S_ADD ] = 2,
49   [ TILEGX_OPC_LDNT1U     ] = 2,
50   [ TILEGX_OPC_LDNT1U_ADD ] = 2,
51   [ TILEGX_OPC_LDNT2S     ] = 2,
52   [ TILEGX_OPC_LDNT2S_ADD ] = 2,
53   [ TILEGX_OPC_LDNT2U     ] = 2,
54   [ TILEGX_OPC_LDNT2U_ADD ] = 2,
55   [ TILEGX_OPC_LDNT4S     ] = 2,
56   [ TILEGX_OPC_LDNT4S_ADD ] = 2,
57   [ TILEGX_OPC_LDNT4U     ] = 2,
58   [ TILEGX_OPC_LDNT4U_ADD ] = 2,
59   [ TILEGX_OPC_LDNT_ADD   ] = 2,
60 
61   /* mem store */
62   [ TILEGX_OPC_ST         ] = 4,
63   [ TILEGX_OPC_ST1        ] = 4,
64   [ TILEGX_OPC_ST1_ADD    ] = 4,
65   [ TILEGX_OPC_ST2        ] = 4,
66   [ TILEGX_OPC_ST2_ADD    ] = 4,
67   [ TILEGX_OPC_ST4        ] = 4,
68   [ TILEGX_OPC_ST4_ADD    ] = 4,
69   [ TILEGX_OPC_ST_ADD     ] = 4,
70   [ TILEGX_OPC_STNT       ] = 4,
71   [ TILEGX_OPC_STNT1      ] = 4,
72   [ TILEGX_OPC_STNT1_ADD  ] = 4,
73   [ TILEGX_OPC_STNT2      ] = 4,
74   [ TILEGX_OPC_STNT2_ADD  ] = 4,
75   [ TILEGX_OPC_STNT4      ] = 4,
76   [ TILEGX_OPC_STNT4_ADD  ] = 4,
77   [ TILEGX_OPC_STNT_ADD   ] = 4,
78 
79   /* conditional branch */
80   [ TILEGX_OPC_BEQZ       ] = 8,
81   [ TILEGX_OPC_BEQZT      ] = 8,
82   [ TILEGX_OPC_BGEZ       ] = 8,
83   [ TILEGX_OPC_BGEZT      ] = 8,
84   [ TILEGX_OPC_BGTZ       ] = 8,
85   [ TILEGX_OPC_BGTZT      ] = 8,
86   [ TILEGX_OPC_BLBC       ] = 8,
87   [ TILEGX_OPC_BLBCT      ] = 8,
88   [ TILEGX_OPC_BLBS       ] = 8,
89   [ TILEGX_OPC_BLBST      ] = 8,
90   [ TILEGX_OPC_BLEZ       ] = 8,
91   [ TILEGX_OPC_BLEZT      ] = 8,
92   [ TILEGX_OPC_BLTZ       ] = 8,
93   [ TILEGX_OPC_BLTZT      ] = 8,
94   [ TILEGX_OPC_BNEZ       ] = 8,
95   [ TILEGX_OPC_BNEZT      ] = 8,
96 };
97 
98 
99 static tilegx_bundle_bits
100 encode_insn_tilegx_X (int p, struct tilegx_decoded_instruction decoded);
101 
102 static tilegx_bundle_bits
103 encode_insn_tilegx_Y (int p, struct tilegx_decoded_instruction decoded);
104 
105 static int decode( tilegx_bundle_bits *p, int count, ULong pc );
106 
107 static uint64_t
RAND(int round)108 RAND(int round) {
109   static volatile uint64_t rand_seed = 0;
110   while (round-- > 0)
111     rand_seed = (rand_seed >> 8) * 201520052007 + 1971;
112 #ifdef DBG
113   printf("RAND: %d\n", (int)rand_seed);
114 #endif
115   return rand_seed;
116 }
117 
118 
main(int argc,char * argv[])119 int main(int argc, char* argv[])
120 {
121   int i, start, end, pipe;
122   struct tilegx_decoded_instruction decoded;
123   if (argc == 1) {
124     pipe = 0x1F;
125     start = 0;
126     end = TILEGX_OPC_NONE;
127   } else if (argc == 3) {
128     start = atoi(argv[1]);
129 
130     if (start >= TILEGX_OPC_NONE)
131       return -1;
132 
133     end = start + 1;
134     /* pipes: X: bit 0,1; Y: bit 2-4 */
135     pipe = atoi(argv[2]);
136   } else {
137     return -1;
138   }
139 
140   for (i = start; i < end; i++) {
141     memset(&decoded, 0, sizeof(decoded));
142     const struct tilegx_opcode *opcode = &tilegx_opcodes[i];
143     decoded.opcode = opcode;
144 #ifdef DBG
145     const char *op_name = decoded.opcode->name;
146     printf("\n\n%d) %s\n", i, op_name);
147 #endif
148 
149     if (op_abnorm[i] & 1)
150       continue;
151 
152     /* X0 pipeline */
153     if (tilegx_opcodes[i].pipes & 1 & pipe)
154       encode_insn_tilegx_X(0, decoded);
155 
156     /* X1 pipeline */
157     if (tilegx_opcodes[i].pipes & 2 & pipe)
158       encode_insn_tilegx_X(1, decoded);
159 
160     /* Y0 pipleline */
161     if (tilegx_opcodes[i].pipes & 4 & pipe)
162       encode_insn_tilegx_Y(0, decoded);
163 
164     /* Y1 pipleline */
165     if (tilegx_opcodes[i].pipes & 8 & pipe)
166       encode_insn_tilegx_Y(1, decoded);
167 
168     /* Y2 pipleline */
169     if (tilegx_opcodes[i].pipes & 16 & pipe)
170       encode_insn_tilegx_Y(2, decoded);
171   }
172 
173   return 0;
174 }
175 
176 static tilegx_bundle_bits
encode_insn_tilegx_X(int p,struct tilegx_decoded_instruction decoded)177 encode_insn_tilegx_X(int p, struct tilegx_decoded_instruction decoded)
178 {
179   const struct tilegx_opcode *opc =
180     decoded.opcode;
181   int op_idx =  decoded.opcode->mnemonic;
182 
183   tilegx_bundle_bits insn = 0;
184   //int pipeX01 = (opc->pipes & 0x01) ? 0 : 1;
185   int op_num  = opc->num_operands;
186 
187   /* Assume either X0 or X1. */
188   if ((opc->pipes & 3) == 0)
189     return -1;
190 
191   /* Insert fnop in other pipe. */
192   insn = tilegx_opcodes[TILEGX_OPC_FNOP].
193     fixed_bit_values[p ? 0 : 1];
194 #ifdef DBG
195   printf(" X%d, ", p);
196 #endif
197 
198   insn |= opc->fixed_bit_values[p];
199 
200   printf("//file: _insn_test_%s_X%d.c\n", decoded.opcode->name, p);
201   printf("//op=%d\n", op_idx);
202   printf("#include <stdio.h>\n");
203   printf("#include <stdlib.h>\n");
204 
205   printf("\n"
206 	 "void func_exit(void) {\n"
207 	 "     printf(\"%cs\\n\", __func__);\n"
208 	 "     exit(0);\n"
209 	 "}\n"
210 	 "\n"
211 	 "void func_call(void) {\n"
212 	 "     printf(\"%cs\\n\", __func__);\n"
213 	 "     exit(0);\n"
214 	 "}\n"
215 	 "\n"
216 	 "unsigned long mem[2] = { 0x%lx, 0x%lx };\n"
217 	 "\n", '%', '%', RAND(op_idx), RAND(op_idx));
218 
219   printf("int main(void) {\n");
220   printf("    unsigned long a[4] = { 0, 0 };\n");
221 
222   printf("    asm __volatile__ (\n");
223 
224   int i, n = 0;
225 
226   if (op_abnorm[op_idx] & 6)
227     {
228       /* loop for each operand. */
229       for (i = 0 ; i < op_num; i++)
230 	{
231 	  const struct tilegx_operand *opd =
232 	    &tilegx_operands[opc->operands[p][i]];
233 
234 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
235 	    /* A register operand, pick register 0-50 randomly. */
236 	    decoded.operand_values[i] = RAND(op_idx) % 51;
237 	    int r = decoded.operand_values[i];
238 	    int64_t d = RAND(op_idx);
239 #ifdef DBG
240 	    printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d);
241 #endif
242 	    int k = 0;
243 	    for (k = 3; k >= 0 ; k--) {
244 	      if (d >> (16 * k) || k == 0) {
245 		printf("                      \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k)));
246 		for (k--; k >= 0; k--)
247 		  printf("                      \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k)));
248 		break;
249 	      }
250 	    }
251 	  } else {
252 	    /* An immediate operand, pick a random value. */
253 	    decoded.operand_values[i] = RAND(op_idx);
254 #ifdef DBG
255 	    printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]);
256 #endif
257 	  }
258 
259 	  Long  op = decoded.operand_values[i];
260 	  decoded.operands[i] = opd;
261 	  ULong x = opd->insert(op);
262 	  insn |= x;
263 	}
264       printf("                      \"");
265       if (op_abnorm[op_idx] & 2)
266 	printf("move r%d, %c2\\n\"\n",  (int)decoded.operand_values[1], '%');
267       else
268 	printf("move r%d, %c2\\n\"\n",  (int)decoded.operand_values[0], '%');
269 
270       printf("                      \"");
271       decode(&insn, 2, 0);
272       printf("\\n\"\n");
273 
274       /* loop for each operand. */
275       n = 0;
276       for (i = 0 ; i < op_num; i++)
277 	{
278 	  const struct tilegx_operand *opd =
279 	    &tilegx_operands[opc->operands[p][i]];
280 
281 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
282 	    /* A register operand */
283 	    printf("                      \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]);
284 	    n++;
285 	  }
286 	}
287 
288       printf("                      ");
289       if (n)
290 	printf(":");
291       for (i = 0; i < n; i++)
292 	{
293 	  printf("\"=r\"(a[%d])", i);
294 	  if (i != n - 1)
295 	    printf(",");
296 	}
297       printf(" : \"r\"(mem)");
298 
299       printf(");\n");
300 
301       printf("    printf(\"%c016lx %c016lx\\n\", mem[0], mem[1]);\n", '%', '%');
302 
303     }
304   else if (op_idx == TILEGX_OPC_J)
305     {
306       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
307       printf("                     :: \"i\"(func_exit));\n");
308     }
309   else if (op_idx == TILEGX_OPC_JAL)
310     {
311       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
312       printf("                     :: \"i\"(func_call));\n");
313     }
314   else if (op_idx == TILEGX_OPC_JR || op_idx == TILEGX_OPC_JRP)
315     {
316       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
317       printf("                     :: \"r\"(func_exit));\n");
318     }
319   else if (op_idx == TILEGX_OPC_JALR || op_idx == TILEGX_OPC_JALRP )
320     {
321       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
322       printf("                     :: \"r\"(func_call));\n");
323     }
324   else if (op_abnorm[op_idx] & 8)
325     {
326       // OPC_BXXX  conditional branch
327       int r = RAND(op_idx) % 51;
328       int d = RAND(op_idx) & 1;
329       printf("                     \"movei r%d, %d\\n\"\n", r, d);
330       printf("                     \"%s r%d,  %c0\\n\"\n", decoded.opcode->name, r, '%');
331       printf("                     \"jal %c1\\n\"\n", '%');
332       printf("                     :: \"i\"(func_exit), \"i\"(func_call));\n");
333     }
334   else
335     {
336       /* loop for each operand. */
337       for (i = 0 ; i < op_num; i++)
338 	{
339 	  const struct tilegx_operand *opd =
340 	    &tilegx_operands[opc->operands[p][i]];
341 
342 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
343 	    /* A register operand, pick register 0-50 randomly. */
344 	    decoded.operand_values[i] = RAND(op_idx) % 51;
345 	    int r = decoded.operand_values[i];
346 	    int64_t d = RAND(op_idx);
347 
348 #ifdef DBG
349 	    printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d);
350 #endif
351 	    int k = 0;
352 	    for (k = 3; k >= 0 ; k--) {
353 	      if (d >> (16 * k) || k == 0) {
354 		printf("                      \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k)));
355 		for (k--; k >= 0; k--)
356 		  printf("                      \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k)));
357 		break;
358 	      }
359 	    }
360 	  } else {
361 	    /* An immediate operand, pick a random value. */
362 	    decoded.operand_values[i] = RAND(op_idx);
363 #ifdef DBG
364 	    printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]);
365 #endif
366 	  }
367 
368 	  Long  op = decoded.operand_values[i];
369 	  decoded.operands[i] = opd;
370 	  ULong x = opd->insert(op);
371 	  insn |= x;
372 	}
373       printf("                      \"");
374       decode(&insn, 2, 0);
375       printf("\\n\"\n");
376 
377       /* loop for each operand. */
378       n = 0;
379       for (i = 0 ; i < op_num; i++)
380 	{
381 	  const struct tilegx_operand *opd =
382 	    &tilegx_operands[opc->operands[p][i]];
383 
384 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
385 	    /* A register operand */
386 	    printf("                      \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]);
387 	    n++;
388 	  }
389 	}
390 
391       printf("                      ");
392       if (n)
393 	printf(":");
394       for (i = 0; i < n; i++)
395 	{
396 	  printf("\"=r\"(a[%d])", i);
397 	  if (i != n - 1)
398 	    printf(",");
399 	}
400 
401       printf(");\n");
402     }
403 
404   for (i = 0; i < n; i++)
405     {
406       printf("    printf(\"%c016lx\\n\", a[%d]);\n", '%', i);
407     }
408   printf("    return 0;\n");
409   printf("}\n");
410   return insn;
411 }
412 
413 static tilegx_bundle_bits
encode_insn_tilegx_Y(int p,struct tilegx_decoded_instruction decoded)414 encode_insn_tilegx_Y (int p, struct tilegx_decoded_instruction decoded )
415 {
416   int i;
417   const struct tilegx_opcode *opc =
418     decoded.opcode;
419   int op_idx =  decoded.opcode->mnemonic;
420 
421   const struct tilegx_operand *opd;
422 
423   tilegx_bundle_bits insn = 0;
424   Int op_num  = opc->num_operands;
425 
426   /* Insert fnop in Y0 and Y1 pipeline. */
427   if (p != 0)
428     insn |= tilegx_opcodes[TILEGX_OPC_FNOP].
429       fixed_bit_values[2];
430 
431   if (p != 1)
432     insn |= tilegx_opcodes[TILEGX_OPC_FNOP].
433       fixed_bit_values[3];
434 
435   /* Fill-in Y2 as dumy load "ld zero, sp" */
436   if (p != 2) {
437     insn |= tilegx_opcodes[TILEGX_OPC_LD].
438       fixed_bit_values[4];
439     opd = &tilegx_operands[tilegx_opcodes[TILEGX_OPC_LD].operands[4][0]];
440     insn |= opd->insert(63);
441     opd = &tilegx_operands[tilegx_opcodes[TILEGX_OPC_LD].operands[4][1]];
442     insn |= opd->insert(54);
443   }
444 #ifdef DBG
445   printf(" Y%d, ", p);
446 #endif
447 
448   insn |= opc->fixed_bit_values[2 + p];
449 
450   printf("//file: _insn_test_%s_Y%d.c\n", decoded.opcode->name, p);
451   printf("//op=%d\n", op_idx);
452   printf("#include <stdio.h>\n");
453   printf("#include <stdlib.h>\n");
454 
455   printf("\n"
456 	 "void func_exit(void) {\n"
457 	 "     printf(\"%cs\\n\", __func__);\n"
458 	 "     exit(0);\n"
459 	 "}\n"
460 	 "\n"
461 	 "void func_call(void) {\n"
462 	 "     printf(\"%cs\\n\", __func__);\n"
463 	 "     exit(0);\n"
464 	 "}\n"
465 	 "\n"
466 	 "unsigned long mem[2] = { 0x%lx, 0x%lx };\n"
467 	 "\n", '%', '%', RAND(op_idx), RAND(op_idx));
468 
469   printf("int main(void) {\n");
470   printf("    unsigned long a[4] = { 0, 0 };\n");
471 
472   printf("    asm __volatile__ (\n");
473 
474   int n = 0;
475 
476   if (op_abnorm[op_idx] & 6)
477     {
478       /* loop for each operand. */
479       for (i = 0 ; i < op_num; i++)
480 	{
481           opd = &tilegx_operands[opc->operands[2 + p][i]];
482 
483 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
484 	    /* A register operand, pick register 0-53 randomly. */
485 	    decoded.operand_values[i] = RAND(op_idx) % 53;
486 	    int r = decoded.operand_values[i];
487 	    int64_t d = RAND(op_idx);
488 #ifdef DBG
489 	    printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d);
490 #endif
491 	    int k = 0;
492 	    for (k = 3; k >= 0 ; k--) {
493 	      if (d >> (16 * k) || k == 0) {
494 		printf("                      \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k)));
495 		for (k--; k >= 0; k--)
496 		  printf("                      \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k)));
497 		break;
498 	      }
499 	    }
500 	  } else {
501 	    /* An immediate operand, pick a random value. */
502 	    decoded.operand_values[i] = RAND(op_idx);
503 #ifdef DBG
504 	    printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]);
505 #endif
506 	  }
507 
508 	  Long  op = decoded.operand_values[i];
509 	  decoded.operands[i] = opd;
510 	  ULong x = opd->insert(op);
511 	  insn |= x;
512 	}
513       printf("                      \"");
514       if (op_abnorm[op_idx] & 2)
515 	printf("move r%d, %c2\\n\"\n",  (int)decoded.operand_values[1], '%');
516       else
517 	printf("move r%d, %c2\\n\"\n",  (int)decoded.operand_values[0], '%');
518 
519       printf("                      \"");
520       decode(&insn, 3, 0);
521       printf("\\n\"\n");
522 
523       /* loop for each operand. */
524       n = 0;
525       for (i = 0 ; i < op_num; i++)
526 	{
527           opd = &tilegx_operands[opc->operands[2 + p][i]];
528 
529 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
530 	    /* A register operand */
531 	    printf("                      \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]);
532 	    n++;
533 	  }
534 	}
535 
536       printf("                      ");
537       if (n)
538 	printf(":");
539       for (i = 0; i < n; i++)
540 	{
541 	  printf("\"=r\"(a[%d])", i);
542 	  if (i != n - 1)
543 	    printf(",");
544 	}
545       printf(" : \"r\"(mem)");
546 
547       printf(");\n");
548 
549       printf("    printf(\"%c016lx %c016lx\\n\", mem[0], mem[1]);\n", '%', '%');
550 
551     }
552   else if (op_idx == TILEGX_OPC_J)
553     {
554       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
555       printf("                     :: \"i\"(func_exit));\n");
556     }
557   else if (op_idx == TILEGX_OPC_JAL)
558     {
559       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
560       printf("                     :: \"i\"(func_call));\n");
561     }
562   else if (op_idx == TILEGX_OPC_JR || op_idx == TILEGX_OPC_JRP)
563     {
564       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
565       printf("                     :: \"r\"(func_exit));\n");
566     }
567   else if (op_idx == TILEGX_OPC_JALR || op_idx == TILEGX_OPC_JALRP )
568     {
569       printf("                     \"%s %c0\\n\"\n", decoded.opcode->name, '%');
570       printf("                     :: \"r\"(func_call));\n");
571     }
572   else if (op_abnorm[op_idx] & 8)
573     {
574       // OPC_BXXX  conditional branch
575       int r = RAND(op_idx) % 51;
576       int d = RAND(op_idx) & 1;
577       printf("                     \"movei r%d, %d\\n\"\n", r, d);
578       printf("                     \"%s r%d,  %c0\\n\"\n", decoded.opcode->name, r, '%');
579       printf("                     \"jal %c1\\n\"\n", '%');
580       printf("                     :: \"i\"(func_exit), \"i\"(func_call));\n");
581     }
582   else
583     {
584       /* loop for each operand. */
585       for (i = 0 ; i < op_num; i++)
586 	{
587           opd = &tilegx_operands[opc->operands[2 + p][i]];
588 
589 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
590 	    /* A register operand, pick register 0-50 randomly. */
591 	    decoded.operand_values[i] = RAND(op_idx) % 51;
592 	    int r = decoded.operand_values[i];
593 	    int64_t d = RAND(op_idx);
594 
595 #ifdef DBG
596 	    printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d);
597 #endif
598 	    int k = 0;
599 	    for (k = 3; k >= 0 ; k--) {
600 	      if (d >> (16 * k) || k == 0) {
601 		printf("                      \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k)));
602 		for (k--; k >= 0; k--)
603 		  printf("                      \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k)));
604 		break;
605 	      }
606 	    }
607 	  } else {
608 	    /* An immediate operand, pick a random value. */
609 	    decoded.operand_values[i] = RAND(op_idx);
610 #ifdef DBG
611 	    printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]);
612 #endif
613 	  }
614 
615 	  Long  op = decoded.operand_values[i];
616 	  decoded.operands[i] = opd;
617 	  ULong x = opd->insert(op);
618 	  insn |= x;
619 	}
620       printf("                      \"");
621       decode(&insn, 3, 0);
622       printf("\\n\"\n");
623 
624       /* loop for each operand. */
625       n = 0;
626       for (i = 0 ; i < op_num; i++)
627 	{
628           opd = &tilegx_operands[opc->operands[2 + p][i]];
629 
630 	  if (opd->type == TILEGX_OP_TYPE_REGISTER) {
631 	    /* A register operand */
632 	    printf("                      \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]);
633 	    n++;
634 	  }
635 	}
636 
637       printf("                      ");
638       if (n)
639 	printf(":");
640       for (i = 0; i < n; i++)
641 	{
642 	  printf("\"=r\"(a[%d])", i);
643 	  if (i != n - 1)
644 	    printf(",");
645 	}
646 
647       printf(");\n");
648     }
649 
650   for (i = 0; i < n; i++)
651     {
652       printf("    printf(\"%c016lx\\n\", a[%d]);\n", '%', i);
653     }
654   printf("    return 0;\n");
655   printf("}\n");
656   return insn;
657 }
658 
display_insn(struct tilegx_decoded_instruction decoded[1])659 static int display_insn ( struct tilegx_decoded_instruction
660                           decoded[1] )
661 {
662   int i;
663   for (i = 0;
664        decoded[i].opcode && (i < 1);
665        i++) {
666     int n;
667     printf("%s ", decoded[i].opcode->name);
668 
669     for (n = 0; n < decoded[i].opcode->num_operands; n++) {
670       const struct tilegx_operand *op = decoded[i].operands[n];
671 
672       if (op->type == TILEGX_OP_TYPE_REGISTER)
673         printf("r%d", (int) decoded[i].operand_values[n]);
674       else
675         printf("%ld", (unsigned long)decoded[i].operand_values[n]);
676 
677       if (n != (decoded[i].opcode->num_operands - 1))
678         printf(", ");
679     }
680     printf(" ");
681   }
682   return i;
683 }
684 
decode(tilegx_bundle_bits * p,int count,ULong pc)685 int decode( tilegx_bundle_bits *p, int count, ULong pc )
686 {
687   struct tilegx_decoded_instruction
688     decode[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
689 
690   if (pc) {
691     printf("%012llx %016llx  ", pc, (ULong)p[0]);
692     pc += 8;
693   }
694   parse_insn_tilegx(p[0], 0, decode);
695 
696   int k;
697 
698   printf("{ ");
699 
700   for(k = 0; decode[k].opcode && (k <TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE);
701       k++) {
702 
703     display_insn(&decode[k]);
704     if (--count > 0)
705       printf("; ");
706   }
707 
708   printf(" }");
709 
710   return count;
711 }
712