Fixing broken instruction offsets on block splits.

This commit is contained in:
Ben Vanik 2013-12-27 15:00:34 -08:00
parent 402c96f9a6
commit 5bc74313e3
3 changed files with 26 additions and 8 deletions

View File

@ -79,8 +79,7 @@ int PPCFunctionBuilder::Emit(FunctionInfo* symbol_info) {
// TODO(benvanik): find a way to avoid using the opcode tables. // TODO(benvanik): find a way to avoid using the opcode tables.
i.type = GetInstrType(i.code); i.type = GetInstrType(i.code);
// Stash instruction offset. Instr* prev_instr = last_instr();
instr_offset_list_[offset] = last_instr();
// Mark label, if we were assigned one earlier on in the walk. // Mark label, if we were assigned one earlier on in the walk.
// We may still get a label, but it'll be inserted by LookupLabel // We may still get a label, but it'll be inserted by LookupLabel
@ -112,6 +111,7 @@ int PPCFunctionBuilder::Emit(FunctionInfo* symbol_info) {
SourceOffset(i.address); SourceOffset(i.address);
if (!i.type) { if (!i.type) {
instr_offset_list_[offset] = prev_instr->next;
XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code); XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code);
Comment("INVALID!"); Comment("INVALID!");
//TraceInvalidInstruction(i); //TraceInvalidInstruction(i);
@ -136,6 +136,20 @@ int PPCFunctionBuilder::Emit(FunctionInfo* symbol_info) {
// 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);
} }
// Stash instruction offset. We do this down here so that if the function
// splits blocks we don't have weird pointers.
if (prev_instr && prev_instr->next) {
instr_offset_list_[offset] = prev_instr->next;
} else if (current_block_) {
instr_offset_list_[offset] = current_block_->instr_head;
} else if (block_tail_) {
instr_offset_list_[offset] = block_tail_->instr_head;
} else {
XEASSERTALWAYS();
}
XEASSERT(instr_offset_list_[offset]->next->opcode == &OPCODE_TRAP_TRUE_info ||
instr_offset_list_[offset]->next->src1.offset == i.address);
} }
return Finalize(); return Finalize();
@ -174,10 +188,15 @@ Label* PPCFunctionBuilder::LookupLabel(uint64_t address) {
// the label. // the label.
label = NewLabel(); label = NewLabel();
label_list_[offset] = label; label_list_[offset] = label;
Instr* prev_instr = instr_offset_list_[offset]; Instr* instr = instr_offset_list_[offset];
if (prev_instr) { if (instr) {
if (instr->prev) {
// Insert label, breaking up existing instructions. // Insert label, breaking up existing instructions.
InsertLabel(label, prev_instr); InsertLabel(label, instr->prev);
} else {
// Instruction is at the head of a block, so just add the label.
MarkLabel(label, instr->block);
}
// Annotate the label, as we won't do it later. // Annotate the label, as we won't do it later.
if (FLAGS_annotate_disassembly) { if (FLAGS_annotate_disassembly) {

View File

@ -217,7 +217,6 @@ private:
protected: protected:
Arena* arena_; Arena* arena_;
private:
uint32_t attributes_; uint32_t attributes_;
uint32_t next_label_id_; uint32_t next_label_id_;

View File

@ -151,7 +151,7 @@ void D3D11GraphicsSystem::Pump() {
DispatchInterruptCallback(0); DispatchInterruptCallback(0);
} else { } else {
// If we have gone too long without an interrupt, fire one. // If we have gone too long without an interrupt, fire one.
if (xe_pal_now() - last_interrupt_time_ > 16 / 1000.0) { if (xe_pal_now() - last_interrupt_time_ > 500 / 1000.0) {
DispatchInterruptCallback(0); DispatchInterruptCallback(0);
} }
} }