diff options
author | claziss <claziss@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-25 11:15:58 +0000 |
---|---|---|
committer | claziss <claziss@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-25 11:15:58 +0000 |
commit | 7ce15a25e13f6fea156c366e813e156bff917b14 (patch) | |
tree | a518e7e353c9e58626c676f4a558352d9ee4df96 /gcc/config/arc/arc.md | |
parent | f34cae5b3e267951ba3ade328bf4dcd0e4d3e628 (diff) | |
download | gcc-7ce15a25e13f6fea156c366e813e156bff917b14.tar.gz |
[ARC] Add basic support for double load and store instructions
gcc/
2016-01-25 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.c (TARGET_DWARF_REGISTER_SPAN): Define.
(arc_init): Check validity mll64 option.
(arc_save_restore): Use double load/store instruction.
(arc_expand_movmem): Likewise.
(arc_split_move): Don't split if we have double load/store
instructions. Returns a boolean.
(arc_process_double_reg_moves): Change function to return boolean
instead of a sequence of instructions.
(arc_dwarf_register_span): New function.
* config/arc/arc-protos.h (arc_split_move): Change prototype.
* config/arc/arc.h (TARGET_CPU_CPP_BUILTINS): Define __ARC_LL64__.
* config/arc/arc.md (*movdi_insn): Emit ldd/std instructions.
(*movdf_insn): Likewise.
* config/arc/arc.opt (mll64): New option.
* config/arc/predicates.md (even_register_operand): New predicate.
* doc/invoke.texi (ARC Options): Add mll64 documentation.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232788 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arc/arc.md')
-rw-r--r-- | gcc/config/arc/arc.md | 109 |
1 files changed, 59 insertions, 50 deletions
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 80f1daabd88..222a468fc1b 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -984,7 +984,7 @@ }") (define_insn_and_split "*movdi_insn" - [(set (match_operand:DI 0 "move_dest_operand" "=w,w,r,m") + [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m") (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))] "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" @@ -993,50 +993,36 @@ switch (which_alternative) { default: - case 0 : - /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"mov%? %R0,%R1\;mov%? %0,%1\"; - else - return \"mov%? %0,%1\;mov%? %R0,%R1\"; - case 1 : - return \"mov%? %L0,%L1\;mov%? %H0,%H1\"; - case 2 : - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), operands[1])) - return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\"; - else switch (GET_CODE (XEXP(operands[1], 0))) - { - case POST_MODIFY: case POST_INC: case POST_DEC: - return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\"; - case PRE_MODIFY: case PRE_INC: case PRE_DEC: - return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\"; - default: - return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\"; - } - case 3 : - switch (GET_CODE (XEXP(operands[0], 0))) - { - case POST_MODIFY: case POST_INC: case POST_DEC: - return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\"; - case PRE_MODIFY: case PRE_INC: case PRE_DEC: - return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\"; - default: - return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\"; - } + return \"#\"; + + case 2: + if (TARGET_LL64 + && ((even_register_operand (operands[0], DImode) + && memory_operand (operands[1], DImode)) + || (memory_operand (operands[0], DImode) + && even_register_operand (operands[1], DImode)))) + return \"ldd%U1%V1 %0,%1%&\"; + return \"#\"; + + case 3: + if (TARGET_LL64 + && ((even_register_operand (operands[0], DImode) + && memory_operand (operands[1], DImode)) + || (memory_operand (operands[0], DImode) + && even_register_operand (operands[1], DImode)))) + return \"std%U0%V0 %1,%0\"; + return \"#\"; } }" - "&& reload_completed && optimize" - [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] - "arc_split_move (operands);" + "reload_completed" + [(const_int 0)] + { + arc_split_move (operands); + DONE; + } [(set_attr "type" "move,move,load,store") ;; ??? The ld/st values could be 4 if it's [reg,bignum]. - (set_attr "length" "8,16,16,16")]) + (set_attr "length" "8,16,*,*")]) ;; Floating point move insns. @@ -1066,23 +1052,46 @@ "" "if (prepare_move_operands (operands, DFmode)) DONE;") -(define_insn "*movdf_insn" +(define_insn_and_split "*movdf_insn" [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m") (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))] "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" - "#" + "* +{ + switch (which_alternative) + { + default: + return \"#\"; + case 4: + if (TARGET_LL64 + && ((even_register_operand (operands[0], DFmode) + && memory_operand (operands[1], DFmode)) + || (memory_operand (operands[0], DFmode) + && even_register_operand (operands[1], DFmode)))) + return \"ldd%U1%V1 %0,%1%&\"; + return \"#\"; + + case 5: + if (TARGET_LL64 + && ((even_register_operand (operands[0], DFmode) + && memory_operand (operands[1], DFmode)) + || (memory_operand (operands[0], DFmode) + && even_register_operand (operands[1], DFmode)))) + return \"std%U0%V0 %1,%0\"; + return \"#\"; + } +}" + "reload_completed" + [(const_int 0)] + { + arc_split_move (operands); + DONE; + } [(set_attr "type" "move,move,move,move,load,store") (set_attr "predicable" "no,no,yes,yes,no,no") ;; ??? The ld/st values could be 16 if it's [reg,bignum]. (set_attr "length" "4,16,8,16,16,16")]) -(define_split - [(set (match_operand:DF 0 "move_dest_operand" "") - (match_operand:DF 1 "move_double_src_operand" ""))] - "reload_completed" - [(match_dup 2)] - "operands[2] = arc_split_move (operands);") - (define_insn_and_split "*movdf_insn_nolrsr" [(set (match_operand:DF 0 "register_operand" "=r") (match_operand:DF 1 "arc_double_register_operand" "D")) |