📄 compile.c
字号:
case PCREL16: pcrel = SEXTSHORT ((buffer[byte] << 8) | (buffer[byte + 1])); break; case PCREL8: pcrel = SEXTCHAR ((buffer[byte])); break; case QIM: switch (buffer[byte] & 0x7) { case 0: imm = 1; break; case 1: imm = 2; break; case 4: imm = -1; break; case 5: imm = -2; break; } break; } } } if (opcode->flavor & O_BYTE) { idx = 0; switch (opcode->flags) { case 'h': dst->flags = flag_shiftbyte; break; case 'p': dst->flags = flag_multbyte; break; case 'B': dst->flags = flag_branch; break; case 'm': dst->flags = flag_mp; break; case 'a': dst->flags = flag_ap; break; case '-': dst->flags = flag_nonep; break; case 0: dst->flags = flag_nostorep; break; case 'c': dst->flags = flag_clearp; break; case 's': /* special */ dst->flags = flag_special; } } else { idx = 1; switch (opcode->flags) { case 'h': dst->flags = flag_shiftword; break; case 'p': dst->flags = flag_multword; break; case 'B': dst->flags = flag_branch; break; case 'm': dst->flags = flag_Mp; break; case 'a': dst->flags = flag_Ap; break; case '-': dst->flags = flag_nonep; break; case 0: dst->flags = flag_nostorep; break; case 'c': dst->flags = flag_clearp; break; case 's': /* special */ dst->flags = flag_special; break; } } for (i = 0; i < opcode->nargs; i++) { ea_type *p = eavector + i; switch (opcode->arg_type[i]) { default: abort (); case FP: gotreg (p, 6, idx); break; case RNIND: disp = 0; case RNIND_D16: case RNIND_D8: gotind (p, disp, rn, idx); break; break; case RDIND: disp = 0; case RDIND_D16: case RDIND_D8: gotind (p, disp, rd, idx); break; case FPIND_D8: gotind (p, disp, 6, idx); break; case CRB: case CRW: gotcr (p, cr); break; case RN: gotreg (p, rn, idx); break; case RD: gotreg (p, rd, idx); break; case RS: gotreg (p, rs, idx); break; case RNDEC: gotinc (p, rn, -1, idx); break; case RNINC: gotinc (p, rn, 1, idx); break; case SPINC: gotinc (p, 7, 1, idx); break; case SPDEC: gotinc (p, 7, -1, idx); break; case ABS24: case ABS16: gotabs (p, abs, R_HARD_0, idx); break; case ABS8: gotabs (p, abs, R_HARD8_0, idx); break; case IMM16: case RLIST: case QIM: case IMM4: case IMM8: gotimm (p, imm); break; case PCREL16: case PCREL8: gotimm (p, ((pcrel + pc + opcode->length) & 0xffff) | (pc & 0xff0000), R_HARD_0, JLONG); } } /* Finished and done - turn from two operand stuff into three */ dst->srca.type = eas.s.ea_nop.s.srcabyte; dst->srcb.type = eas.s.ea_nop.s.srcbbyte; dst->dst.type = eas.s.ea_nop.s.dstbyte; if (opcode->nargs) { switch (opcode->nargs) { case 1: howto_workout (&dst->srca, &eavector[0], 0); if (opcode->dst != '!') howto_workout (&dst->dst, &eavector[0], 2); break; case 2: if (opcode->src2 == '!') { howto_workout (&dst->srca, &eavector[0], 0); howto_workout (&dst->dst, &eavector[1], 2); } else { howto_workout (&dst->srca, &eavector[0], 0); howto_workout (&dst->srcb, &eavector[1], 1); if (opcode->dst != '!') { howto_workout (&dst->dst, &eavector[1], 2); } } break; } /* Some extra stuff with pre inc and post dec, make sure that if the same ea is there twice, only one of the ops is auto inc/dec */ fix_incdecs (dst); /* Some special cases */ if (dst->opcode == exec_dispatch[O_PJSR] || dst->opcode == exec_dispatch[O_PJMP]) { /* Both the @abs:24 and @rn turn into a disp word, chose the right a mode since @abs:24 is 4 bytes long */ if (opcode->length == 4) { dst->srca.type = eas.s.ea_lval24.s.srcabyte; } else { dst->srca.type = eas.s.ea_reg.s.srcalong; } dst->srca.r2.rptr = &cpu.regs[R_HARD_0]; /* For [P]JSR, keep return address precomputed */ dst->srcb.literal = pc + opcode->length; dst->srcb.type = eas.s.ea_imm.s.srcbword; } else if (dst->opcode == exec_dispatch[O_MULXU]) { /* This is a multiply -fix the destination op */ if (dst->dst.type == eas.s.ea_reg.s.dstword) { dst->dst.type = eas.s.ea_reg.s.dstlong; } else { dst->dst.type = eas.s.ea_reg.s.dstword; } dst->dst.reg.bptr = regptr[rd][JWORD]; } else if (dst->opcode == exec_dispatch[O_DIVXU]) { /* This is a wider than normal, fix the source operand */ dst->srcb.type = (dst->srcb.type == eas.s.ea_reg.s.srcbword) ? eas.s.ea_reg.s.srcblong : eas.s.ea_reg.s.srcbword; dst->dst.type = (dst->dst.type == eas.s.ea_reg.s.dstword) ? eas.s.ea_reg.s.dstlong : eas.s.ea_reg.s.dstword; } else if (dst->opcode == exec_dispatch[O_LDM]) { /* Turn of the stack ref */ dst->srca.type = eas.s.ea_nop.s.srcabyte; } else if (dst->opcode == exec_dispatch[O_STM]) { /* Turn of the stack ref */ dst->srcb.type = eas.s.ea_nop.s.srcbbyte; } /* extends read one size and write another */ else if (dst->opcode == exec_dispatch[O_EXTS] || dst->opcode == exec_dispatch[O_EXTU]) { dst->dst.type = eas.s.ea_reg.s.dstword; dst->dst.reg.bptr = regptr[rd][JWORD]; dst->flags = flag_Ap; } if (opcode->flags == 'h') thinkabout_shifts (dst, opcode->flavor & O_BYTE); /* For a branch, turn off one level of indirection */ if (opcode->src1 == 'B') { indoff (&dst->srca, 0); } } dst->next_pc = pc + opcode->length; compcycles (dst, opcode); return; next:; } /* Couldn't understand anything */ dst->opcode = exec_dispatch[O_TRAPA]; dst->next_pc = pc + 1;}compile (pc){ int idx; /* find the next cache entry to use */ idx = cpu.cache_top + 1; cpu.compiles++; if (idx >= cpu.csize) { idx = 1; } cpu.cache_top = idx; /* Throw away its old meaning */ cpu.cache_idx[cpu.cache[idx].oldpc] = 0; /* set to new address */ cpu.cache[idx].oldpc = pc; /* fill in instruction info */ find (pc, cpu.memory + pc, cpu.cache + idx); /* point to new cache entry */ cpu.cache_idx[pc] = idx;}baddefault (x){ printf ("bad default %d\n", x);}static int fetch_l (arg) ea_type *arg;{ int l, r; int h = *(arg->reg.wptr); r = (union rtype *) (arg->reg.wptr) - &cpu.regs[0]; r++; l = cpu.regs[r].s[LOW]; return (h << 16) | l;}#define FETCH(dst, arg, n) \{ \ int r; unsigned char*lval; \ DISPATCH((arg).type) \ { LABELN(FETCH_NOP,n): \ dst= 0; \ break; \ DEFAULT baddefault((arg).type); break; \ LABELN(FETCH_LVAL,n): \ dst = (*(((arg).reg.wptr)) + (arg.literal)) ; \ break; \ LABELN(FETCH_LVAL24,n): \ dst = (*(((arg).reg.wptr)) + *(((arg).r2.wptr)) + (arg.literal)) &0xffffff; \ break; \ LABELN(FETCH_CRB,n): \ dst = (*((arg).reg.segptr) - cpu.memory)>>16; \ break; \ LABELN(FETCH_CRW,n): \ dst = BUILDSR();\ break; \ LABELN(FETCH_REG_B,n): \ dst = *((arg).reg.bptr); \ break; \ LABELN(FETCH_REG_W,n): \ dst = *((arg).reg.wptr); \ break; \ LABELN(FETCH_REG_L,n): \ dst = fetch_l(&(arg));\ break; \ LABELN(FETCH_INC_B,n): \ lval = elval ((arg), 0); \ dst = byteat (lval); \ (*((arg).reg.wptr))++; \ break; \ LABELN(FETCH_INC_W,n): \ lval = elval ((arg), 0); \ dst = wordat (lval); \ (*(((arg).reg.wptr))) += 2; \ break; \ LABELN(FETCH_DEC_B, n): \ (*(arg).reg.wptr)--; \ lval = elval ((arg), 0); \ r = byteat (lval); \ dst = r; \ break; \ LABELN(FETCH_DEC_W, n): \ (*((arg).reg.wptr)) -= 2; \ lval = elval ((arg), 0); \ r = wordat (lval); \ dst = r; \ break; \ LABELN(FETCH_DISP_B,n): \ lval = displval ((arg)); \ dst = byteat (lval); \ break; \ LABELN(FETCH_DISP_W,n): \ lval = displval ((arg)); \ dst = wordat (lval); \ break; \ LABELN(FETCH_IMM, n): \ dst = (arg).literal; \ break; \ } \ ENDDISPATCH; \}static union{ short int i; struct { char low; char high; } u;}littleendian;staticvoidinit_pointers (){ static int init; if (!init) { int i; init = 1; littleendian.i = 1; for (i = 0; i < (int) R_LAST; i++) { if (littleendian.u.high) { /* big endian host */ LOW = 1; HIGH = 0; regptr[i][0] = ((unsigned char *) (cpu.regs + i)) + 3; regptr[i][1] = ((unsigned char *) (cpu.regs + i)) + 2; } else { LOW = 0; HIGH = 1; regptr[i][0] = (unsigned char *) &(cpu.regs[i]); regptr[i][1] = (unsigned char *) (&(cpu.regs[i])); } regptr[i][2] = (unsigned char *) &(cpu.regs[i]); } memcpy (segregptr + 0, regptr + R_SR, sizeof (segregptr[0])); memcpy (segregptr + 1, regptr + R_TP, sizeof (segregptr[1])); memcpy (segregptr + 3, regptr + R_BR, sizeof (segregptr[3])); memcpy (segregptr + 4, regptr + R_EP, sizeof (segregptr[4])); memcpy (segregptr + 5, regptr + R_DP, sizeof (segregptr[5])); memcpy (segregptr + 6, regptr + R_CP, sizeof (segregptr[6])); memcpy (segregptr + 7, regptr + R_TP, sizeof (segregptr[7])); /* Pointers to into the cpu state for the seg registers */ segmap[R0] = &cpu.regs[R_DP].c; segmap[R1] = &cpu.regs[R_DP].c; segmap[R2] = &cpu.regs[R_DP].c; segmap[R3] = &cpu.regs[R_DP].c; segmap[R4] = &cpu.regs[R_EP].c; segmap[R5] = &cpu.regs[R_EP].c; segmap[R6] = &cpu.regs[R_TP].c; segmap[R7] = &cpu.regs[R_TP].c; segmap[R_HARD_0] = &cpu.regs[R_DP].c; segmap[R_HARD8_0] = &cpu.regs[R_BP].c; cpu.memory = (unsigned char *) calloc (sizeof (char), H8500_MSIZE); cpu.cache_idx = (unsigned short *) calloc (sizeof (short), H8500_MSIZE); /* initialize the seg registers */ cpu.regs[R_DP].c = cpu.memory; cpu.regs[R_TP].c = cpu.memory; cpu.regs[R_CP].c = cpu.memory; cpu.regs[R_BP].c = cpu.memory; cpu.regs[R_EP].c = cpu.memory; cpu.regs[R7].s[LOW] = 0xfffe; cpu.regs[R6].s[LOW] = 0xfffe; if (!cpu.cache) sim_set_simcache_size (CSIZE); }}#define PUSHWORD(x) \{ \ int sp = cpu.regs[R7].s[LOW]; \ unsigned char *p; \ \ sp -= 2; \ p = (sp & 0xffff) + (cpu.regs[R_TP].c); \ cpu.regs[R7].s[LOW] = sp; \ setwordat (p, x); \} \#define POPWORD(d) \{ \ int spx= cpu.regs[R7].s[LOW]; \ unsigned char *p; \ \ p = (spx& 0xffff) + (cpu.regs[R_TP].c); \ spx+= 2; \ cpu.regs[R7].s[LOW] = spx; \ d = wordat (p); \} \/* simulate a monitor trap */trap (){ switch (cpu.regs[R3].s[LOW] & 0xff) { case 33: /* exit */ cpu.exception = SIGQUIT; break; case 34: /* abort */ cpu.exception = SIGABRT; break; case 6: /* print char in r0 */ printf ("%c", cpu.regs[R0].s[LOW]); break; }}voidcontrol_c (sig, code, scp, addr) int sig; int code; char *scp; char *addr;{ cpu.exception = SIGINT;}static jmp_buf jbuf;static voidsegv (){ cpu.exception = SIGSEGV; longjmp (jbuf, 1);}intsim_stop (sd) SIM_DESC sd;{ cpu.exception = SIGINT; return 1;}voidsim_resume (sd, step, siggnal) SIM_DESC sd;{ static int init1; int res; int tmp; int arga; int argb; int bit; int pc; int C, Z, V, N; int cycles = 0; int insts = 0; int tick_start = get_now (); void (*prev) (); void (*prev_seg) (); if (!init1) { int i; init1 = 1; init_pointers (); for (i = 0; i < N_EATYPES; i++) { eas.a[i].s.srcabyte = LABEL_REFN (FETCH_NOP, 0); eas.a[i].s.srcaword = LABEL_REFN (FETCH_NOP, 0); eas.a[i].s.srcalong = LABEL_REFN (FETCH_NOP, 0); eas.a[i].s.srcbbyte = LABEL_REFN (FETCH_NOP, 1); eas.a[i].s.srcbword = LABEL_REFN (FETCH_NOP, 1); eas.a[i].s.srcblong = LABEL_REFN (FETCH_NOP, 1); eas.a[i].s.dstbyte = LABEL_REF (STORE_NOP); eas.a[i].s.dstword = LABEL_REF (STORE_NOP); eas.a[i].s.dstlong = LABEL_REF (STORE_NOP); } eas.s.ea_lval.s.srcabyte = LABEL_REFN (FETCH_LVAL, 0); eas.s.ea_lval.s.srcaword = LABEL_REFN (FETCH_LVAL, 0); eas.s.ea_lval24.s.srcabyte = LABEL_REFN (FETCH_LVAL24, 0); eas.s.ea_lval24.s.srcaword = LABEL_REFN (FETCH_LVAL24, 0); eas.s.ea_nop.s.srcabyte = LABEL_REFN (FETCH_NOP, 0); eas.s.ea_nop.s.srcaword = LABEL_REFN (FETCH_NOP, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -