auto ARM::pipeline_step() -> void { pipeline.execute = pipeline.decode; pipeline.decode = pipeline.fetch; unsigned sequential = Sequential; if(pipeline.nonsequential) { pipeline.nonsequential = false; sequential = Nonsequential; } if(cpsr().t == 0) { r(15).data += 4; pipeline.fetch.address = r(15) & ~3; pipeline.fetch.instruction = read(Prefetch | Word | sequential, pipeline.fetch.address); } else { r(15).data += 2; pipeline.fetch.address = r(15) & ~1; pipeline.fetch.instruction = read(Prefetch | Half | sequential, pipeline.fetch.address); } } auto ARM::arm_step() -> void { if(pipeline.reload) { pipeline.reload = false; r(15).data &= ~3; pipeline.fetch.address = r(15) & ~3; pipeline.fetch.instruction = read(Prefetch | Word | Nonsequential, pipeline.fetch.address); pipeline_step(); } pipeline_step(); if(processor.irqline && cpsr().i == 0) { vector(0x00000018, Processor::Mode::IRQ); return; } instructions++; if(trace) { print(disassemble_registers(), "\n"); print(disassemble_arm_instruction(pipeline.execute.address), "\n"); usleep(100000); } if(condition(instruction() >> 28) == false) return; #define decode(pattern, execute) if( \ (instruction() & std::integral_constant::value) \ == std::integral_constant::value \ ) return arm_op_ ## execute() decode("???? 0001 0010 ++++ ++++ ++++ 0001 ????", branch_exchange_register); decode("???? 0000 00?? ???? ???? ???? 1001 ????", multiply); decode("???? 0000 1??? ???? ???? ???? 1001 ????", multiply_long); decode("???? 0001 0?00 ++++ ???? ---- 0000 ----", move_to_register_from_status); decode("???? 0001 0?00 ???? ???? ---- 1001 ????", memory_swap); decode("???? 0001 0?10 ???? ++++ ---- 0000 ????", move_to_status_from_register); decode("???? 0011 0?10 ???? ++++ ???? ???? ????", move_to_status_from_immediate); decode("???? 000? ?0?1 ???? ???? ---- 11?1 ????", load_register); decode("???? 000? ?1?1 ???? ???? ???? 11?1 ????", load_immediate); decode("???? 000? ?0?? ???? ???? ---- 1011 ????", move_half_register); decode("???? 000? ?1?? ???? ???? ???? 1011 ????", move_half_immediate); decode("???? 000? ???? ???? ???? ???? ???0 ????", data_immediate_shift); decode("???? 000? ???? ???? ???? ???? 0??1 ????", data_register_shift); decode("???? 001? ???? ???? ???? ???? ???? ????", data_immediate); decode("???? 010? ???? ???? ???? ???? ???? ????", move_immediate_offset); decode("???? 011? ???? ???? ???? ???? ???0 ????", move_register_offset); decode("???? 100? ???? ???? ???? ???? ???? ????", move_multiple); decode("???? 101? ???? ???? ???? ???? ???? ????", branch); decode("???? 1111 ???? ???? ???? ???? ???? ????", software_interrupt); #undef decode crash = true; } auto ARM::thumb_step() -> void { if(pipeline.reload) { pipeline.reload = false; r(15).data &= ~1; pipeline.fetch.address = r(15) & ~1; pipeline.fetch.instruction = read(Prefetch | Half | Nonsequential, pipeline.fetch.address); pipeline_step(); } pipeline_step(); if(processor.irqline && cpsr().i == 0) { vector(0x00000018, Processor::Mode::IRQ); r(14) += 2; return; } instructions++; if(trace) { print(disassemble_registers(), "\n"); print(disassemble_thumb_instruction(pipeline.execute.address), "\n"); } #define decode(pattern, execute) if( \ (instruction() & std::integral_constant::value) \ == std::integral_constant::value \ ) return thumb_op_ ## execute() decode("0001 10?? ???? ????", adjust_register); decode("0001 11?? ???? ????", adjust_immediate); decode("000? ???? ???? ????", shift_immediate); decode("001? ???? ???? ????", immediate); decode("0100 00?? ???? ????", alu); decode("0100 0111 0??? ?---", branch_exchange); decode("0100 01?? ???? ????", alu_hi); decode("0100 1??? ???? ????", load_literal); decode("0101 ???? ???? ????", move_register_offset); decode("0110 ???? ???? ????", move_word_immediate); decode("0111 ???? ???? ????", move_byte_immediate); decode("1000 ???? ???? ????", move_half_immediate); decode("1001 ???? ???? ????", move_stack); decode("1010 ???? ???? ????", add_register_hi); decode("1011 0000 ???? ????", adjust_stack); decode("1011 ?10? ???? ????", stack_multiple); decode("1100 ???? ???? ????", move_multiple); decode("1101 1111 ???? ????", software_interrupt); decode("1101 ???? ???? ????", branch_conditional); decode("1110 0??? ???? ????", branch_short); decode("1111 0??? ???? ????", branch_long_prefix); decode("1111 1??? ???? ????", branch_long_suffix); #undef decode crash = true; }