char *get_opw_disas(struct Operand *op) { char *disas = (char *)malloc(LEN*sizeof(char)); switch (op->m) { case 0: sprintf(disas, "%%R%d", op->r); return disas; case 2: if (op->r == 7) { sprintf(disas, "#%d", (*get_word_from_memory(memory.R[7]))); return disas; } case 1: case 4: sprintf(disas, "0x%x", *op->address); return disas; case 3: case 5: sprintf(disas, "0x%x", *get_word_from_memory(*op->address)); return disas; case 6: sprintf(disas, "0x%x", (*op->address) + (*get_word_from_memory(memory.R[7]))); return disas; default: sprintf(disas, "0x%x", *get_word_from_memory((*op->address) + (*get_word_from_memory(memory.R[7])))); return disas; } }
// instruction MOV int mov(int addr, int addrs) { int n, z; put_value_w(addr, *get_word_from_memory(addrs)); int op = *get_word_from_memory(addr); NWORD(n, op); Z(z, op); set_flags(n, z, 0, flags.C); return 0; }
// instruction CMP int cmp(int addr, int addrs) { int n, z, v, c; int diff; diff = *get_word_from_memory(addrs) - *get_word_from_memory(addr); VWORD(v, diff); CWORD(c, diff); NWORD(n, diff); Z(z, diff); set_flags(n, z, v, c); return 0; }
int mul(int addr, int addrs) { int n, z, c; int op; op = (*get_word_from_memory(addr)) * (*get_word_from_memory(addrs)); put_value_w(addrs, (*get_word_from_memory(addr)) * (*get_word_from_memory(addrs))); NWORD(n, op); CWORD(c, op); Z(z, op); set_flags(n, z, 0, c); return 0; }
//instruction INC int inc(int addr, int addrs) { int n, z, v; int op; op = *get_word_from_memory(addr) + 1; put_value_w(addr, *get_word_from_memory(addr) + 1); VWORD(v, op); NWORD(n, op); Z(z, op); set_flags(n, z, v, flags.C); return 0; }
// instruction ADD int add(int addr, int addrs) { int n, z, v, c; int op; op = *get_word_from_memory(addr) + *get_word_from_memory(addrs); put_value_w(addr, *get_word_from_memory(addr) + *get_word_from_memory(addrs)); NWORD(n, op); VWORD(v, op); CWORD(c, op); Z(z, op); set_flags(n, z, v, c); return 0; }
struct Operand get_rs(instruction instr) { // source struct Operand source; source.m = instr.da_instr.ms; source.r = instr.da_instr.rs; source.address = get_word_from_memory(R0_INDEX + instr.da_instr.rs * 2); return source; }
struct Operand get_rd(instruction instr) { // destination struct Operand dest; dest.m = instr.sa_instr.md; dest.r = instr.sa_instr.rd; dest.address = get_word_from_memory(R0_INDEX + instr.sa_instr.rd * 2); return dest; }
//fetches the raw integer instruction ARM_WORD fetch_instruction(ARMSIM_CTX *ctx, ARM_ADDRESS * address) {// use the address argument to pass back the address as_log(ctx, "Entering fetch_instruction\n",0); ARM_WORD instruction = 0; (*address) = increment(ctx->registers, AR_r15, 4, 1); instruction = get_word_from_memory(ctx, *address); char * logstring = (char*)malloc(sizeof(char)*LOG_STRING_LENGTH); sprintf(logstring, "\t\tFETCH(%#010x) -> %#010x", *address, instruction); as_log(ctx, logstring, 0); free(logstring); as_log(ctx, "Leaving fetch_instruction\n",0); return instruction; }
int get_opw(struct Operand *op) { // get address for word operand int addr; switch (op->m) { case 0: return R0_INDEX + op->r * 2; case 1: addr = *op->address; return addr; case 2: if (op->r == 7) { addr = memory.R[7]; } else { addr = *op->address; } // then we should (*op->address) += 2; return addr; case 3: addr = *get_word_from_memory(*op->address); // then we should (*op->address) += 2; return addr; case 4: *op->address -= 2; addr = *op->address; return addr; case 5: *op->address -= 2; addr = *get_word_from_memory(*op->address); return addr; case 6: addr = (*op->address) + (*get_word_from_memory(memory.R[7])); return addr; case 7: addr = *get_word_from_memory((*op->address) + (*get_word_from_memory(memory.R[7]))); return addr; } return WRONG_ADDR; }
void put_value_w(int address, word value) { // put word in memory word *dest_address; dest_address = get_word_from_memory(address); *dest_address = value; }
int cycle(ARMSIM_CTX *ctx){ as_log(ctx, "Entering cycle\n",0); if(ctx->irq != 0 && can_irq(ctx->registers)){ unsigned int irq_ret = get_effective_pc(ctx) + 4; if(ctx->log_hook_defined != 0){ as_log(ctx, "----------------------------------------------------------------------------------------", 0); char * string1 = (char*)malloc(sizeof(char)*LOG_STRING_LENGTH); sprintf(string1, "!!!! IRQ: ePC=%#010x, tPC=%#010x !!!!", get_effective_pc(ctx), get_register(ctx->registers, AR_r15)); as_log(ctx, string1, 0); free(string1); char * string2 = (char*)malloc(sizeof(char)*LOG_STRING_LENGTH); char * instruction_string = instruction_to_string(master_decode(irq_ret - 4, get_word_from_memory(ctx, irq_ret - 4))); sprintf(string2, "???? Effective IRQ return: %s ????", instruction_string); as_log(ctx, string2, 0); free(string2); } set_mode(ctx->registers, AM_IRQ); set_cpsr(ctx->registers, get_cpsr(ctx->registers) | 0xC0); set_register(ctx->registers, AR_r14, irq_ret); branch_cpu(ctx, 0x00000018); ctx->irq = 0; } ctx-> per = as_execute_instruction(ctx, ctx->pdr); ctx->pdr = as_decode_instruction(ctx, ctx->pfr_address, ctx->pfr_instruction); ARM_ADDRESS * address = (ARM_ADDRESS*)malloc(sizeof(ARM_ADDRESS)); ctx->pfr_instruction = fetch_instruction(ctx, address); ctx->pfr_address = *address; free(address); if(ctx->per != 0) { ctx->steps += 1; if (ctx->trace_hook_defined != 0) { cpu_trace(ctx, ctx->per); } } as_log(ctx, "Leaving cycle\n",0); return (ctx->per != 0); }
ARMSIM_STATUS as_get_ram_word(ARMSIM_CTX *ctx, ARM_ADDRESS address, ARM_WORD *pval) { (*pval) = get_word_from_memory(ctx, address); return AS_OK; }