[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:
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user