📄 ia64.md
字号:
;; ??? This causes us to lose REG_LABEL notes, because the insn splitter;; does not attempt to preserve any REG_NOTES on the input instruction.(define_insn_and_split "movdi_symbolic" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "symbolic_operand" "s")) (clobber (match_operand:DI 2 "register_operand" "+r")) (use (reg:DI 1))] "" "* abort ();" "" [(const_int 0)] "ia64_expand_load_address (operands[0], operands[1], operands[2]); DONE;")(define_insn "*movdi_internal" [(set (match_operand:DI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") (match_operand:DI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] "ia64_move_ok (operands[0], operands[1])" "*{ static const char * const alt[] = { \"%,mov %0 = %r1\", \"%,addl %0 = %1, r0\", \"%,movl %0 = %1\", \"%,ld8%O1 %0 = %1%P1\", \"%,st8%Q0 %0 = %r1%P0\", \"%,getf.sig %0 = %1\", \"%,setf.sig %0 = %r1\", \"%,mov %0 = %1\", \"%,ldf8 %0 = %1%P1\", \"%,stf8 %0 = %1%P0\", \"%,mov %0 = %1\", \"%,mov %0 = %r1\", \"%,mov %0 = %1\", \"%,mov %0 = %1\", \"%,mov %0 = %1\", \"%,mov %0 = %1\", \"mov %0 = pr\", \"mov pr = %1, -1\" }; if (which_alternative == 2 && ! TARGET_NO_PIC && symbolic_operand (operands[1], VOIDmode)) abort (); return alt[which_alternative];}" [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")])(define_split [(set (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "symbolic_operand" ""))] "reload_completed && ! TARGET_NO_PIC" [(const_int 0)] "{ ia64_expand_load_address (operands[0], operands[1], NULL_RTX); DONE;}")(define_expand "load_fptr" [(set (match_dup 2) (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" ""))) (set (match_operand:DI 0 "register_operand" "") (match_dup 3))] "" "{ operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); operands[3] = gen_rtx_MEM (DImode, operands[2]); RTX_UNCHANGING_P (operands[3]) = 1;}")(define_insn "*load_fptr_internal1" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))] "" "addl %0 = @ltoff(@fptr(%1)), gp" [(set_attr "itanium_class" "ialu")])(define_insn "load_gprel" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))] "" "addl %0 = @gprel(%1), gp" [(set_attr "itanium_class" "ialu")])(define_insn "gprel64_offset" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] "" "movl %0 = @gprel(%1)" [(set_attr "itanium_class" "long_i")])(define_expand "load_gprel64" [(set (match_dup 2) (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3))) (set (match_operand:DI 0 "register_operand" "") (plus:DI (match_dup 3) (match_dup 2)))] "" "{ operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); operands[3] = pic_offset_table_rtx;}")(define_expand "load_symptr" [(set (match_operand:DI 2 "register_operand" "") (plus:DI (match_dup 4) (match_operand:DI 1 "got_symbolic_operand" ""))) (set (match_operand:DI 0 "register_operand" "") (match_dup 3))] "" "{ operands[3] = gen_rtx_MEM (DImode, operands[2]); operands[4] = pic_offset_table_rtx; RTX_UNCHANGING_P (operands[3]) = 1;}")(define_insn "*load_symptr_internal1" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))] "" "addl %0 = @ltoff(%1), gp" [(set_attr "itanium_class" "ialu")]);; With no offsettable memory references, we've got to have a scratch;; around to play with the second word.(define_expand "movti" [(parallel [(set (match_operand:TI 0 "general_operand" "") (match_operand:TI 1 "general_operand" "")) (clobber (match_scratch:DI 2 ""))])] "" "{ if (! reload_in_progress && ! reload_completed && ! ia64_move_ok (operands[0], operands[1])) operands[1] = force_reg (TImode, operands[1]);}")(define_insn_and_split "*movti_internal" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") (match_operand:TI 1 "general_operand" "ri,m,r")) (clobber (match_scratch:DI 2 "=X,&r,&r"))] "ia64_move_ok (operands[0], operands[1])" "#" "reload_completed" [(const_int 0)] "{ rtx adj1, adj2, in[2], out[2], insn; int first; adj1 = ia64_split_timode (in, operands[1], operands[2]); adj2 = ia64_split_timode (out, operands[0], operands[2]); first = 0; if (reg_overlap_mentioned_p (out[0], in[1])) { if (reg_overlap_mentioned_p (out[1], in[0])) abort (); first = 1; } if (adj1 && adj2) abort (); if (adj1) emit_insn (adj1); if (adj2) emit_insn (adj2); insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); if (GET_CODE (out[first]) == MEM && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY) REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (out[first], 0), 0), REG_NOTES (insn)); insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); if (GET_CODE (out[!first]) == MEM && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY) REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (out[!first], 0), 0), REG_NOTES (insn)); DONE;}" [(set_attr "itanium_class" "unknown") (set_attr "predicable" "no")]);; ??? SSA creates these. Can't allow memories since we don't have;; the scratch register. Fortunately combine will know how to add;; the clobber and scratch.(define_insn_and_split "*movti_internal_reg" [(set (match_operand:TI 0 "register_operand" "=r") (match_operand:TI 1 "nonmemory_operand" "ri"))] "" "#" "reload_completed" [(const_int 0)] "{ rtx in[2], out[2]; int first; ia64_split_timode (in, operands[1], NULL_RTX); ia64_split_timode (out, operands[0], NULL_RTX); first = 0; if (reg_overlap_mentioned_p (out[0], in[1])) { if (reg_overlap_mentioned_p (out[1], in[0])) abort (); first = 1; } emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); DONE;}" [(set_attr "itanium_class" "unknown") (set_attr "predicable" "no")])(define_expand "reload_inti" [(parallel [(set (match_operand:TI 0 "register_operand" "=r") (match_operand:TI 1 "" "m")) (clobber (match_operand:TI 2 "register_operand" "=&r"))])] "" "{ unsigned int s_regno = REGNO (operands[2]); if (s_regno == REGNO (operands[0])) s_regno += 1; operands[2] = gen_rtx_REG (DImode, s_regno);}")(define_expand "reload_outti" [(parallel [(set (match_operand:TI 0 "" "=m") (match_operand:TI 1 "register_operand" "r")) (clobber (match_operand:TI 2 "register_operand" "=&r"))])] "" "{ unsigned int s_regno = REGNO (operands[2]); if (s_regno == REGNO (operands[1])) s_regno += 1; operands[2] = gen_rtx_REG (DImode, s_regno);}");; Floating Point Moves;;;; Note - Patterns for SF mode moves are compulsory, but;; patterns for DF are optional, as GCC can synthesise them.(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] "" "{ if (! reload_in_progress && ! reload_completed && ! ia64_move_ok (operands[0], operands[1])) operands[1] = force_reg (SFmode, operands[1]);}")(define_insn "*movsf_internal" [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %F1 ldfs %0 = %1%P1 stfs %0 = %F1%P0 getf.s %0 = %F1 setf.s %0 = %1 mov %0 = %1 ld4%O1 %0 = %1%P1 st4%Q0 %0 = %1%P0" [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ if (! reload_in_progress && ! reload_completed && ! ia64_move_ok (operands[0], operands[1])) operands[1] = force_reg (DFmode, operands[1]);}")(define_insn "*movdf_internal" [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %F1 ldfd %0 = %1%P1 stfd %0 = %F1%P0 getf.d %0 = %F1 setf.d %0 = %1 mov %0 = %1 ld8%O1 %0 = %1%P1 st8%Q0 %0 = %1%P0" [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]);; With no offsettable memory references, we've got to have a scratch;; around to play with the second word if the variable winds up in GRs.(define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") (match_operand:TF 1 "general_operand" ""))] "INTEL_EXTENDED_IEEE_FORMAT" "{ /* We must support TFmode loads into general registers for stdarg/vararg and unprototyped calls. We split them into DImode loads for convenience. We don't need TFmode stores from general regs, because a stdarg/vararg routine does a block store to memory of unnamed arguments. */ if (GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))) { /* We're hoping to transform everything that deals with TFmode quantities and GR registers early in the compiler. */ if (no_new_pseudos) abort (); /* Struct to register can just use TImode instead. */ if ((GET_CODE (operands[1]) == SUBREG && GET_MODE (SUBREG_REG (operands[1])) == TImode) || (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1])))) { emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])), SUBREG_REG (operands[1])); DONE; } if (GET_CODE (operands[1]) == CONST_DOUBLE) { emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])), operand_subword (operands[1], 0, 0, TFmode)); emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1), operand_subword (operands[1], 1, 0, TFmode)); DONE; } /* If the quantity is in a register not known to be GR, spill it. */ if (register_operand (operands[1], TFmode)) operands[1] = spill_tfmode_operand (operands[1], 1); if (GET_CODE (operands[1]) == MEM) { rtx out[2]; out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])); out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1); emit_move_insn (out[0], adjust_address (operands[1], DImode, 0)); emit_move_insn (out[1], adjust_address (operands[1], DImode, 8)); DONE; } abort (); } if (! reload_in_progress && ! reload_completed) { operands[0] = spill_tfmode_operand (operands[0], 0); operands[1] = spill_tfmode_operand (operands[1], 0); if (! ia64_move_ok (operands[0], operands[1])) operands[1] = force_reg (TFmode, operands[1]); }}");; ??? There's no easy way to mind volatile acquire/release semantics.(define_insn "*movtf_internal" [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m") (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))] "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %F1 ldfe %0 = %1%P1 stfe %0 = %F1%P0" [(set_attr "itanium_class" "fmisc,fld,stf")]);; ::::::::::::::::::::;; ::
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -