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