/* Text representation of status */ void tty_report(int cyc) { sim_log("\nCycle %d. CC=%s, Stat=%s\n", cyc, cc_name(cc), stat_name(status)); sim_log("F: predPC = 0x%x\n", pc_curr->pc); sim_log("D: instr = %s, rA = %s, rB = %s, valC = 0x%x, valP = 0x%x, Stat = %s\n", iname(HPACK(if_id_curr->icode, if_id_curr->ifun)), reg_name(if_id_curr->ra), reg_name(if_id_curr->rb), if_id_curr->valc, if_id_curr->valp, stat_name(if_id_curr->status)); sim_log("E: instr = %s, valC = 0x%x, valA = 0x%x, valB = 0x%x\n srcA = %s, srcB = %s, dstE = %s, dstM = %s, Stat = %s\n", iname(HPACK(id_ex_curr->icode, id_ex_curr->ifun)), id_ex_curr->valc, id_ex_curr->vala, id_ex_curr->valb, reg_name(id_ex_curr->srca), reg_name(id_ex_curr->srcb), reg_name(id_ex_curr->deste), reg_name(id_ex_curr->destm), stat_name(id_ex_curr->status)); sim_log("M: instr = %s, Cnd = %d, valE = 0x%x, valA = 0x%x\n dstE = %s, dstM = %s, Stat = %s\n", iname(HPACK(ex_mem_curr->icode, ex_mem_curr->ifun)), ex_mem_curr->takebranch, ex_mem_curr->vale, ex_mem_curr->vala, reg_name(ex_mem_curr->deste), reg_name(ex_mem_curr->destm), stat_name(ex_mem_curr->status)); sim_log("W: instr = %s, valE = 0x%x, valM = 0x%x, dstE = %s, dstM = %s, Stat = %s\n", iname(HPACK(mem_wb_curr->icode, mem_wb_curr->ifun)), mem_wb_curr->vale, mem_wb_curr->valm, reg_name(mem_wb_curr->deste), reg_name(mem_wb_curr->destm), stat_name(mem_wb_curr->status)); }
void int_num(FILE *fd, struct reg_t *a, struct reg_t *b) { if (a->size==word_size) { if (a->use!=RET && b->use!=RET) { fprintf(fd, "\tmovl %s, %%eax\n", reg_name(a)); fprintf(fd, "\tidivl %s\n", reg_name(b)); } else if (a->use!=RET && b->use==RET) { fprintf(fd, "\tpushq %%rdx\n"); fprintf(fd, "\tpushq %%rax\n"); fprintf(fd, "\tpushq %%rbx\n"); if (strcmp(reg_name(a), "%ebx")) { fprintf(fd, "\tmovl %%eax, %%ebx\n"); fprintf(fd, "\tmovl %s, %%eax\n", reg_name(a)); } else { fprintf(fd, "\tpushq %%rcx\n"); fprintf(fd, "\tmovl %%ebx, %%ecx\n"); fprintf(fd, "\tmovl %%eax, %%ebx\n"); fprintf(fd, "\tmovl %%ecx, %%eax\n"); fprintf(fd, "\tpopq %%rcx\n"); } fprintf(fd, "\tcltd\n"); fprintf(fd, "\tidivl %%ebx\n"); fprintf(fd, "\tpopq %%rbx\n"); fprintf(fd, "\tpopq %%rax\n"); fprintf(fd, "\tmovl %%edx, %%eax\n"); fprintf(fd, "\tpopq %%rdx\n"); /* T.T my eyes are bleeding. */ } else if (a->use==RET && b->use!=RET) { fprintf(fd, "\tidivl %s\n", reg_name(b)); } } else { fprintf(stderr, "Internal error: int_num passed size: %ld. No size handler found.\n", a->size); exit(1); } }
void int_neg(FILE *fd, struct reg_t *r) { size_t s=r->size; if (r->use!=RET) { if (s==char_size) { fprintf(fd, "\tnegb %s\n", reg_name(r)); fprintf(fd, "\tmovb %s, %%al\n", reg_name(r)); } else if (s==word_size) { fprintf(fd, "\tnegl %s\n", reg_name(r)); fprintf(fd, "\tmovl %s, %%eax\n", reg_name(r)); } else if (s==pointer_size) { fprintf(fd, "\tnegq %s\n", reg_name(r)); fprintf(fd, "\tmovq %s, %%rax\n", reg_name(r)); } else { fprintf(fd, "Internal error: %d size passed to int_neg\n", s); exit(1); } } else { if (s==char_size) fprintf(fd, "\tnegb %s\n", reg_name(r)); else if (s==word_size) fprintf(fd, "\tnegl %s\n", reg_name(r)); else if (s==pointer_size) fprintf(fd, "\tnegq %s\n", reg_name(r)); else { fprintf(fd, "Internal error: %d size passed to int_neg\n", s); exit(1); } } }
void int_dec(FILE *fd, struct reg_t *r) { if (r->size==word_size) { fprintf(fd, "\tdecl %s\n", reg_name(r)); if (r->use!=RET) fprintf(fd, "\tmovl %s, %%eax\n", reg_name(r)); } else { fprintf(stderr, "Internal Error: unknown size: %ld passed to int_dec\n", r->size); exit(1); } }
/* May need to disable updating of memory & condition codes */ static void update_state(bool_t update_mem, bool_t update_cc) { /* Writeback(s): If either register is REG_NONE, write will have no effect . Order of two writes determines semantics of popl %esp. According to ISA, %esp will get popped value */ if (wb_destE != REG_NONE) { sim_log("Writeback: Wrote 0x%x to register %s\n", wb_valE, reg_name(wb_destE)); set_reg_val(reg, wb_destE, wb_valE); } if (wb_destM != REG_NONE) { sim_log("Writeback: Wrote 0x%x to register %s\n", wb_valM, reg_name(wb_destM)); set_reg_val(reg, wb_destM, wb_valM); } /* Memory write */ if (mem_write && !update_mem) { sim_log("Disabled write of 0x%x to address 0x%x\n", mem_data, mem_addr); } if (update_mem && mem_write) { if (!set_word_val(mem, mem_addr, mem_data)) { sim_log("Couldn't write to address 0x%x\n", mem_addr); } else { sim_log("Wrote 0x%x to address 0x%x\n", mem_data, mem_addr); #ifdef HAS_GUI if (gui_mode) { if (mem_addr % 4 != 0) { /* Just did a misaligned write. Need to display both words */ word_t align_addr = mem_addr & ~0x3; word_t val; get_word_val(mem, align_addr, &val); set_memory(align_addr, val); align_addr+=4; get_word_val(mem, align_addr, &val); set_memory(align_addr, val); } else { set_memory(mem_addr, mem_data); } } #endif } } if (update_cc) cc = cc_in; }
/* May need to disable updating of memory & condition codes */ static void update_state(bool_t update_mem, bool_t update_cc) { /* Writeback(s): If either register is REG_NONE, write will have no effect . Order of two writes determines semantics of popl %esp. According to ISA, %esp will get popped value */ if (wb_destE != REG_NONE) { sim_log("\tWriteback: Wrote 0x%x to register %s\n", wb_valE, reg_name(wb_destE)); set_reg_val(reg, wb_destE, wb_valE); //printf("set_reg_valE %d %d %d\n", PSIM_ID, wb_destE, wb_valE); //fflush(stdout); } if (wb_destM != REG_NONE && wb_testM == REG_NONE) { sim_log("\tWriteback: Wrote 0x%x to register %s\n", wb_valM, reg_name(wb_destM)); set_reg_val(reg, wb_destM, wb_valM); //printf("set_reg_valM %d %d %d\n", PSIM_ID, wb_destM, wb_valM); //fflush(stdout); } /* Memory write */ if(wb_testM != REG_NONE){ set_reg_val(reg, wb_testM, wb_valM); printf("PSIM_ID %d test_result: %d on %d\n", PSIM_ID, wb_valM, mem_test_address); //fflush(stdout); } if (mem_write && !update_mem) { sim_log("\tDisabled write of 0x%x to address 0x%x\n", mem_data, mem_addr); } if (update_mem && mem_write) { // printf("WRITE: %d %d\n", mem_addr, mem_data); if (!set_word_val(mem, mem_addr, mem_data)) { sim_log("\tCouldn't write to address 0x%x\n", mem_addr); } else { sim_log("\tWrote 0x%x to address 0x%x\n", mem_data, mem_addr); } /* int ans; printf("%d %d\n",mem_addr, mem_data); int b = get_word_val(mem, mem_addr, &ans); printf("%d\n", ans); */ } if (update_cc) cc = cc_in; }
char *format_if_id(if_id_ptr state){ char valcstring[9]; char valpstring[9]; wstring(state->valc, 4, 32, valcstring); wstring(state->valp, 4, 32, valpstring); sprintf(status_msg, "%s %s %s %s %s %s", stat_name(state->status), iname(HPACK(state->icode,state->ifun)), reg_name(state->ra), reg_name(state->rb), valcstring, valpstring); return status_msg; }
static char *format_f() { char valcstring[9]; char valpstring[9]; wstring(valc, 4, 32, valcstring); wstring(valp, 4, 32, valpstring); sprintf(status_msg, "%s %s %s %s %s", iname(HPACK(icode, ifun)), reg_name(ra), reg_name(rb), valcstring, valpstring); return status_msg; }
void SourceAssembler::ldr_nearby_label(Register r, Label& L, Condition cond) { // Loads the address of the label. // Label must be within approximately 256 instructions GUARANTEE(r != pc, "probably incorrect code"); // EVC ASM doesn't understand adrls #if EVC_ASM_QUIRK stream()->print("\tadrl%s\t%s, ", cond_name(cond), reg_name(r)); // stream()->print("\tldr%s\t%s, ", cond_name(cond), reg_name(r)); #else stream()->print("\tadr%s\t%s, ", cond_name(cond), reg_name(r)); #endif L.print_on(stream()); emit_comment_and_cr(); }
char *format_mem_wb(mem_wb_ptr state){ char valestring[9]; char valmstring[9]; wstring(state->vale, 4, 32, valestring); wstring(state->valm, 4, 32, valmstring); sprintf(status_msg, "%s %s %s %s %s %s", stat_name(state->status), iname(HPACK(state->icode, state->ifun)), valestring, valmstring, reg_name(state->deste), reg_name(state->destm)); return status_msg; }
std::string authority() { if(rand(2)) return server(); return reg_name(); }
void SourceAssembler::ldr_string(Register r, const char* string, Condition cond) { GUARANTEE(r != pc, "probably incorrect code"); GUARANTEE(string != NULL, "Sanity check"); Literal lit(string); // EVC ASM doesn't understand adrls #if EVC_ASM_QUIRK // stream()->print("\tldr%s\t%s, _D%d", stream()->print("\tadrl%s\t%s, _D%d", cond_name(cond), reg_name(r), lit.id()); #else stream()->print("\tadr%s\t%s, _D%d", cond_name(cond), reg_name(r), lit.id()); #endif emit_comment_and_cr(); _literals.add(lit); }
static char *format_d() { char valastring[9]; char valbstring[9]; wstring(vala, 4, 32, valastring); wstring(valb, 4, 32, valbstring); sprintf(status_msg, "%s %s %s %s %s %s", valastring, valbstring, reg_name(destE), reg_name(destM), reg_name(srcA), reg_name(srcB)); return status_msg; }
char *format_ex_mem(ex_mem_ptr state){ char valestring[9]; char valastring[9]; wstring(state->vale, 4, 32, valestring); wstring(state->vala, 4, 32, valastring); sprintf(status_msg, "%s %s %c %s %s %s %s", stat_name(state->status), iname(HPACK(state->icode, state->ifun)), state->takebranch ? 'Y' : 'N', valestring, valastring, reg_name(state->deste), reg_name(state->destm)); return status_msg; }
void SourceAssembler::ldr_label(Register r, Label& L, Condition cond) { // Loads the address of the label. GUARANTEE(r != pc, "probably incorrect code"); stream()->print("\tldr%s\t%s, =", cond_name(cond), reg_name(r)); L.print_on(stream()); emit_comment_and_cr(); }
void SourceAssembler::ldr_from(Register r, Label& L, int offset, Condition cond) { // Loads the contents of the label. Must be within ~1024 instructions stream()->print("\tldr%s\t%s, ", cond_name(cond), reg_name(r)); L.print_on(stream()); if (offset != 0) { stream()->print(" + %d", offset); } emit_comment_and_cr(); }
void int_sub(FILE *fd, struct reg_t *b, struct reg_t *a) { if (a->size==char_size) { fprintf(fd, "\tsubb %s, %s\n", reg_name(a), reg_name(b)); fprintf(fd, "\tmovb %s, %%al\n", reg_name(b)); } else if (a->size==word_size) { fprintf(fd, "\tsubl %s, %s\n", reg_name(a), reg_name(b)); if (b->use!=RET) fprintf(fd, "\tmovl %s, %%eax\n", reg_name(b)); } else if (a->size==pointer_size) { fprintf(fd, "\tsubq %s, %s\n", reg_name(a), reg_name(b)); if (b->use!=RET) fprintf(fd, "\tmovq %s, %%rax\n", reg_name(b)); } }
static inline int print_reg(struct string *str, struct operand *op) { struct live_interval *interval = op->reg.interval; if (interval_has_fixed_reg(interval)) return str_append(str, "r%lu=%s", interval->var_info->vreg, reg_name(interval->reg)); else return str_append(str, "r%lu", interval->var_info->vreg); }
char *format_id_ex(id_ex_ptr state){ char valcstring[9]; char valastring[9]; char valbstring[9]; wstring(state->valc, 4, 32, valcstring); wstring(state->vala, 4, 32, valastring); wstring(state->valb, 4, 32, valbstring); sprintf(status_msg, "%s %s %s %s %s %s %s %s %s", stat_name(state->status), iname(HPACK(state->icode, state->ifun)), valcstring, valastring, valbstring, reg_name(state->deste), reg_name(state->destm), reg_name(state->srca), reg_name(state->srcb)); return status_msg; }
void int_div(FILE *fd, struct reg_t *a, struct reg_t *b) { /* The X86 handles integer division in some stupid way. For some reason the div instruction takes just one argument, and DX:AX is the numerator, and the argument is the denominator. This code has to be complicated to deal with that nonsense. */ if (b->use!=RET && a->use!=RET) fprintf(fd, "\tmovl %s, %%eax\n", reg_name(a)); else if (b->use==RET) { fprintf(fd, "\tpushq %%rbx\n"); fprintf(fd, "\tmovl %%eax, %%ebx\n"); fprintf(fd, "\tcltd\n"); fprintf(fd, "\tidivl %%ebx\n"); fprintf(fd, "\tmovl %%ebx, %%eax\n"); fprintf(fd, "\tpopq %%rbx\n"); } else { fprintf(fd, "\tcltd\n"); fprintf(fd, "\tidivl %s\n", reg_name(b)); } /* TBH I don't even know what this means. I just copied this from the GNU C compiler's output. */ }
void int_mul(FILE *fd, struct reg_t *a, struct reg_t *b) { /* The nice people at Intel need to learn to be more F*cking consistent. D:< */ if (a->size==word_size) { if (b->use!=RET && a->use==RET) fprintf(fd, "\tmull %s\n", reg_name(b)); else if (b->use==RET && a->use!=RET) fprintf(fd, "\tmull %s\n", reg_name(a)); else if (b->use!=RET && a->use!=RET) { fprintf(fd, "\tmovl %s, %%eax\n", reg_name(b)); fprintf(fd, "\tmull %s\n", reg_name(a)); fprintf(fd, "\tmovl %%eax, %s\n", reg_name(b)); } } else if (a->size==pointer_size) fprintf(fd, "\tmulq %s\n", reg_name(b)); }
/*------------------------------------------------------------------------*/ static void do_modrm(char subtype) { int mod = MOD(modrm()); int rm = RM(modrm()); int extend = (addrsize == 32) ? 4 : 2; /* specifies two registers */ if (mod == 3) { reg_name(rm, subtype); return; } if (must_do_size) { if (wordop) { if (addrsize==32 || opsize==32) /* then must specify size */ uprintf( Info->GetStringName(DISASM_ID_DWORD_PTR) ); else uprintf( Info->GetStringName(DISASM_ID_WORD_PTR) ); } else uprintf( Info->GetStringName(DISASM_ID_BYTE_PTR) ); uputchar(' '); } /* mem operand with 32 bit ofs */ if ((mod == 0) && (rm == 5) && (addrsize == 32)) { ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex('d', extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); } else /* 16 bit dsplcmnt */ if ((mod == 0) && (rm == 6) && (addrsize == 16)) { ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex('w', extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); } else { /*All other*/ if ( (addrsize != 32) || (rm != 4) ) ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD ); if (addrsize == 16) switch (rm) { case 0: uprintf("bx+si"); break; case 1: uprintf("bx+di"); break; case 2: uprintf("bp+si"); break; case 3: uprintf("bp+di"); break; case 4: uprintf("si"); break; case 5: uprintf("di"); break; case 6: uprintf("bp"); break; case 7: uprintf("bx"); break; } else switch (rm) { case 0: uprintf("eax"); break; case 1: uprintf("ecx"); break; case 2: uprintf("edx"); break; case 3: uprintf("ebx"); break; case 4: do_sib(mod); break; case 5: uprintf("ebp"); break; case 6: uprintf("esi"); break; case 7: uprintf("edi"); break; } switch (mod) { case 1: outhex('b', extend, 1, addrsize, 0); break; case 2: outhex('v', extend, 1, addrsize, 1); break; } CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD ); uputchar(']'); } }
/* Return resulting exception status */ static exc_t sim_step() { word_t aluA; word_t aluB; word_t alufun; exc_t status = update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; if (get_byte_val(mem, valp, &instr)) { icode = HI4(instr); ifun = LO4(instr); } else { instr = HPACK(I_NOP,0); icode = I_NOP; ifun = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } if (status == EXC_NONE && !gen_instr_valid()) { status = EXC_INSTR; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == EXC_NONE && icode == I_HALT) { status = EXC_HALT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = (icode == I_JMP) && take_branch(cc, ifun); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (status == EXC_NONE && gen_mem_read()) { if (!get_word_val(mem, mem_addr, &valm)) { sim_log("Couldn't read at address 0x%x\n", mem_addr); return EXC_ADDR; } } else valm = 0; mem_write = status == EXC_NONE && gen_mem_write(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }
static void percent(char type, char subtype) { unsigned int vofs = 0; char *name; int extend = (addrsize == 32) ? 4 : 2; unsigned char c; switch(type) { case 'A': /* Direct address */ outhex(subtype, extend, 0, addrsize, 0); break; case 'C': /* reg(r/m) picks control reg */ uprintf("CR%d", REG(modrm())); must_do_size = 0; break; case 'D': /* reg(r/m) picks debug reg */ uprintf("DR%d", REG(modrm())); must_do_size = 0; break; case 'E': /* r/m picks operand */ do_modrm(subtype); break; case 'G': /* reg(r/m) picks register */ if(subtype == 'f') reg_name(RM(modrm()), subtype); else reg_name(REG(modrm()), subtype); must_do_size = 0; break; case 'I': /* Immediate data */ outhex(subtype, 0, 0, opsize, 0); break; case 'J': /* Relative IP offset */ switch(bytes(subtype)) {/* Size of offset value */ case 1: vofs = (unsigned int) (signed char) getbyte(); break; case 2: vofs = getbyte(); vofs += getbyte() << 8; vofs = (unsigned int) (signed short) vofs; break; case 4: vofs = (unsigned int) getbyte(); vofs |= (unsigned int) getbyte() << 8; vofs |= (unsigned int) getbyte() << 16; vofs |= (unsigned int) getbyte() << 24; break; } name = addr_to_hex((int) (vofs + inst_offset)); uprintf("%s", name); break; case 'K': switch(subtype) { case 'f': ua_str("FAR@"); break; case 'n': ua_str("NEAR@"); break; case 's': ua_str("SHORT@"); break; } break; case 'M': /* r/m picks memory */ do_modrm(subtype); break; case 'O': /* Offset only */ ua_str("%p:["); outhex(subtype, extend, 0, addrsize, 0); uputchar(']'); break; case 'P': /* Prefix byte */ ua_str("%p:"); break; case 'R': /* mod(r/m) picks register */ reg_name(REG(modrm()), subtype); must_do_size = 0; break; case 'S': /* reg(r/m) picks segment register */ uputchar("ECSDFG"[REG(modrm())]); uputchar('S'); must_do_size = 0; break; case 'T': /* reg(r/m) picks T reg */ uprintf("TR%d", REG(modrm())); must_do_size = 0; break; case 'X': /* DS:SI type operator */ uprintf("DS:["); if(addrsize == 32) uputchar('E'); uprintf("SI]"); break; case 'Y': /* ES:DI type operator */ uprintf("ES:["); if(addrsize == 32) uputchar('E'); uprintf("DI]"); break; case '2': /* Extended decode with second byte */ ua_str(second[getbyte()]); break; case 'g': /* modrm group 'subtype' (0--7) */ ua_str(groups[subtype-'0'][REG(modrm())]); break; case 'd': /* Size of operand == dword? */ if(opsize == 32) uputchar('D'); uputchar(subtype);/* No real subtype; following char */ break; case 'w': /* Insert explicit size specifier */ if(opsize == 32) uputchar('D'); else uputchar('W'); uputchar(subtype);/* No real subtype; following char */ break; case 'e': /* Extended reg name */ if(opsize == 32) { if(subtype == 'w') uputchar('D'); else { uputchar('E'); uputchar(subtype); } } else uputchar(subtype); break; case 'f': /* 80x87 opcode */ floating_point(subtype-'0'); break; case 'j': if(addrsize == 32 || opsize == 32) /* both of them?! */ uputchar('E'); break; case 'p': /* Prefix byte */ switch(subtype) { case 'C': case 'D': case 'E': case 'F': case 'G': case 'S': prefix = subtype; c = getbyte(); wordop = c & 1; ua_str(opmap1[c]); break; case ':': if(prefix) uprintf("%cS:", prefix); break; case ' ': c = getbyte(); wordop = c & 1; ua_str(opmap1[c]); break; } break; case 's': /* Size override */ switch(subtype) { case 'a': addrsize = 48 - addrsize; c = getbyte(); wordop = c & 1; ua_str(opmap1[c]); /* ua_str(opmap1[getbyte()]); */ break; case 'o': opsize = 48 - opsize; c = getbyte(); wordop = c & 1; ua_str(opmap1[c]); /* ua_str(opmap1[getbyte()]); */ break; } break; } }
static void do_modrm(char subtype) { int mod = MOD(modrm()); int rm = RM(modrm()); int extend = (addrsize == 32) ? 4 : 2; if(mod == 3) { /* Specifies two registers */ reg_name(rm, subtype); return; } if(must_do_size) { if(wordop) { if(addrsize == 32 || opsize == 32) ua_str("DWORD@PTR@"); else ua_str("WORD@PTR@"); } else ua_str("BYTE@PTR@"); } if((mod == 0) && (rm == 5) && (addrsize == 32)) { /* Mem operand with 32 bit offset */ ua_str("%p:["); outhex('d', extend, 0, addrsize, 0); uputchar(']'); return; } if((mod == 0) && (rm == 6) && (addrsize == 16)) { /* 16 bit displacement */ ua_str("%p:["); outhex('w', extend, 0, addrsize, 0); uputchar(']'); return; } if((addrsize != 32) || (rm != 4)) ua_str("%p:["); if(addrsize == 16) { switch(rm) { case 0: uprintf("BX+SI"); break; case 1: uprintf("BX+DI"); break; case 2: uprintf("BP+SI"); break; case 3: uprintf("BP+DI"); break; case 4: uprintf("SI"); break; case 5: uprintf("DI"); break; case 6: uprintf("BP"); break; case 7: uprintf("BX"); break; } } else { switch(rm) { case 0: uprintf("EAX"); break; case 1: uprintf("ECX"); break; case 2: uprintf("EDX"); break; case 3: uprintf("EBX"); break; case 4: do_sib(mod); break; case 5: uprintf("EBP"); break; case 6: uprintf("ESI"); break; case 7: uprintf("EDI"); break; } } switch(mod) { case 1: outhex('b', extend, 1, addrsize, 0); break; case 2: outhex('v', extend, 1, addrsize, 1); break; } uputchar(']'); }
void do_if_stage() { exc_t nstatus = EXC_NONE; word_t fetchpc = gen_f_pc(); word_t valp = fetchpc; bool_t fetch_ok; byte_t instr; byte_t regids = HPACK(REG_NONE, REG_NONE); word_t valc = 0; f_pc = fetchpc; if (fetchpc == 0) { sim_log("Fetch: Fetch pc = 0, nominal pc = 0x%x\n", pc_curr->pc); } /* Ready to fetch instruction. Speculatively fetch register byte and immediate word */ fetch_ok = get_byte_val(mem, valp, &instr); if (fetch_ok) { if_id_next->icode = GET_ICODE(instr); if_id_next->ifun = GET_FUN(instr); } else { if_id_next->icode = I_NOP; if_id_next->ifun = 0; nstatus = EXC_ADDR; } valp++; if (fetch_ok && gen_need_regids()) { fetch_ok = get_byte_val(mem, valp, ®ids); valp ++; } if_id_next->ra = HI4(regids); if_id_next->rb = LO4(regids); if (fetch_ok && gen_need_valC()) { fetch_ok = get_word_val(mem, valp, &valc); valp+= 4; } if_id_next->valp = valp; if_id_next->valc = valc; pc_next->pc = gen_new_F_predPC(); if (!gen_instr_valid()) { byte_t instr = HPACK(if_id_next->icode, if_id_next->ifun); sim_log("Fetch: Instruction code %s (0x%x) invalid\n", iname(instr), instr); nstatus = EXC_INSTR; } pc_next->exception = (nstatus == EXC_NONE) ? EXC_NONE : EXC_BUBBLE; if_id_next->stage_pc = fetchpc; if_id_next->exception = nstatus; /* Recompute icode for one-write implementation of popl */ if_id_next->icode = gen_new_D_icode(); sim_log("Fetch: Fetched %s at 0x%x, ra = %s, rb = %s, valp = 0x%x, status = %s\n", iname(HPACK(if_id_next->icode, if_id_next->ifun)), if_id_next->stage_pc, reg_name(if_id_next->ra), reg_name(if_id_next->rb), if_id_next->valp, exc_name(nstatus)); }
/* Return resulting status */ static byte_t sim_step() { word_t aluA; word_t aluB; word_t alufun; status = STAT_AOK; imem_error = dmem_error = FALSE; update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; instr = HPACK(I_NOP, F_NONE); imem_error = !get_byte_val(mem, valp, &instr); if (imem_error) { sim_log("Couldn't fetch at address 0x%x\n", valp); } imem_icode = HI4(instr); imem_ifun = LO4(instr); icode = gen_icode(); ifun = gen_ifun(); instr_valid = gen_instr_valid(); valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == STAT_AOK && icode == I_HALT) { status = STAT_HLT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } cond = cond_holds(cc, ifun); destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = cond && (icode == I_JMP); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (gen_mem_read()) { dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm); if (dmem_error) { sim_log("Couldn't read at address 0x%x\n", mem_addr); } } else valm = 0; mem_write = gen_mem_write(); if (mem_write) { /* Do a test read of the data memory to make sure address is OK */ word_t junk; dmem_error = dmem_error || !get_word_val(mem, mem_addr, &junk); } status = gen_Stat(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }
/* Main table driver */ static void percent( char type, char subtype ) { DWORD vofs; int extend = (addrsize == 32) ? 4 : 2; BYTE c; switch (type) { case 'A': /* direct address */ SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE ); outhex(subtype, extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE ); break; case 'C': /* reg(r/m) picks control reg */ uprintf("C%d", REG(modrm())); must_do_size = 0; break; case 'D': /* reg(r/m) picks debug reg */ uprintf("D%d", REG(modrm())); must_do_size = 0; break; case 'E': /* r/m picks operand */ do_modrm(subtype); break; case 'G': /* reg(r/m) picks register */ if (subtype == 'F') /* 80*87 operand? */ reg_name(RM(modrm()), subtype); else reg_name(REG(modrm()), subtype); must_do_size = 0; break; case 'I': /* immed data */ SET_FLAG( Info->CurrentFlags,DISASM_FL_DATA ); outhex(subtype, 0, 0, opsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_DATA ); break; case 'J': /* relative IP offset */ vofs = 0; switch(bytes(subtype)) { /* sizeof offset value */ case 1: vofs = (DWORD)getbyte(); break; case 2: vofs = (DWORD)getbyte(); vofs |= (DWORD)getbyte() << 8; vofs &= 0xFFFFu; break; case 4: vofs = (DWORD)getbyte(); /* yuk! */ vofs |= (DWORD)getbyte() << 8; vofs |= (DWORD)getbyte() << 16; vofs |= (DWORD)getbyte() << 24; break; } SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET ); uprintf("%s", addr_to_hex(vofs + Info->instruction_length,1,bytes(subtype)) ); CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET ); break; case 'K': if (do_distance==0) break; switch (subtype) { case 'f': uprintf( Info->GetStringName(DISASM_ID_FAR) ); uputchar(' '); break; case 'n': uprintf( Info->GetStringName(DISASM_ID_NEAR) ); uputchar(' '); break; case 's': uprintf( Info->GetStringName(DISASM_ID_SHORT) ); uputchar(' '); break; } break; case 'M': /* r/m picks memory */ do_modrm(subtype); break; case 'O': /* offset only */ ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex(subtype, extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); break; case 'P': /* prefix byte (rh) */ ua_str("%p:"); break; case 'R': /* mod(r/m) picks register */ reg_name(REG(modrm()), subtype); /* rh */ must_do_size = 0; break; case 'S': /* reg(r/m) picks segment reg */ uputchar("ecsdfg"[REG(modrm())]); uputchar('s'); must_do_size = 0; break; case 'T': /* reg(r/m) picks T reg */ uprintf("tr%d", REG(modrm())); must_do_size = 0; break; case 'X': /* ds:si type operator */ uprintf("ds:["); if (addrsize == 32) uputchar('e'); uprintf("si]"); break; case 'Y': /* es:di type operator */ uprintf("es:["); if (addrsize == 32) uputchar('e'); uprintf("di]"); break; case '2': /* old [pop cs]! now indexes */ ua_str(second[getbyte()]); /* instructions in 386/486 */ break; case 'g': /* modrm group `subtype' (0--7) */ ua_str( GetOPGroup(subtype) ); break; case 'd': /* sizeof operand==dword? */ if (opsize == 32) uputchar('d'); uputchar(subtype); break; case 'w': /* insert explicit size specifier */ if (opsize == 32) uputchar('d'); else uputchar('w'); uputchar(subtype); break; case 'e': /* extended reg name */ if (opsize == 32) { if (subtype == 'w') uputchar('d'); else { uputchar('e'); uputchar(subtype); } } else uputchar(subtype); break; case 'f': /* '87 opcode */ floating_point(subtype-'0'); break; case 'j': if (addrsize==32 || opsize==32) /* both of them?! */ uputchar('e'); break; case 'p': /* prefix byte */ switch (subtype) { case 'c': case 'd': case 'e': case 'f': case 'g': case 's': prefix = subtype; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; case ':': if (prefix) uprintf("%cs:", prefix); break; case ' ': c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; } break; case 's': /* size override */ switch (subtype) { case 'a': addrsize = 48 - addrsize; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; case 'o': opsize = 48 - opsize; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; } break; } }
int main(int argc,char **argv) { int s; struct atmif_sioc sioc; struct he_ioctl_reg req; if (argc < 3) { fprintf(stderr,"usage: hediag itf [cmd]\n"); fprintf(stderr,"\t\treadpci address\n"); fprintf(stderr,"\t\treadrcm address\n"); fprintf(stderr,"\t\treadtcm address\n"); fprintf(stderr,"\t\treadmbox address\n"); exit(1); } if (strcmp(argv[2], "readpci") == 0) { req.addr = strtol(argv[3], NULL, 0); req.type = HE_REGTYPE_PCI; } else if (strcmp(argv[2], "readrcm") == 0) { req.addr = strtol(argv[3], NULL, 0); req.type = HE_REGTYPE_RCM; } else if (strcmp(argv[2], "readtcm") == 0) { req.addr = strtol(argv[3], NULL, 0); req.type = HE_REGTYPE_TCM; } else if (strcmp(argv[2], "readmbox") == 0) { req.addr = strtol(argv[3], NULL, 0); req.type = HE_REGTYPE_MBOX; } if ((s = socket(PF_ATMPVC, SOCK_DGRAM, ATM_AAL5)) < 0) { perror("socket"); exit(1); } sioc.number = atoi(argv[1]); sioc.arg = &req; sioc.length = sizeof(req); if (ioctl(s, HE_GET_REG, &sioc) < 0) { perror("ioctl HE_GET_REG"); exit(1); } if (reg_name(req.addr)) printf("%s = 0x%x\n", reg_name(req.addr), req.val); else printf("0x%x = 0x%x\n", req.addr, req.val); exit(0); }
void InterpreterStubs::generate_interpreter_fill_in_tags() { Segment seg(this, code_segment, "Interpreter fill in tags"); Register param_size = tmp0; // must be preserved Register callinfo = tmp1; { bind_local("interpreter_fill_in_tags"); comment("%s: size of parameters", reg_name(tmp0)); comment("%s: call info from call size", reg_name(tmp1)); comment(""); comment("Must preserve lr, %s (method), and %s (parameter size)", reg_name(r0), reg_name(tmp0)); Label loop_entry; // tos_val = r0 must be preserved Register arg_index = tmp2; Register one_reg = tmp3; Register tag_address = JavaStackDirection < 0 ? tmp4 : jsp; mov_imm(one_reg, 1 << CallInfo::format1_tag_start); sub(arg_index, param_size, one, set_CC); report_fatal("shouldn't be called on no arguments", lt); if (JavaStackDirection < 0) { comment("Tag address of last argument"); add(tag_address, jsp, imm(BytesPerWord)); } else { comment("jsp points to tag address of last argument"); } bind(loop_entry); comment("test the bit in the call info"); tst(callinfo, reg_shift(one_reg, lsl, arg_index)); mov(tos_tag, imm(obj_tag), ne); mov(tos_tag, imm(int_tag), eq); if (JavaStackDirection < 0) { str(tos_tag, add_index(tag_address, arg_index, lsl, 3)); } else { str(tos_tag, sub_index(tag_address, arg_index, lsl, 3)); } sub(arg_index, arg_index, one, set_CC); b(loop_entry, ge); mov(pc, reg(locals)); } { Register bit_offset = tmp1; // callinfo not needed Register one_reg = tmp2; Register tag_address = tmp3; Register x1 = tmp4; Register x2 = tmp5; Register index = tos_tag; Label loop; bind_local("interpreter_fill_in_extended_tags"); comment("Total number of tags"); if (HARDWARE_LITTLE_ENDIAN) { ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord)); } else { ldrh(bit_offset, imm_index3(lr, -2 * BytesPerWord + 2)); } comment("Tag address of first argument"); if (JavaStackDirection < 0) { add(tag_address, jsp, imm_shift(param_size, lsl, 3)); } else { sub(tag_address, jsp, imm_shift(param_size, lsl, 3)); } // tag_address points to the last address of the previous stack add_imm(tag_address, tag_address, JavaFrame::arg_offset_from_sp(-1) + BytesPerWord); comment("Index of last argument"); sub(index, param_size, one); comment("Bit number of first argument"); sub(bit_offset, bit_offset, reg(param_size)); mov(bit_offset, imm_shift(bit_offset, lsl, 2)); add(bit_offset, bit_offset, imm(32 + 32 + 16)); comment("A useful constant"); mov(one_reg, one); bind(loop); comment("Get the bit offset for this argument"); add(x1, bit_offset, imm_shift(index, lsl, 2)); comment("Get the appropriate word"); mov(x2, imm_shift(x1, lsr, 5)); ldr(x2, sub_index(lr, x2, lsl, 2)); comment("Pick out the nybble"); andr(x1, x1, imm(31)); mov(x2, reg_shift(x2, lsr, x1)); andr(x2, x2, imm(15), set_CC); comment("Convert the nybble into a stack type"); sub(x2, x2, one, ne); mov(x2, reg_shift(one_reg, lsl, x2), ne); if (JavaStackDirection < 0) { str(x2, sub_index(tag_address, index, lsl, 3)); } else { str(x2, add_index(tag_address, index, lsl, 3)); } comment("Update the info"); sub(index, index, one, set_CC); b(loop, ge); mov(pc, reg(locals)); } }