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