📄 m68k.c
字号:
{#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l (%Rsp)+,%0I0x%x\n", mask);#else asm_fprintf (stream, "\tmoveml %Rsp@+,%0I0x%x\n", mask);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tmovm.l -%d(%s),%0I0x%x\n", offset + fsize, reg_names[FRAME_POINTER_REGNUM], mask);#else asm_fprintf (stream, "\tmoveml %s@(-%d),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], offset + fsize, mask);#endif } } if (fmask) { if (big) {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm -%d(%s,%Ra1.l),%0I0x%x\n", foffset + fsize, reg_names[FRAME_POINTER_REGNUM], fmask);#else asm_fprintf (stream, "\tfmovem %s@(-%d,%Ra1:l),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], foffset + fsize, fmask);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm (%Rsp)+,%0I0x%x\n", fmask);#else asm_fprintf (stream, "\tfmovem %Rsp@+,%0I0x%x\n", fmask);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tfmovm -%d(%s),%0I0x%x\n", foffset + fsize, reg_names[FRAME_POINTER_REGNUM], fmask);#else asm_fprintf (stream, "\tfmovem %s@(-%d),%0I0x%x\n", reg_names[FRAME_POINTER_REGNUM], foffset + fsize, fmask);#endif } } if (fpoffset != 0) for (regno = 55; regno >= 24; regno--) if (m68k_save_reg (regno)) { if (big) {#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd -%d(%s,%Ra1.l), %s\n", fpoffset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %s@(-%d,%Ra1:l), %s\n", reg_names[FRAME_POINTER_REGNUM], fpoffset + fsize, reg_names[regno]);#endif } else if (restore_from_sp) {#ifdef MOTOROLA asm_fprintf (stream, "\tfpmovd (%Rsp)+,%s\n", reg_names[regno]);#else asm_fprintf (stream, "\tfpmoved %Rsp@+, %s\n", reg_names[regno]);#endif } else {#ifdef MOTOROLA fprintf (stream, "\tfpmovd -%d(%s), %s\n", fpoffset + fsize, reg_names[FRAME_POINTER_REGNUM], reg_names[regno]);#else fprintf (stream, "\tfpmoved %s@(-%d), %s\n", reg_names[FRAME_POINTER_REGNUM], fpoffset + fsize, reg_names[regno]);#endif } fpoffset -= 8; } if (frame_pointer_needed) fprintf (stream, "\tunlk %s\n", reg_names[FRAME_POINTER_REGNUM]); else if (fsize) {#ifndef NO_ADDSUB_Q if (fsize + 4 <= 8) { if (!TARGET_5200) {#ifdef MOTOROLA asm_fprintf (stream, "\taddq.w %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddqw %0I%d,%Rsp\n", fsize + 4);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\taddq.l %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddql %0I%d,%Rsp\n", fsize + 4);#endif } } else if (fsize + 4 <= 16 && TARGET_CPU32) { /* On the CPU32 it is faster to use two addqw instructions to add a small integer (8 < N <= 16) to a register. */ /* asm_fprintf() cannot handle %. */#ifdef MOTOROLA asm_fprintf (stream, "\taddq.w %0I8,%Rsp\n\taddq.w %0I%d,%Rsp\n", fsize + 4 - 8);#else asm_fprintf (stream, "\taddqw %0I8,%Rsp\n\taddqw %0I%d,%Rsp\n", fsize + 4 - 8);#endif } else#endif /* not NO_ADDSUB_Q */ if (fsize + 4 < 0x8000) { if (TARGET_68040) { /* asm_fprintf() cannot handle %. */#ifdef MOTOROLA asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);#endif } else {#ifdef MOTOROLA asm_fprintf (stream, "\tlea (%d,%Rsp),%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\tlea %Rsp@(%d),%Rsp\n", fsize + 4);#endif } } else { /* asm_fprintf() cannot handle %. */#ifdef MOTOROLA asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);#else asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);#endif } } if (current_function_calls_eh_return) {#ifdef MOTOROLA asm_fprintf (stream, "\tadd.l %Ra0,%Rsp\n");#else asm_fprintf (stream, "\taddl %Ra0,%Rsp\n");#endif } if (current_function_pops_args) asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args); else fprintf (stream, "\trts\n");}#endif /* !CRDS *//* Similar to general_operand, but exclude stack_pointer_rtx. */intnot_sp_operand (op, mode) register rtx op; enum machine_mode mode;{ return op != stack_pointer_rtx && nonimmediate_operand (op, mode);}/* Return TRUE if X is a valid comparison operator for the dbcc instruction. Note it rejects floating point comparison operators. (In the future we could use Fdbcc). It also rejects some comparisons when CC_NO_OVERFLOW is set. */ intvalid_dbcc_comparison_p (x, mode) rtx x; enum machine_mode mode ATTRIBUTE_UNUSED;{ switch (GET_CODE (x)) { case EQ: case NE: case GTU: case LTU: case GEU: case LEU: return 1; /* Reject some when CC_NO_OVERFLOW is set. This may be over conservative */ case GT: case LT: case GE: case LE: return ! (cc_prev_status.flags & CC_NO_OVERFLOW); default: return 0; }}/* Return nonzero if flags are currently in the 68881 flag register. */intflags_in_68881 (){ /* We could add support for these in the future */ return cc_status.flags & CC_IN_68881;}/* Output a dbCC; jCC sequence. Note we do not handle the floating point version of this sequence (Fdbcc). We also do not handle alternative conditions when CC_NO_OVERFLOW is set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will kick those out before we get here. */voidoutput_dbcc_and_branch (operands) rtx *operands;{ switch (GET_CODE (operands[3])) { case EQ:#ifdef MOTOROLA output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);#else output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);#endif break; case NE:#ifdef MOTOROLA output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);#else output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);#endif break; case GT:#ifdef MOTOROLA output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);#else output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);#endif break; case GTU:#ifdef MOTOROLA output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);#else output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);#endif break; case LT:#ifdef MOTOROLA output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);#else output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);#endif break; case LTU:#ifdef MOTOROLA output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);#else output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);#endif break; case GE:#ifdef MOTOROLA output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);#else output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);#endif break; case GEU:#ifdef MOTOROLA output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);#else output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);#endif break; case LE:#ifdef MOTOROLA output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);#else output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);#endif break; case LEU:#ifdef MOTOROLA output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);#else output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);#endif break; default: abort (); } /* If the decrement is to be done in SImode, then we have to compensate for the fact that dbcc decrements in HImode. */ switch (GET_MODE (operands[0])) { case SImode:#ifdef MOTOROLA output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);#else output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);#endif break; case HImode: break; default: abort (); }}const char *output_scc_di(op, operand1, operand2, dest) rtx op; rtx operand1; rtx operand2; rtx dest;{ rtx loperands[7]; enum rtx_code op_code = GET_CODE (op); /* This does not produce a useful cc. */ CC_STATUS_INIT; /* The m68k cmp.l instruction requires operand1 to be a reg as used below. Swap the operands and change the op if these requirements are not fulfilled. */ if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG) { rtx tmp = operand1; operand1 = operand2; operand2 = tmp; op_code = swap_condition (op_code); } loperands[0] = operand1; if (GET_CODE (operand1) == REG) loperands[1] = gen_rtx_REG (SImode, REGNO (operand1) + 1); else loperands[1] = adjust_address (operand1, SImode, 4); if (operand2 != const0_rtx) { loperands[2] = operand2; if (GET_CODE (operand2) == REG) loperands[3] = gen_rtx_REG (SImode, REGNO (operand2) + 1); else loperands[3] = adjust_address (operand2, SImode, 4); } loperands[4] = gen_label_rtx(); if (operand2 != const0_rtx) {#ifdef MOTOROLA#ifdef SGS_CMP_ORDER output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);#else output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);#endif#else#ifdef SGS_CMP_ORDER output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);#else output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);#endif#endif } else { if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[0])) output_asm_insn ("tst%.l %0", loperands); else {#ifdef SGS_CMP_ORDER output_asm_insn ("cmp%.w %0,%#0", loperands);#else output_asm_insn ("cmp%.w %#0,%0", loperands);#endif }#ifdef MOTOROLA output_asm_insn ("jbne %l4", loperands);#else output_asm_insn ("jne %l4", loperands);#endif if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (loperands[1])) output_asm_insn ("tst%.l %1", loperands); else {#ifdef SGS_CMP_ORDER output_asm_insn ("cmp%.w %1,%#0", loperands);#else output_asm_insn ("cmp%.w %#0,%1", loperands);#endif } } loperands[5] = dest; switch (op_code) { case EQ: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (loperands[4])); output_asm_insn ("seq %5", loperands); break; case NE: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (loperands[4])); output_asm_insn ("sne %5", loperands); break; case GT: loperands[6] = gen_label_rtx();#ifdef MOTOROLA output_asm_insn ("shi %5\n\tjbra %l6", loperands);#else output_asm_insn ("shi %5\n\tjra %l6", loperands);#endif ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (loperands[4])); output_asm_insn ("sgt %5", loperands); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (loperands[6])); break; case GTU: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (loperands[4])); output_asm_insn ("shi %5", loperands); break; case LT: loperands[6] = gen_label_rtx();#ifdef MOTOROLA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -