1
0
mirror of https://github.com/lefticus/6502-cpp.git synced 2024-12-30 07:31:38 +00:00

Optimize around single instruction jump statements

This commit is contained in:
Jason Turner 2021-05-25 19:12:16 -06:00
parent 13dbaafbfd
commit bb51249b4c
2 changed files with 12 additions and 8 deletions

View File

@ -30,6 +30,10 @@ constexpr bool is_opcode(const mos6502 &op, const auto... opcodes) { return ((op
constexpr bool is_end_of_block(const auto &begin) constexpr bool is_end_of_block(const auto &begin)
{ {
if (begin->text.ends_with("__optimizable") || begin->op.value.ends_with("__optimizable")) {
return false;
}
if (begin->type == ASMLine::Type::Label) { return true; } if (begin->type == ASMLine::Type::Label) { return true; }
return is_opcode(*begin, return is_opcode(*begin,

View File

@ -363,7 +363,7 @@ void subtract_16_bit(const Personality &personality,
void increment_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg) void increment_16_bit(const Personality &personality, std::vector<mos6502> &instructions, int reg)
{ {
std::string skip_high_byte_label = "skip_inc_high_byte_" + std::to_string(instructions.size()); std::string skip_high_byte_label = "skip_inc_high_byte_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::inc, personality.get_register(reg)); instructions.emplace_back(mos6502::OpCode::inc, personality.get_register(reg));
instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, skip_high_byte_label)); instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, skip_high_byte_label));
instructions.emplace_back(mos6502::OpCode::inc, personality.get_register(reg + 1)); instructions.emplace_back(mos6502::OpCode::inc, personality.get_register(reg + 1));
@ -573,7 +573,7 @@ void translate_instruction(const Personality &personality,
case AVR::OpCode::cpse: { case AVR::OpCode::cpse: {
instructions.emplace_back(mos6502::OpCode::lda, personality.get_register(o1_reg_num)); 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::cmp, personality.get_register(o2_reg_num));
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -582,7 +582,7 @@ void translate_instruction(const Personality &personality,
instructions.emplace_back( instructions.emplace_back(
mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value)))))); mos6502::OpCode::lda, Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value))))));
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num)); instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -591,7 +591,7 @@ void translate_instruction(const Personality &personality,
instructions.emplace_back(mos6502::OpCode::lda, instructions.emplace_back(mos6502::OpCode::lda,
Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value.c_str())))))); Operand(o2.type, fixup_8bit_literal("$" + std::to_string(1 << (to_int(o2.value.c_str()))))));
instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num)); instructions.emplace_back(mos6502::OpCode::bit, personality.get_register(o1_reg_num));
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -602,7 +602,7 @@ void translate_instruction(const Personality &personality,
return; return;
} else if (o1.value == ".+2") { } else if (o1.value == ".+2") {
// assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs // assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::bne, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -664,7 +664,7 @@ void translate_instruction(const Personality &personality,
if (o1.value == ".+2") { if (o1.value == ".+2") {
// assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs // assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::bcc, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::bcc, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -729,7 +729,7 @@ void translate_instruction(const Personality &personality,
case AVR::OpCode::brsh: { case AVR::OpCode::brsh: {
if (o1.value == ".+2") { if (o1.value == ".+2") {
// assumes 6502 'borrow' for Carry flag instead of carry, so bcs instead of bcc // assumes 6502 'borrow' for Carry flag instead of carry, so bcs instead of bcc
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::bcs, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::bcs, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;
@ -772,7 +772,7 @@ void translate_instruction(const Personality &personality,
case AVR::OpCode::breq: { case AVR::OpCode::breq: {
if (o1.value == ".+2") { if (o1.value == ".+2") {
// assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs // assumes 6502 'borrow' for Carry flag instead of carry, so bcc instead of bcs
std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()); std::string new_label_name = "skip_next_instruction_" + std::to_string(instructions.size()) + "__optimizable";
instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name)); instructions.emplace_back(mos6502::OpCode::beq, Operand(Operand::Type::literal, new_label_name));
instructions.emplace_back(ASMLine::Type::Directive, new_label_name); instructions.emplace_back(ASMLine::Type::Directive, new_label_name);
return; return;