[JIT] New opcodes: OPCODE_LOAD_OFFSET and OPCODE_STORE_OFFSET

These take full advantage of x86 addressing, and eliminate extra add operations.
This commit is contained in:
DrChat
2018-02-14 16:26:49 -06:00
parent 1de598e4ce
commit e54c24e150
8 changed files with 352 additions and 35 deletions

View File

@@ -195,10 +195,15 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
break;
case OPCODE_LOAD:
case OPCODE_LOAD_OFFSET:
if (i->src1.value->IsConstant()) {
assert_false(i->flags & LOAD_STORE_BYTE_SWAP);
auto memory = processor_->memory();
auto address = i->src1.value->constant.i32;
if (i->opcode->num == OPCODE_LOAD_OFFSET) {
address += i->src2.value->constant.i32;
}
auto mmio_range =
processor_->memory()->LookupVirtualMappedRange(address);
if (FLAGS_inline_mmio_access && mmio_range) {
@@ -246,12 +251,21 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
}
break;
case OPCODE_STORE:
case OPCODE_STORE_OFFSET:
if (FLAGS_inline_mmio_access && i->src1.value->IsConstant()) {
auto address = i->src1.value->constant.i32;
if (i->opcode->num == OPCODE_STORE_OFFSET) {
address += i->src2.value->constant.i32;
}
auto mmio_range =
processor_->memory()->LookupVirtualMappedRange(address);
if (mmio_range) {
auto value = i->src2.value;
if (i->opcode->num == OPCODE_STORE_OFFSET) {
value = i->src3.value;
}
i->Replace(&OPCODE_STORE_MMIO_info, 0);
i->src1.offset = reinterpret_cast<uint64_t>(mmio_range);
i->src2.offset = address;

View File

@@ -35,9 +35,11 @@ bool MemorySequenceCombinationPass::Run(HIRBuilder* builder) {
while (block) {
auto i = block->instr_head;
while (i) {
if (i->opcode == &OPCODE_LOAD_info) {
if (i->opcode == &OPCODE_LOAD_info ||
i->opcode == &OPCODE_LOAD_OFFSET_info) {
CombineLoadSequence(i);
} else if (i->opcode == &OPCODE_STORE_info) {
} else if (i->opcode == &OPCODE_STORE_info ||
i->opcode == &OPCODE_STORE_OFFSET_info) {
CombineStoreSequence(i);
}
i = i->next;
@@ -112,6 +114,10 @@ void MemorySequenceCombinationPass::CombineStoreSequence(Instr* i) {
// store_convert v0, v1.i64, [swap|i64->i32,trunc]
auto src = i->src2.value;
if (i->opcode == &OPCODE_STORE_OFFSET_info) {
src = i->src3.value;
}
if (src->IsConstant()) {
// Constant value write - ignore.
return;
@@ -135,7 +141,11 @@ void MemorySequenceCombinationPass::CombineStoreSequence(Instr* i) {
// Pull the original value (from before the byte swap).
// The byte swap itself will go away in DCE.
i->set_src2(def->src1.value);
if (i->opcode == &OPCODE_STORE_info) {
i->set_src2(def->src1.value);
} else if (i->opcode == &OPCODE_STORE_OFFSET_info) {
i->set_src3(def->src1.value);
}
// TODO(benvanik): extend/truncate.
}