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