Tweaks to get the generator running on the next app.
This commit is contained in:
parent
f1ea74dcff
commit
3dfd9c4b00
55
TODO.md
55
TODO.md
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue