Utility to dump instruction translation counts.
This commit is contained in:
parent
b6b27e621a
commit
5827f5f5d8
|
@ -122,6 +122,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
||||||
// TraceInvalidInstruction(i);
|
// TraceInvalidInstruction(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
++i.type->translation_count;
|
||||||
|
|
||||||
typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i);
|
typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i);
|
||||||
InstrEmitter emit = (InstrEmitter)i.type->emit;
|
InstrEmitter emit = (InstrEmitter)i.type->emit;
|
||||||
|
|
|
@ -10,14 +10,30 @@
|
||||||
#include <alloy/frontend/ppc/ppc_instr.h>
|
#include <alloy/frontend/ppc/ppc_instr.h>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <alloy/frontend/ppc/ppc_instr_tables.h>
|
#include <alloy/frontend/ppc/ppc_instr_tables.h>
|
||||||
|
#include <alloy/string_buffer.h>
|
||||||
#include <poly/poly.h>
|
#include <poly/poly.h>
|
||||||
|
|
||||||
namespace alloy {
|
namespace alloy {
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
namespace ppc {
|
namespace ppc {
|
||||||
|
|
||||||
|
std::vector<InstrType*> all_instrs_;
|
||||||
|
|
||||||
|
void DumpAllInstrCounts() {
|
||||||
|
StringBuffer sb;
|
||||||
|
sb.Append("Instruction translation counts:\n");
|
||||||
|
for (auto instr_type : all_instrs_) {
|
||||||
|
if (instr_type->translation_count) {
|
||||||
|
sb.Append("%8d : %s\n", instr_type->translation_count, instr_type->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stdout, sb.GetString());
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
void InstrOperand::Dump(std::string& out_str) {
|
void InstrOperand::Dump(std::string& out_str) {
|
||||||
if (display) {
|
if (display) {
|
||||||
out_str += display;
|
out_str += display;
|
||||||
|
@ -322,48 +338,39 @@ InstrType* GetInstrType(uint32_t code) {
|
||||||
switch (code >> 26) {
|
switch (code >> 26) {
|
||||||
case 4:
|
case 4:
|
||||||
// Opcode = 4, index = bits 10-0 (10)
|
// Opcode = 4, index = bits 10-0 (10)
|
||||||
slot =
|
slot = tables::instr_table_4[select_bits(code, 0, 10)];
|
||||||
alloy::frontend::ppc::tables::instr_table_4[select_bits(code, 0, 10)];
|
|
||||||
break;
|
break;
|
||||||
case 19:
|
case 19:
|
||||||
// Opcode = 19, index = bits 10-1 (10)
|
// Opcode = 19, index = bits 10-1 (10)
|
||||||
slot = alloy::frontend::ppc::tables::instr_table_19[select_bits(code, 1,
|
slot = tables::instr_table_19[select_bits(code, 1, 10)];
|
||||||
10)];
|
|
||||||
break;
|
break;
|
||||||
case 30:
|
case 30:
|
||||||
// Opcode = 30, index = bits 4-1 (4)
|
// Opcode = 30, index = bits 4-1 (4)
|
||||||
// Special cased to an uber instruction.
|
// Special cased to an uber instruction.
|
||||||
slot =
|
slot = tables::instr_table_30[select_bits(code, 0, 0)];
|
||||||
alloy::frontend::ppc::tables::instr_table_30[select_bits(code, 0, 0)];
|
|
||||||
break;
|
break;
|
||||||
case 31:
|
case 31:
|
||||||
// Opcode = 31, index = bits 10-1 (10)
|
// Opcode = 31, index = bits 10-1 (10)
|
||||||
slot = alloy::frontend::ppc::tables::instr_table_31[select_bits(code, 1,
|
slot = tables::instr_table_31[select_bits(code, 1, 10)];
|
||||||
10)];
|
|
||||||
break;
|
break;
|
||||||
case 58:
|
case 58:
|
||||||
// Opcode = 58, index = bits 1-0 (2)
|
// Opcode = 58, index = bits 1-0 (2)
|
||||||
slot =
|
slot = tables::instr_table_58[select_bits(code, 0, 1)];
|
||||||
alloy::frontend::ppc::tables::instr_table_58[select_bits(code, 0, 1)];
|
|
||||||
break;
|
break;
|
||||||
case 59:
|
case 59:
|
||||||
// Opcode = 59, index = bits 5-1 (5)
|
// Opcode = 59, index = bits 5-1 (5)
|
||||||
slot =
|
slot = tables::instr_table_59[select_bits(code, 1, 5)];
|
||||||
alloy::frontend::ppc::tables::instr_table_59[select_bits(code, 1, 5)];
|
|
||||||
break;
|
break;
|
||||||
case 62:
|
case 62:
|
||||||
// Opcode = 62, index = bits 1-0 (2)
|
// Opcode = 62, index = bits 1-0 (2)
|
||||||
slot =
|
slot = tables::instr_table_62[select_bits(code, 0, 1)];
|
||||||
alloy::frontend::ppc::tables::instr_table_62[select_bits(code, 0, 1)];
|
|
||||||
break;
|
break;
|
||||||
case 63:
|
case 63:
|
||||||
// Opcode = 63, index = bits 10-1 (10)
|
// Opcode = 63, index = bits 10-1 (10)
|
||||||
slot = alloy::frontend::ppc::tables::instr_table_63[select_bits(code, 1,
|
slot = tables::instr_table_63[select_bits(code, 1, 10)];
|
||||||
10)];
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
slot =
|
slot = tables::instr_table[select_bits(code, 26, 31)];
|
||||||
alloy::frontend::ppc::tables::instr_table[select_bits(code, 26, 31)];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (slot && slot->opcode) {
|
if (slot && slot->opcode) {
|
||||||
|
@ -372,9 +379,8 @@ InstrType* GetInstrType(uint32_t code) {
|
||||||
|
|
||||||
// Slow lookup via linear scan.
|
// Slow lookup via linear scan.
|
||||||
// This is primarily due to laziness. It could be made fast like the others.
|
// This is primarily due to laziness. It could be made fast like the others.
|
||||||
for (size_t n = 0;
|
for (size_t n = 0; n < poly::countof(tables::instr_table_scan); n++) {
|
||||||
n < poly::countof(alloy::frontend::ppc::tables::instr_table_scan); n++) {
|
slot = &(tables::instr_table_scan[n]);
|
||||||
slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]);
|
|
||||||
if (slot->opcode == (code & slot->opcode_mask)) {
|
if (slot->opcode == (code & slot->opcode_mask)) {
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
@ -389,6 +395,7 @@ int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
|
||||||
if (!instr_type) {
|
if (!instr_type) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
all_instrs_.push_back(instr_type);
|
||||||
assert_null(instr_type->emit);
|
assert_null(instr_type->emit);
|
||||||
instr_type->emit = emit;
|
instr_type->emit = emit;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -561,10 +561,12 @@ class InstrType {
|
||||||
uint32_t flags; // xe_ppc_instr_flag_e
|
uint32_t flags; // xe_ppc_instr_flag_e
|
||||||
InstrDisasmFn disasm;
|
InstrDisasmFn disasm;
|
||||||
char name[16];
|
char name[16];
|
||||||
|
uint32_t translation_count;
|
||||||
|
|
||||||
InstrEmitFn emit;
|
InstrEmitFn emit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void DumpAllInstrCounts();
|
||||||
InstrType* GetInstrType(uint32_t code);
|
InstrType* GetInstrType(uint32_t code);
|
||||||
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
|
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count,
|
||||||
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
|
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
|
||||||
{ \
|
{ \
|
||||||
opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \
|
opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \
|
||||||
Disasm_##disasm_fn, #name, \
|
Disasm_##disasm_fn, #name, 0, \
|
||||||
}
|
}
|
||||||
#define FLAG(t) kXEPPCInstrFlag##t
|
#define FLAG(t) kXEPPCInstrFlag##t
|
||||||
|
|
||||||
|
@ -844,7 +844,7 @@ static InstrType** instr_table = instr_table_prep(
|
||||||
#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
|
#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
|
||||||
{ \
|
{ \
|
||||||
opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \
|
opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \
|
||||||
kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, \
|
kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, 0, \
|
||||||
}
|
}
|
||||||
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
|
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
|
||||||
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
|
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
|
||||||
|
|
|
@ -124,6 +124,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||||
string_buffer_.Reset();
|
string_buffer_.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
alloy::frontend::ppc::DumpAllInstrCounts();
|
||||||
|
}
|
||||||
|
|
||||||
// Emit function.
|
// Emit function.
|
||||||
uint32_t emit_flags = 0;
|
uint32_t emit_flags = 0;
|
||||||
if (debug_info) {
|
if (debug_info) {
|
||||||
|
|
Loading…
Reference in New Issue