Home | History | Annotate | Download | only in tilegx
      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
    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 
    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
    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
    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 
    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 
    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