| //gcc a.c ../../../VEX/priv/tilegx_disasm.c -I ../../../ -I ../../../VEX/priv/ -I ../../../VEX/pub/ |
| |
| #include <stdio.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include "tilegx_disasm.h" |
| |
| #undef DGB |
| |
| static unsigned char op_abnorm[TILEGX_OPC_NONE] = { |
| /* Black list */ |
| [ TILEGX_OPC_BPT ] = 1, |
| [ TILEGX_OPC_INFO ] = 1, |
| [ TILEGX_OPC_INFOL ] = 1, |
| [ TILEGX_OPC_DRAIN ] = 1, |
| [ TILEGX_OPC_IRET ] = 1, |
| [ TILEGX_OPC_SWINT0 ] = 1, |
| [ TILEGX_OPC_SWINT1 ] = 1, |
| [ TILEGX_OPC_SWINT2 ] = 1, |
| [ TILEGX_OPC_SWINT3 ] = 1, |
| [ TILEGX_OPC_LD4S_TLS ] = 1, |
| [ TILEGX_OPC_LD_TLS ] = 1, |
| [ TILEGX_OPC_MFSPR ] = 1, |
| [ TILEGX_OPC_MTSPR ] = 1, |
| [ TILEGX_OPC_ILL ] = 1, |
| [ TILEGX_OPC_NAP ] = 1, |
| |
| /* mem load */ |
| [ TILEGX_OPC_LD ] = 2, |
| [ TILEGX_OPC_LD_ADD ] = 2, |
| [ TILEGX_OPC_LD1S ] = 2, |
| [ TILEGX_OPC_LD1S_ADD ] = 2, |
| [ TILEGX_OPC_LD1U ] = 2, |
| [ TILEGX_OPC_LD1U_ADD ] = 2, |
| [ TILEGX_OPC_LD2S ] = 2, |
| [ TILEGX_OPC_LD2S_ADD ] = 2, |
| [ TILEGX_OPC_LD2U ] = 2, |
| [ TILEGX_OPC_LD2U_ADD ] = 2, |
| [ TILEGX_OPC_LD4S ] = 2, |
| [ TILEGX_OPC_LD4S_ADD ] = 2, |
| [ TILEGX_OPC_LD4U ] = 2, |
| [ TILEGX_OPC_LD4U_ADD ] = 2, |
| [ TILEGX_OPC_LDNA ] = 2, |
| [ TILEGX_OPC_LDNA_ADD ] = 2, |
| [ TILEGX_OPC_LDNT ] = 2, |
| [ TILEGX_OPC_LDNT1S ] = 2, |
| [ TILEGX_OPC_LDNT1S_ADD ] = 2, |
| [ TILEGX_OPC_LDNT1U ] = 2, |
| [ TILEGX_OPC_LDNT1U_ADD ] = 2, |
| [ TILEGX_OPC_LDNT2S ] = 2, |
| [ TILEGX_OPC_LDNT2S_ADD ] = 2, |
| [ TILEGX_OPC_LDNT2U ] = 2, |
| [ TILEGX_OPC_LDNT2U_ADD ] = 2, |
| [ TILEGX_OPC_LDNT4S ] = 2, |
| [ TILEGX_OPC_LDNT4S_ADD ] = 2, |
| [ TILEGX_OPC_LDNT4U ] = 2, |
| [ TILEGX_OPC_LDNT4U_ADD ] = 2, |
| [ TILEGX_OPC_LDNT_ADD ] = 2, |
| |
| /* mem store */ |
| [ TILEGX_OPC_ST ] = 4, |
| [ TILEGX_OPC_ST1 ] = 4, |
| [ TILEGX_OPC_ST1_ADD ] = 4, |
| [ TILEGX_OPC_ST2 ] = 4, |
| [ TILEGX_OPC_ST2_ADD ] = 4, |
| [ TILEGX_OPC_ST4 ] = 4, |
| [ TILEGX_OPC_ST4_ADD ] = 4, |
| [ TILEGX_OPC_ST_ADD ] = 4, |
| [ TILEGX_OPC_STNT ] = 4, |
| [ TILEGX_OPC_STNT1 ] = 4, |
| [ TILEGX_OPC_STNT1_ADD ] = 4, |
| [ TILEGX_OPC_STNT2 ] = 4, |
| [ TILEGX_OPC_STNT2_ADD ] = 4, |
| [ TILEGX_OPC_STNT4 ] = 4, |
| [ TILEGX_OPC_STNT4_ADD ] = 4, |
| [ TILEGX_OPC_STNT_ADD ] = 4, |
| |
| /* conditional branch */ |
| [ TILEGX_OPC_BEQZ ] = 8, |
| [ TILEGX_OPC_BEQZT ] = 8, |
| [ TILEGX_OPC_BGEZ ] = 8, |
| [ TILEGX_OPC_BGEZT ] = 8, |
| [ TILEGX_OPC_BGTZ ] = 8, |
| [ TILEGX_OPC_BGTZT ] = 8, |
| [ TILEGX_OPC_BLBC ] = 8, |
| [ TILEGX_OPC_BLBCT ] = 8, |
| [ TILEGX_OPC_BLBS ] = 8, |
| [ TILEGX_OPC_BLBST ] = 8, |
| [ TILEGX_OPC_BLEZ ] = 8, |
| [ TILEGX_OPC_BLEZT ] = 8, |
| [ TILEGX_OPC_BLTZ ] = 8, |
| [ TILEGX_OPC_BLTZT ] = 8, |
| [ TILEGX_OPC_BNEZ ] = 8, |
| [ TILEGX_OPC_BNEZT ] = 8, |
| }; |
| |
| |
| static tilegx_bundle_bits |
| encode_insn_tilegx_X (int p, struct tilegx_decoded_instruction decoded); |
| |
| static tilegx_bundle_bits |
| encode_insn_tilegx_Y (int p, struct tilegx_decoded_instruction decoded); |
| |
| static int decode( tilegx_bundle_bits *p, int count, ULong pc ); |
| |
| static uint64_t |
| RAND(int round) { |
| static volatile uint64_t rand_seed = 0; |
| while (round-- > 0) |
| rand_seed = (rand_seed >> 8) * 201520052007 + 1971; |
| #ifdef DBG |
| printf("RAND: %d\n", (int)rand_seed); |
| #endif |
| return rand_seed; |
| } |
| |
| |
| int main(int argc, char* argv[]) |
| { |
| int i, start, end, pipe; |
| struct tilegx_decoded_instruction decoded; |
| if (argc == 1) { |
| pipe = 0x1F; |
| start = 0; |
| end = TILEGX_OPC_NONE; |
| } else if (argc == 3) { |
| start = atoi(argv[1]); |
| |
| if (start >= TILEGX_OPC_NONE) |
| return -1; |
| |
| end = start + 1; |
| /* pipes: X: bit 0,1; Y: bit 2-4 */ |
| pipe = atoi(argv[2]); |
| } else { |
| return -1; |
| } |
| |
| for (i = start; i < end; i++) { |
| memset(&decoded, 0, sizeof(decoded)); |
| const struct tilegx_opcode *opcode = &tilegx_opcodes[i]; |
| decoded.opcode = opcode; |
| #ifdef DBG |
| const char *op_name = decoded.opcode->name; |
| printf("\n\n%d) %s\n", i, op_name); |
| #endif |
| |
| if (op_abnorm[i] & 1) |
| continue; |
| |
| /* X0 pipeline */ |
| if (tilegx_opcodes[i].pipes & 1 & pipe) |
| encode_insn_tilegx_X(0, decoded); |
| |
| /* X1 pipeline */ |
| if (tilegx_opcodes[i].pipes & 2 & pipe) |
| encode_insn_tilegx_X(1, decoded); |
| |
| /* Y0 pipleline */ |
| if (tilegx_opcodes[i].pipes & 4 & pipe) |
| encode_insn_tilegx_Y(0, decoded); |
| |
| /* Y1 pipleline */ |
| if (tilegx_opcodes[i].pipes & 8 & pipe) |
| encode_insn_tilegx_Y(1, decoded); |
| |
| /* Y2 pipleline */ |
| if (tilegx_opcodes[i].pipes & 16 & pipe) |
| encode_insn_tilegx_Y(2, decoded); |
| } |
| |
| return 0; |
| } |
| |
| static tilegx_bundle_bits |
| encode_insn_tilegx_X(int p, struct tilegx_decoded_instruction decoded) |
| { |
| const struct tilegx_opcode *opc = |
| decoded.opcode; |
| int op_idx = decoded.opcode->mnemonic; |
| |
| tilegx_bundle_bits insn = 0; |
| //int pipeX01 = (opc->pipes & 0x01) ? 0 : 1; |
| int op_num = opc->num_operands; |
| |
| /* Assume either X0 or X1. */ |
| if ((opc->pipes & 3) == 0) |
| return -1; |
| |
| /* Insert fnop in other pipe. */ |
| insn = tilegx_opcodes[TILEGX_OPC_FNOP]. |
| fixed_bit_values[p ? 0 : 1]; |
| #ifdef DBG |
| printf(" X%d, ", p); |
| #endif |
| |
| insn |= opc->fixed_bit_values[p]; |
| |
| printf("//file: _insn_test_%s_X%d.c\n", decoded.opcode->name, p); |
| printf("//op=%d\n", op_idx); |
| printf("#include <stdio.h>\n"); |
| printf("#include <stdlib.h>\n"); |
| |
| printf("\n" |
| "void func_exit(void) {\n" |
| " printf(\"%cs\\n\", __func__);\n" |
| " exit(0);\n" |
| "}\n" |
| "\n" |
| "void func_call(void) {\n" |
| " printf(\"%cs\\n\", __func__);\n" |
| " exit(0);\n" |
| "}\n" |
| "\n" |
| "unsigned long mem[2] = { 0x%lx, 0x%lx };\n" |
| "\n", '%', '%', RAND(op_idx), RAND(op_idx)); |
| |
| printf("int main(void) {\n"); |
| printf(" unsigned long a[4] = { 0, 0 };\n"); |
| |
| printf(" asm __volatile__ (\n"); |
| |
| int i, n = 0; |
| |
| if (op_abnorm[op_idx] & 6) |
| { |
| /* loop for each operand. */ |
| for (i = 0 ; i < op_num; i++) |
| { |
| const struct tilegx_operand *opd = |
| &tilegx_operands[opc->operands[p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand, pick register 0-50 randomly. */ |
| decoded.operand_values[i] = RAND(op_idx) % 51; |
| int r = decoded.operand_values[i]; |
| int64_t d = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d); |
| #endif |
| int k = 0; |
| for (k = 3; k >= 0 ; k--) { |
| if (d >> (16 * k) || k == 0) { |
| printf(" \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k))); |
| for (k--; k >= 0; k--) |
| printf(" \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k))); |
| break; |
| } |
| } |
| } else { |
| /* An immediate operand, pick a random value. */ |
| decoded.operand_values[i] = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]); |
| #endif |
| } |
| |
| Long op = decoded.operand_values[i]; |
| decoded.operands[i] = opd; |
| ULong x = opd->insert(op); |
| insn |= x; |
| } |
| printf(" \""); |
| if (op_abnorm[op_idx] & 2) |
| printf("move r%d, %c2\\n\"\n", (int)decoded.operand_values[1], '%'); |
| else |
| printf("move r%d, %c2\\n\"\n", (int)decoded.operand_values[0], '%'); |
| |
| printf(" \""); |
| decode(&insn, 2, 0); |
| printf("\\n\"\n"); |
| |
| /* loop for each operand. */ |
| n = 0; |
| for (i = 0 ; i < op_num; i++) |
| { |
| const struct tilegx_operand *opd = |
| &tilegx_operands[opc->operands[p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand */ |
| printf(" \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]); |
| n++; |
| } |
| } |
| |
| printf(" "); |
| if (n) |
| printf(":"); |
| for (i = 0; i < n; i++) |
| { |
| printf("\"=r\"(a[%d])", i); |
| if (i != n - 1) |
| printf(","); |
| } |
| printf(" : \"r\"(mem)"); |
| |
| printf(");\n"); |
| |
| printf(" printf(\"%c016lx %c016lx\\n\", mem[0], mem[1]);\n", '%', '%'); |
| |
| } |
| else if (op_idx == TILEGX_OPC_J) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"i\"(func_exit));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JAL) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"i\"(func_call));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JR || op_idx == TILEGX_OPC_JRP) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"r\"(func_exit));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JALR || op_idx == TILEGX_OPC_JALRP ) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"r\"(func_call));\n"); |
| } |
| else if (op_abnorm[op_idx] & 8) |
| { |
| // OPC_BXXX conditional branch |
| int r = RAND(op_idx) % 51; |
| int d = RAND(op_idx) & 1; |
| printf(" \"movei r%d, %d\\n\"\n", r, d); |
| printf(" \"%s r%d, %c0\\n\"\n", decoded.opcode->name, r, '%'); |
| printf(" \"jal %c1\\n\"\n", '%'); |
| printf(" :: \"i\"(func_exit), \"i\"(func_call));\n"); |
| } |
| else |
| { |
| /* loop for each operand. */ |
| for (i = 0 ; i < op_num; i++) |
| { |
| const struct tilegx_operand *opd = |
| &tilegx_operands[opc->operands[p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand, pick register 0-50 randomly. */ |
| decoded.operand_values[i] = RAND(op_idx) % 51; |
| int r = decoded.operand_values[i]; |
| int64_t d = RAND(op_idx); |
| |
| #ifdef DBG |
| printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d); |
| #endif |
| int k = 0; |
| for (k = 3; k >= 0 ; k--) { |
| if (d >> (16 * k) || k == 0) { |
| printf(" \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k))); |
| for (k--; k >= 0; k--) |
| printf(" \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k))); |
| break; |
| } |
| } |
| } else { |
| /* An immediate operand, pick a random value. */ |
| decoded.operand_values[i] = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]); |
| #endif |
| } |
| |
| Long op = decoded.operand_values[i]; |
| decoded.operands[i] = opd; |
| ULong x = opd->insert(op); |
| insn |= x; |
| } |
| printf(" \""); |
| decode(&insn, 2, 0); |
| printf("\\n\"\n"); |
| |
| /* loop for each operand. */ |
| n = 0; |
| for (i = 0 ; i < op_num; i++) |
| { |
| const struct tilegx_operand *opd = |
| &tilegx_operands[opc->operands[p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand */ |
| printf(" \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]); |
| n++; |
| } |
| } |
| |
| printf(" "); |
| if (n) |
| printf(":"); |
| for (i = 0; i < n; i++) |
| { |
| printf("\"=r\"(a[%d])", i); |
| if (i != n - 1) |
| printf(","); |
| } |
| |
| printf(");\n"); |
| } |
| |
| for (i = 0; i < n; i++) |
| { |
| printf(" printf(\"%c016lx\\n\", a[%d]);\n", '%', i); |
| } |
| printf(" return 0;\n"); |
| printf("}\n"); |
| return insn; |
| } |
| |
| static tilegx_bundle_bits |
| encode_insn_tilegx_Y (int p, struct tilegx_decoded_instruction decoded ) |
| { |
| int i; |
| const struct tilegx_opcode *opc = |
| decoded.opcode; |
| int op_idx = decoded.opcode->mnemonic; |
| |
| const struct tilegx_operand *opd; |
| |
| tilegx_bundle_bits insn = 0; |
| Int op_num = opc->num_operands; |
| |
| /* Insert fnop in Y0 and Y1 pipeline. */ |
| if (p != 0) |
| insn |= tilegx_opcodes[TILEGX_OPC_FNOP]. |
| fixed_bit_values[2]; |
| |
| if (p != 1) |
| insn |= tilegx_opcodes[TILEGX_OPC_FNOP]. |
| fixed_bit_values[3]; |
| |
| /* Fill-in Y2 as dumy load "ld zero, sp" */ |
| if (p != 2) { |
| insn |= tilegx_opcodes[TILEGX_OPC_LD]. |
| fixed_bit_values[4]; |
| opd = &tilegx_operands[tilegx_opcodes[TILEGX_OPC_LD].operands[4][0]]; |
| insn |= opd->insert(63); |
| opd = &tilegx_operands[tilegx_opcodes[TILEGX_OPC_LD].operands[4][1]]; |
| insn |= opd->insert(54); |
| } |
| #ifdef DBG |
| printf(" Y%d, ", p); |
| #endif |
| |
| insn |= opc->fixed_bit_values[2 + p]; |
| |
| printf("//file: _insn_test_%s_Y%d.c\n", decoded.opcode->name, p); |
| printf("//op=%d\n", op_idx); |
| printf("#include <stdio.h>\n"); |
| printf("#include <stdlib.h>\n"); |
| |
| printf("\n" |
| "void func_exit(void) {\n" |
| " printf(\"%cs\\n\", __func__);\n" |
| " exit(0);\n" |
| "}\n" |
| "\n" |
| "void func_call(void) {\n" |
| " printf(\"%cs\\n\", __func__);\n" |
| " exit(0);\n" |
| "}\n" |
| "\n" |
| "unsigned long mem[2] = { 0x%lx, 0x%lx };\n" |
| "\n", '%', '%', RAND(op_idx), RAND(op_idx)); |
| |
| printf("int main(void) {\n"); |
| printf(" unsigned long a[4] = { 0, 0 };\n"); |
| |
| printf(" asm __volatile__ (\n"); |
| |
| int n = 0; |
| |
| if (op_abnorm[op_idx] & 6) |
| { |
| /* loop for each operand. */ |
| for (i = 0 ; i < op_num; i++) |
| { |
| opd = &tilegx_operands[opc->operands[2 + p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand, pick register 0-53 randomly. */ |
| decoded.operand_values[i] = RAND(op_idx) % 53; |
| int r = decoded.operand_values[i]; |
| int64_t d = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d); |
| #endif |
| int k = 0; |
| for (k = 3; k >= 0 ; k--) { |
| if (d >> (16 * k) || k == 0) { |
| printf(" \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k))); |
| for (k--; k >= 0; k--) |
| printf(" \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k))); |
| break; |
| } |
| } |
| } else { |
| /* An immediate operand, pick a random value. */ |
| decoded.operand_values[i] = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]); |
| #endif |
| } |
| |
| Long op = decoded.operand_values[i]; |
| decoded.operands[i] = opd; |
| ULong x = opd->insert(op); |
| insn |= x; |
| } |
| printf(" \""); |
| if (op_abnorm[op_idx] & 2) |
| printf("move r%d, %c2\\n\"\n", (int)decoded.operand_values[1], '%'); |
| else |
| printf("move r%d, %c2\\n\"\n", (int)decoded.operand_values[0], '%'); |
| |
| printf(" \""); |
| decode(&insn, 3, 0); |
| printf("\\n\"\n"); |
| |
| /* loop for each operand. */ |
| n = 0; |
| for (i = 0 ; i < op_num; i++) |
| { |
| opd = &tilegx_operands[opc->operands[2 + p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand */ |
| printf(" \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]); |
| n++; |
| } |
| } |
| |
| printf(" "); |
| if (n) |
| printf(":"); |
| for (i = 0; i < n; i++) |
| { |
| printf("\"=r\"(a[%d])", i); |
| if (i != n - 1) |
| printf(","); |
| } |
| printf(" : \"r\"(mem)"); |
| |
| printf(");\n"); |
| |
| printf(" printf(\"%c016lx %c016lx\\n\", mem[0], mem[1]);\n", '%', '%'); |
| |
| } |
| else if (op_idx == TILEGX_OPC_J) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"i\"(func_exit));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JAL) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"i\"(func_call));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JR || op_idx == TILEGX_OPC_JRP) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"r\"(func_exit));\n"); |
| } |
| else if (op_idx == TILEGX_OPC_JALR || op_idx == TILEGX_OPC_JALRP ) |
| { |
| printf(" \"%s %c0\\n\"\n", decoded.opcode->name, '%'); |
| printf(" :: \"r\"(func_call));\n"); |
| } |
| else if (op_abnorm[op_idx] & 8) |
| { |
| // OPC_BXXX conditional branch |
| int r = RAND(op_idx) % 51; |
| int d = RAND(op_idx) & 1; |
| printf(" \"movei r%d, %d\\n\"\n", r, d); |
| printf(" \"%s r%d, %c0\\n\"\n", decoded.opcode->name, r, '%'); |
| printf(" \"jal %c1\\n\"\n", '%'); |
| printf(" :: \"i\"(func_exit), \"i\"(func_call));\n"); |
| } |
| else |
| { |
| /* loop for each operand. */ |
| for (i = 0 ; i < op_num; i++) |
| { |
| opd = &tilegx_operands[opc->operands[2 + p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand, pick register 0-50 randomly. */ |
| decoded.operand_values[i] = RAND(op_idx) % 51; |
| int r = decoded.operand_values[i]; |
| int64_t d = RAND(op_idx); |
| |
| #ifdef DBG |
| printf(" %d) r%-2d %016lx\n", i, (int)r, (unsigned long)d); |
| #endif |
| int k = 0; |
| for (k = 3; k >= 0 ; k--) { |
| if (d >> (16 * k) || k == 0) { |
| printf(" \"moveli r%d, %d\\n\"\n", r, (int)(d >> (16 * k))); |
| for (k--; k >= 0; k--) |
| printf(" \"shl16insli r%d, r%d, %d\\n\"\n", r, r, (int)(int16_t)(d >> (16 * k))); |
| break; |
| } |
| } |
| } else { |
| /* An immediate operand, pick a random value. */ |
| decoded.operand_values[i] = RAND(op_idx); |
| #ifdef DBG |
| printf(" %d) %016lx\n", (int)i, (unsigned long)decoded.operand_values[i]); |
| #endif |
| } |
| |
| Long op = decoded.operand_values[i]; |
| decoded.operands[i] = opd; |
| ULong x = opd->insert(op); |
| insn |= x; |
| } |
| printf(" \""); |
| decode(&insn, 3, 0); |
| printf("\\n\"\n"); |
| |
| /* loop for each operand. */ |
| n = 0; |
| for (i = 0 ; i < op_num; i++) |
| { |
| opd = &tilegx_operands[opc->operands[2 + p][i]]; |
| |
| if (opd->type == TILEGX_OP_TYPE_REGISTER) { |
| /* A register operand */ |
| printf(" \"move %c%d, r%d\\n\"\n", '%', n, (int)decoded.operand_values[i]); |
| n++; |
| } |
| } |
| |
| printf(" "); |
| if (n) |
| printf(":"); |
| for (i = 0; i < n; i++) |
| { |
| printf("\"=r\"(a[%d])", i); |
| if (i != n - 1) |
| printf(","); |
| } |
| |
| printf(");\n"); |
| } |
| |
| for (i = 0; i < n; i++) |
| { |
| printf(" printf(\"%c016lx\\n\", a[%d]);\n", '%', i); |
| } |
| printf(" return 0;\n"); |
| printf("}\n"); |
| return insn; |
| } |
| |
| static int display_insn ( struct tilegx_decoded_instruction |
| decoded[1] ) |
| { |
| int i; |
| for (i = 0; |
| decoded[i].opcode && (i < 1); |
| i++) { |
| int n; |
| printf("%s ", decoded[i].opcode->name); |
| |
| for (n = 0; n < decoded[i].opcode->num_operands; n++) { |
| const struct tilegx_operand *op = decoded[i].operands[n]; |
| |
| if (op->type == TILEGX_OP_TYPE_REGISTER) |
| printf("r%d", (int) decoded[i].operand_values[n]); |
| else |
| printf("%ld", (unsigned long)decoded[i].operand_values[n]); |
| |
| if (n != (decoded[i].opcode->num_operands - 1)) |
| printf(", "); |
| } |
| printf(" "); |
| } |
| return i; |
| } |
| |
| int decode( tilegx_bundle_bits *p, int count, ULong pc ) |
| { |
| struct tilegx_decoded_instruction |
| decode[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; |
| |
| if (pc) { |
| printf("%012llx %016llx ", pc, (ULong)p[0]); |
| pc += 8; |
| } |
| parse_insn_tilegx(p[0], 0, decode); |
| |
| int k; |
| |
| printf("{ "); |
| |
| for(k = 0; decode[k].opcode && (k <TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE); |
| k++) { |
| |
| display_insn(&decode[k]); |
| if (--count > 0) |
| printf("; "); |
| } |
| |
| printf(" }"); |
| |
| return count; |
| } |