void ARMAssembler::epilog(uint32_t touched) { touched &= LSAVED; if (touched) { // write prolog code uint32_t* pc = mPC; mPC = mPrologPC; STM(AL, FD, SP, 1, touched | LLR); mPC = pc; // write epilog code LDM(AL, FD, SP, 1, touched | LLR); BX(AL, LR); } else { // heh, no registers to save! // write prolog code uint32_t* pc = mPC; mPC = mPrologPC; MOV(AL, 0, R0, R0); // NOP mPC = pc; // write epilog code BX(AL, LR); } }
// Execute one instruction cycle // void one_instruction_cycle(CPU *cpu) { // If the CPU isn't running, say so and return. // If the pc is out of range, complain and stop running the CPU. // if ((*cpu).running==0){ printf("The CPU is not running. \n"); return; } // Get instruction and increment pc // int instr_loc = (*cpu).pc; // Instruction's location (pc before increment) (*cpu).ir = (*cpu).mem[(*cpu).pc]; (*cpu).pc++; // Making sure the instruction is if ((*cpu).reg_R<0 || (*cpu).reg_R>NREG || (*cpu).addr_MM<0 || (*cpu).addr_MM>100 ) { printf("Error. The register or memory address given in the instruction is out of bounds.\n"); return; } //Decode opcode into opcode, reg_r, addr_MM, and instruction sign (*cpu).opcode = abs((*cpu).mem[instr_loc] / 1000); (*cpu).reg_R = abs((*cpu).mem[instr_loc] / 100) % 10; (*cpu).addr_MM = abs((*cpu).mem[instr_loc] % 100); // In case first instruction stored in memory is a zero, we need to give it a sign of 0. if((*cpu).mem[instr_loc] != 0) { (*cpu).instr_sign = (*cpu).mem[instr_loc] / abs((*cpu).mem[instr_loc]); } else{ (*cpu).instr_sign=0; } // Echo instruction printf("At %02d instr %d %d %02d: ", instr_loc, (*cpu).opcode, (*cpu).reg_R, (*cpu).addr_MM); switch ((*cpu).opcode) { case 0: HALT(cpu); break; case 1: LD(cpu); break; case 2: ST(cpu); break; case 3: ADD(cpu); break; case 4: NEG(cpu); break; case 5: LDM(cpu); break; case 6: ADDM(cpu); break; case 7: BR(cpu); break; case 8: BRC(cpu); break; case 9: switch ((*cpu).reg_R) { case 0: GETC(cpu); break; case 1: OUT(cpu); break; case 2: PUTS(cpu); break; case 3: dump_CPU(cpu); break; case 4: dump_memory(cpu); break; case 5: printf("Ignored"); break; case 6: printf("Ignored"); break; case 7: printf("Ignored"); break; case 8: printf("Ignored"); break; case 9: printf("Ignored"); break; } break; default: printf("Bad opcode!? %d\n", (*cpu).opcode); } }