📄 sparc.md
字号:
[(reg 0) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] "" "*{ return output_cbranch (operands[0], 0, 1, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*inverted_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_op" [(reg 0) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] "" "*{ return output_cbranch (operands[0], 0, 1, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*normal_fp_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand:CCFP 1 "ccfp_reg_operand" "c") (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] "TARGET_V9" "*{ return output_cbranch (operands[0], operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*inverted_fp_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand:CCFP 1 "ccfp_reg_operand" "c") (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] "TARGET_V9" "*{ return output_cbranch (operands[0], operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*normal_fpe_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] "TARGET_V9" "*{ return output_cbranch (operands[0], operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*inverted_fpe_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] "TARGET_V9" "*{ return output_cbranch (operands[0], operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")]);; Sparc V9-specific jump insns. None of these are guaranteed to be;; in the architecture.;; There are no 32 bit brreg insns.(define_insn "*normal_int_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "v9_regcmp_op" [(match_operand:DI 1 "register_operand" "r") (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] "TARGET_V9" "*{ return output_v9branch (operands[0], 1, 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")])(define_insn "*inverted_int_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "v9_regcmp_op" [(match_operand:DI 1 "register_operand" "r") (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] "TARGET_V9" "*{ return output_v9branch (operands[0], 1, 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence);}" [(set_attr "type" "branch")]);; Esoteric move insns (lo_sum, high, pic).(define_insn "*lo_sum_si" [(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")))] "" ;; V9 needs "add" because of the code models. We still use "or" for v8 ;; so we can compare the old compiler with the new. "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". [(set_attr "length" "1")]);; For PIC, symbol_refs are put inside unspec so that the optimizer will not;; confuse them with real addresses.(define_insn "*pic_lo_sum_si" [(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")] 0)))] "" ;; V9 needs "add" because of the code models. We still use "or" for v8 ;; so we can compare the old compiler with the new. "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". [(set_attr "length" "1")]);; For PIC, symbol_refs are put inside unspec so that the optimizer will not;; confuse them with real addresses.(define_insn "*pic_sethi_si" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] "check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")])(define_insn "*sethi_si" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand 1 "" "")))] "check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")])(define_insn "*sethi_hi" [(set (match_operand:HI 0 "register_operand" "=r") (high:HI (match_operand 1 "" "")))] "check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")]);; Special pic pattern, for loading the address of a label into a register.;; It clobbers o7 because the call puts the return address (i.e. pc value);; there.(define_insn "*move_pic_label_si" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "move_pic_label" "i")) (set (reg:SI 15) (pc))] "" "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" [(set_attr "type" "multi") (set_attr "length" "4")]);; v9 special pic pattern, for loading the address of a label into a register.(define_insn "*move_pic_label_di" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "move_pic_label" "i")) (set (reg:DI 15) (pc))] "TARGET_V9" "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0" [(set_attr "type" "multi") (set_attr "length" "4")])(define_insn "*lo_sum_di_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "0") (match_operand:DI 2 "immediate_operand" "in")))] "! TARGET_V9" "*{ /* Don't output a 64 bit constant, since we can't trust the assembler to handle it correctly. */ if (GET_CODE (operands[2]) == CONST_DOUBLE) operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); return \"or %R1,%%lo(%a2),%R0\";}" ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". [(set_attr "length" "1")]);; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9.;; ??? The previous comment is obsolete.;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?(define_insn "*lo_sum_di_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (lo_sum:DI (match_operand:DI 1 "register_operand" "0") (match_operand:DI 2 "immediate_operand" "in")))] "TARGET_V9" "*{ /* Don't output a 64 bit constant, since we can't trust the assembler to handle it correctly. */ if (GET_CODE (operands[2]) == CONST_DOUBLE) operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); /* Note that we use add here. This is important because Medium/Anywhere code model support depends on it. */ return \"add %1,%%lo(%a2),%0\";}" ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". [(set_attr "length" "1")])(define_insn "*sethi_di_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "" "")))] "! TARGET_V9 && check_pic (1)" "*{ rtx op0 = operands[0]; rtx op1 = operands[1]; if (GET_CODE (op1) == CONST_INT) { operands[0] = operand_subword (op0, 1, 0, DImode); output_asm_insn (\"sethi %%hi(%a1),%0\", operands); operands[0] = operand_subword (op0, 0, 0, DImode); if (INTVAL (op1) < 0) return \"mov -1,%0\"; else return \"mov 0,%0\"; } else if (GET_CODE (op1) == CONST_DOUBLE) { operands[0] = operand_subword (op0, 1, 0, DImode); operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); output_asm_insn (\"sethi %%hi(%a1),%0\", operands); operands[0] = operand_subword (op0, 0, 0, DImode); operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); return singlemove_string (operands); } else abort (); return \"\";}" [(set_attr "type" "move") (set_attr "length" "2")]);;; ??? This pattern originally clobbered a scratch register. However, this;;; is invalid, the movdi pattern may not use a temp register because it;;; may be called from reload to reload a DImode value. In that case, we;;; end up with a scratch register that never gets allocated. To avoid this,;;; we use global register 1 which is never otherwise used by gcc as a temp.;;; The correct solution here might be to force DImode constants to memory,;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg;;; 1 will then no longer need to be considered a fixed reg.;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo;;; on constants. Symbols have to be handled by the linker, so we must use;;; %uhi and %ulo for them, but gas will handle these correctly.;;; ??? This comment is obsolete, gas handles them now.(define_insn "*sethi_di_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "const_double_operand" ""))) (clobber (reg:DI 1))] "TARGET_V9 && check_pic (1)" "*{ rtx high, low; split_double (operands[1], &high, &low); if (high == const0_rtx) { operands[1] = low; output_asm_insn (\"sethi %%hi(%a1),%0\", operands); } else { operands[1] = high; output_asm_insn (singlemove_string (operands), operands); operands[1] = low; output_asm_insn (\"sllx %0,32,%0\", operands); if (low != const0_rtx) output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands); } return \"\";}" [(set_attr "type" "move") (set_attr "length" "5")]);; Most of the required support for the various code models is here.;; We can do this because sparcs need the high insn to load the address. We;; just need to get high to do the right thing for each code model. Then each;; uses the same "%X+%lo(...)" in the load/store insn.;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are;; always 0.;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0.;; The data segment has a maximum size of 32 bits, but may be located anywhere.;; MEDANY_BASE_REG contains the start address, currently %g4.;; When TARGET_FULLANY, symbolic addresses are 64 bits.(define_insn "*sethi_di_medlow" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "" "")));; ??? Why the clobber? (clobber (reg:DI 1))] "TARGET_MEDLOW && check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")]);; WARNING: %0 gets %hi(%1)+%g4.;; You cannot OR in %lo(%1), it must be added in.(define_insn "*sethi_di_medany_data" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "data_segment_operand" "")));; ??? Why the clobber? (clobber (reg:DI 1))] "TARGET_MEDANY && check_pic (1)" "sethi %%hi(%a1),%0; add %0,%%g4,%0" [(set_attr "type" "move") (set_attr "length" "2")])(define_insn "*sethi_di_medany_text" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "text_segment_operand" "")));; ??? Why the clobber? (clobber (reg:DI 1))] "TARGET_MEDANY && check_pic (1)" "sethi %%hi(%a1),%0" [(set_attr "type" "move") (set_attr "length" "1")])(define_insn "*sethi_di_fullany" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "" ""))) (clobber (reg:DI 1))] "TARGET_FULLANY && check_pic (1)" "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0" [(set_attr "type" "move") (set_attr "length" "5")]);; Move instructions(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, QImode)) DONE;}")(define_insn "*movqi_insn" [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] "register_operand (operands[0], QImode) || register_operand (operands[1], QImode) || operands[1] == const0_rtx" "@ mov %1,%0 sethi %%hi(%a1),%0 ldub %1,%0 stb %r1,%0" [(set_attr "type" "move,move,load,store") (set_attr "length" "*,1,*,1")])(define_insn "*lo_sum_qi" [(set (match_operand:QI 0 "register_operand" "=r") (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") (match_operand 2 "immediate_operand" "in")) 0))] "" "or %1,%%lo(%a2),%0" [(set_attr "length" "1")])(define_insn "*store_qi" [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -