📄 m68k.md
字号:
This isn't so on the 68010, but we have no alternative for it. */ && (TARGET_68020 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) return \"clr%.l %0\"; else if (DATA_REG_P (operands[0])) return output_move_const_into_data_reg (operands); else if (ADDRESS_REG_P (operands[0]) && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"move%.w %1,%0\"; else if (push_operand (operands[0], SImode) && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"pea %a1\"; } else if ((GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) && push_operand (operands[0], SImode)) return \"pea %a1\"; else if ((GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST) && ADDRESS_REG_P (operands[0])) return \"lea %a1,%0\"; return \"move%.l %1,%0\";}")(define_insn "movhi" [(set (match_operand:HI 0 "general_operand" "=g") (match_operand:HI 1 "general_operand" "g"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { if (operands[1] == const0_rtx && (DATA_REG_P (operands[0]) || GET_CODE (operands[0]) == MEM) /* clr insns on 68000 read before writing. This isn't so on the 68010, but we have no alternative for it. */ && (TARGET_68020 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) return \"clr%.w %0\"; else if (DATA_REG_P (operands[0]) && INTVAL (operands[1]) < 128 && INTVAL (operands[1]) >= -128) {#if defined(MOTOROLA) && !defined(CRDS) return \"moveq%.l %1,%0\";#else return \"moveq %1,%0\";#endif } else if (INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) return \"move%.w %1,%0\"; } else if (CONSTANT_P (operands[1])) return \"move%.l %1,%0\";#ifndef SGS_NO_LI /* Recognize the insn before a tablejump, one that refers to a table of offsets. Such an insn will need to refer to a label on the insn. So output one. Use the label-number of the table of offsets to generate this label. This code, and similar code below, assumes that there will be at most one reference to each table. */ if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) == PLUS && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS) { rtx labelref = XEXP (XEXP (operands[1], 0), 1);#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)#ifdef SGS asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\", CODE_LABEL_NUMBER (XEXP (labelref, 0)));#else /* not SGS */ asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\", CODE_LABEL_NUMBER (XEXP (labelref, 0)));#endif /* not SGS */#else /* SGS_SWITCH_TABLES or not MOTOROLA */ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", CODE_LABEL_NUMBER (XEXP (labelref, 0)));#ifdef SGS_SWITCH_TABLES /* Set flag saying we need to define the symbol LD%n (with value L%n-LI%n) at the end of the switch table. */ switch_table_difference_label_flag = 1;#endif /* SGS_SWITCH_TABLES */#endif /* SGS_SWITCH_TABLES or not MOTOROLA */ }#endif /* SGS_NO_LI */ return \"move%.w %1,%0\";}")(define_insn "movstricthi" [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm")) (match_operand:HI 1 "general_operand" "rmn"))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) { if (operands[1] == const0_rtx && (DATA_REG_P (operands[0]) || GET_CODE (operands[0]) == MEM) /* clr insns on 68000 read before writing. This isn't so on the 68010, but we have no alternative for it. */ && (TARGET_68020 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) return \"clr%.w %0\"; } return \"move%.w %1,%0\";}")(define_insn "movqi" [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a") (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))] "" "*{ rtx xoperands[4]; /* This is probably useless, since it loses for pushing a struct of several bytes a byte at a time. */ if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx && ! ADDRESS_REG_P (operands[1])) { xoperands[1] = operands[1]; xoperands[2] = gen_rtx (MEM, QImode, gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx)); /* Just pushing a byte puts it in the high byte of the halfword. */ /* We must put it in the low-order, high-numbered byte. */ output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands); return \"\"; } /* Moving a byte into an address register is not possible. */ /* Use d0 as an intermediate, but don't clobber its contents. */ if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM) { /* ??? For 2.5, don't allow this choice and use secondary reloads instead. See if the address register is used in the address. If it is, we have to generate a more complex sequence than those below. */ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, operands[1], NULL_RTX)) { /* See if the stack pointer is used in the address. If it isn't, we can push d0 or d1 (the insn can't use both of them) on the stack, perform our move into d0/d1, copy the byte from d0/1, and pop d0/1. */ if (! reg_mentioned_p (stack_pointer_rtx, operands[1])) { if (! refers_to_regno_p (0, 1, operands[1], NULL_RTX)) return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\"; else return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\"; } else { /* Otherwise, we know that d0 cannot be used in the address (since sp and one address register is). Assume that sp is being used as a base register and replace the address register that is our operand[0] with d0. */ rtx reg_map[FIRST_PSEUDO_REGISTER]; int i; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) reg_map[i] = 0; reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0); operands[1] = copy_rtx (operands[1]); replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0); return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; } } /* If the address of operand 1 uses d0, choose d1 as intermediate. */ if (refers_to_regno_p (0, 1, operands[1], NULL_RTX)) return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\"; /* Otherwise d0 is usable. (An effective address on the 68k can't use two d-regs.) */ else return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\"; } /* Likewise for moving from an address reg. */ if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM) { /* ??? For 2.5, don't allow this choice and use secondary reloads instead. See if the address register is used in the address. If it is, we have to generate a more complex sequence than those below. */ if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1, operands[0], NULL_RTX)) { /* See if the stack pointer is used in the address. If it isn't, we can push d0 or d1 (the insn can't use both of them) on the stack, copy the byte to d0/1, perform our move from d0/d1, and pop d0/1. */ if (! reg_mentioned_p (stack_pointer_rtx, operands[0])) { if (! refers_to_regno_p (0, 1, operands[0], NULL_RTX)) return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\"; else return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\"; } else { /* Otherwise, we know that d0 cannot be used in the address (since sp and one address register is). Assume that sp is being used as a base register and replace the address register that is our operand[1] with d0. */ rtx reg_map[FIRST_PSEUDO_REGISTER]; int i; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) reg_map[i] = 0; reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0); operands[0] = copy_rtx (operands[0]); replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0); return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; } } if (refers_to_regno_p (0, 1, operands[0], NULL_RTX)) return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\"; else return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\"; } /* clr and st insns on 68000 read before writing. This isn't so on the 68010, but we have no alternative for it. */ if (TARGET_68020 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { if (operands[1] == const0_rtx) return \"clr%.b %0\"; if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == -1) { CC_STATUS_INIT; return \"st %0\"; } } if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1])) return \"move%.l %1,%0\"; if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1])) return \"move%.w %1,%0\"; return \"move%.b %1,%0\";}")(define_insn "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm")) (match_operand:QI 1 "general_operand" "dmn"))] "" "*{ if (operands[1] == const0_rtx /* clr insns on 68000 read before writing. This isn't so on the 68010, but we have no alternative for it. */ && (TARGET_68020 || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))) return \"clr%.b %0\"; return \"move%.b %1,%0\";}")(define_insn "movsf" [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm") (match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))]; [(set (match_operand:SF 0 "general_operand" "=rmf"); (match_operand:SF 1 "general_operand" "rmfF"))] "" "*{ if (which_alternative >= 4) return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\"; if (FPA_REG_P (operands[0])) { if (FPA_REG_P (operands[1])) return \"fpmove%.s %x1,%x0\"; else if (GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_single (operands); else if (FP_REG_P (operands[1])) return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\"; return \"fpmove%.s %x1,%x0\"; } if (FPA_REG_P (operands[1])) { if (FP_REG_P (operands[0])) return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\"; else return \"fpmove%.s %x1,%x0\"; } if (FP_REG_P (operands[0])) { if (FP_REG_P (operands[1])) return \"f%$move%.x %1,%0\"; else if (ADDRESS_REG_P (operands[1])) return \"move%.l %1,%-\;f%$move%.s %+,%0\"; else if (GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_single (operands); return \"f%$move%.s %f1,%0\"; } if (FP_REG_P (operands[1])) { if (ADDRESS_REG_P (operands[0])) return \"fmove%.s %1,%-\;move%.l %+,%0\"; return \"fmove%.s %f1,%0\"; } return \"move%.l %1,%0\";}")(define_insn "movdf" [(set (match_operand:DF 0 "general_operand" "=rm,rf,rf,&rof<>,y,rm,x,!x,!rm") (match_operand:DF 1 "general_operand" "rf,m,0,rofE<>,rmE,y,xH,rm,x"))]; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>"); (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))] "" "*{ if (which_alternative == 7) return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\"; if (FPA_REG_P (operands[0])) { if (GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_double (operands); if (FP_REG_P (operands[1])) return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\"; return \"fpmove%.d %x1,%x0\"; } else if (FPA_REG_P (operands[1])) { if (FP_REG_P(operands[0])) return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\"; else return \"fpmove%.d %x1,%x0\"; } if (FP_REG_P (operands[0])) { if (FP_REG_P (operands[1])) return \"f%&move%.x %1,%0\"; if (REG_P (operands[1])) { rtx xoperands[2]; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); output_asm_insn (\"move%.l %1,%-\", xoperands); output_asm_insn (\"move%.l %1,%-\", operands); return \"f%&move%.d %+,%0\"; } if (GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_double (operands); return \"f%&move%.d %f1,%0\"; } else if (FP_REG_P (operands[1])) { if (REG_P (operands[0])) { output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands); operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); return \"move%.l %+,%0\"; } else return \"fmove%.d %f1,%0\"; } return output_move_double (operands);}")(define_expand "movxf" [(set (match_operand:XF 0 "nonimmediate_operand" "") (match_operand:XF 1 "general_operand" ""))] "" "{ if (CONSTANT_P (operands[1])) { operands[1] = force_const_mem (XFmode, operands[1]); if (! memory_address_p (XFmode, XEXP (operands[1], 0)) && ! reload_in_progress) operands[1] = change_address (operands[1], XFmode, XEXP (operands[1], 0)); }}")(define_insn "" [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f") (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))] "TARGET_68881" "*{ if (FP_REG_P (operands[0])) { if (FP_REG_P (operands[1])) return \"fmove%.x %1,%0\"; if (REG_P (operands[1])) { rtx xoperands[2]; xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); output_asm_insn (\"move%.l %1,%-\", xoperands); xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); output_asm_insn (\"move%.l %1,%-\", xoperands);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -