📄 a29k.md
字号:
(define_expand "loadhi" [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (const_int -4)))) (set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_dup 1)))]) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 2) (const_int 16) (ashift:PSI (match_dup 3) (const_int 3))))] "" "")(define_expand "storehinhww" [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") (const_int -4)))) (set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_dup 0)))]) (set (zero_extract:SI (match_dup 2) (const_int 16) (ashift:PSI (match_dup 3) (const_int 3))) (match_operand:SI 1 "gpc_reg_operand" "")) (set (mem:SI (match_dup 0)) (match_dup 2))] "" "")(define_expand "storehihww" [(set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" ""))) (set (match_operand:SI 2 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535) (ashift:PSI (match_dup 3) (const_int 3)))) (match_operand:SI 1 "gpc_reg_operand" "")) (ashift:SI (zero_extend:SI (match_dup 4)) (ashift:PSI (match_dup 3) (const_int 3))))) (set (mem:SI (and:SI (match_dup 0) (const_int -3))) (match_dup 2))] "" "{ operands[4] = gen_lowpart (HImode, operands[1]); }")(define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) { if (! gpc_reg_operand (operands[1], HImode)) operands[1] = copy_to_mode_reg (HImode, operands[1]); if (! TARGET_DW_ENABLE) { rtx general = gen_reg_rtx (SImode); rtx bp = gen_reg_rtx (PSImode); rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww; rtx seq = (*fcn) (XEXP (operands[0], 0), gen_lowpart (SImode, operands[1]), general, bp); a29k_set_memflags (seq, operands[0]); emit_insn (seq); DONE; } } else if (GET_CODE (operands[1]) == MEM) { if (! TARGET_DW_ENABLE) { rtx general = gen_reg_rtx (SImode); rtx bp = gen_reg_rtx (PSImode); rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]), XEXP (operands[1], 0), general, bp); a29k_set_memflags (seq, operands[1]); emit_insn (seq); DONE; } }}")(define_expand "reload_inhi" [(parallel [(match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "reload_memory_operand" "m") (match_operand:PSI 2 "register_operand" "=b")])] "! TARGET_DW_ENABLE" "{ rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]), a29k_get_reloaded_address (operands[1]), gen_rtx (REG, SImode, R_TAV), operands[2]); a29k_set_memflags (seq, operands[1]); emit_insn (seq); DONE;}")(define_expand "reload_outhi" [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m") (match_operand:SI 1 "register_operand" "m") (match_operand:PSI 2 "register_operand" "=b")])] "! TARGET_DW_ENABLE" "{ rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww; rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]), gen_lowpart (SImode, operands[1]), gen_rtx (REG, SImode, R_TAV), operands[2]); a29k_set_memflags (seq, operands[0]); emit_insn (seq); DONE;}");; Subroutines to load/store bytes. Operands 0 and 1 are the output and;; input, respectively, except that the address is passed for a MEM instead ;; of the MEM itself and the short item is passed in QImode.;;;; Operand 2 is a scratch general register and operand 3 is a scratch register;; used for BP. When called before reload, pseudos are passed for both;; operands. During reload, R_TAV is used for the general register, and;; a reload register of class BR_REGS (R_VP) for BP.;;;; We have two versions of the store operations, for when byte writes are;; supported and when they are not.(define_expand "loadqi" [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (const_int -4)))) (set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_dup 1)))]) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 2) (const_int 8) (ashift:PSI (match_dup 3) (const_int 3))))] "" "")(define_expand "storeqinhww" [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") (const_int -4)))) (set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_dup 0)))]) (set (zero_extract:SI (match_dup 2) (const_int 8) (ashift:PSI (match_dup 3) (const_int 3))) (match_operand:SI 1 "gpc_reg_operand" "")) (set (mem:SI (match_dup 0)) (match_dup 2))] "" "")(define_expand "storeqihww" [(set (match_operand:PSI 3 "register_operand" "") (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" ""))) (set (match_operand:SI 2 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (ashift:SI (const_int 255) (ashift:PSI (match_dup 3) (const_int 3)))) (match_operand:SI 1 "gpc_reg_operand" "")) (ashift:SI (zero_extend:SI (match_dup 4)) (ashift:PSI (match_dup 3) (const_int 3))))) (set (mem:SI (and:SI (match_dup 0) (const_int -4))) (match_dup 2))] "" "{ operands[4] = gen_lowpart (QImode, operands[1]); }")(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) { if (! gpc_reg_operand (operands[1], QImode)) operands[1] = copy_to_mode_reg (QImode, operands[1]); if (! TARGET_DW_ENABLE) { rtx general = gen_reg_rtx (SImode); rtx bp = gen_reg_rtx (PSImode); rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww; rtx seq = (*fcn) (XEXP (operands[0], 0), gen_lowpart (SImode, operands[1]), general, bp); a29k_set_memflags (seq, operands[0]); emit_insn (seq); DONE; } } else if (GET_CODE (operands[1]) == MEM) { if (! TARGET_DW_ENABLE) { rtx general = gen_reg_rtx (SImode); rtx bp = gen_reg_rtx (PSImode); rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), XEXP (operands[1], 0), general, bp); a29k_set_memflags (seq, operands[1]); emit_insn (seq); DONE; } }}")(define_expand "reload_inqi" [(parallel [(match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "reload_memory_operand" "m") (match_operand:PSI 2 "register_operand" "=b")])] "! TARGET_DW_ENABLE" "{ rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), a29k_get_reloaded_address (operands[1]), gen_rtx (REG, SImode, R_TAV), operands[2]); a29k_set_memflags (seq, operands[1]); emit_insn (seq); DONE;}")(define_expand "reload_outqi" [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m") (match_operand:SI 1 "register_operand" "m") (match_operand:PSI 2 "register_operand" "=b")])] "! TARGET_DW_ENABLE" "{ rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww; rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]), gen_lowpart (SImode, operands[1]), gen_rtx (REG, SImode, R_TAV), operands[2]); a29k_set_memflags (seq, operands[0]); emit_insn (seq); DONE;}");; Now the actual insns used to move data around. We include here the;; DEFINE_SPLITs that may be needed. In some cases these will be;; split again. For floating-point, if we can look inside the constant,;; always split it. This can eliminate unnecessary insns.(define_insn "" [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m") (match_operand:SF 1 "in_operand" "r,E,F,m,r"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && ! TARGET_29050" "@ sll %0,%1,0 # const %0,%1\;consth %0,%1 load 0,0,%0,%1 store 0,0,%1,%0" [(set_attr "type" "misc,multi,multi,load,store")])(define_insn "" [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m,*a,r") (match_operand:SF 1 "in_operand" "r,E,F,m,r,r,*a"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && TARGET_29050" "@ sll %0,%1,0 # const %0,%1\;consth %0,%1 load 0,0,%0,%1 store 0,0,%1,%0 mtacc %1,1,%0 mfacc %0,1,%1" [(set_attr "type" "misc,multi,multi,load,store,fadd,fadd")]);; Turn this into SImode. It will then be split up that way.(define_split [(set (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "float_const_operand" ""))] "HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT" [(set (match_dup 0) (match_dup 1))] "{ operands[0] = operand_subword (operands[0], 0, 0, SFmode); operands[1] = operand_subword (operands[1], 0, 0, SFmode); if (operands[0] == 0 || operands[1] == 0) FAIL;}")(define_insn "" [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m") (match_operand:DF 1 "in_operand" "rE,F,m,r")) (clobber (match_scratch:PSI 2 "=X,X,&c,&c"))] "(gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode)) && ! TARGET_29050" "@ # const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1 mtsrim cr,1\;loadm 0,0,%0,%1 mtsrim cr,1\;storem 0,0,%1,%0" [(set_attr "type" "multi")])(define_insn "" [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m,?*a,?r") (match_operand:DF 1 "in_operand" "rE,F,m,r,r,*a")) (clobber (match_scratch:PSI 2 "=X,X,&c,&c,X,X"))] "(gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode)) && TARGET_29050" "@ # const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1 mtsrim cr,1\;loadm 0,0,%0,%1 mtsrim cr,1\;storem 0,0,%1,%0 mtacc %1,2,%0 mfacc %0,2,%1" [(set_attr "type" "multi,multi,multi,multi,fadd,fadd")]);; Split register-register copies and constant loads into two SImode loads,;; one for each word. In the constant case, they will get further split.;; Don't so this until register allocation, though, since it will;; interfere with register allocation. Normally copy the lowest-addressed;; word first; the exception is if we are copying register to register and;; the lowest register of the first operand is the highest register of the;; second operand.(define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") (match_operand:DF 1 "gpc_reg_or_float_constant_operand" "")) (clobber (match_scratch:PSI 2 ""))] "reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 5) (match_dup 6))] "{ if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1]) + 1) { operands[3] = operand_subword (operands[0], 1, 1, DFmode); operands[4] = operand_subword (operands[1], 1, 1, DFmode); operands[5] = operand_subword (operands[0], 0, 1, DFmode); operands[6] = operand_subword (operands[1], 0, 1, DFmode); } else { operands[3] = operand_subword (operands[0], 0, 1, DFmode); operands[4] = operand_subword (operands[1], 0, 1, DFmode); operands[5] = operand_subword (operands[0], 1, 1, DFmode); operands[6] = operand_subword (operands[1], 1, 1, DFmode); } if (operands[3] == 0 || operands[4] == 0 || operands[5] == 0 || operands[6] == 0) FAIL;}");; Split memory loads and stores into the MTSR and LOADM/STOREM.(define_split [(set (match_operand:DF 0 "out_operand" "") (match_operand:DF 1 "in_operand" "")) (clobber (reg:PSI 179))] "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], DFmode) || memory_operand (operands[1], DFmode))" [(set (reg:PSI 179) (const_int 1)) (parallel [(set (match_dup 0) (match_dup 1)) (use (reg:PSI 179)) (clobber (reg:PSI 179))])] "");; DI move is similar to DF move.(define_insn "" [(set (match_operand:DI 0 "out_operand" "=?r,r,m") (match_operand:DI 1 "in_operand" "rn,m,r")) (clobber (match_scratch:PSI 2 "=X,&c,&c"))] "(gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode))" "@ # mtsrim cr,1\;loadm 0,0,%0,%1 mtsrim cr,1\;storem 0,0,%1,%0" [(set_attr "type" "multi")])(define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (match_operand:DI 1 "gpc_reg_or_integer_constant_operand" "")) (clobber (match_scratch:PSI 2 ""))] "reload_completed" [(set (match_dup 3) (match_dup 4)) (set (match_dup 5) (match_dup 6))] "{ if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1]) + 1) { operands[3] = operand_subword (operands[0], 1, 1, DImode); operands[4] = operand_subword (operands[1], 1, 1, DImode); operands[5] = operand_subword (operands[0], 0, 1, DImode); operands[6] = operand_subword (operands[1], 0, 1, DImode); } else { operands[3] = operand_subword (operands[0], 0, 1, DImode); operands[4] = operand_subword (operands[1], 0, 1, DImode); operands[5] = operand_subword (operands[0], 1, 1, DImode); operands[6] = operand_subword (operands[1], 1, 1, DImode); }}")(define_split [(set (match_operand:DI 0 "out_operand" "") (match_operand:DI 1 "in_operand" "")) (clobber (reg:PSI 179))] "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], DImode) || memory_operand (operands[1], DImode))" [(set (reg:PSI 179) (const_int 1)) (parallel [(set (match_dup 0) (match_dup 1)) (use (reg:PSI 179)) (clobber (reg:PSI 179))])] "");; TImode moves are very si
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -