Try to get carry/zero/N flags set properly for various branch states

This commit is contained in:
Jason Turner 2021-05-11 22:00:33 -06:00
parent 6c0e5a660d
commit 905e850abb
2 changed files with 13 additions and 6 deletions

View File

@ -23,8 +23,8 @@ bool optimize(std::vector<mos6502> &instructions)
// remove unused flag-fix-up blocks
// it might make sense in the future to only insert these if determined they are needed?
for (size_t op = 10; op < instructions.size(); ++op) {
if (instructions[op].opcode == mos6502::OpCode::lda) {
if (instructions[op - 1].text == "; END remove if next is lda") {
if (instructions[op].opcode == mos6502::OpCode::lda || instructions[op].opcode == mos6502::OpCode::bcc || instructions[op].opcode == mos6502::OpCode::bcs) {
if (instructions[op - 1].text == "; END remove if next is lda, bcc, bcs") {
for (size_t inner_op = op - 1; inner_op > 1; --inner_op) {
instructions[inner_op] = mos6502(ASMLine::Type::Directive,
"; removed unused flag fix-up: " + instructions[inner_op].to_string());

View File

@ -269,7 +269,7 @@ void fixup_16_bit_N_Z_flags(std::vector<mos6502> &instructions)
// if low order byte is negative, shift right by one bit, then we'll get the proper Z/N flags
instructions.emplace_back(mos6502::OpCode::lsr);
instructions.emplace_back(ASMLine::Type::Label, set_flag_label);
instructions.emplace_back(ASMLine::Type::Directive, "; END remove if next is lda");
instructions.emplace_back(ASMLine::Type::Directive, "; END remove if next is lda, bcc, bcs");
}
void add_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg, const std::uint16_t value)
@ -394,7 +394,8 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
instructions.emplace_back(mos6502::OpCode::sbc, personality.get_register(o2_reg_num));
instructions.emplace_back(mos6502::OpCode::sta, personality.get_register(o1_reg_num));
fixup_16_bit_N_Z_flags(instructions);
instructions.emplace_back(mos6502::OpCode::tax);
// fixup_16_bit_N_Z_flags(instructions);
return;
}
case AVR::OpCode::sbc: {
@ -554,7 +555,9 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
case AVR::OpCode::cpi: {
// note that this will leave the C flag in the 6502 borrow state, not normal carry state
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
instructions.emplace_back(mos6502::OpCode::cmp, Operand(o2.type, fixup_8bit_literal(o2.value)));
instructions.emplace_back(mos6502::OpCode::sec);
instructions.emplace_back(mos6502::OpCode::sbc, Operand(o2.type, fixup_8bit_literal(o2.value)));
instructions.emplace_back(mos6502::OpCode::tax);
return;
}
case AVR::OpCode::brlo: {
@ -606,7 +609,9 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
case AVR::OpCode::cp: {
// note that this will leave the C flag in the 6502 borrow state, not normal carry state
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
instructions.emplace_back(mos6502::OpCode::cmp, personality.get_register(o2_reg_num));
instructions.emplace_back(mos6502::OpCode::sec);
instructions.emplace_back(mos6502::OpCode::sbc, personality.get_register(o2_reg_num));
instructions.emplace_back(mos6502::OpCode::tax);
return;
}
case AVR::OpCode::cpc: {
@ -617,6 +622,7 @@ void translate_instruction(const Personality &personality, std::vector<mos6502>
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num));
instructions.emplace_back(mos6502::OpCode::sbc, personality.get_register(o2_reg_num));
fixup_16_bit_N_Z_flags(instructions);
return;
}
@ -794,6 +800,7 @@ bool fix_long_branches(std::vector<mos6502> &instructions, int &branch_patch_cou
bool fix_overwritten_flags(std::vector<mos6502> &instructions)
{
// return false;
if (instructions.size() < 3) {
return false;
}