annotate gcc/config/nds32/nds32-doubleword.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ;; DImode/DFmode patterns description of Andes NDS32 cpu for GNU compiler
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 ;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 ;; Contributed by Andes Technology Corporation.
kono
parents:
diff changeset
4 ;;
kono
parents:
diff changeset
5 ;; This file is part of GCC.
kono
parents:
diff changeset
6 ;;
kono
parents:
diff changeset
7 ;; GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 ;; under the terms of the GNU General Public License as published
kono
parents:
diff changeset
9 ;; by the Free Software Foundation; either version 3, or (at your
kono
parents:
diff changeset
10 ;; option) any later version.
kono
parents:
diff changeset
11 ;;
kono
parents:
diff changeset
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
kono
parents:
diff changeset
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
kono
parents:
diff changeset
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
kono
parents:
diff changeset
15 ;; License for more details.
kono
parents:
diff changeset
16 ;;
kono
parents:
diff changeset
17 ;; You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 ;; along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 ;; <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 ;; -------------------------------------------------------------
kono
parents:
diff changeset
23 ;; Move DImode/DFmode instructions.
kono
parents:
diff changeset
24 ;; -------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 (define_expand "movdi"
kono
parents:
diff changeset
28 [(set (match_operand:DI 0 "general_operand" "")
kono
parents:
diff changeset
29 (match_operand:DI 1 "general_operand" ""))]
kono
parents:
diff changeset
30 ""
kono
parents:
diff changeset
31 {
kono
parents:
diff changeset
32 /* Need to force register if mem <- !reg. */
kono
parents:
diff changeset
33 if (MEM_P (operands[0]) && !REG_P (operands[1]))
kono
parents:
diff changeset
34 operands[1] = force_reg (DImode, operands[1]);
kono
parents:
diff changeset
35 })
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 (define_expand "movdf"
kono
parents:
diff changeset
38 [(set (match_operand:DF 0 "general_operand" "")
kono
parents:
diff changeset
39 (match_operand:DF 1 "general_operand" ""))]
kono
parents:
diff changeset
40 ""
kono
parents:
diff changeset
41 {
kono
parents:
diff changeset
42 /* Need to force register if mem <- !reg. */
kono
parents:
diff changeset
43 if (MEM_P (operands[0]) && !REG_P (operands[1]))
kono
parents:
diff changeset
44 operands[1] = force_reg (DFmode, operands[1]);
kono
parents:
diff changeset
45 })
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 (define_insn "move_<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 [(set (match_operand:DIDF 0 "nonimmediate_operand" "=r, r, r, r, Da, m, f, Q, f, *r, *f")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 (match_operand:DIDF 1 "general_operand" " r, i, Da, m, r, r, Q, f, f, *f, *r"))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51 "register_operand(operands[0], <MODE>mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 || register_operand(operands[1], <MODE>mode)"
111
kono
parents:
diff changeset
53 {
kono
parents:
diff changeset
54 switch (which_alternative)
kono
parents:
diff changeset
55 {
kono
parents:
diff changeset
56 case 0:
kono
parents:
diff changeset
57 return "movd44\t%0, %1";
kono
parents:
diff changeset
58 case 1:
kono
parents:
diff changeset
59 /* reg <- const_int, we ask gcc to split instruction. */
kono
parents:
diff changeset
60 return "#";
kono
parents:
diff changeset
61 case 2:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 /* The memory format is (mem (reg)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 we can generate 'lmw.bi' instruction. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 return nds32_output_double (operands, true);
111
kono
parents:
diff changeset
65 case 3:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 /* We haven't 64-bit load instruction,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 we split this pattern to two SImode pattern. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 return "#";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 case 4:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 /* The memory format is (mem (reg)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71 we can generate 'smw.bi' instruction. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 return nds32_output_double (operands, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 case 5:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 /* We haven't 64-bit store instruction,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 we split this pattern to two SImode pattern. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 return "#";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 case 6:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 return nds32_output_float_load (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 case 7:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 return nds32_output_float_store (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 case 8:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 return "fcpysd\t%0, %1, %1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 case 9:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 return "fmfdr\t%0, %1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 case 10:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 return "fmtdr\t%1, %0";
111
kono
parents:
diff changeset
87 default:
kono
parents:
diff changeset
88 gcc_unreachable ();
kono
parents:
diff changeset
89 }
kono
parents:
diff changeset
90 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 [(set_attr "type" "alu,alu,load,load,store,store,fload,fstore,fcpy,fmfdr,fmtdr")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95 (if_then_else (match_test "!TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 (const_int 2))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 (const_int 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 ;; Alternative 2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 ;; Alternative 3
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 (const_int 8)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 ;; Alternative 4
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 ;; Alternative 5
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 (const_int 8)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 ;; Alternative 6
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 ;; Alternative 7
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 ;; Alternative 8
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 ;; Alternative 9
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 ;; Alternative 10
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 ])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 (set_attr "feature" " v1, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 ;; Split move_di pattern when the hard register is odd.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 (define_split
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 [(set (match_operand:DIDF 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 (match_operand:DIDF 1 "register_operand" ""))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
125 "(NDS32_IS_GPR_REGNUM (REGNO (operands[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 && ((REGNO (operands[0]) & 0x1) == 1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127 || (NDS32_IS_GPR_REGNUM (REGNO (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 && ((REGNO (operands[1]) & 0x1) == 1))"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 [(set (match_dup 2) (match_dup 3))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 (set (match_dup 4) (match_dup 5))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 operands[2] = gen_lowpart (SImode, operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 operands[4] = gen_highpart (SImode, operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 operands[3] = gen_lowpart (SImode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 operands[5] = gen_highpart (SImode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 )
111
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 (define_split
kono
parents:
diff changeset
140 [(set (match_operand:DIDF 0 "register_operand" "")
kono
parents:
diff changeset
141 (match_operand:DIDF 1 "const_double_operand" ""))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142 "flag_pic || reload_completed"
111
kono
parents:
diff changeset
143 [(set (match_dup 2) (match_dup 3))
kono
parents:
diff changeset
144 (set (match_dup 4) (match_dup 5))]
kono
parents:
diff changeset
145 {
kono
parents:
diff changeset
146 /* Construct lowpart rtx. */
kono
parents:
diff changeset
147 operands[2] = gen_lowpart (SImode, operands[0]);
kono
parents:
diff changeset
148 operands[3] = gen_lowpart (SImode, operands[1]);
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 /* Construct highpart rtx. */
kono
parents:
diff changeset
151 /* Note that operands[1] can be VOIDmode constant,
kono
parents:
diff changeset
152 so we need to use gen_highpart_mode().
kono
parents:
diff changeset
153 Refer to gcc/emit-rtl.c for more information. */
kono
parents:
diff changeset
154 operands[4] = gen_highpart (SImode, operands[0]);
kono
parents:
diff changeset
155 operands[5] = gen_highpart_mode (SImode,
kono
parents:
diff changeset
156 GET_MODE (operands[0]), operands[1]);
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 /* Actually we would like to create move behavior by ourself.
kono
parents:
diff changeset
159 So that movsi expander could have chance to split large constant. */
kono
parents:
diff changeset
160 emit_move_insn (operands[2], operands[3]);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 if ((UINTVAL (operands[3]) & mask) == (UINTVAL (operands[5]) & mask))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 emit_move_insn (operands[4], operands[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 emit_move_insn (operands[4], operands[5]);
111
kono
parents:
diff changeset
167 DONE;
kono
parents:
diff changeset
168 })
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 ;; There is 'movd44' instruction for DImode/DFmode movement under V3/V3M ISA.
kono
parents:
diff changeset
171 ;; We only need to split it under V2 ISA or none-16-bit code generation.
kono
parents:
diff changeset
172 (define_split
kono
parents:
diff changeset
173 [(set (match_operand:DIDF 0 "register_operand" "")
kono
parents:
diff changeset
174 (match_operand:DIDF 1 "register_operand" ""))]
kono
parents:
diff changeset
175 "reload_completed
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 && (TARGET_ISA_V2 || !TARGET_16_BIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 && NDS32_IS_GPR_REGNUM (REGNO (operands[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 && NDS32_IS_GPR_REGNUM (REGNO (operands[1]))"
111
kono
parents:
diff changeset
179 [(set (match_dup 0) (match_dup 1))
kono
parents:
diff changeset
180 (set (match_dup 2) (match_dup 3))]
kono
parents:
diff changeset
181 {
kono
parents:
diff changeset
182 operands[2] = gen_highpart (SImode, operands[0]);
kono
parents:
diff changeset
183 operands[3] = gen_highpart (SImode, operands[1]);
kono
parents:
diff changeset
184 operands[0] = gen_lowpart (SImode, operands[0]);
kono
parents:
diff changeset
185 operands[1] = gen_lowpart (SImode, operands[1]);
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 /* Handle a partial overlap. */
kono
parents:
diff changeset
188 if (rtx_equal_p (operands[0], operands[3]))
kono
parents:
diff changeset
189 {
kono
parents:
diff changeset
190 rtx tmp0 = operands[0];
kono
parents:
diff changeset
191 rtx tmp1 = operands[1];
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 operands[0] = operands[2];
kono
parents:
diff changeset
194 operands[1] = operands[3];
kono
parents:
diff changeset
195 operands[2] = tmp0;
kono
parents:
diff changeset
196 operands[3] = tmp1;
kono
parents:
diff changeset
197 }
kono
parents:
diff changeset
198 })
kono
parents:
diff changeset
199
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 (define_split
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
201 [(set (match_operand:DIDF 0 "nds32_general_register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
202 (match_operand:DIDF 1 "memory_operand" ""))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
203 "reload_completed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
204 && nds32_split_double_word_load_store_p (operands, true)"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
205 [(set (match_dup 2) (match_dup 3))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
206 (set (match_dup 4) (match_dup 5))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
207 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 nds32_spilt_doubleword (operands, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
209 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 (define_split
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
212 [(set (match_operand:DIDF 0 "memory_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
213 (match_operand:DIDF 1 "nds32_general_register_operand" ""))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 "reload_completed
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
215 && nds32_split_double_word_load_store_p (operands, false)"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
216 [(set (match_dup 2) (match_dup 3))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
217 (set (match_dup 4) (match_dup 5))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 nds32_spilt_doubleword (operands, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221
111
kono
parents:
diff changeset
222 ;; -------------------------------------------------------------
kono
parents:
diff changeset
223 ;; Boolean DImode instructions.
kono
parents:
diff changeset
224 ;; -------------------------------------------------------------
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 ;; Nowadays, the generic code is supposed to split the DImode
kono
parents:
diff changeset
227 ;; boolean operations and have good code generation.
kono
parents:
diff changeset
228 ;; Unless we find out some bad cases, there is no need to
kono
parents:
diff changeset
229 ;; define DImode boolean operations by ourself.
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 ;; -------------------------------------------------------------