Do not assume that the destination is a temporary location,
as our peephole optimizer will break this. For example, the
following IR code (generated via from `x ^= gety()`):
(0) binst6 <- BITXOR x, call5
(0) x <- STORE_F binst6
after peephole optimization becomes:
(7) x <- BITXOR x, call5
Therefore we cannot assume that the output of the virtual
xor instruction can be utilized as a temporary value.
BITXOR becomes `(x | y) - (x & y)`, which would wrongly be
generated as:
x = x | y;
temp0 = x & y;
x = x - temp0;
While this particular case can be fixed by using temp0 first
and then x, the cross-product case would not be so simple.
Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
Fixes #190
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
- stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
+ stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
stmt.o3.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_SUB_F;
stmt.o3.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_SUB_F;
- stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+ stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + j;
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + j;
- stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+ stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
- stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+ stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
stmt.opcode = INSTR_BITOR;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
- stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+ stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
stmt.opcode = INSTR_BITAND;
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
- stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+ stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
for (j = 0; j < 3; ++j) {
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 1) % 3;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 2) % 3;
for (j = 0; j < 3; ++j) {
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 1) % 3;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 2) % 3;
- stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+ stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
code_push_statement(code, &stmt, instr->m_context);
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 2) % 3;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 1) % 3;
code_push_statement(code, &stmt, instr->m_context);
stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 2) % 3;
stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 1) % 3;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
code_push_statement(code, &stmt, instr->m_context);
}
stmt.opcode = INSTR_SUB_V;
- stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+ stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);
stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
code_push_statement(code, &stmt, instr->m_context);