📄 h8300.md
字号:
} case 3: return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; case 4: return \"mov.w %f1,%T0\;mov.w %e1,%T0\"; case 5: return \"mov.w %T1,%e0\;mov.w %T1,%f0\"; default: abort (); }}" [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])(define_insn "*movsi_h8300hs" [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r") (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))] "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode)) && !(GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG && GET_CODE (operands[1]) == REG && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))" "*{ switch (which_alternative) { case 0: return \"sub.l %S0,%S0\"; case 7: return \"clrmac\"; case 8: return \"clrmac\;ldmac %1,macl\"; case 9: return \"stmac macl,%0\"; default: if (GET_CODE (operands[1]) == CONST_INT) { int val = INTVAL (operands[1]); /* Look for constants which can be made by adding an 8-bit number to zero in one of the two low bytes. */ if (val == (val & 0xff)) { operands[1] = GEN_INT ((char) val & 0xff); return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\"; } if (val == (val & 0xff00)) { operands[1] = GEN_INT ((char) (val >> 8) & 0xff); return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\"; } /* Look for constants that can be obtained by subs, inc, and dec to 0. */ switch (val & 0xffffffff) { case 0xffffffff: return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\"; case 0xfffffffe: return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\"; case 0xfffffffc: return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\"; case 0x0000ffff: return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\"; case 0x0000fffe: return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\"; case 0xffff0000: return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\"; case 0xfffe0000: return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\"; case 0x00010000: return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\"; case 0x00020000: return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\"; } } } return \"mov.l %S1,%S0\";}" [(set (attr "length") (symbol_ref "compute_mov_length (operands)")) (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])(define_insn "*movsi_h8sx" [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r") (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))] "TARGET_H8300SX" "@ sub.l %S0,%S0 mov.l %S1,%S0 mov.l %S1,%S0 mov.l %S1,%S0 clrmac clrmac\;ldmac %1,macl stmac macl,%0" [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*") (set_attr "length" "2,2,*,*,2,6,4") (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])(define_insn "*movsf_h8sx" [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ") (match_operand:SF 1 "general_operand_src" "G,rQi"))] "TARGET_H8300SX" "@ sub.l %S0,%S0 mov.l %S1,%S0" [(set_attr "length" "2,*") (set_attr "length_table" "*,movl") (set_attr "cc" "set_zn,set_znv")]);; Implement block moves using movmd. Defining movmemsi allows the full;; range of constant lengths (up to 0x40000 bytes when using movmd.l).;; See h8sx_emit_movmd for details.(define_expand "movmemsi" [(use (match_operand:BLK 0 "memory_operand" "")) (use (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:SI 2 "" "")) (use (match_operand:SI 3 "const_int_operand" ""))] "TARGET_H8300SX" { if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3]))) DONE; else FAIL; });; Expander for generating movmd insns. Operand 0 is the destination;; memory region, operand 1 is the source, operand 2 is the counter;; register and operand 3 is the chunk size (1, 2 or 4).(define_expand "movmd" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (unspec [(match_operand:HI 2 "register_operand" "") (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD) (clobber (match_dup 4)) (clobber (match_dup 5)) (set (match_dup 2) (const_int 0))])] "TARGET_H8300SX" { operands[4] = copy_rtx (XEXP (operands[0], 0)); operands[5] = copy_rtx (XEXP (operands[1], 0)); });; This is a difficult instruction to reload since operand 0 must be the;; frame pointer. See h8300_reg_class_from_letter for an explanation.(define_insn "movmd_internal_normal" [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r")) (mem:BLK (match_operand:HI 4 "register_operand" "1,1"))) (unspec [(match_operand:HI 5 "register_operand" "2,2") (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD) (clobber (match_operand:HI 0 "register_operand" "=d,??D")) (clobber (match_operand:HI 1 "register_operand" "=f,f")) (set (match_operand:HI 2 "register_operand" "=c,c") (const_int 0))] "TARGET_H8300SX && TARGET_NORMAL_MODE" "@ movmd%m6 #" [(set_attr "length" "2,14") (set_attr "can_delay" "no") (set_attr "cc" "none,clobber")])(define_insn "movmd_internal" [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r")) (mem:BLK (match_operand:SI 4 "register_operand" "1,1"))) (unspec [(match_operand:HI 5 "register_operand" "2,2") (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD) (clobber (match_operand:SI 0 "register_operand" "=d,??D")) (clobber (match_operand:SI 1 "register_operand" "=f,f")) (set (match_operand:HI 2 "register_operand" "=c,c") (const_int 0))] "TARGET_H8300SX && !TARGET_NORMAL_MODE" "@ movmd%m6 #" [(set_attr "length" "2,14") (set_attr "can_delay" "no") (set_attr "cc" "none,clobber")]);; Split the above instruction if the destination register isn't er6.;; We need a sequence like:;;;; mov.l er6,@-er7;; mov.l <dest>,er6;; movmd.sz;; mov.l er6,<dest>;; mov.l @er7+,er6;;;; where <dest> is the current destination register (operand 4).;; The fourth instruction will be deleted if <dest> dies here.(define_split [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (unspec [(match_operand:HI 2 "register_operand" "") (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD) (clobber (match_operand:HI 4 "register_operand" "")) (clobber (match_operand:HI 5 "register_operand" "")) (set (match_dup 2) (const_int 0))] "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed && REGNO (operands[4]) != DESTINATION_REG" [(const_int 0)] { rtx dest; h8300_swap_into_er6 (XEXP (operands[0], 0)); dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx); emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3])); h8300_swap_out_of_er6 (operands[4]); DONE; })(define_split [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (unspec [(match_operand:HI 2 "register_operand" "") (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD) (clobber (match_operand:SI 4 "register_operand" "")) (clobber (match_operand:SI 5 "register_operand" "")) (set (match_dup 2) (const_int 0))] "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed && REGNO (operands[4]) != DESTINATION_REG" [(const_int 0)] { rtx dest; h8300_swap_into_er6 (XEXP (operands[0], 0)); dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx); emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3])); h8300_swap_out_of_er6 (operands[4]); DONE; });; Expand a call to stpcpy() using movsd. Operand 0 should point to;; the final character, but movsd leaves it pointing to the character;; after that.(define_expand "movstr" [(use (match_operand 0 "register_operand" "")) (use (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:BLK 2 "memory_operand" ""))] "TARGET_H8300SX" { operands[1] = replace_equiv_address (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); operands[2] = replace_equiv_address (operands[2], copy_to_mode_reg (Pmode, XEXP (operands[2], 0))); emit_insn (gen_movsd (operands[1], operands[2], gen_reg_rtx (Pmode))); emit_insn (gen_add3_insn (operands[0], XEXP (operands[1], 0), constm1_rtx)); DONE; });; Expander for generating a movsd instruction. Operand 0 is the;; destination string, operand 1 is the source string and operand 2;; is a scratch register.(define_expand "movsd" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY)) (clobber (match_dup 3)) (clobber (match_dup 4)) (clobber (match_operand 2 "register_operand" ""))])] "TARGET_H8300SX" { operands[3] = copy_rtx (XEXP (operands[0], 0)); operands[4] = copy_rtx (XEXP (operands[1], 0)); });; See comments above memcpy_internal().(define_insn "stpcpy_internal_normal" [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r")) (unspec:BLK [(mem:BLK (match_operand:HI 4 "register_operand" "1,1"))] UNSPEC_STPCPY)) (clobber (match_operand:HI 0 "register_operand" "=d,??D")) (clobber (match_operand:HI 1 "register_operand" "=f,f")) (clobber (match_operand:HI 2 "register_operand" "=c,c"))] "TARGET_H8300SX && TARGET_NORMAL_MODE" "@ \n1:\tmovsd\t2f\;bra\t1b\n2: #" [(set_attr "length" "6,18") (set_attr "cc" "none,clobber")])(define_insn "stpcpy_internal" [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r")) (unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" "1,1"))] UNSPEC_STPCPY)) (clobber (match_operand:SI 0 "register_operand" "=d,??D")) (clobber (match_operand:SI 1 "register_operand" "=f,f")) (clobber (match_operand:SI 2 "register_operand" "=c,c"))] "TARGET_H8300SX && !TARGET_NORMAL_MODE" "@ \n1:\tmovsd\t2f\;bra\t1b\n2: #" [(set_attr "length" "6,18") (set_attr "cc" "none,clobber")]);; Split the above instruction if the destination isn't er6. This works;; in the same way as the movmd splitter.(define_split [(set (match_operand:BLK 0 "memory_operand" "") (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY)) (clobber (match_operand:HI 2 "register_operand" "")) (clobber (match_operand:HI 3 "register_operand" "")) (clobber (match_operand:HI 4 "register_operand" ""))] "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed && REGNO (operands[2]) != DESTINATION_REG" [(const_int 0)] { rtx dest; h8300_swap_into_er6 (XEXP (operands[0], 0)); dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx); emit_insn (gen_movsd (dest, operands[1], operands[4])); h8300_swap_out_of_er6 (operands[2]); DONE; })(define_split [(set (match_operand:BLK 0 "memory_operand" "") (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY)) (clobber (match_operand:SI 2 "register_operand" "")) (clobber (match_operand:SI 3 "register_operand" "")) (clobber (match_operand:SI 4 "register_operand" ""))] "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed && REGNO (operands[2]) != DESTINATION_REG" [(const_int 0)] { rtx dest; h8300_swap_into_er6 (XEXP (operands[0], 0)); dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx); emit_insn (gen_movsd (dest, operands[1], operands[4])); h8300_swap_out_of_er6 (operands[2]); DONE; })(include "mova.md")(define_expand "movsf" [(set (match_operand:SF 0 "general_operand_dst" "") (match_operand:SF 1 "general_operand_src" ""))] "" "{ if (TARGET_H8300) { if (h8300_expand_movsi (operands)) DONE; } else if (!TARGET_H8300SX) { /* One of the ops has to be in a register. */ if (!register_operand (operand1, SFmode) && !register_operand (operand0, SFmode)) { operands[1] = copy_to_mode_reg (SFmode, operand1); } }}")(define_insn "*movsf_h8300" [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))] "TARGET_H8300 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "*{ /* Copy of the movsi stuff. */ unsigned int rn = -1; switch (which_alternative) { case 0: return \"sub.w %e0,%e0\;sub.w %f0,%f0\"; case 1: if (REGNO (operands[0]) < REGNO (operands[1])) return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; else return \"mov.w %f1,%f0\;mov.w %e1,%e0\"; case 2: /* Make sure we don't trample the register we index with. */ if (GET_CODE (operands[1]) == MEM) { rtx inside = XEXP (operands[1], 0); if (REG_P (inside)) { rn = REGNO (inside); } else if (GET_CODE (inside) == PLUS) { rtx lhs = XEXP (inside, 0); rtx rhs = XEXP (inside, 1); if (REG_P (lhs)) rn = REGNO (lhs); if (REG_P (rhs)) rn = REGNO (rhs); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -