📄 sparc.md
字号:
{ operands[0] = validize_mem (operands[0]); operands[1] = force_reg (HImode, operands[1]); } } /* Fixup TLS cases. */ if (tls_symbolic_operand (operands [1])) operands[1] = legitimize_tls_address (operands[1]); /* Fixup PIC cases. */ if (flag_pic) { if (CONSTANT_P (operands[1]) && pic_address_needs_scratch (operands[1])) operands[1] = legitimize_pic_address (operands[1], HImode, 0); if (symbolic_operand (operands[1], HImode)) { operands[1] = legitimize_pic_address (operands[1], HImode, (reload_in_progress ? operands[0] : NULL_RTX)); goto movhi_is_ok; } } /* This makes sure we will not get rematched due to splittage. */ if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode)) ; else if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM) { sparc_emit_set_const32 (operands[0], operands[1]); DONE; } movhi_is_ok: ;})(define_insn "*movhi_const64_special" [(set (match_operand:HI 0 "register_operand" "=r") (match_operand:HI 1 "const64_high_operand" ""))] "TARGET_ARCH64" "sethi\t%%hi(%a1), %0")(define_insn "*movhi_insn" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] "(register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode))" "@ mov\t%1, %0 sethi\t%%hi(%a1), %0 lduh\t%1, %0 sth\t%r1, %0" [(set_attr "type" "*,*,load,store") (set_attr "us3load_type" "*,*,3cycle,*")]);; We always work with constants here.(define_insn "*movhi_lo_sum" [(set (match_operand:HI 0 "register_operand" "=r") (ior:HI (match_operand:HI 1 "register_operand" "%r") (match_operand:HI 2 "small_int" "I")))] "" "or\t%1, %2, %0")(define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] ""{ /* Working with CONST_INTs is easier, so convert a double if needed. */ if (GET_CODE (operands[1]) == CONST_DOUBLE) operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); /* Handle sets of MEM first. */ if (GET_CODE (operands[0]) == MEM) { if (reg_or_0_operand (operands[1], SImode)) goto movsi_is_ok; if (! reload_in_progress) { operands[0] = validize_mem (operands[0]); operands[1] = force_reg (SImode, operands[1]); } } /* Fixup TLS cases. */ if (tls_symbolic_operand (operands [1])) operands[1] = legitimize_tls_address (operands[1]); /* Fixup PIC cases. */ if (flag_pic) { if (CONSTANT_P (operands[1]) && pic_address_needs_scratch (operands[1])) operands[1] = legitimize_pic_address (operands[1], SImode, 0); if (GET_CODE (operands[1]) == LABEL_REF) { /* shit */ emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1])); DONE; } if (symbolic_operand (operands[1], SImode)) { operands[1] = legitimize_pic_address (operands[1], SImode, (reload_in_progress ? operands[0] : NULL_RTX)); goto movsi_is_ok; } } /* If we are trying to toss an integer constant into the FPU registers, force it into memory. */ if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) >= SPARC_FIRST_FP_REG && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG && CONSTANT_P (operands[1])) operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), operands[1])); /* This makes sure we will not get rematched due to splittage. */ if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode)) ; else if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM) { sparc_emit_set_const32 (operands[0], operands[1]); DONE; } movsi_is_ok: ;});; This is needed to show CSE exactly which bits are set;; in a 64-bit register by sethi instructions.(define_insn "*movsi_const64_special" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "const64_high_operand" ""))] "TARGET_ARCH64" "sethi\t%%hi(%a1), %0")(define_insn "*movsi_insn" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d") (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))] "(register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ mov\t%1, %0 fmovs\t%1, %0 sethi\t%%hi(%a1), %0 clr\t%0 ld\t%1, %0 ld\t%1, %0 st\t%r1, %0 st\t%1, %0 fzeros\t%0" [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])(define_insn "*movsi_lo_sum" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "in")))] "" "or\t%1, %%lo(%a2), %0")(define_insn "*movsi_high" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "immediate_operand" "in")))] "" "sethi\t%%hi(%a1), %0");; The next two patterns must wrap the SYMBOL_REF in an UNSPEC;; so that CSE won't optimize the address computation away.(define_insn "movsi_lo_sum_pic" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] "flag_pic" "or\t%1, %%lo(%a2), %0")(define_insn "movsi_high_pic" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] "flag_pic && check_pic (1)" "sethi\t%%hi(%a1), %0")(define_expand "movsi_pic_label_ref" [(set (match_dup 3) (high:SI (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_dup 4) (lo_sum:SI (match_dup 3) (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) (set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_dup 5) (match_dup 4)))] "flag_pic"{ current_function_uses_pic_offset_table = 1; operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); if (no_new_pseudos) { operands[3] = operands[0]; operands[4] = operands[0]; } else { operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); } operands[5] = pic_offset_table_rtx;})(define_insn "*movsi_high_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "sethi\t%%hi(%a2-(%a1-.)), %0")(define_insn "*movsi_lo_sum_pic_label_ref" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] "flag_pic" "or\t%1, %%lo(%a3-(%a2-.)), %0")(define_expand "movdi" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") (match_operand:DI 1 "general_operand" ""))] ""{ /* Where possible, convert CONST_DOUBLE into a CONST_INT. */ if (GET_CODE (operands[1]) == CONST_DOUBLE#if HOST_BITS_PER_WIDE_INT == 32 && ((CONST_DOUBLE_HIGH (operands[1]) == 0 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))#endif ) operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); /* Handle MEM cases first. */ if (GET_CODE (operands[0]) == MEM) { /* If it's a REG, we can always do it. The const zero case is more complex, on v9 we can always perform it. */ if (register_operand (operands[1], DImode) || (TARGET_V9 && (operands[1] == const0_rtx))) goto movdi_is_ok; if (! reload_in_progress) { operands[0] = validize_mem (operands[0]); operands[1] = force_reg (DImode, operands[1]); } } /* Fixup TLS cases. */ if (tls_symbolic_operand (operands [1])) operands[1] = legitimize_tls_address (operands[1]); if (flag_pic) { if (CONSTANT_P (operands[1]) && pic_address_needs_scratch (operands[1])) operands[1] = legitimize_pic_address (operands[1], DImode, 0); if (GET_CODE (operands[1]) == LABEL_REF) { if (! TARGET_ARCH64) abort (); emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); DONE; } if (symbolic_operand (operands[1], DImode)) { operands[1] = legitimize_pic_address (operands[1], DImode, (reload_in_progress ? operands[0] : NULL_RTX)); goto movdi_is_ok; } } /* If we are trying to toss an integer constant into the FPU registers, force it into memory. */ if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) >= SPARC_FIRST_FP_REG && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG && CONSTANT_P (operands[1])) operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), operands[1])); /* This makes sure we will not get rematched due to splittage. */ if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode)) ; else if (TARGET_ARCH64 && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM) { sparc_emit_set_const64 (operands[0], operands[1]); DONE; } movdi_is_ok: ;});; Be careful, fmovd does not exist when !v9.;; We match MEM moves directly when we have correct even;; numbered registers, but fall into splits otherwise.;; The constraint ordering here is really important to;; avoid insane problems in reload, especially for patterns;; of the form:;;;; (set (mem:DI (plus:SI (reg:SI 30 %fp);; (const_int -5016)));; (reg:DI 2 %g2));;(define_insn "*movdi_insn_sp32_v9" [(set (match_operand:DI 0 "nonimmediate_operand" "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W") (match_operand:DI 1 "input_operand" " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))] "! TARGET_ARCH64 && TARGET_V9 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" "@ stx\t%%g0, %0 # std\t%1, %0 ldd\t%1, %0 # # # # std\t%1, %0 ldd\t%1, %0 # # fmovd\\t%1, %0 ldd\\t%1, %0 std\\t%1, %0" [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore") (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*") (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])(define_insn "*movdi_insn_sp32" [(set (match_operand:DI 0 "nonimmediate_operand" "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f") (match_operand:DI 1 "input_operand" " J,U,T,r,o,i,r, f, T, o, f, f"))] "! TARGET_ARCH64 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" "@ # std\t%1, %0 ldd\t%1, %0 # # # # std\t%1, %0 ldd\t%1, %0 # # #" [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*") (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")]);; The following are generated by sparc_emit_set_const64(define_insn "*movdi_sp64_dbl" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "const64_operand" ""))] "(TARGET_ARCH64 && HOST_BITS_PER_WIDE_INT != 64)" "mov\t%1, %0");; This is needed to show CSE exactly which bits are set;; in a 64-bit register by sethi instructions.(define_insn "*movdi_const64_special" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "const64_high_operand" ""))] "TARGET_ARCH64" "sethi\t%%hi(%a1), %0")(define_insn "*movdi_insn_sp64_novis" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W") (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))] "TARGET_ARCH64 && ! TARGET_VIS && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" "@ mov\t%1, %0 sethi\t%%hi(%a1), %0 clr\t%0 ldx\t%1, %0 stx\t%r1, %0 fmovd\t%1, %0 ldd\t%1, %0 std\t%1, %0" [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore") (set_attr "fptype" "*,*,*,*,*,double,*,*")])(define_insn "*movdi_insn_sp64_vis" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b") (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))] "TARGET_ARCH64 && TARGET_VIS && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" "@ mov\t%1, %0 sethi\t%%hi(%a1), %0 clr\t%0 ldx\t%1, %0 stx\t%r1, %0 fmovd\t%1, %0 ldd\t%1, %0 std\t%1, %0 fzero\t%0" [(set_attr "type" "*,*,*,load
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -