Tweaks to get the generator running on the next app.

This commit is contained in:
Ben Vanik 2013-02-03 23:26:20 -08:00
parent f1ea74dcff
commit 3dfd9c4b00
5 changed files with 56 additions and 23 deletions

55
TODO.md
View File

@ -42,20 +42,40 @@ KeBugCheck:
## Instructions ## Instructions
``` ```
rlwimix
rldiclx
lwarx lwarx
stwcx stwcx
lfd
lfdx addcx
lfs addicx
lfsu divwx
lfsx extswx
stfd faddx
stfiwx fcfidx
stfs fcmpu
stfsu fctiwzx
stfsx fdivx
fmaddsx
fmrx
fmulsx
fmulx
fnegx
frspx
mulldx
negx
rlwimix
rldiclx
rldicrx
sradx
srdx
srwx
subfcx
subfzex
new:
extldi
mfmsr
mtmsrd
srdi
``` ```
### XER CA bit (carry) ### XER CA bit (carry)
@ -134,5 +154,16 @@ Slow path:
- If not found, need new function codegen! - If not found, need new function codegen!
``` ```
## Linking/multicore processing
Need to split up processing of functions.
ModuleGenerator::Generate's BuildFunction loop is the real time hog here.
Spin up N threads. Each as a module and steals functions from the queue to
generate. After the module hits a certain size it's dumped to disk and another
is created.
Afterwards, all modules are loaded lazily and linked together. The final one
is writen out and loaded again lazily.
JIT works on that.
## Debugging ## Debugging

View File

@ -341,9 +341,7 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block) {
typedef int (*InstrEmitter)(FunctionGenerator& g, IRBuilder<>& b, typedef int (*InstrEmitter)(FunctionGenerator& g, IRBuilder<>& b,
InstrData& i); InstrData& i);
InstrEmitter emit = (InstrEmitter)i.type->emit; InstrEmitter emit = (InstrEmitter)i.type->emit;
XEASSERTNOTNULL(emit); if (!i.type->emit || emit(*this, *builder_, i)) {
int result = emit(*this, *builder_, i);
if (result) {
// This printf is handy for sort/uniquify to find instructions. // This printf is handy for sort/uniquify to find instructions.
//printf("unimplinstr %s\n", i.type->name); //printf("unimplinstr %s\n", i.type->name);

View File

@ -96,6 +96,7 @@ int ModuleGenerator::Generate() {
// value (so that we can call it), the second actually builds the function. // value (so that we can call it), the second actually builds the function.
std::vector<FunctionSymbol*> functions; std::vector<FunctionSymbol*> functions;
if (!sdb_->GetAllFunctions(functions)) { if (!sdb_->GetAllFunctions(functions)) {
XELOGI(XT("Beginning prep of %ld functions..."), functions.size());
for (std::vector<FunctionSymbol*>::iterator it = functions.begin(); for (std::vector<FunctionSymbol*>::iterator it = functions.begin();
it != functions.end(); ++it) { it != functions.end(); ++it) {
FunctionSymbol* fn = *it; FunctionSymbol* fn = *it;
@ -115,13 +116,20 @@ int ModuleGenerator::Generate() {
break; break;
} }
} }
XELOGI(XT("Function prep complete"));
} }
// Build out all the user functions. // Build out all the user functions.
size_t n = 0;
XELOGI(XT("Beginning generation of %ld functions..."), functions.size());
for (std::map<uint32_t, CodegenFunction*>::iterator it = for (std::map<uint32_t, CodegenFunction*>::iterator it =
functions_.begin(); it != functions_.end(); ++it) { functions_.begin(); it != functions_.end(); ++it, ++n) {
FunctionSymbol* symbol = it->second->symbol;
XELOGI(XT("Generating %ld/%ld %.8X %s"),
n, functions_.size(), symbol->start_address, symbol->name());
BuildFunction(it->second); BuildFunction(it->second);
} }
XELOGI(XT("Function generation complete"));
di_builder_->finalize(); di_builder_->finalize();
@ -283,9 +291,6 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
} }
void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) { void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) {
// Module* m = gen_module_;
// LLVMContext& context = m->getContext();
// Create the function (and setup args/attributes/etc). // Create the function (and setup args/attributes/etc).
Function* f = CreateFunctionDefinition(fn->name()); Function* f = CreateFunctionDefinition(fn->name());

View File

@ -200,12 +200,12 @@ int XexSymbolDatabase::AddImports(const xe_xex2_import_library_t* library) {
VariableSymbol* var = GetOrInsertVariable(info->value_address); VariableSymbol* var = GetOrInsertVariable(info->value_address);
if (kernel_export) { if (kernel_export) {
if (info->thunk_address) { if (info->thunk_address) {
xesnprintfa(name, XECOUNT(name), "__imp__%s", kernel_export->name); xesnprintfa(name, XECOUNT(name), "__imp_%s", kernel_export->name);
} else { } else {
xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name); xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name);
} }
} else { } else {
xesnprintfa(name, XECOUNT(name), "__imp__%s_%.3X", library->name, xesnprintfa(name, XECOUNT(name), "__imp_%s_%.3X", library->name,
info->ordinal); info->ordinal);
} }
var->set_name(name); var->set_name(name);

View File

@ -415,8 +415,7 @@ int xe_xex2_decrypt_key(xe_xex2_header_t *header) {
// Guess key based on file info. // Guess key based on file info.
// TODO: better way to finding out which key to use? // TODO: better way to finding out which key to use?
const uint8_t *xexkey; const uint8_t *xexkey;
if (header->file_format_info.compression_type == XEX_COMPRESSION_NORMAL && if (header->file_format_info.encryption_type == XEX_ENCRYPTION_NORMAL) {
header->file_format_info.encryption_type == XEX_ENCRYPTION_NORMAL) {
xexkey = xe_xex2_retail_key; xexkey = xe_xex2_retail_key;
} else { } else {
xexkey = xe_xex2_devkit_key; xexkey = xe_xex2_devkit_key;