📄 writecode.c
字号:
emit ("register int FAIL%d=fail(context,2);\n", nibs); break; } ; /* work out how to fetch the immediate value */ } s++; }}voidinfo_special (p, getdst, nostore, before, nosrc) opcode_entry_type *p; int *getdst; int *nostore; int *before; int *nosrc;{ switch (p->opcode) { case OPC_exts: case OPC_extsb: case OPC_extsl: *nostore = 1; *nosrc = 1; break; case OPC_ldm: *nostore = 1; *nosrc = 1; break; case OPC_negb: case OPC_neg: case OPC_sla: case OPC_slab: case OPC_slal: case OPC_sda: case OPC_sdab: case OPC_sdal: case OPC_com: case OPC_comb: case OPC_adc: case OPC_sbc: case OPC_nop: case OPC_adcb: case OPC_add: case OPC_addb: case OPC_addl: case OPC_inc: case OPC_sub: case OPC_subb: case OPC_subl: case OPC_and: case OPC_andb: case OPC_xorb: case OPC_xor: break; case OPC_mult: case OPC_multl: case OPC_div: case OPC_divl: *nostore = 1; break; case OPC_testb: case OPC_test: case OPC_testl: case OPC_cp: case OPC_cpb: case OPC_cpl: case OPC_bit: *nostore = 1; *before = 0; break; case OPC_bpt: case OPC_jr: case OPC_jp: case OPC_ret: case OPC_call: case OPC_tcc: *nosrc = 1; *nostore = 1; *before = 1; break; case OPC_sc: *nostore = 1; *before = 0; break; case OPC_clrb: case OPC_clr: *before = 1; *nosrc = 1; break; case OPC_ldi: case OPC_ldib: case OPC_lddb: case OPC_ldd: *before = 1; *nostore = 1; *nosrc = 1; break; case OPC_ldk: case OPC_ld: case OPC_ldb: case OPC_ldl: *before = 1; *getdst = 0; break; case OPC_push: case OPC_pushl: case OPC_pop: case OPC_popl: *before = 1; *getdst = 0; break; case OPC_lda: *nosrc = 1; break; }}/* calculate the lvalues required for the opcode */voidinfo_lvals (p) opcode_entry_type *p;{ /* emit code to work out lvalues, if any */ unsigned int *i = p->arg_info; while (*i) { current_name = reg_n (*i); current_size = size_name (p->type); switch (*i & CLASS_MASK) { case CLASS_X: /* address(reg) */ emit ("register <addr_type> oplval_<name>= ((base_<name> + (short)get_word_reg(context,reg_<name>)) & 0xffff) + (base_<name> & ~0xffff);\n"); break; case CLASS_IR: /* Indirect register */ emit ("register int oplval_<name> = get_<ptr_mode>_reg(context,reg_<name>);\n"); break; case CLASS_DA: emit ("register int oplval_<name>=base_<name>;\n"); break; case CLASS_IMM: case CLASS_REG_WORD: case CLASS_REG_LONG: case CLASS_REG_BYTE: case CLASS_PR: break; case CLASS_BA: emit ("register int oplval_<name> = get_<ptr_mode>_reg(context,reg_<name>) + (short)(imm_src);\n"); break; case CLASS_BX: emit ("register int oplval_<name> = get_<ptr_mode>_reg(context,reg_<name>)\n"); emit (" + get_word_reg(context,reg_aux_x);\n"); break; } i++; }}/* emit code to fetch the args from calculated lvalues */int allregs;voidinfo_fetch (p, getdst) opcode_entry_type *p; int getdst;{ unsigned int *i = p->arg_info; int had_src = 0; allregs = 1; while (*i) { current_name = reg_n (*i); current_size = size_name (p->type); switch (*i & CLASS_MASK) { case CLASS_X: case CLASS_IR: case CLASS_BA: case CLASS_BX: case CLASS_DA: if (!getdst && IS_DST (*i)) break; emit ("register int op_<name>= get_<size>_<mem>_da(context,oplval_<name>);\n"); allregs = 0; break; case CLASS_IMM: if (!had_src) { if (p->opcode == OPC_out || p->opcode == OPC_outb || p->opcode == OPC_sout || p->opcode == OPC_soutb) { /* The imm is a dest here */ emit ("register int op_dst = imm_src;\n"); } else { emit ("register int op_src = imm_src;\n"); } } break; case CLASS_REG_QUAD: if (!getdst && IS_DST (*i)) break; had_src |= IS_SRC (*i); emit ("UDItype op_<name> ;\n"); break; case CLASS_REG_WORD: if (!getdst && IS_DST (*i)) break; had_src |= IS_SRC (*i); emit ("register int op_<name> = get_word_reg(context,reg_<name>);\n"); break; case CLASS_REG_LONG: if (!getdst && IS_DST (*i)) break; had_src |= IS_SRC (*i); emit ("register int op_<name> = get_long_reg(context,reg_<name>);\n"); break; case CLASS_REG_BYTE: if (!getdst && IS_DST (*i)) break; had_src |= IS_SRC (*i); emit ("register int op_<name> = get_byte_reg(context,reg_<name>);\n"); break; } i++; }}static voidnormal_flags (p, s, neg) opcode_entry_type *p; char *s;{ emit (" %s;\n", s); emit ("NORMAL_FLAGS(context,%d, tmp, op_dst, op_src,%d); \n", p->type,neg);}static voidtest_normal_flags (p, s, opt) opcode_entry_type *p; char *s; int opt;{ emit (" %s;\n", s); if (0 && opt) { emit ("context->broken_flags = TST_FLAGS;\n"); emit ("context->size = %d;\n", p->type); } else { emit ("TEST_NORMAL_FLAGS(context,%d, tmp); \n", p->type); }}static voidoptimize_normal_flags (p, s,neg) opcode_entry_type *p; char *s;{ emit (" %s;\n", s);#if 0 emit ("context->broken_flags = CMP_FLAGS;\n");#else emit ("NORMAL_FLAGS(context,%d, tmp, op_dst, op_src,%d); \n", p->type, neg);#endif}staticvoidjp (p) opcode_entry_type *p;{ emit ("if(op_cc == 8 || COND(context,op_cc)) pc = oplval_dst;\n");}static voidjr (p) opcode_entry_type *p;{ emit ("if(op_cc == 8 || COND(context,op_cc)) pc = oplval_dst;\n");}static voidret (p) opcode_entry_type *p;{ emit ("if(op_cc == 8 || COND(context,op_cc))\n{\n"); emit ("pc = get_<ptr_mode>_<mem>_ir(context,<sp>);\n"); emit ("put_<ptr_mode>_reg(context,<sp>, get_<ptr_mode>_reg(context,<sp>) + <ptr_size>);\n"); emit ("};\n");}static voidcall (p) opcode_entry_type *p;{ emit ("put_<ptr_mode>_reg(context,<sp>,tmp = get_<ptr_mode>_reg(context,<sp>) - <ptr_size>);\n"); emit ("put_<ptr_mode>_<mem>_da(context,tmp, pc);\n"); emit ("pc = oplval_dst;\n");}static voidpush (p) opcode_entry_type *p;{ emit ("tmp = op_src;\n"); emit ("oplval_dst -= %d;\n", p->type / 8); emit ("put_<ptr_mode>_reg(context,reg_dst, oplval_dst);\n");}static voidpop (p) opcode_entry_type *p;{ emit ("tmp = op_src;\n"); emit ("put_<ptr_mode>_reg(context,reg_src, oplval_src + %d);\n", p->type / 8);}static voidld (p) opcode_entry_type *p;{ emit ("tmp = op_src;\n");}static voidsc (){ emit ("support_call(context,imm_src);\n");}static voidbpt (){ emit ("pc -=2; \n"); emit ("context->exception = SIM_BREAKPOINT;\n");}static voidldi (p, size, inc) opcode_entry_type *p; int size; int inc;{ int dinc = (size / 8) * inc; current_size = size_name (size); emit ("{ \n"); emit ("int type = %s;\n", insn_4 (7)); emit ("int rs = get_<ptr_mode>_reg(context,reg_src);\n"); emit ("int rd = get_<ptr_mode>_reg(context,reg_dst);\n"); emit ("int rr = get_word_reg(context,reg_aux_r);\n"); emit ("do {\n"); emit ("put_<size>_<mem>_da(context,rd, get_<size>_<mem>_da(context,rs));\n"); emit ("rd += %d;\n", dinc); emit ("rs += %d;\n", dinc); emit ("rr --;\n"); emit ("context->cycles += 9;\n"); emit ("} while (!type && rr != 0 && context->exception <= 1);\n"); emit ("if (context->exception>1) pc -=4;\n"); emit ("put_<ptr_mode>_reg(context,reg_src, rs);\n"); emit ("put_<ptr_mode>_reg(context,reg_dst, rd);\n"); emit ("put_word_reg(context,reg_aux_r, rr);\n"); emit ("}\n");}static voidshift (p, arith) opcode_entry_type *p; int arith;{ /* We can't use `(char)' since char might be unsigned. We can't use `(signed char)' because the compiler might be K&R. This seems safe, since it only assumes that bytes are 8 bits. */ emit ("op_src = (op_src << (sizeof (int) * 8 - 8)) >> (sizeof (int) * 8 - 8);\n");#if 0 /* Original code: fails if characters are unsigned. */ emit ("op_src = (char)op_src;\n");#endif emit ("if (op_src < 0) \n"); emit ("{\n"); emit ("op_src = -op_src;\n"); emit ("op_dst = (%s <c_size>)op_dst;\n", arith ? "" : "unsigned"); emit ("tmp = (%s op_dst) >> op_src;\n", arith ? "" : "(unsigned)"); emit ("context->carry = op_dst >> (op_src-1);\n", p->type); emit ("}\n"); emit ("else\n"); emit ("{\n"); emit ("tmp = op_dst << op_src;\n"); emit ("context->carry = op_dst >> (%d - op_src);\n", p->type); emit ("}\n"); emit ("context->zero = (<c_size>)tmp == 0;\n"); emit ("context->sign = (int)((<c_size>)tmp) < 0;\n"); emit ("context->overflow = ((int)tmp < 0) != ((int)op_dst < 0);\n"); emit ("context->cycles += 3*op_src;\n"); emit ("context->broken_flags = 0;\n");}static voidrotate (p, through_carry, size, left) opcode_entry_type *p; int through_carry; int size; int left;{ if (!left) { emit ("while (op_src--) {\n"); emit ("int rotbit;\n"); emit ("rotbit = op_dst & 1;\n"); emit ("op_dst = ((unsigned)op_dst) >> 1;\n"); if (through_carry) { emit ("op_dst |= context->carry << %d;\n", size - 1); } else { emit ("op_dst |= rotbit << %d;\n", size - 1); } emit ("context->carry = rotbit;\n"); emit ("}\n"); } else { emit ("while (op_src--) {\n"); emit ("int rotbit;\n"); emit ("rotbit = (op_dst >> (%d))&1;\n", size - 1); emit ("op_dst <<=1;\n"); if (through_carry) { emit ("if (context->carry) op_dst |=1;\n"); } else { emit ("if (rotbit) op_dst |= 1;\n"); } emit ("context->carry = rotbit;\n"); emit ("}\n"); } emit ("tmp = (<c_size>)op_dst;\n"); emit ("context->zero = tmp == 0;\n"); emit ("context->sign = (int)tmp < 0;\n"); emit ("context->overflow = ((int)tmp < 0) != ((int)op_dst < 0);\n"); emit ("context->cycles += 3*op_src;\n"); emit ("context->broken_flags = 0;\n");}static voidadiv (p) opcode_entry_type *p;{ emit ("if (op_src==0)\n"); emit ("{\n"); emit ("context->exception = SIM_DIV_ZERO;\n"); emit ("}\n"); emit ("else\n"); emit ("{\n"); if (p->type == 32) { emit ("op_dst.low = (int)get_long_reg(context,reg_dst+2);\n"); emit ("op_dst.high = (int)get_long_reg(context,reg_dst+0);\n");#ifdef __GNUC__ emit ("tmp = (((long long)op_dst.high << 32) + (op_dst.low)) / (int)op_src;\n");#else emit ("tmp = (long)op_dst.low / (int)op_src;\n");#endif emit ("put_long_reg(context,reg_dst+2, tmp);\n");#ifdef __GNUC__ emit ("put_long_reg(context,reg_dst, (((long long)op_dst.high << 32) + (op_dst.low)) %% (int)op_src);\n");#else emit ("put_long_reg(context,reg_dst, (int)op_dst.low %% (int)op_src);\n");#endif emit ("context->zero = op_src == 0 || (op_dst.low==0 && op_dst.high==0);\n"); } else { emit ("tmp = (long)op_dst / (short)op_src;\n"); emit ("put_word_reg(context,reg_dst+1, tmp);\n"); emit ("put_word_reg(context,reg_dst, (long) op_dst %% (short)op_src);\n"); emit ("context->zero = op_src == 0 || op_dst==0;\n"); } emit ("context->sign = (int)tmp < 0;\n"); emit ("context->overflow =(tmp & 0x%x) != 0;\n", ~((1 << (p->type)) - 1)); emit ("context->carry = (tmp & 0x%x) != 0;\n", ~(1 << (p->type))); emit ("}\n");}static voiddobit (p)opcode_entry_type *p;{ emit("context->zero = (op_dst & (1<<op_src))==0;\n"); emit("context->broken_flags = 0;\n");}static voiddoset (p, v)opcode_entry_type*p;int v;{ if (v) emit (" tmp = op_dst | (1<< op_src);\n"); else emit (" tmp = op_dst & ~(1<< op_src);\n");}static voidmult (p) opcode_entry_type *p;{ if (p->type == 32) { emit ("op_dst.low = get_long_reg(context,reg_dst+2);\n"); emit ("tmp = op_dst.low * op_src;\n"); emit ("put_long_reg(context,reg_dst+2, tmp);\n"); emit ("put_long_reg(context,reg_dst, 0);\n"); } else { emit ("op_dst = get_word_reg(context,reg_dst+1);\n"); emit ("tmp = op_dst * op_src;\n"); emit ("put_long_reg(context,reg_dst, tmp);\n"); } emit ("context->sign = (int)tmp < 0;\n"); emit ("context->overflow =0;\n"); emit ("context->carry = (tmp & 0x%x) != 0;\n", ~((1 << (p->type)) - 1)); emit ("context->zero = tmp == 0;\n");}static voidexts (p) opcode_entry_type *p;{ /* Fetch the ls part of the src */ current_size = size_name (p->type * 2); if (p->type == 32) { emit ("tmp= get_long_reg(context,reg_dst+2);\n"); emit ("if (tmp & (1<<%d)) {\n", p->type - 1); emit ("put_long_reg(context,reg_dst, 0xffffffff);\n"); emit ("}\n"); emit ("else\n"); emit ("{\n"); emit ("put_long_reg(context,reg_dst, 0);\n"); emit ("}\n"); } else { emit ("tmp= get_<size>_reg(context,reg_dst);\n"); emit ("if (tmp & (1<<%d)) {\n", p->type - 1); emit ("tmp |= 0x%x;\n", ~((1 << p->type) - 1)); emit ("}\n"); emit ("else\n"); emit ("{\n"); emit ("tmp &= 0x%x;\n", ((1 << p->type) - 1)); emit ("}\n"); emit ("put_<size>_reg(context,reg_dst, tmp);\n"); }}doflag(on)int on;{ /* Load up the flags */ emit(" COND (context, 0x0b);\n"); if (on) emit ("{ int on =1;\n "); else emit ("{ int on =0;\n "); emit ("if (imm_src & 1)\n"); emit ("PSW_OVERFLOW = on;\n"); emit ("if (imm_src & 2)\n"); emit ("PSW_SIGN = on;\n"); emit ("if (imm_src & 4)\n"); emit ("PSW_ZERO = on;\n"); emit ("if (imm_src & 8)\n"); emit ("PSW_CARRY = on;\n"); emit("}\n");}/* emit code to perform operation */voidinfo_docode (p) opcode_entry_type *p;{ switch (p->opcode) { case OPC_clr: case OPC_clrb: emit ("tmp = 0;\n"); break; case OPC_ex: case OPC_exb: emit ("tmp = op_src; \n"); if (allregs) { emit ("put_<size>_reg(context,reg_src, op_dst);\n"); } else { emit ("put_<size>_mem_da(context, oplval_src, op_dst);\n"); } break; case OPC_adc: case OPC_adcb: normal_flags (p, "op_src += COND(context,7);tmp = op_dst + op_src ;",0); break; case OPC_sbc:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -