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
```
rlwimix
rldiclx
lwarx
stwcx
lfd
lfdx
lfs
lfsu
lfsx
stfd
stfiwx
stfs
stfsu
stfsx
addcx
addicx
divwx
extswx
faddx
fcfidx
fcmpu
fctiwzx
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)
@ -134,5 +154,16 @@ Slow path:
- 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

View File

@ -341,9 +341,7 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block) {
typedef int (*InstrEmitter)(FunctionGenerator& g, IRBuilder<>& b,
InstrData& i);
InstrEmitter emit = (InstrEmitter)i.type->emit;
XEASSERTNOTNULL(emit);
int result = emit(*this, *builder_, i);
if (result) {
if (!i.type->emit || emit(*this, *builder_, i)) {
// This printf is handy for sort/uniquify to find instructions.
//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.
std::vector<FunctionSymbol*> functions;
if (!sdb_->GetAllFunctions(functions)) {
XELOGI(XT("Beginning prep of %ld functions..."), functions.size());
for (std::vector<FunctionSymbol*>::iterator it = functions.begin();
it != functions.end(); ++it) {
FunctionSymbol* fn = *it;
@ -115,13 +116,20 @@ int ModuleGenerator::Generate() {
break;
}
}
XELOGI(XT("Function prep complete"));
}
// 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 =
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);
}
XELOGI(XT("Function generation complete"));
di_builder_->finalize();
@ -283,9 +291,6 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
}
void ModuleGenerator::PrepareFunction(FunctionSymbol* fn) {
// Module* m = gen_module_;
// LLVMContext& context = m->getContext();
// Create the function (and setup args/attributes/etc).
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);
if (kernel_export) {
if (info->thunk_address) {
xesnprintfa(name, XECOUNT(name), "__imp__%s", kernel_export->name);
xesnprintfa(name, XECOUNT(name), "__imp_%s", kernel_export->name);
} else {
xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name);
}
} else {
xesnprintfa(name, XECOUNT(name), "__imp__%s_%.3X", library->name,
xesnprintfa(name, XECOUNT(name), "__imp_%s_%.3X", library->name,
info->ordinal);
}
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.
// TODO: better way to finding out which key to use?
const uint8_t *xexkey;
if (header->file_format_info.compression_type == XEX_COMPRESSION_NORMAL &&
header->file_format_info.encryption_type == XEX_ENCRYPTION_NORMAL) {
if (header->file_format_info.encryption_type == XEX_ENCRYPTION_NORMAL) {
xexkey = xe_xex2_retail_key;
} else {
xexkey = xe_xex2_devkit_key;