📄 gen68k.c
字号:
case bt_char: case bt_charu: case bt_uchar: case bt_schar: case bt_short: case bt_int16: return TRUE; default: break; } if (ep->nodetype == en_cast) { switch (ep->v.p[0]->etp->type) { case bt_char: case bt_charu: case bt_uchar: case bt_schar: case bt_short: case bt_int16: return TRUE; default: return FALSE; } } return FALSE;}void g_move P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){ switch (ap2->mode) { case am_areg: g_code (op_movea, len, ap1, ap2); break; default: g_code (op_move, len, ap1, ap2); break; }}static void g_movem P2 (ADDRESS *, ap1, ADDRESS *, ap2){#ifdef COLDFIRE if (is_coldfire ()) { switch (ap1->mode) { case am_ainc: ap1 = copy_addr (ap1, am_ind); g_code (op_movem, IL4, ap1, ap2); g_code (op_add, IL4, mk_immed (4L * count_registers (ap2->u.mask)), mk_reg (ap1->preg)); return; case am_adec: g_code (op_sub, IL4, mk_immed (4L * count_registers (ap2->u.mask)), mk_reg (ap1->preg)); ap1 = copy_addr (ap1, am_ind); g_code (op_movem, IL4, ap1, ap2); return; default: break; } switch (ap2->mode) { case am_ainc: ap2 = copy_addr (ap2, am_ind); g_code (op_movem, IL4, ap1, ap2); g_code (op_add, IL4, mk_immed (4L * count_registers (ap1->u.mask)), mk_reg (ap2->preg)); return; case am_adec: g_code (op_sub, IL4, mk_immed (4L * count_registers (ap1->u.mask)), mk_reg (ap2->preg)); ap2 = copy_addr (ap2, am_ind); g_code (op_movem, IL4, ap1, ap2); return; default: break; } }#endif /* COLDFIRE */ g_code (op_movem, IL4, ap1, ap2);}#ifdef FLOAT_IEEEstatic void g_fmovem P2 (ADDRESS *, ap1, ADDRESS *, ap2){#ifdef COLDFIRE if (is_coldfire ()) { switch (ap1->mode) { case am_ainc: ap1 = copy_addr (ap1, am_ind); g_fcode (op_fmovem, IL12, ap1, ap2); g_code (op_add, IL4, mk_immed (12L * count_registers (ap2->u.mask)), mk_reg (ap1->preg)); return; case am_adec: g_code (op_sub, IL4, mk_immed (12L * count_registers (ap2->u.mask)), mk_reg (ap1->preg)); ap1 = copy_addr (ap1, am_ind); g_fcode (op_fmovem, IL12, ap1, ap2); return; default: break; } switch (ap2->mode) { case am_ainc: ap2 = copy_addr (ap2, am_ind); g_fcode (op_fmovem, IL12, ap1, ap2); g_code (op_add, IL4, mk_immed (12L * count_registers (ap1->u.mask)), mk_reg (ap2->preg)); return; case am_adec: g_code (op_sub, IL4, mk_immed (12L * count_registers (ap1->u.mask)), mk_reg (ap2->preg)); ap2 = copy_addr (ap2, am_ind); g_fcode (op_fmovem, IL12, ap1, ap2); return; default: break; } }#endif /* COLDFIRE */ g_fcode (op_fmovem, IL12, ap1, ap2);}#endif /* FLOAT_IEEE */static void g_call P1 (ADDRESS *, ap){ ADDRESS *ap1; EXPR *ep; LABEL label;
if (ap == NIL_ADDRESS)
return;
switch (ap->mode) {
case am_immed:
g_code (op_trap, IL0, ap, NIL_ADDRESS);
break; case am_direct: switch (codemodel_option) { case model_absolute: g_code (op_jsr, IL0, ap, NIL_ADDRESS); break; case model_small: label = nextlabel++; ap = copy_addr (ap, am_indxpc); ep = mk_node (en_sub, ap->u.offset, mk_lcon (label), tp_void); ap->u.offset = mk_node (en_add, ep, mk_icon ((IVAL) 2L, tp_int), tp_void); g_label (label); g_code (op_jsr, IL0, ap, NIL_ADDRESS); break; case model_large: ap1 = address_register (); label = nextlabel++; ap = copy_addr (ap, am_immed); ep = mk_node (en_sub, ap->u.offset, mk_lcon (label), tp_void); ap->u.offset = mk_node (en_add, ep, mk_icon ((IVAL) 2L, tp_int), tp_void); g_move (IL4, ap, ap1); freeop (ap1); ap = copy_addr (ap1, am_indx2pc); ap->u.offset = mk_const ((IVAL) 0L); g_label (label); g_code (op_jsr, IL0, ap, NIL_ADDRESS); break; default: CANNOT_REACH_HERE (); } break; case am_ind: g_code (op_jsr, IL0, ap, NIL_ADDRESS); break; default: CANNOT_REACH_HERE (); }}static void g_add P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){ switch (ap2->mode) { case am_areg: g_code (op_adda, len, ap1, ap2); break; default: g_code (op_add, len, ap1, ap2); break; }}static void g_sub P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){ switch (ap2->mode) { case am_areg: g_code (op_suba, len, ap1, ap2); break; default: g_code (op_sub, len, ap1, ap2); break; }}static void g_move8 P2 (ADDRESS *, ap1, ADDRESS *, ap2){ switch (ap1->mode) { case am_mreg: if (ap2->mode == am_mreg) { if (ap2->preg == ap1->preg && ap2->sreg == ap1->sreg) { return; } } else { if (ap1->preg < ap1->sreg) { g_movem (mk_smask ((REGMASK) REGBIT (ap1->preg) | REGBIT (ap1->sreg)), ap2); return; } } break;#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, IL8, ap1, ap2); return;#endif /* FLOAT_IEEE */ default: break; } if (ap2->mode == am_mreg && ap1->mode != am_immed) { if (ap2->preg < ap2->sreg && ap1->mode != am_mreg) { g_movem (ap1, mk_rmask ((REGMASK) REGBIT (ap2->preg) | REGBIT (ap2->sreg))); return; } } switch (ap2->mode) { case am_adec: g_move (IL4, mk_high (ap1), mk_high (ap2)); g_move (IL4, mk_low (ap1), mk_low (ap2)); break;#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, IL8, ap1, ap2); break;#endif /* FLOAT_IEEE */ default:#ifdef COLDFIRE if (is_coldfire ()) { ADDRESS *ap = data_register (); g_move (IL4, mk_high (ap1), ap); g_move (IL4, ap, mk_high (ap2)); g_move (IL4, mk_low (ap1), ap); g_move (IL4, ap, mk_low (ap2)); freeop (ap); return; }#endif /* COLDIFRE */ g_move (IL4, mk_high (ap1), mk_high (ap2)); g_move (IL4, mk_low (ap1), mk_low (ap2)); break; }}static void g_move12 P2 (ADDRESS *, ap1, ADDRESS *, ap2){ switch (ap1->mode) { case am_xreg: if (ap2->mode == am_xreg) { if (ap2->preg == ap1->preg && ap2->sreg == ap1->sreg && ap2->u.xreg == ap1->u.xreg) return; } else { if (ap1->preg < ap1->sreg && ap1->sreg < ap1->u.xreg) { g_movem (mk_smask ((REGMASK) REGBIT (ap1->preg) | REGBIT (ap1->sreg) | REGBIT (ap1->u.xreg)), ap2); return; } } break;#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, IL12, ap1, ap2); return;#endif /* FLOAT_IEEE */ default: break; } if (ap2->mode == am_xreg) { if (ap2->preg < ap2->sreg && ap2->sreg < ap2->u.xreg && ap1->mode != am_xreg) { g_movem (ap1, mk_rmask ((REGMASK) REGBIT (ap2->preg) | REGBIT (ap2->sreg) | REGBIT (ap2->u.xreg))); return; } } switch (ap2->mode) { case am_adec: g_move (IL4, mk_top (ap1), mk_top (ap2)); g_move (IL4, mk_high (ap1), mk_high (ap2)); g_move (IL4, mk_low (ap1), mk_low (ap2)); break;#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, IL12, ap1, ap2); break;#endif /* FLOAT_IEEE */ default:#ifdef COLDFIRE if (is_coldfire ()) { ADDRESS *ap = data_register (); g_move (IL4, mk_top (ap1), ap); g_move (IL4, ap, mk_top (ap2)); g_move (IL4, mk_high (ap1), ap); g_move (IL4, ap, mk_high (ap2)); g_move (IL4, mk_low (ap1), ap); g_move (IL4, ap, mk_low (ap2)); freeop (ap); return; }#endif /* COLDFIRE */ g_move (IL4, mk_top (ap1), mk_top (ap2)); g_move (IL4, mk_high (ap1), mk_high (ap2)); g_move (IL4, mk_low (ap1), mk_low (ap2)); break; }}/* * mk_legal will coerce the addressing mode in ap into a mode that is * satisfactory for the flag word. */static ADDRESS *mk_legal P3 (ADDRESS *, ap, FLAGS, flags, const TYP *, tp){ ADDRESS *ap2; ILEN ilen = (ILEN) tp->size; if (flags & F_NOVALUE) { freeop (ap); return NIL_ADDRESS; } if (ap == NIL_ADDRESS) { FATAL ((__FILE__, "mk_legal", "ap = 0")); }#ifdef COLDFIRE if ((flags & F_COLD) && (ilen < IL4) && is_coldfire ()) { ap = g_extend (ap, tp, is_unsigned_type (tp) ? tp_ulong : tp_long); }#endif /* COLDFIRE */ switch (ap->mode) { case am_immed: if (flags & F_IMMED) { return ap; /* mode ok */ } break; case am_areg: if (flags & F_AREG && (!(flags & F_VOL) || is_temporary_register (ap->preg))) { return ap; } break; case am_dreg: if (flags & F_DREG && (!(flags & F_VOL) || is_temporary_register (ap->preg))) { return ap; } break; case am_mreg: if (flags & F_DREG && (!(flags & F_VOL) || (is_temporary_register (ap->sreg) && is_temporary_register (ap->preg))) && (tp->size > 4L)) { return ap; } break; case am_xreg: if (flags & F_DREG && (!(flags & F_VOL) || (is_temporary_register (ap->u.xreg) && is_temporary_register (ap->sreg) && is_temporary_register (ap->preg)))) { return ap; } break; case am_ind: case am_indx: case am_indx2: case am_indx3: case am_indx4: case am_direct: case am_ainc: if (flags & F_MEM) { return ap; } break; case am_freg: if ((flags & F_FREG) && (!(flags & F_VOL) || is_temporary_register (ap->preg))) { return ap; } break; default: break; } if ((flags & (F_DREG | F_AREG)) == (F_DREG | F_AREG)) { /* decide, which mode is better */ if (ap->mode == am_immed) { if (is_byte (ap->u.offset)) { flags = (FLAGS) (flags & F_DREG); } else if (is_short (ap->u.offset) && ilen == IL4) { flags = (FLAGS) (flags & F_AREG); } } if (is_free_data () && (flags & F_DREG) && tp->type != bt_pointer32) { freeop (ap); /* maybe we can use it... */ ap2 = data_register (); /* allocate to dreg */ switch (ap->mode) {#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, ilen, ap, ap2); break;#endif /* FLOAT_IEEE */ case am_mreg: g_move (ilen, mk_high (ap), ap2); break; default: switch (ilen) { case IL8: g_code (op_move, IL4, mk_high (ap), ap2); break; default: g_move (ilen, ap, ap2); break; } } return ap2; } if (is_free_addr () && (flags & F_AREG)) { freeop (ap); ap2 = address_register (); g_move (ilen, ap, ap2); return ap2; } } if (flags & F_DREG) { freeop (ap); /* maybe we can use it... */ switch (ilen) { case IL1: case IL2: case IL4: ap2 = data_register (); /* allocate to dreg */ switch (ap->mode) {#ifdef FLOAT_IEEE case am_freg: g_fcode (op_fmove, ilen, ap, ap2); break;#endif /* FLOAT_IEEE */ case am_mreg: g_move (ilen, mk_high (ap), ap2); break; default: g_move (ilen, ap, ap2); break; } return ap2; case IL8: ap2 = mdata_register (); g_move8 (ap, ap2); return ap2; case IL12: ap2 = xdata_register (); g_move12 (ap, ap2); return ap2; default: break; } } if (flags & F_AREG) { if (ilen < IL2) { FATAL ( (__FILE__, "mk_legal", "illegal size %d --> An, mode=%d, flags=0x%x", ilen, ap->mode, (int) flags)); } else { freeop (ap); ap2 = address_register (); g_move (ilen, ap, ap2); return ap2; } }#ifdef FLOAT_IEEE if (flags & F_FREG) { freeop (ap); /* maybe we can use it... */ switch (tp->type) { case bt_float: case bt_double: case bt_longdouble: ap2 = float_register (); g_fcode (op_fmove, ilen, ap, ap2); return ap2; case bt_char: case bt_schar: case bt_short: case bt_int16: case bt_long: case bt_int32: ap2 = float_register (); g_code (op_fmove, ilen, ap, ap2); return ap2; default: break; } }#endif /* FLOAT_IEEE */ if (flags & F_MEM) { freeop (ap); ap2 = mk_scratch (tp->size); switch (tp->size) { case 1L: case 2L: case 4L: g_move (ilen, ap, ap2); break; case 8L: g_move8 (ap, ap2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -