annotate gcc/config/nds32/nds32.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 ;; Machine 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 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
kono
parents:
diff changeset
22
kono
parents:
diff changeset
23 ;; Include predicates definition.
kono
parents:
diff changeset
24 (include "predicates.md")
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 ;; Include constraints definition.
kono
parents:
diff changeset
27 (include "constraints.md")
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 ;; Include iterators definition.
kono
parents:
diff changeset
30 (include "iterators.md")
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 ;; Include pipelines definition.
kono
parents:
diff changeset
33 (include "pipelines.md")
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 ;; Include constants definition.
kono
parents:
diff changeset
37 (include "constants.md")
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 ;; Include intrinsic functions definition.
kono
parents:
diff changeset
41 (include "nds32-intrinsic.md")
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 ;; Include block move for nds32 multiple load/store behavior.
kono
parents:
diff changeset
44 (include "nds32-multiple.md")
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 ;; Include DImode/DFmode operations.
kono
parents:
diff changeset
47 (include "nds32-doubleword.md")
kono
parents:
diff changeset
48
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 ;; Include floating-point patterns.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 (include "nds32-fpu.md")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51
111
kono
parents:
diff changeset
52 ;; Include peephole patterns.
kono
parents:
diff changeset
53 (include "nds32-peephole2.md")
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 ;; ------------------------------------------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
57
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
58 ;; CPU pipeline model.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
59 (define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,simple"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 (const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 (cond [(match_test "nds32_cpu_option == CPU_N7") (const_string "n7")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 (match_test "nds32_cpu_option == CPU_E8") (const_string "e8")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 (match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8") (const_string "n8")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 (match_test "nds32_cpu_option == CPU_N9") (const_string "n9")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
65 (match_test "nds32_cpu_option == CPU_N10") (const_string "n10")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 (match_test "nds32_cpu_option == CPU_N12") (const_string "n13")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 (match_test "nds32_cpu_option == CPU_N13") (const_string "n13")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69 (match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 (const_string "n9"))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71
111
kono
parents:
diff changeset
72 ;; Insn type, it is used to default other attribute values.
kono
parents:
diff changeset
73 (define_attr "type"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext"
111
kono
parents:
diff changeset
77 (const_string "unknown"))
kono
parents:
diff changeset
78
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 ;; Insn sub-type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 (define_attr "subtype"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 "simple,shift,saturation"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 (const_string "simple"))
111
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 ;; Length, in bytes, default is 4-bytes.
kono
parents:
diff changeset
85 (define_attr "length" "" (const_int 4))
kono
parents:
diff changeset
86
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 ;; Indicate the amount of micro instructions.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 (define_attr "combo"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89 "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 (const_string "1"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 ;; v1 : Baseline Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 ;; v2 : Baseline Version 2 Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95 ;; v3m : Baseline Version 3m Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 ;; v3 : Baseline Version 3 Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 ;; pe1 : Performance Extension Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 ;; pe2 : Performance Extension Version 2 Instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 ;; se : String Extension instructions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 (define_attr "feature"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 "v1,v2,v3m,v3,pe1,pe2,se,fpu"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 (const_string "v1"))
111
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 ;; Enabled, which is used to enable/disable insn alternatives.
kono
parents:
diff changeset
105 ;; Note that we use length and TARGET_16_BIT here as criteria.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 ;; If the instruction pattern already check TARGET_16_BIT to determine
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 ;; the length by itself, its enabled attribute should be customized to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 ;; avoid the conflict between length attribute and this default setting.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 (define_attr "enabled" "no,yes"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 (if_then_else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 (and (eq_attr "length" "2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 (match_test "!TARGET_16_BIT"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 (const_string "no")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 (cond [(eq_attr "feature" "v1") (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
125 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127 (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 (eq_attr "feature" "fpu") (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 (const_string "no"))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 (const_string "yes"))))
111
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
140
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 (include "nds32-dspext.md")
111
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 ;; Move instructions.
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 ;; For QImode and HImode, the immediate value can be fit in imm20s.
kono
parents:
diff changeset
146 ;; So there is no need to split rtx for QI and HI patterns.
kono
parents:
diff changeset
147
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 (define_expand "mov<mode>"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 [(set (match_operand:QIHI 0 "general_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 (match_operand:QIHI 1 "general_operand" ""))]
111
kono
parents:
diff changeset
151 ""
kono
parents:
diff changeset
152 {
kono
parents:
diff changeset
153 /* Need to force register if mem <- !reg. */
kono
parents:
diff changeset
154 if (MEM_P (operands[0]) && !REG_P (operands[1]))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 operands[1] = force_reg (<MODE>mode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 if (MEM_P (operands[1]) && optimize > 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 rtx reg = gen_reg_rtx (SImode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 operands[1] = gen_lowpart (<MODE>mode, reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 }
111
kono
parents:
diff changeset
164 })
kono
parents:
diff changeset
165
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 (define_expand "movmisalign<mode>"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 [(set (match_operand:SIDI 0 "general_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 (match_operand:SIDI 1 "general_operand" ""))]
111
kono
parents:
diff changeset
169 ""
kono
parents:
diff changeset
170 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 rtx addr;
111
kono
parents:
diff changeset
172 if (MEM_P (operands[0]) && !REG_P (operands[1]))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 operands[1] = force_reg (<MODE>mode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 if (MEM_P (operands[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 addr = force_reg (Pmode, XEXP (operands[0], 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 addr = force_reg (Pmode, XEXP (operands[1], 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185 DONE;
111
kono
parents:
diff changeset
186 })
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 (define_expand "movsi"
kono
parents:
diff changeset
189 [(set (match_operand:SI 0 "general_operand" "")
kono
parents:
diff changeset
190 (match_operand:SI 1 "general_operand" ""))]
kono
parents:
diff changeset
191 ""
kono
parents:
diff changeset
192 {
kono
parents:
diff changeset
193 /* Need to force register if mem <- !reg. */
kono
parents:
diff changeset
194 if (MEM_P (operands[0]) && !REG_P (operands[1]))
kono
parents:
diff changeset
195 operands[1] = force_reg (SImode, operands[1]);
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 /* If operands[1] is a large constant and cannot be performed
kono
parents:
diff changeset
198 by a single instruction, we need to split it. */
kono
parents:
diff changeset
199 if (CONST_INT_P (operands[1])
kono
parents:
diff changeset
200 && !satisfies_constraint_Is20 (operands[1])
kono
parents:
diff changeset
201 && !satisfies_constraint_Ihig (operands[1]))
kono
parents:
diff changeset
202 {
kono
parents:
diff changeset
203 rtx high20_rtx;
kono
parents:
diff changeset
204 HOST_WIDE_INT low12_int;
kono
parents:
diff changeset
205 rtx tmp_rtx;
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
kono
parents:
diff changeset
210 low12_int = INTVAL (operands[1]) & 0xfff;
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 emit_move_insn (tmp_rtx, high20_rtx);
kono
parents:
diff changeset
213 emit_move_insn (operands[0], plus_constant (SImode,
kono
parents:
diff changeset
214 tmp_rtx,
kono
parents:
diff changeset
215 low12_int));
kono
parents:
diff changeset
216 DONE;
kono
parents:
diff changeset
217 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 && SYMBOLIC_CONST_P (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222 if (TARGET_ICT_MODEL_LARGE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 && nds32_indirect_call_referenced_p (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
224 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225 nds32_expand_ict_move (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228 else if (nds32_tls_referenced_p (operands [1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 nds32_expand_tls_move (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
233 else if (flag_pic)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
234 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
235 nds32_expand_pic_move (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
236 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
237 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238 }
111
kono
parents:
diff changeset
239 })
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 (define_insn "*mov<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r,U45,U33,U37,U45, m, l, l, l, d, d, r, d, r, r, r, *f, *f, r, *f, Q")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r,U45,U33,U37,U45,Ufe, m,Ip05, Is05, Is20, Ihig, *f, r, *f, Q, *f"))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 "register_operand(operands[0], <MODE>mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 || register_operand(operands[1], <MODE>mode)"
111
kono
parents:
diff changeset
246 {
kono
parents:
diff changeset
247 switch (which_alternative)
kono
parents:
diff changeset
248 {
kono
parents:
diff changeset
249 case 0:
kono
parents:
diff changeset
250 return "mov55\t%0, %1";
kono
parents:
diff changeset
251 case 1:
kono
parents:
diff changeset
252 return "ori\t%0, %1, 0";
kono
parents:
diff changeset
253 case 2:
kono
parents:
diff changeset
254 case 3:
kono
parents:
diff changeset
255 case 4:
kono
parents:
diff changeset
256 case 5:
kono
parents:
diff changeset
257 return nds32_output_16bit_store (operands, <byte>);
kono
parents:
diff changeset
258 case 6:
kono
parents:
diff changeset
259 return nds32_output_32bit_store (operands, <byte>);
kono
parents:
diff changeset
260 case 7:
kono
parents:
diff changeset
261 case 8:
kono
parents:
diff changeset
262 case 9:
kono
parents:
diff changeset
263 case 10:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 case 11:
111
kono
parents:
diff changeset
265 return nds32_output_16bit_load (operands, <byte>);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 case 12:
111
kono
parents:
diff changeset
267 return nds32_output_32bit_load (operands, <byte>);
kono
parents:
diff changeset
268 case 13:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 return "movpi45\t%0, %1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270 case 14:
111
kono
parents:
diff changeset
271 return "movi55\t%0, %1";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 case 15:
111
kono
parents:
diff changeset
273 return "movi\t%0, %1";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 case 16:
111
kono
parents:
diff changeset
275 return "sethi\t%0, hi20(%1)";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276 case 17:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 if (TARGET_FPU_SINGLE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 return "fcpyss\t%0, %1, %1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 return "#";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 case 18:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
282 return "fmtsr\t%1, %0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 case 19:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 return "fmfsr\t%0, %1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 case 20:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 return nds32_output_float_load (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 case 21:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 return nds32_output_float_store (operands);
111
kono
parents:
diff changeset
289 default:
kono
parents:
diff changeset
290 gcc_unreachable ();
kono
parents:
diff changeset
291 }
kono
parents:
diff changeset
292 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
294 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
295 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")])
111
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
kono
parents:
diff changeset
299 ;; are able to match such instruction template.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
300 (define_insn "move_addr"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301 [(set (match_operand:SI 0 "nds32_general_register_operand" "=l, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
302 (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))]
111
kono
parents:
diff changeset
303 ""
kono
parents:
diff changeset
304 "la\t%0, %1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 [(set_attr "type" "alu")
111
kono
parents:
diff changeset
306 (set_attr "length" "8")])
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 (define_insn "sethi"
111
kono
parents:
diff changeset
310 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
311 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
kono
parents:
diff changeset
312 ""
kono
parents:
diff changeset
313 "sethi\t%0, hi20(%1)"
kono
parents:
diff changeset
314 [(set_attr "type" "alu")
kono
parents:
diff changeset
315 (set_attr "length" "4")])
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318 (define_insn "lo_sum"
111
kono
parents:
diff changeset
319 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
320 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
321 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
kono
parents:
diff changeset
322 ""
kono
parents:
diff changeset
323 "ori\t%0, %1, lo12(%2)"
kono
parents:
diff changeset
324 [(set_attr "type" "alu")
kono
parents:
diff changeset
325 (set_attr "length" "4")])
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 ;; Zero extension instructions.
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 (define_insn "zero_extend<mode>si2"
kono
parents:
diff changeset
333 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
kono
parents:
diff changeset
334 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
kono
parents:
diff changeset
335 ""
kono
parents:
diff changeset
336 {
kono
parents:
diff changeset
337 switch (which_alternative)
kono
parents:
diff changeset
338 {
kono
parents:
diff changeset
339 case 0:
kono
parents:
diff changeset
340 return "ze<size>33\t%0, %1";
kono
parents:
diff changeset
341 case 1:
kono
parents:
diff changeset
342 return "ze<size>\t%0, %1";
kono
parents:
diff changeset
343 case 2:
kono
parents:
diff changeset
344 return nds32_output_16bit_load (operands, <byte>);
kono
parents:
diff changeset
345 case 3:
kono
parents:
diff changeset
346 return nds32_output_32bit_load (operands, <byte>);
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 default:
kono
parents:
diff changeset
349 gcc_unreachable ();
kono
parents:
diff changeset
350 }
kono
parents:
diff changeset
351 }
kono
parents:
diff changeset
352 [(set_attr "type" "alu,alu,load,load")
kono
parents:
diff changeset
353 (set_attr "length" " 2, 4, 2, 4")])
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 ;; Sign extension instructions.
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 (define_insn "extend<mode>si2"
kono
parents:
diff changeset
359 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
kono
parents:
diff changeset
360 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
kono
parents:
diff changeset
361 ""
kono
parents:
diff changeset
362 {
kono
parents:
diff changeset
363 switch (which_alternative)
kono
parents:
diff changeset
364 {
kono
parents:
diff changeset
365 case 0:
kono
parents:
diff changeset
366 return "se<size>33\t%0, %1";
kono
parents:
diff changeset
367 case 1:
kono
parents:
diff changeset
368 return "se<size>\t%0, %1";
kono
parents:
diff changeset
369 case 2:
kono
parents:
diff changeset
370 return nds32_output_32bit_load_s (operands, <byte>);
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 default:
kono
parents:
diff changeset
373 gcc_unreachable ();
kono
parents:
diff changeset
374 }
kono
parents:
diff changeset
375 }
kono
parents:
diff changeset
376 [(set_attr "type" "alu,alu,load")
kono
parents:
diff changeset
377 (set_attr "length" " 2, 4, 4")])
kono
parents:
diff changeset
378
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 ;; ----------------------------------------------------------------------------
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381 (define_expand "extv"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 [(set (match_operand 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 (sign_extract (match_operand 1 "nonimmediate_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 (match_operand 2 "const_int_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 (match_operand 3 "const_int_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 enum nds32_expand_result_type result = nds32_expand_extv (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389 switch (result)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 case EXPAND_DONE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394 case EXPAND_FAIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 FAIL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
397 case EXPAND_CREATE_TEMPLATE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
400 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
402 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 (define_expand "insv"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406 (match_operand 1 "const_int_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407 (match_operand 2 "const_int_operand" ""))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
408 (match_operand 3 "register_operand" ""))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 enum nds32_expand_result_type result = nds32_expand_insv (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 switch (result)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
414 case EXPAND_DONE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
415 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
416 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
417 case EXPAND_FAIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
418 FAIL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
420 case EXPAND_CREATE_TEMPLATE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
425 })
111
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 ;; Arithmetic instructions.
kono
parents:
diff changeset
428
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
429 (define_insn "addsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
430 [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
431 (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))]
111
kono
parents:
diff changeset
433 ""
kono
parents:
diff changeset
434 {
kono
parents:
diff changeset
435 switch (which_alternative)
kono
parents:
diff changeset
436 {
kono
parents:
diff changeset
437 case 0:
kono
parents:
diff changeset
438 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
kono
parents:
diff changeset
439 where 0 <= x <= 31 */
kono
parents:
diff changeset
440 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
kono
parents:
diff changeset
441 return "subi45\t%0, %2";
kono
parents:
diff changeset
442 case 1:
kono
parents:
diff changeset
443 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
kono
parents:
diff changeset
444 where 0 <= x <= 7 */
kono
parents:
diff changeset
445 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
kono
parents:
diff changeset
446 return "subi333\t%0, %1, %2";
kono
parents:
diff changeset
447 case 2:
kono
parents:
diff changeset
448 return "addi45\t%0, %2";
kono
parents:
diff changeset
449 case 3:
kono
parents:
diff changeset
450 return "addi333\t%0, %1, %2";
kono
parents:
diff changeset
451 case 4:
kono
parents:
diff changeset
452 return "add45\t%0, %2";
kono
parents:
diff changeset
453 case 5:
kono
parents:
diff changeset
454 return "add333\t%0, %1, %2";
kono
parents:
diff changeset
455 case 6:
kono
parents:
diff changeset
456 return "addi10.sp\t%2";
kono
parents:
diff changeset
457 case 7:
kono
parents:
diff changeset
458 return "addri36.sp\t%0, %2";
kono
parents:
diff changeset
459 case 8:
kono
parents:
diff changeset
460 return "addi\t%0, %1, %2";
kono
parents:
diff changeset
461 case 9:
kono
parents:
diff changeset
462 return "add\t%0, %1, %2";
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 default:
kono
parents:
diff changeset
465 gcc_unreachable ();
kono
parents:
diff changeset
466 }
kono
parents:
diff changeset
467 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
111
kono
parents:
diff changeset
471
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 (define_insn "subsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473 [(set (match_operand:SI 0 "register_operand" "=d, l, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
474 (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 (match_operand:SI 2 "register_operand" " r, l, r, r")))]
111
kono
parents:
diff changeset
476 ""
kono
parents:
diff changeset
477 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
478 sub45\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
479 sub333\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
480 subri\t%0, %2, %1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
481 sub\t%0, %1, %2"
111
kono
parents:
diff changeset
482 [(set_attr "type" "alu,alu,alu,alu")
kono
parents:
diff changeset
483 (set_attr "length" " 2, 2, 4, 4")])
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 ;; GCC intends to simplify (plus (ashift ...) (reg))
kono
parents:
diff changeset
487 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
kono
parents:
diff changeset
488 ;; and needs to ensure it is exact_log2 value.
kono
parents:
diff changeset
489 (define_insn "*add_slli"
kono
parents:
diff changeset
490 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
491 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
492 (match_operand:SI 2 "immediate_operand" " i"))
kono
parents:
diff changeset
493 (match_operand:SI 3 "register_operand" " r")))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
494 "TARGET_ISA_V3 && optimize_size
111
kono
parents:
diff changeset
495 && (exact_log2 (INTVAL (operands[2])) != -1)
kono
parents:
diff changeset
496 && (exact_log2 (INTVAL (operands[2])) <= 31)"
kono
parents:
diff changeset
497 {
kono
parents:
diff changeset
498 /* Get floor_log2 of the immediate value
kono
parents:
diff changeset
499 so that we can generate 'add_slli' instruction. */
kono
parents:
diff changeset
500 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 return "add_slli\t%0, %3, %1, %2";
kono
parents:
diff changeset
503 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505 (set_attr "combo" "2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
506 (set_attr "length" "4")])
111
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 (define_insn "*add_srli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
509 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
511 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
512 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
513 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
514 "add_srli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
515 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
516 (set_attr "combo" "2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517 (set_attr "length" "4")])
111
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 ;; GCC intends to simplify (minus (reg) (ashift ...))
kono
parents:
diff changeset
521 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
kono
parents:
diff changeset
522 ;; and needs to ensure it is exact_log2 value.
kono
parents:
diff changeset
523 (define_insn "*sub_slli"
kono
parents:
diff changeset
524 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
525 (minus:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
526 (mult:SI (match_operand:SI 2 "register_operand" " r")
kono
parents:
diff changeset
527 (match_operand:SI 3 "immediate_operand" " i"))))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528 "TARGET_ISA_V3 && optimize_size
111
kono
parents:
diff changeset
529 && (exact_log2 (INTVAL (operands[3])) != -1)
kono
parents:
diff changeset
530 && (exact_log2 (INTVAL (operands[3])) <= 31)"
kono
parents:
diff changeset
531 {
kono
parents:
diff changeset
532 /* Get floor_log2 of the immediate value
kono
parents:
diff changeset
533 so that we can generate 'sub_slli' instruction. */
kono
parents:
diff changeset
534 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536 return "sub_slli\t%0, %1, %2, %3";
kono
parents:
diff changeset
537 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
539 (set_attr "combo" "2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 (set_attr "length" "4")])
111
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 (define_insn "*sub_srli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
544 (minus:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546 (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
548 "sub_srli\t%0, %1, %2, %3"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
549 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
550 (set_attr "combo" "2")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
551 (set_attr "length" "4")])
111
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553
kono
parents:
diff changeset
554 ;; Multiplication instructions.
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 (define_insn "mulsi3"
kono
parents:
diff changeset
557 [(set (match_operand:SI 0 "register_operand" "=w, r")
kono
parents:
diff changeset
558 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
kono
parents:
diff changeset
559 (match_operand:SI 2 "register_operand" " w, r")))]
kono
parents:
diff changeset
560 ""
kono
parents:
diff changeset
561 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562 mul33\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 mul\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
564 [(set_attr "type" "mul,mul")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
565 (set_attr "length" " 2, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
566 (set_attr "feature" "v3m, v1")])
111
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 (define_insn "mulsidi3"
kono
parents:
diff changeset
569 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents:
diff changeset
570 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
kono
parents:
diff changeset
571 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
kono
parents:
diff changeset
572 "TARGET_ISA_V2 || TARGET_ISA_V3"
kono
parents:
diff changeset
573 "mulsr64\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
574 [(set_attr "type" "mul")
111
kono
parents:
diff changeset
575 (set_attr "length" "4")])
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 (define_insn "umulsidi3"
kono
parents:
diff changeset
578 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents:
diff changeset
579 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
kono
parents:
diff changeset
580 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
kono
parents:
diff changeset
581 "TARGET_ISA_V2 || TARGET_ISA_V3"
kono
parents:
diff changeset
582 "mulr64\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
583 [(set_attr "type" "mul")
111
kono
parents:
diff changeset
584 (set_attr "length" "4")])
kono
parents:
diff changeset
585
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 ;; Multiply-accumulate instructions.
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 (define_insn "*maddr32_0"
kono
parents:
diff changeset
590 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
591 (plus:SI (match_operand:SI 3 "register_operand" " 0")
kono
parents:
diff changeset
592 (mult:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
593 (match_operand:SI 2 "register_operand" " r"))))]
kono
parents:
diff changeset
594 ""
kono
parents:
diff changeset
595 "maddr32\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
596 [(set_attr "type" "mac")
111
kono
parents:
diff changeset
597 (set_attr "length" "4")])
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 (define_insn "*maddr32_1"
kono
parents:
diff changeset
600 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
601 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
602 (match_operand:SI 2 "register_operand" " r"))
kono
parents:
diff changeset
603 (match_operand:SI 3 "register_operand" " 0")))]
kono
parents:
diff changeset
604 ""
kono
parents:
diff changeset
605 "maddr32\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
606 [(set_attr "type" "mac")
111
kono
parents:
diff changeset
607 (set_attr "length" "4")])
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 (define_insn "*msubr32"
kono
parents:
diff changeset
610 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
611 (minus:SI (match_operand:SI 3 "register_operand" " 0")
kono
parents:
diff changeset
612 (mult:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
613 (match_operand:SI 2 "register_operand" " r"))))]
kono
parents:
diff changeset
614 ""
kono
parents:
diff changeset
615 "msubr32\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
616 [(set_attr "type" "mac")
111
kono
parents:
diff changeset
617 (set_attr "length" "4")])
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 ;; Div Instructions.
kono
parents:
diff changeset
621
kono
parents:
diff changeset
622 (define_insn "divmodsi4"
kono
parents:
diff changeset
623 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
624 (div:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
625 (match_operand:SI 2 "register_operand" " r")))
kono
parents:
diff changeset
626 (set (match_operand:SI 3 "register_operand" "=r")
kono
parents:
diff changeset
627 (mod:SI (match_dup 1) (match_dup 2)))]
kono
parents:
diff changeset
628 ""
kono
parents:
diff changeset
629 "divsr\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
630 [(set_attr "type" "div")
111
kono
parents:
diff changeset
631 (set_attr "length" "4")])
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 (define_insn "udivmodsi4"
kono
parents:
diff changeset
634 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
635 (udiv:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
636 (match_operand:SI 2 "register_operand" " r")))
kono
parents:
diff changeset
637 (set (match_operand:SI 3 "register_operand" "=r")
kono
parents:
diff changeset
638 (umod:SI (match_dup 1) (match_dup 2)))]
kono
parents:
diff changeset
639 ""
kono
parents:
diff changeset
640 "divr\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
641 [(set_attr "type" "div")
111
kono
parents:
diff changeset
642 (set_attr "length" "4")])
kono
parents:
diff changeset
643
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
644 ;; divsr/divr will keep quotient only when quotient and remainder is the same
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
645 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
646 ;; want remainder.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
647 (define_insn "divsi4"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
648 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
649 (div:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
650 (match_operand:SI 2 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
651 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
652 "divsr\t%0, %0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
653 [(set_attr "type" "div")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
654 (set_attr "length" "4")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
655
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
656 (define_insn "udivsi4"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
657 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
658 (udiv:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
659 (match_operand:SI 2 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
660 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
661 "divr\t%0, %0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
662 [(set_attr "type" "div")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
663 (set_attr "length" "4")])
111
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 ;; Boolean instructions.
kono
parents:
diff changeset
668 ;; Note: We define the DImode versions in nds32-doubleword.md.
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
671 ;; 'AND' operation
kono
parents:
diff changeset
672 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 (define_insn "bitc"
kono
parents:
diff changeset
675 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
676 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
kono
parents:
diff changeset
677 (match_operand:SI 2 "register_operand" " r")))]
kono
parents:
diff changeset
678 "TARGET_ISA_V3"
kono
parents:
diff changeset
679 "bitc\t%0, %2, %1"
kono
parents:
diff changeset
680 [(set_attr "type" "alu")
kono
parents:
diff changeset
681 (set_attr "length" "4")]
kono
parents:
diff changeset
682 )
kono
parents:
diff changeset
683
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684 (define_expand "andsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
685 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
686 (and:SI (match_operand:SI 1 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
687 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
688 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
689 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
690 if (CONST_INT_P (operands[2])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
691 && !nds32_and_operand (operands[2], SImode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
692 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
693 nds32_expand_constant (SImode, INTVAL (operands[2]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
694 operands[0], operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
695 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
696 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
697 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
698
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
699 (define_insn "*andsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
700 [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
701 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
702 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
111
kono
parents:
diff changeset
703 ""
kono
parents:
diff changeset
704 {
kono
parents:
diff changeset
705 HOST_WIDE_INT mask = INTVAL (operands[2]);
kono
parents:
diff changeset
706
kono
parents:
diff changeset
707 /* 16-bit andi instructions:
kono
parents:
diff changeset
708 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
kono
parents:
diff changeset
709 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
kono
parents:
diff changeset
710 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
kono
parents:
diff changeset
711 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
kono
parents:
diff changeset
712 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
kono
parents:
diff changeset
713 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 switch (which_alternative)
kono
parents:
diff changeset
716 {
kono
parents:
diff changeset
717 case 0:
kono
parents:
diff changeset
718 return "and33\t%0, %2";
kono
parents:
diff changeset
719 case 1:
kono
parents:
diff changeset
720 return "and\t%0, %1, %2";
kono
parents:
diff changeset
721 case 2:
kono
parents:
diff changeset
722 return "zeb33\t%0, %1";
kono
parents:
diff changeset
723 case 3:
kono
parents:
diff changeset
724 return "zeh33\t%0, %1";
kono
parents:
diff changeset
725 case 4:
kono
parents:
diff changeset
726 return "xlsb33\t%0, %1";
kono
parents:
diff changeset
727 case 5:
kono
parents:
diff changeset
728 return "x11b33\t%0, %1";
kono
parents:
diff changeset
729 case 6:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
730 return "bmski33\t%0, %B2";
111
kono
parents:
diff changeset
731 case 7:
kono
parents:
diff changeset
732 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
kono
parents:
diff changeset
733 return "fexti33\t%0, %2";
kono
parents:
diff changeset
734 case 8:
kono
parents:
diff changeset
735 return "zeb\t%0, %1";
kono
parents:
diff changeset
736 case 9:
kono
parents:
diff changeset
737 return "zeh\t%0, %1";
kono
parents:
diff changeset
738 case 10:
kono
parents:
diff changeset
739 return "andi\t%0, %1, %2";
kono
parents:
diff changeset
740 case 11:
kono
parents:
diff changeset
741 operands[2] = GEN_INT (~mask);
kono
parents:
diff changeset
742 return "bitci\t%0, %1, %2";
kono
parents:
diff changeset
743 case 12:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
744 return "bclr\t%0, %1, %b2";
111
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 default:
kono
parents:
diff changeset
747 gcc_unreachable ();
kono
parents:
diff changeset
748 }
kono
parents:
diff changeset
749 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
750 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
751 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
752 (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
111
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 (define_insn "*and_slli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
755 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
756 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
757 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
758 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
760 "and_slli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
761 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
762 (set_attr "length" "4")])
111
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 (define_insn "*and_srli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
765 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
766 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
767 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
768 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
769 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
770 "and_srli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
771 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
772 (set_attr "length" "4")])
111
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
776 ;; 'OR' operation
kono
parents:
diff changeset
777 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 ;; For V3/V3M ISA, we have 'or33' instruction.
kono
parents:
diff changeset
780 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
782 (define_expand "iorsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
784 (ior:SI (match_operand:SI 1 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
785 (match_operand:SI 2 "general_operand" "")))]
111
kono
parents:
diff changeset
786 ""
kono
parents:
diff changeset
787 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 if (!nds32_ior_operand (operands[2], SImode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789 operands[2] = force_reg (SImode, operands[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790 })
111
kono
parents:
diff changeset
791
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
792 (define_insn "*iorsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
795 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
796 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797 "@
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 or33\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 or\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800 ori\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 bset\t%0, %1, %B2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 [(set_attr "type" "alu,alu,alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 (set_attr "length" " 2, 4, 4, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
804 (set_attr "feature" "v3m, v1, v1,pe1")])
111
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 (define_insn "*or_slli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
812 "or_slli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
813 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
814 (set_attr "length" "4")])
111
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 (define_insn "*or_srli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
817 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
818 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
819 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
820 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
821 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
822 "or_srli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
823 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
824 (set_attr "length" "4")])
111
kono
parents:
diff changeset
825
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
828 ;; 'XOR' operation
kono
parents:
diff changeset
829 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
830
kono
parents:
diff changeset
831 ;; For V3/V3M ISA, we have 'xor33' instruction.
kono
parents:
diff changeset
832 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
833
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
834 (define_expand "xorsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
836 (xor:SI (match_operand:SI 1 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
837 (match_operand:SI 2 "general_operand" "")))]
111
kono
parents:
diff changeset
838 ""
kono
parents:
diff changeset
839 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 if (!nds32_xor_operand (operands[2], SImode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 operands[2] = force_reg (SImode, operands[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
842 })
111
kono
parents:
diff changeset
843
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 (define_insn "*xorsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
845 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
846 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
847 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
848 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
849 "@
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
850 xor33\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
851 xor\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
852 xori\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
853 btgl\t%0, %1, %B2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
854 [(set_attr "type" "alu,alu,alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
855 (set_attr "length" " 2, 4, 4, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
856 (set_attr "feature" "v3m, v1, v1,pe1")])
111
kono
parents:
diff changeset
857
kono
parents:
diff changeset
858 (define_insn "*xor_slli"
kono
parents:
diff changeset
859 [(set (match_operand:SI 0 "register_operand" "= r")
kono
parents:
diff changeset
860 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
111
kono
parents:
diff changeset
862 (match_operand:SI 3 "register_operand" " r")))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
864 "xor_slli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 (set_attr "length" "4")])
111
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 (define_insn "*xor_srli"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
869 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
871 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
872 (match_operand:SI 3 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 "TARGET_ISA_V3 && optimize_size"
111
kono
parents:
diff changeset
874 "xor_srli\t%0, %3, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
875 [(set_attr "type" "alu_shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876 (set_attr "length" "4")])
111
kono
parents:
diff changeset
877
kono
parents:
diff changeset
878 ;; Rotate Right Instructions.
kono
parents:
diff changeset
879
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880 (define_insn "*rotrsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 [(set (match_operand:SI 0 "register_operand" "= r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
111
kono
parents:
diff changeset
884 ""
kono
parents:
diff changeset
885 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 rotri\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887 rotr\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 [(set_attr "type" " alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 (set_attr "subtype" "shift,shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 (set_attr "length" " 4, 4")])
111
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
894 ;; 'NEG' operation
kono
parents:
diff changeset
895 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 ;; For V3/V3M ISA, we have 'neg33' instruction.
kono
parents:
diff changeset
898 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
kono
parents:
diff changeset
899 ;; And for V2 ISA, there is NO 'neg33' instruction.
kono
parents:
diff changeset
900 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
kono
parents:
diff changeset
901 (define_insn "negsi2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902 [(set (match_operand:SI 0 "register_operand" "=l, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
111
kono
parents:
diff changeset
904 ""
kono
parents:
diff changeset
905 "@
kono
parents:
diff changeset
906 neg33\t%0, %1
kono
parents:
diff changeset
907 subri\t%0, %1, 0"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
908 [(set_attr "type" "alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 (set_attr "length" " 2, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910 (set_attr "feature" "v3m, v1")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
911
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912 (define_expand "negsf2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 [(set (match_operand:SF 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914 (neg:SF (match_operand:SF 1 "register_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920 rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
921
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
922 emit_insn (gen_xorsi3 (new_dst,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 new_src,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924 gen_int_mode (0x80000000, SImode)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 (define_expand "negdf2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 [(set (match_operand:DF 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 (neg:DF (match_operand:DF 1 "register_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 (define_insn_and_split "soft_negdf2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 [(set (match_operand:DF 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 (neg:DF (match_operand:DF 1 "register_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 "!TARGET_FPU_DOUBLE"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 "#"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 "!TARGET_FPU_DOUBLE"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943 [(const_int 1)]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 rtx src = operands[1];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 rtx dst = operands[0];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947 rtx ori_dst = operands[0];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949 bool need_extra_move_for_dst_p;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950 /* FPU register can't change mode to SI directly, so we need create a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951 tmp register to handle it, and FPU register can't do `xor` or btgl. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 if (HARD_REGISTER_P (src)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 rtx tmp = gen_reg_rtx (DFmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956 emit_move_insn (tmp, src);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 src = tmp;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 if (HARD_REGISTER_P (dst)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963 need_extra_move_for_dst_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964 rtx tmp = gen_reg_rtx (DFmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
965 dst = tmp;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
967
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 rtx dst_high_part = simplify_gen_subreg (
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969 SImode, dst,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970 DFmode, subreg_highpart_offset (SImode, DFmode));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971 rtx dst_low_part = simplify_gen_subreg (
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
972 SImode, dst,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
973 DFmode, subreg_lowpart_offset (SImode, DFmode));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
974 rtx src_high_part = simplify_gen_subreg (
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
975 SImode, src,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
976 DFmode, subreg_highpart_offset (SImode, DFmode));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
977 rtx src_low_part = simplify_gen_subreg (
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
978 SImode, src,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 DFmode, subreg_lowpart_offset (SImode, DFmode));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981 emit_insn (gen_xorsi3 (dst_high_part,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 src_high_part,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983 gen_int_mode (0x80000000, SImode)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 emit_move_insn (dst_low_part, src_low_part);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 if (need_extra_move_for_dst_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 emit_move_insn (ori_dst, dst);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
990 })
111
kono
parents:
diff changeset
991
kono
parents:
diff changeset
992
kono
parents:
diff changeset
993 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
994 ;; 'ONE_COMPLIMENT' operation
kono
parents:
diff changeset
995 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
996
kono
parents:
diff changeset
997 ;; For V3/V3M ISA, we have 'not33' instruction.
kono
parents:
diff changeset
998 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
kono
parents:
diff changeset
999 (define_insn "one_cmplsi2"
kono
parents:
diff changeset
1000 [(set (match_operand:SI 0 "register_operand" "=w, r")
kono
parents:
diff changeset
1001 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
kono
parents:
diff changeset
1002 ""
kono
parents:
diff changeset
1003 "@
kono
parents:
diff changeset
1004 not33\t%0, %1
kono
parents:
diff changeset
1005 nor\t%0, %1, %1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1006 [(set_attr "type" "alu,alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1007 (set_attr "length" " 2, 4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1008 (set_attr "feature" "v3m, v1")])
111
kono
parents:
diff changeset
1009
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1012
kono
parents:
diff changeset
1013 ;; Shift instructions.
kono
parents:
diff changeset
1014
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1015 (define_expand "<shift>si3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1016 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1017 (shift_rotate:SI (match_operand:SI 1 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1018 (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
111
kono
parents:
diff changeset
1019 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1020 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1021 if (operands[2] == const0_rtx)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1022 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1023 emit_move_insn (operands[0], operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1024 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1025 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1026 })
111
kono
parents:
diff changeset
1027
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1028 (define_insn "*ashlsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1029 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1030 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1031 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
111
kono
parents:
diff changeset
1032 ""
kono
parents:
diff changeset
1033 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1034 slli333\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1035 slli\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1036 sll\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1037 [(set_attr "type" " alu, alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1038 (set_attr "subtype" "shift,shift,shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1039 (set_attr "length" " 2, 4, 4")])
111
kono
parents:
diff changeset
1040
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1041 (define_insn "*ashrsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1042 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1043 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1044 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
111
kono
parents:
diff changeset
1045 ""
kono
parents:
diff changeset
1046 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1047 srai45\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1048 srai\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1049 sra\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1050 [(set_attr "type" " alu, alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1051 (set_attr "subtype" "shift,shift,shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1052 (set_attr "length" " 2, 4, 4")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1053
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1054 (define_insn "*lshrsi3"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1055 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1056 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1057 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1058 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1059 "@
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1060 srli45\t%0, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1061 srli\t%0, %1, %2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1062 srl\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1063 [(set_attr "type" " alu, alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1064 (set_attr "subtype" "shift,shift,shift")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1065 (set_attr "length" " 2, 4, 4")])
111
kono
parents:
diff changeset
1066
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1071 ;; Conditional Move patterns
kono
parents:
diff changeset
1072 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1073
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1074 (define_expand "mov<mode>cc"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1075 [(set (match_operand:QIHISI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1076 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1077 (match_operand:QIHISI 2 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1078 (match_operand:QIHISI 3 "register_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1079 "TARGET_CMOV && !optimize_size"
111
kono
parents:
diff changeset
1080 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1081 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1082 switch (result)
111
kono
parents:
diff changeset
1083 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1084 case EXPAND_DONE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1085 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1086 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1087 case EXPAND_FAIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1088 FAIL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1090 case EXPAND_CREATE_TEMPLATE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1091 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1092 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1093 gcc_unreachable ();
111
kono
parents:
diff changeset
1094 }
kono
parents:
diff changeset
1095 })
kono
parents:
diff changeset
1096
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1097 (define_insn "cmovz<mode>"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1098 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1099 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
111
kono
parents:
diff changeset
1100 (const_int 0))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1101 (match_operand:QIHISI 2 "register_operand" " r, 0")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1102 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
111
kono
parents:
diff changeset
1103 "TARGET_CMOV"
kono
parents:
diff changeset
1104 "@
kono
parents:
diff changeset
1105 cmovz\t%0, %2, %1
kono
parents:
diff changeset
1106 cmovn\t%0, %3, %1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1107 [(set_attr "type" "alu")
111
kono
parents:
diff changeset
1108 (set_attr "length" "4")])
kono
parents:
diff changeset
1109
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1110 (define_insn "cmovn<mode>"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1112 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
111
kono
parents:
diff changeset
1113 (const_int 0))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1114 (match_operand:QIHISI 2 "register_operand" " r, 0")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1115 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
111
kono
parents:
diff changeset
1116 "TARGET_CMOV"
kono
parents:
diff changeset
1117 "@
kono
parents:
diff changeset
1118 cmovn\t%0, %2, %1
kono
parents:
diff changeset
1119 cmovz\t%0, %3, %1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1120 [(set_attr "type" "alu")
111
kono
parents:
diff changeset
1121 (set_attr "length" "4")])
kono
parents:
diff changeset
1122
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1123 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1124 ;; It should be removed once after we change the expansion form of the cmovn.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1125 (define_insn "*cmovn_simplified_<mode>"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1126 [(set (match_operand:QIHISI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1127 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1128 (match_operand:QIHISI 2 "register_operand" "r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1129 (match_operand:QIHISI 3 "register_operand" "0")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1130 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1131 "cmovn\t%0, %2, %1"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1132 [(set_attr "type" "alu")])
111
kono
parents:
diff changeset
1133
kono
parents:
diff changeset
1134 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1135 ;; Conditional Branch patterns
kono
parents:
diff changeset
1136 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 (define_expand "cbranchsi4"
kono
parents:
diff changeset
1139 [(set (pc)
kono
parents:
diff changeset
1140 (if_then_else (match_operator 0 "comparison_operator"
kono
parents:
diff changeset
1141 [(match_operand:SI 1 "register_operand" "")
kono
parents:
diff changeset
1142 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
kono
parents:
diff changeset
1143 (label_ref (match_operand 3 "" ""))
kono
parents:
diff changeset
1144 (pc)))]
kono
parents:
diff changeset
1145 ""
kono
parents:
diff changeset
1146 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1147 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1148 switch (result)
111
kono
parents:
diff changeset
1149 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1150 case EXPAND_DONE:
111
kono
parents:
diff changeset
1151 DONE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1152 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1153 case EXPAND_FAIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1154 FAIL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1155 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1156 case EXPAND_CREATE_TEMPLATE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1157 break;
111
kono
parents:
diff changeset
1158 default:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1159 gcc_unreachable ();
111
kono
parents:
diff changeset
1160 }
kono
parents:
diff changeset
1161 })
kono
parents:
diff changeset
1162
kono
parents:
diff changeset
1163
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1164 (define_insn "cbranchsi4_equality_zero"
111
kono
parents:
diff changeset
1165 [(set (pc)
kono
parents:
diff changeset
1166 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1167 [(match_operand:SI 1 "register_operand" "t,l, r")
111
kono
parents:
diff changeset
1168 (const_int 0)])
kono
parents:
diff changeset
1169 (label_ref (match_operand 2 "" ""))
kono
parents:
diff changeset
1170 (pc)))]
kono
parents:
diff changeset
1171 ""
kono
parents:
diff changeset
1172 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1173 return nds32_output_cbranchsi4_equality_zero (insn, operands);
111
kono
parents:
diff changeset
1174 }
kono
parents:
diff changeset
1175 [(set_attr "type" "branch")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1176 (set_attr_alternative "enabled"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1177 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1178 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1179 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1180 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1181 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1182 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1183 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1184 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1185 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1186 ;; Alternative 2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1187 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1188 ])
111
kono
parents:
diff changeset
1189 (set_attr_alternative "length"
kono
parents:
diff changeset
1190 [
kono
parents:
diff changeset
1191 ;; Alternative 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1192 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1193 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1194 (le (minus (match_dup 2) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1195 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1196 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1197 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1198 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1199 (le (minus (match_dup 2) (pc)) (const_int 65500)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1200 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1201 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1202 (const_int 8)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1203 (const_int 10))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1204 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1205 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1206 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1207 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1208 (le (minus (match_dup 2) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1209 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1210 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1211 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1212 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1213 (le (minus (match_dup 2) (pc)) (const_int 65500)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1214 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1215 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1216 (const_int 8)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1217 (const_int 10))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1218 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1219 ;; Alternative 2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1220 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
111
kono
parents:
diff changeset
1221 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
kono
parents:
diff changeset
1222 (le (minus (match_dup 2) (pc)) (const_int 65500)))
kono
parents:
diff changeset
1223 (const_int 4)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1224 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1225 (const_int 10))
111
kono
parents:
diff changeset
1226 ])])
kono
parents:
diff changeset
1227
kono
parents:
diff changeset
1228
kono
parents:
diff changeset
1229 ;; This pattern is dedicated to V2 ISA,
kono
parents:
diff changeset
1230 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1231 (define_insn "cbranchsi4_equality_reg"
111
kono
parents:
diff changeset
1232 [(set (pc)
kono
parents:
diff changeset
1233 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1234 [(match_operand:SI 1 "register_operand" "v, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1235 (match_operand:SI 2 "register_operand" "l, r")])
111
kono
parents:
diff changeset
1236 (label_ref (match_operand 3 "" ""))
kono
parents:
diff changeset
1237 (pc)))]
kono
parents:
diff changeset
1238 "TARGET_ISA_V2"
kono
parents:
diff changeset
1239 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1240 return nds32_output_cbranchsi4_equality_reg (insn, operands);
111
kono
parents:
diff changeset
1241 }
kono
parents:
diff changeset
1242 [(set_attr "type" "branch")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1243 (set_attr_alternative "enabled"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1244 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1245 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1246 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1247 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1248 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1249 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1250 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1251 ])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1252 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1253 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1254 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1255 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1256 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1257 (le (minus (match_dup 3) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1258 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1259 (if_then_else (and (ge (minus (match_dup 3) (pc))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1260 (const_int -16350))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1261 (le (minus (match_dup 3) (pc))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1262 (const_int 16350)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1263 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1264 (const_int 8)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1265 (const_int 8))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1266 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1267 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1268 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1269 (le (minus (match_dup 3) (pc)) (const_int 16350)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1270 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1271 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1272 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1273 ])])
111
kono
parents:
diff changeset
1274
kono
parents:
diff changeset
1275
kono
parents:
diff changeset
1276 ;; This pattern is dedicated to V3/V3M,
kono
parents:
diff changeset
1277 ;; because V3/V3M DO HAVE beqc/bnec instruction.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1278 (define_insn "cbranchsi4_equality_reg_or_const_int"
111
kono
parents:
diff changeset
1279 [(set (pc)
kono
parents:
diff changeset
1280 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1281 [(match_operand:SI 1 "register_operand" "v, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1282 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
111
kono
parents:
diff changeset
1283 (label_ref (match_operand 3 "" ""))
kono
parents:
diff changeset
1284 (pc)))]
kono
parents:
diff changeset
1285 "TARGET_ISA_V3 || TARGET_ISA_V3M"
kono
parents:
diff changeset
1286 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1287 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
111
kono
parents:
diff changeset
1288 }
kono
parents:
diff changeset
1289 [(set_attr "type" "branch")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1290 (set_attr_alternative "enabled"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1291 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1292 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1293 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1294 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1295 (const_string "no"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1296 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1297 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1298 ;; Alternative 2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1299 (const_string "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1300 ])
111
kono
parents:
diff changeset
1301 (set_attr_alternative "length"
kono
parents:
diff changeset
1302 [
kono
parents:
diff changeset
1303 ;; Alternative 0
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1304 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1305 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1306 (le (minus (match_dup 3) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1307 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1308 (if_then_else (and (ge (minus (match_dup 3) (pc))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1309 (const_int -16350))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1310 (le (minus (match_dup 3) (pc))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1311 (const_int 16350)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1312 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1313 (const_int 8)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1314 (const_int 8))
111
kono
parents:
diff changeset
1315 ;; Alternative 1
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1316 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1317 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1318 (le (minus (match_dup 3) (pc)) (const_int 16350)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1319 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1320 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1321 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1322 ;; Alternative 2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1323 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1324 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1325 (le (minus (match_dup 3) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1326 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1327 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1328 (const_int 10))
111
kono
parents:
diff changeset
1329 ])])
kono
parents:
diff changeset
1330
kono
parents:
diff changeset
1331
kono
parents:
diff changeset
1332 (define_insn "*cbranchsi4_greater_less_zero"
kono
parents:
diff changeset
1333 [(set (pc)
kono
parents:
diff changeset
1334 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
kono
parents:
diff changeset
1335 [(match_operand:SI 1 "register_operand" "r")
kono
parents:
diff changeset
1336 (const_int 0)])
kono
parents:
diff changeset
1337 (label_ref (match_operand 2 "" ""))
kono
parents:
diff changeset
1338 (pc)))]
kono
parents:
diff changeset
1339 ""
kono
parents:
diff changeset
1340 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1341 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
111
kono
parents:
diff changeset
1342 }
kono
parents:
diff changeset
1343 [(set_attr "type" "branch")
kono
parents:
diff changeset
1344 (set (attr "length")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1345 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1346 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1347 (le (minus (match_dup 2) (pc)) (const_int 65500)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1348 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1349 (const_int 10))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1350 (const_int 10)))])
111
kono
parents:
diff changeset
1351
kono
parents:
diff changeset
1352
kono
parents:
diff changeset
1353 (define_expand "cstoresi4"
kono
parents:
diff changeset
1354 [(set (match_operand:SI 0 "register_operand" "")
kono
parents:
diff changeset
1355 (match_operator:SI 1 "comparison_operator"
kono
parents:
diff changeset
1356 [(match_operand:SI 2 "register_operand" "")
kono
parents:
diff changeset
1357 (match_operand:SI 3 "nonmemory_operand" "")]))]
kono
parents:
diff changeset
1358 ""
kono
parents:
diff changeset
1359 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1360 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1361 switch (result)
111
kono
parents:
diff changeset
1362 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 case EXPAND_DONE:
111
kono
parents:
diff changeset
1364 DONE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1365 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 case EXPAND_FAIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 FAIL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1368 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1369 case EXPAND_CREATE_TEMPLATE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1370 break;
111
kono
parents:
diff changeset
1371 default:
kono
parents:
diff changeset
1372 gcc_unreachable ();
kono
parents:
diff changeset
1373 }
kono
parents:
diff changeset
1374 })
kono
parents:
diff changeset
1375
kono
parents:
diff changeset
1376
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1377 (define_expand "slts_compare"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 (lt:SI (match_operand:SI 1 "general_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1380 (match_operand:SI 2 "general_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1382 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1383 if (!REG_P (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1384 operands[1] = force_reg (SImode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1385
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1386 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1387 operands[2] = force_reg (SImode, operands[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1388 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1389
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1390 (define_insn "slts_compare_impl"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1391 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1392 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1393 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
111
kono
parents:
diff changeset
1394 ""
kono
parents:
diff changeset
1395 "@
kono
parents:
diff changeset
1396 slts45\t%1, %2
kono
parents:
diff changeset
1397 sltsi45\t%1, %2
kono
parents:
diff changeset
1398 slts\t%0, %1, %2
kono
parents:
diff changeset
1399 sltsi\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1400 [(set_attr "type" "alu, alu, alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1401 (set_attr "length" " 2, 2, 4, 4")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1402
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1403 (define_insn "slt_eq0"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1404 [(set (match_operand:SI 0 "register_operand" "=t, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1405 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1406 (const_int 0)))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1407 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1408 "@
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1409 slti45\t%1, 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1410 slti\t%0, %1, 1"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1411 [(set_attr "type" "alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1412 (set_attr "length" " 2, 4")])
111
kono
parents:
diff changeset
1413
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1414 (define_expand "slt_compare"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1415 [(set (match_operand:SI 0 "register_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1416 (ltu:SI (match_operand:SI 1 "general_operand" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1417 (match_operand:SI 2 "general_operand" "")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1418 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1419 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1420 if (!REG_P (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1421 operands[1] = force_reg (SImode, operands[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1422
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1423 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1424 operands[2] = force_reg (SImode, operands[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1425 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1426
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1427 (define_insn "slt_compare_impl"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1428 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1429 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1430 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
111
kono
parents:
diff changeset
1431 ""
kono
parents:
diff changeset
1432 "@
kono
parents:
diff changeset
1433 slt45\t%1, %2
kono
parents:
diff changeset
1434 slti45\t%1, %2
kono
parents:
diff changeset
1435 slt\t%0, %1, %2
kono
parents:
diff changeset
1436 slti\t%0, %1, %2"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1437 [(set_attr "type" "alu, alu, alu, alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1438 (set_attr "length" " 2, 2, 4, 4")])
111
kono
parents:
diff changeset
1439
kono
parents:
diff changeset
1440
kono
parents:
diff changeset
1441 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 ;; Unconditional and other jump instructions.
kono
parents:
diff changeset
1444
kono
parents:
diff changeset
1445 (define_insn "jump"
kono
parents:
diff changeset
1446 [(set (pc) (label_ref (match_operand 0 "" "")))]
kono
parents:
diff changeset
1447 ""
kono
parents:
diff changeset
1448 {
kono
parents:
diff changeset
1449 /* This unconditional jump has two forms:
kono
parents:
diff changeset
1450 32-bit instruction => j imm24s << 1
kono
parents:
diff changeset
1451 16-bit instruction => j8 imm8s << 1
kono
parents:
diff changeset
1452
kono
parents:
diff changeset
1453 For 32-bit case,
kono
parents:
diff changeset
1454 we assume it is always reachable.
kono
parents:
diff changeset
1455 For 16-bit case,
kono
parents:
diff changeset
1456 it must satisfy { 255 >= (label - pc) >= -256 } condition.
kono
parents:
diff changeset
1457 However, since the $pc for nds32 is at the beginning of the instruction,
kono
parents:
diff changeset
1458 we should leave some length space for current insn.
kono
parents:
diff changeset
1459 So we use range -250 ~ 250. */
kono
parents:
diff changeset
1460 switch (get_attr_length (insn))
kono
parents:
diff changeset
1461 {
kono
parents:
diff changeset
1462 case 2:
kono
parents:
diff changeset
1463 return "j8\t%0";
kono
parents:
diff changeset
1464 case 4:
kono
parents:
diff changeset
1465 return "j\t%0";
kono
parents:
diff changeset
1466 default:
kono
parents:
diff changeset
1467 gcc_unreachable ();
kono
parents:
diff changeset
1468 }
kono
parents:
diff changeset
1469 }
kono
parents:
diff changeset
1470 [(set_attr "type" "branch")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1471 (set_attr "enabled" "yes")
111
kono
parents:
diff changeset
1472 (set (attr "length")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1473 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1474 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1475 (le (minus (match_dup 0) (pc)) (const_int 250)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1476 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1477 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 (const_int 4))
111
kono
parents:
diff changeset
1479 (const_int 4))
kono
parents:
diff changeset
1480 (const_int 4)))])
kono
parents:
diff changeset
1481
kono
parents:
diff changeset
1482 (define_insn "indirect_jump"
kono
parents:
diff changeset
1483 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
kono
parents:
diff changeset
1484 ""
kono
parents:
diff changeset
1485 "@
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1486 jr5\t%0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1487 jr\t%0"
111
kono
parents:
diff changeset
1488 [(set_attr "type" "branch,branch")
kono
parents:
diff changeset
1489 (set_attr "length" " 2, 4")])
kono
parents:
diff changeset
1490
kono
parents:
diff changeset
1491 ;; Subroutine call instruction returning no value.
kono
parents:
diff changeset
1492 ;; operands[0]: It should be a mem RTX whose address is
kono
parents:
diff changeset
1493 ;; the address of the function.
kono
parents:
diff changeset
1494 ;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
kono
parents:
diff changeset
1495 ;; operands[2]: It is the number of registers used as operands.
kono
parents:
diff changeset
1496
kono
parents:
diff changeset
1497 (define_expand "call"
kono
parents:
diff changeset
1498 [(parallel [(call (match_operand 0 "memory_operand" "")
kono
parents:
diff changeset
1499 (match_operand 1))
kono
parents:
diff changeset
1500 (clobber (reg:SI LP_REGNUM))
kono
parents:
diff changeset
1501 (clobber (reg:SI TA_REGNUM))])]
kono
parents:
diff changeset
1502 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1503 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1504 rtx insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1505 rtx sym = XEXP (operands[0], 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1506
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1507 if (TARGET_ICT_MODEL_LARGE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1508 && nds32_indirect_call_referenced_p (sym))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1509 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1510 rtx reg = gen_reg_rtx (Pmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1511 emit_move_insn (reg, sym);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1512 operands[0] = gen_const_mem (Pmode, reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1513 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1514
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1515 if (flag_pic)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1516 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1517 insn = emit_call_insn (gen_call_internal
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1518 (XEXP (operands[0], 0), GEN_INT (0)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1519 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1520 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1521 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1522 }
111
kono
parents:
diff changeset
1523 )
kono
parents:
diff changeset
1524
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1525 (define_insn "call_internal"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1526 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
111
kono
parents:
diff changeset
1527 (match_operand 1))
kono
parents:
diff changeset
1528 (clobber (reg:SI LP_REGNUM))
kono
parents:
diff changeset
1529 (clobber (reg:SI TA_REGNUM))])]
kono
parents:
diff changeset
1530 ""
kono
parents:
diff changeset
1531 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 rtx_insn *next_insn = next_active_insn (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1533 bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534 && NDS32_ALIGN_P ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1535 switch (which_alternative)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1536 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1537 case 0:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1538 if (TARGET_16_BIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1539 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1540 if (align_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1541 return "jral5\t%0\;.align 2";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1542 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1543 return "jral5\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1544 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1545 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1546 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1547 if (align_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1548 return "jral\t%0\;.align 2";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1549 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1550 return "jral\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1551 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1552 case 1:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1553 return nds32_output_call (insn, operands, operands[0],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1554 "bal\t%0", "jal\t%0", align_p);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1555 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1556 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1557 }
111
kono
parents:
diff changeset
1558 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1559 [(set_attr "enabled" "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1560 (set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1561 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1562 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1563 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1564 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1565 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1566 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1567 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1568 (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1569 (const_int 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1570 (if_then_else (match_test "nds32_long_call_p (operands[0])")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1571 (const_int 12)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1572 (const_int 4)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1573 ])]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1574 )
111
kono
parents:
diff changeset
1575
kono
parents:
diff changeset
1576 ;; Subroutine call instruction returning a value.
kono
parents:
diff changeset
1577 ;; operands[0]: It is the hard regiser in which the value is returned.
kono
parents:
diff changeset
1578 ;; The rest three operands are the same as the
kono
parents:
diff changeset
1579 ;; three operands of the 'call' instruction.
kono
parents:
diff changeset
1580 ;; (but with numbers increased by one)
kono
parents:
diff changeset
1581
kono
parents:
diff changeset
1582 (define_expand "call_value"
kono
parents:
diff changeset
1583 [(parallel [(set (match_operand 0)
kono
parents:
diff changeset
1584 (call (match_operand 1 "memory_operand" "")
kono
parents:
diff changeset
1585 (match_operand 2)))
kono
parents:
diff changeset
1586 (clobber (reg:SI LP_REGNUM))
kono
parents:
diff changeset
1587 (clobber (reg:SI TA_REGNUM))])]
kono
parents:
diff changeset
1588 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1589 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1590 rtx insn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1591 rtx sym = XEXP (operands[1], 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1592
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1593 if (TARGET_ICT_MODEL_LARGE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1594 && nds32_indirect_call_referenced_p (sym))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1595 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1596 rtx reg = gen_reg_rtx (Pmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1597 emit_move_insn (reg, sym);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1598 operands[1] = gen_const_mem (Pmode, reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1599 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1600
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1601 if (flag_pic)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1602 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1603 insn =
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1604 emit_call_insn (gen_call_value_internal
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1605 (operands[0], XEXP (operands[1], 0), GEN_INT (0)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1606 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1607 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1608 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1609 }
111
kono
parents:
diff changeset
1610 )
kono
parents:
diff changeset
1611
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1612 (define_insn "call_value_internal"
111
kono
parents:
diff changeset
1613 [(parallel [(set (match_operand 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1614 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
111
kono
parents:
diff changeset
1615 (match_operand 2)))
kono
parents:
diff changeset
1616 (clobber (reg:SI LP_REGNUM))
kono
parents:
diff changeset
1617 (clobber (reg:SI TA_REGNUM))])]
kono
parents:
diff changeset
1618 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1619 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1620 rtx_insn *next_insn = next_active_insn (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1621 bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1622 && NDS32_ALIGN_P ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1623 switch (which_alternative)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1624 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1625 case 0:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1626 if (TARGET_16_BIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1627 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1628 if (align_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1629 return "jral5\t%1\;.align 2";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1630 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1631 return "jral5\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1632 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1633 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1634 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1635 if (align_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1636 return "jral\t%1\;.align 2";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1637 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1638 return "jral\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1639 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1640 case 1:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1641 return nds32_output_call (insn, operands, operands[1],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1642 "bal\t%1", "jal\t%1", align_p);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1643 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1644 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1645 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1646 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1647 [(set_attr "enabled" "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1648 (set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1649 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1650 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1651 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1652 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1653 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1654 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1655 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1656 (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1657 (const_int 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1658 (if_then_else (match_test "nds32_long_call_p (operands[1])")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1659 (const_int 12)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1660 (const_int 4)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1661 ])]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1662 )
111
kono
parents:
diff changeset
1663
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1664 ;; Call subroutine returning any type.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1665
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1666 (define_expand "untyped_call"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1667 [(parallel [(call (match_operand 0 "" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1668 (const_int 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1669 (match_operand 1 "" "")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1670 (match_operand 2 "" "")])]
111
kono
parents:
diff changeset
1671 ""
kono
parents:
diff changeset
1672 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1673 int i;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1674
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1675 emit_call_insn (gen_call (operands[0], const0_rtx));
111
kono
parents:
diff changeset
1676
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1677 for (i = 0; i < XVECLEN (operands[2], 0); i++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1678 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1679 rtx set = XVECEXP (operands[2], 0, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1680 emit_move_insn (SET_DEST (set), SET_SRC (set));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1681 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1682
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1683 /* The optimizer does not know that the call sets the function value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1684 registers we stored in the result block. We avoid problems by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1685 claiming that all hard registers are used and clobbered at this
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1686 point. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1687 emit_insn (gen_blockage ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1688 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1689 })
111
kono
parents:
diff changeset
1690
kono
parents:
diff changeset
1691 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1692
kono
parents:
diff changeset
1693 ;; The sibcall patterns.
kono
parents:
diff changeset
1694
kono
parents:
diff changeset
1695 ;; sibcall
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1696 ;; sibcall_internal
111
kono
parents:
diff changeset
1697
kono
parents:
diff changeset
1698 (define_expand "sibcall"
kono
parents:
diff changeset
1699 [(parallel [(call (match_operand 0 "memory_operand" "")
kono
parents:
diff changeset
1700 (const_int 0))
kono
parents:
diff changeset
1701 (clobber (reg:SI TA_REGNUM))
kono
parents:
diff changeset
1702 (return)])]
kono
parents:
diff changeset
1703 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1704 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1705 rtx sym = XEXP (operands[0], 0);
111
kono
parents:
diff changeset
1706
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1707 if (TARGET_ICT_MODEL_LARGE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1708 && nds32_indirect_call_referenced_p (sym))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1710 rtx reg = gen_reg_rtx (Pmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1711 emit_move_insn (reg, sym);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1712 operands[0] = gen_const_mem (Pmode, reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1713 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1714 })
111
kono
parents:
diff changeset
1715
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1716 (define_insn "sibcall_internal"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1717 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
111
kono
parents:
diff changeset
1718 (match_operand 1))
kono
parents:
diff changeset
1719 (clobber (reg:SI TA_REGNUM))
kono
parents:
diff changeset
1720 (return)])]
kono
parents:
diff changeset
1721 ""
kono
parents:
diff changeset
1722 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1723 switch (which_alternative)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1724 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1725 case 0:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1726 if (TARGET_16_BIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1727 return "jr5\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1728 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1729 return "jr\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1730 case 1:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1731 if (nds32_long_call_p (operands[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1732 return "b\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1733 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1734 return "j\t%0";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1735 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1736 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1737 }
111
kono
parents:
diff changeset
1738 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1739 [(set_attr "enabled" "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1740 (set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1741 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1742 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1743 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1744 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1745 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1746 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1747 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1748 (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1749 (const_int 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1750 (if_then_else (match_test "nds32_long_call_p (operands[0])")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1751 (const_int 12)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1752 (const_int 4)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1753 ])]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1754 )
111
kono
parents:
diff changeset
1755
kono
parents:
diff changeset
1756 ;; sibcall_value
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1757 ;; sibcall_value_internal
111
kono
parents:
diff changeset
1758 ;; sibcall_value_immediate
kono
parents:
diff changeset
1759
kono
parents:
diff changeset
1760 (define_expand "sibcall_value"
kono
parents:
diff changeset
1761 [(parallel [(set (match_operand 0)
kono
parents:
diff changeset
1762 (call (match_operand 1 "memory_operand" "")
kono
parents:
diff changeset
1763 (const_int 0)))
kono
parents:
diff changeset
1764 (clobber (reg:SI TA_REGNUM))
kono
parents:
diff changeset
1765 (return)])]
kono
parents:
diff changeset
1766 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1767 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1768 rtx sym = XEXP (operands[1], 0);
111
kono
parents:
diff changeset
1769
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1770 if (TARGET_ICT_MODEL_LARGE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1771 && nds32_indirect_call_referenced_p (sym))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1772 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1773 rtx reg = gen_reg_rtx (Pmode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1774 emit_move_insn (reg, sym);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1775 operands[1] = gen_const_mem (Pmode, reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1776 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1777 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1778
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1779 (define_insn "sibcall_value_internal"
111
kono
parents:
diff changeset
1780 [(parallel [(set (match_operand 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1781 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
111
kono
parents:
diff changeset
1782 (match_operand 2)))
kono
parents:
diff changeset
1783 (clobber (reg:SI TA_REGNUM))
kono
parents:
diff changeset
1784 (return)])]
kono
parents:
diff changeset
1785 ""
kono
parents:
diff changeset
1786 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1787 switch (which_alternative)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1788 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1789 case 0:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1790 if (TARGET_16_BIT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1791 return "jr5\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1792 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1793 return "jr\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1794 case 1:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1795 if (nds32_long_call_p (operands[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1796 return "b\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1797 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1798 return "j\t%1";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1799 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1800 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1801 }
111
kono
parents:
diff changeset
1802 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1803 [(set_attr "enabled" "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1804 (set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1805 (set_attr_alternative "length"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1806 [
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1807 ;; Alternative 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1808 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1809 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1810 (const_int 4))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1811 ;; Alternative 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1812 (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1813 (const_int 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1814 (if_then_else (match_test "nds32_long_call_p (operands[1])")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1815 (const_int 12)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1816 (const_int 4)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1817 ])]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1818 )
111
kono
parents:
diff changeset
1819
kono
parents:
diff changeset
1820 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1821
kono
parents:
diff changeset
1822 ;; prologue and epilogue.
kono
parents:
diff changeset
1823
kono
parents:
diff changeset
1824 (define_expand "prologue" [(const_int 0)]
kono
parents:
diff changeset
1825 ""
kono
parents:
diff changeset
1826 {
kono
parents:
diff changeset
1827 /* Note that only under V3/V3M ISA, we could use v3push prologue.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1828 In addition, we need to check if v3push is indeed available. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1829 if (NDS32_V3PUSH_AVAILABLE_P)
111
kono
parents:
diff changeset
1830 nds32_expand_prologue_v3push ();
kono
parents:
diff changeset
1831 else
kono
parents:
diff changeset
1832 nds32_expand_prologue ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1833
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1834 /* If cfun->machine->fp_as_gp_p is true, we can generate special
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1835 directive to guide linker doing fp-as-gp optimization.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1836 However, for a naked function, which means
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1837 it should not have prologue/epilogue,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1838 using fp-as-gp still requires saving $fp by push/pop behavior and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1839 there is no benefit to use fp-as-gp on such small function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1840 So we need to make sure this function is NOT naked as well. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1841 if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1842 emit_insn (gen_omit_fp_begin (gen_rtx_REG (SImode, FP_REGNUM)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1843
111
kono
parents:
diff changeset
1844 DONE;
kono
parents:
diff changeset
1845 })
kono
parents:
diff changeset
1846
kono
parents:
diff changeset
1847 (define_expand "epilogue" [(const_int 0)]
kono
parents:
diff changeset
1848 ""
kono
parents:
diff changeset
1849 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1850 /* If cfun->machine->fp_as_gp_p is true, we can generate special
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1851 directive to guide linker doing fp-as-gp optimization.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1852 However, for a naked function, which means
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1853 it should not have prologue/epilogue,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1854 using fp-as-gp still requires saving $fp by push/pop behavior and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1855 there is no benefit to use fp-as-gp on such small function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1856 So we need to make sure this function is NOT naked as well. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1857 if (cfun->machine->fp_as_gp_p && !cfun->machine->naked_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1858 emit_insn (gen_omit_fp_end (gen_rtx_REG (SImode, FP_REGNUM)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1859
111
kono
parents:
diff changeset
1860 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1861 In addition, we need to check if v3push is indeed available. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1862 if (NDS32_V3PUSH_AVAILABLE_P)
111
kono
parents:
diff changeset
1863 nds32_expand_epilogue_v3pop (false);
kono
parents:
diff changeset
1864 else
kono
parents:
diff changeset
1865 nds32_expand_epilogue (false);
kono
parents:
diff changeset
1866 DONE;
kono
parents:
diff changeset
1867 })
kono
parents:
diff changeset
1868
kono
parents:
diff changeset
1869 (define_expand "sibcall_epilogue" [(const_int 0)]
kono
parents:
diff changeset
1870 ""
kono
parents:
diff changeset
1871 {
kono
parents:
diff changeset
1872 /* Pass true to indicate that this is sibcall epilogue and
kono
parents:
diff changeset
1873 exit from a function without the final branch back to the
kono
parents:
diff changeset
1874 calling function. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1875 nds32_expand_epilogue (true);
111
kono
parents:
diff changeset
1876
kono
parents:
diff changeset
1877 DONE;
kono
parents:
diff changeset
1878 })
kono
parents:
diff changeset
1879
kono
parents:
diff changeset
1880
kono
parents:
diff changeset
1881 ;; nop instruction.
kono
parents:
diff changeset
1882
kono
parents:
diff changeset
1883 (define_insn "nop"
kono
parents:
diff changeset
1884 [(const_int 0)]
kono
parents:
diff changeset
1885 ""
kono
parents:
diff changeset
1886 {
kono
parents:
diff changeset
1887 if (TARGET_16_BIT)
kono
parents:
diff changeset
1888 return "nop16";
kono
parents:
diff changeset
1889 else
kono
parents:
diff changeset
1890 return "nop";
kono
parents:
diff changeset
1891 }
kono
parents:
diff changeset
1892 [(set_attr "type" "misc")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1893 (set_attr "enabled" "yes")
111
kono
parents:
diff changeset
1894 (set (attr "length")
kono
parents:
diff changeset
1895 (if_then_else (match_test "TARGET_16_BIT")
kono
parents:
diff changeset
1896 (const_int 2)
kono
parents:
diff changeset
1897 (const_int 4)))])
kono
parents:
diff changeset
1898
kono
parents:
diff changeset
1899
kono
parents:
diff changeset
1900 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1901 ;; Stack push/pop operations
kono
parents:
diff changeset
1902 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1903
kono
parents:
diff changeset
1904 ;; The pattern for stack push.
kono
parents:
diff changeset
1905 ;; Both stack_push_multiple and stack_v3push use the following pattern.
kono
parents:
diff changeset
1906 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
kono
parents:
diff changeset
1907 (define_insn "*stack_push"
kono
parents:
diff changeset
1908 [(match_parallel 0 "nds32_stack_push_operation"
kono
parents:
diff changeset
1909 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
kono
parents:
diff changeset
1910 (match_operand:SI 1 "const_int_operand" "")))
kono
parents:
diff changeset
1911 (match_operand:SI 2 "register_operand" ""))
kono
parents:
diff changeset
1912 ])]
kono
parents:
diff changeset
1913 ""
kono
parents:
diff changeset
1914 {
kono
parents:
diff changeset
1915 return nds32_output_stack_push (operands[0]);
kono
parents:
diff changeset
1916 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1917 [(set_attr "type" "store_multiple")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1918 (set_attr "combo" "12")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1919 (set_attr "enabled" "yes")
111
kono
parents:
diff changeset
1920 (set (attr "length")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1921 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
111
kono
parents:
diff changeset
1922 (const_int 2)
kono
parents:
diff changeset
1923 (const_int 4)))])
kono
parents:
diff changeset
1924
kono
parents:
diff changeset
1925
kono
parents:
diff changeset
1926 ;; The pattern for stack pop.
kono
parents:
diff changeset
1927 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
kono
parents:
diff changeset
1928 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
kono
parents:
diff changeset
1929 (define_insn "*stack_pop"
kono
parents:
diff changeset
1930 [(match_parallel 0 "nds32_stack_pop_operation"
kono
parents:
diff changeset
1931 [(set (match_operand:SI 1 "register_operand" "")
kono
parents:
diff changeset
1932 (mem:SI (reg:SI SP_REGNUM)))
kono
parents:
diff changeset
1933 ])]
kono
parents:
diff changeset
1934 ""
kono
parents:
diff changeset
1935 {
kono
parents:
diff changeset
1936 return nds32_output_stack_pop (operands[0]);
kono
parents:
diff changeset
1937 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1938 [(set_attr "type" "load_multiple")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1939 (set_attr "combo" "12")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1940 (set_attr "enabled" "yes")
111
kono
parents:
diff changeset
1941 (set (attr "length")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1942 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
111
kono
parents:
diff changeset
1943 (const_int 2)
kono
parents:
diff changeset
1944 (const_int 4)))])
kono
parents:
diff changeset
1945
kono
parents:
diff changeset
1946
kono
parents:
diff changeset
1947 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1948 ;; Return operation patterns
kono
parents:
diff changeset
1949 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
1950
kono
parents:
diff changeset
1951 ;; Use this pattern to expand a return instruction
kono
parents:
diff changeset
1952 ;; with simple_return rtx if no epilogue is required.
kono
parents:
diff changeset
1953 (define_expand "return"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1954 [(parallel [(return)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1955 (clobber (reg:SI FP_REGNUM))])]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1956 "nds32_can_use_return_insn ()"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1957 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1958 /* Emit as the simple return. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1959 if (!cfun->machine->fp_as_gp_p
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1960 && cfun->machine->naked_p
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1961 && (cfun->machine->va_args_size == 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1962 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1963 emit_jump_insn (gen_return_internal ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1964 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1965 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1966 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1967
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1968 ;; This pattern is expanded only by the shrink-wrapping optimization
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1969 ;; on paths where the function prologue has not been executed.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1970 ;; However, such optimization may reorder the prologue/epilogue blocks
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1971 ;; together with basic blocks within function body.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1972 ;; So we must disable this pattern if we have already decided
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1973 ;; to perform fp_as_gp optimization, which requires prologue to be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1974 ;; first block and epilogue to be last block.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1975 (define_expand "simple_return"
111
kono
parents:
diff changeset
1976 [(simple_return)]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1977 "!cfun->machine->fp_as_gp_p"
111
kono
parents:
diff changeset
1978 ""
kono
parents:
diff changeset
1979 )
kono
parents:
diff changeset
1980
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1981 (define_insn "*nds32_return"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1982 [(parallel [(return)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1983 (clobber (reg:SI FP_REGNUM))])]
111
kono
parents:
diff changeset
1984 ""
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1985 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1986 return nds32_output_return ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1987 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1988 [(set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1989 (set_attr "enabled" "yes")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1990 (set_attr "length" "4")])
111
kono
parents:
diff changeset
1991
kono
parents:
diff changeset
1992 (define_insn "return_internal"
kono
parents:
diff changeset
1993 [(simple_return)]
kono
parents:
diff changeset
1994 ""
kono
parents:
diff changeset
1995 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1996 if (nds32_isr_function_critical_p (current_function_decl))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1997 return "iret";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1998
111
kono
parents:
diff changeset
1999 if (TARGET_16_BIT)
kono
parents:
diff changeset
2000 return "ret5";
kono
parents:
diff changeset
2001 else
kono
parents:
diff changeset
2002 return "ret";
kono
parents:
diff changeset
2003 }
kono
parents:
diff changeset
2004 [(set_attr "type" "branch")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2005 (set_attr "enabled" "yes")
111
kono
parents:
diff changeset
2006 (set (attr "length")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2007 (if_then_else (match_test "nds32_isr_function_critical_p (current_function_decl)")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2008 (const_int 4)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2009 (if_then_else (match_test "TARGET_16_BIT")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2010 (const_int 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2011 (const_int 4))))])
111
kono
parents:
diff changeset
2012
kono
parents:
diff changeset
2013
kono
parents:
diff changeset
2014 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
2015 ;; Jump Table patterns
kono
parents:
diff changeset
2016 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
2017 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
kono
parents:
diff changeset
2018 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
kono
parents:
diff changeset
2019 ;;
kono
parents:
diff changeset
2020 ;; operands[0]: The index to dispatch on.
kono
parents:
diff changeset
2021 ;; operands[1]: The lower bound for indices in the table.
kono
parents:
diff changeset
2022 ;; operands[2]: The total range of indices int the table.
kono
parents:
diff changeset
2023 ;; i.e. The largest index minus the smallest one.
kono
parents:
diff changeset
2024 ;; operands[3]: A label that precedes the table itself.
kono
parents:
diff changeset
2025 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
kono
parents:
diff changeset
2026 ;;
kono
parents:
diff changeset
2027 ;; We need to create following sequences for jump table code generation:
kono
parents:
diff changeset
2028 ;; A) k <-- (plus (operands[0]) (-operands[1]))
kono
parents:
diff changeset
2029 ;; B) if (gtu k operands[2]) then goto operands[4]
kono
parents:
diff changeset
2030 ;; C) t <-- operands[3]
kono
parents:
diff changeset
2031 ;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
kono
parents:
diff changeset
2032 ;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
kono
parents:
diff changeset
2033 ;; F) jump to target with register t or z
kono
parents:
diff changeset
2034 ;;
kono
parents:
diff changeset
2035 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
kono
parents:
diff changeset
2036 (define_expand "casesi"
kono
parents:
diff changeset
2037 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
kono
parents:
diff changeset
2038 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
kono
parents:
diff changeset
2039 (match_operand:SI 2 "immediate_operand" "i") ; total range
kono
parents:
diff changeset
2040 (match_operand:SI 3 "" "") ; table label
kono
parents:
diff changeset
2041 (match_operand:SI 4 "" "")] ; Out of range label
kono
parents:
diff changeset
2042 ""
kono
parents:
diff changeset
2043 {
kono
parents:
diff changeset
2044 rtx add_tmp;
kono
parents:
diff changeset
2045 rtx reg, test;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2046 rtx tmp_reg;
111
kono
parents:
diff changeset
2047
kono
parents:
diff changeset
2048 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
kono
parents:
diff changeset
2049 if (operands[1] != const0_rtx)
kono
parents:
diff changeset
2050 {
kono
parents:
diff changeset
2051 reg = gen_reg_rtx (SImode);
kono
parents:
diff changeset
2052 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
kono
parents:
diff changeset
2053
kono
parents:
diff changeset
2054 /* If the integer value is not in the range of imm15s,
kono
parents:
diff changeset
2055 we need to force register first because our addsi3 pattern
kono
parents:
diff changeset
2056 only accept nds32_rimm15s_operand predicate. */
kono
parents:
diff changeset
2057 add_tmp = force_reg (SImode, add_tmp);
kono
parents:
diff changeset
2058
kono
parents:
diff changeset
2059 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
kono
parents:
diff changeset
2060 operands[0] = reg;
kono
parents:
diff changeset
2061 }
kono
parents:
diff changeset
2062
kono
parents:
diff changeset
2063 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
kono
parents:
diff changeset
2064 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
kono
parents:
diff changeset
2065 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
kono
parents:
diff changeset
2066 operands[4]));
kono
parents:
diff changeset
2067
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2068 tmp_reg = gen_reg_rtx (SImode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2069 /* Step C, D, E, and F, using another temporary register tmp_reg. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2070 if (flag_pic)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2071 emit_use (pic_offset_table_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2072
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2073 emit_jump_insn (gen_casesi_internal (operands[0],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2074 operands[3],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2075 tmp_reg));
111
kono
parents:
diff changeset
2076 DONE;
kono
parents:
diff changeset
2077 })
kono
parents:
diff changeset
2078
kono
parents:
diff changeset
2079 ;; We are receiving operands from casesi pattern:
kono
parents:
diff changeset
2080 ;;
kono
parents:
diff changeset
2081 ;; operands[0]: The index that have been substracted with lower bound.
kono
parents:
diff changeset
2082 ;; operands[1]: A label that precedes the table itself.
kono
parents:
diff changeset
2083 ;; operands[2]: A temporary register to retrieve value in table.
kono
parents:
diff changeset
2084 ;;
kono
parents:
diff changeset
2085 ;; We need to perform steps C, D, E, and F:
kono
parents:
diff changeset
2086 ;;
kono
parents:
diff changeset
2087 ;; C) t <-- operands[1]
kono
parents:
diff changeset
2088 ;; D) z <-- (mem (plus (operands[0] << m) t))
kono
parents:
diff changeset
2089 ;; m is 2 for normal jump table.
kono
parents:
diff changeset
2090 ;; m is 0, 1, or 2 for pc relative jump table based on diff size.
kono
parents:
diff changeset
2091 ;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
kono
parents:
diff changeset
2092 ;; F) Jump to target with register t or z.
kono
parents:
diff changeset
2093 ;;
kono
parents:
diff changeset
2094 ;; The USE in this pattern is needed to tell flow analysis that this is
kono
parents:
diff changeset
2095 ;; a CASESI insn. It has no other purpose.
kono
parents:
diff changeset
2096 (define_insn "casesi_internal"
kono
parents:
diff changeset
2097 [(parallel [(set (pc)
kono
parents:
diff changeset
2098 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
kono
parents:
diff changeset
2099 (const_int 4))
kono
parents:
diff changeset
2100 (label_ref (match_operand 1 "" "")))))
kono
parents:
diff changeset
2101 (use (label_ref (match_dup 1)))
kono
parents:
diff changeset
2102 (clobber (match_operand:SI 2 "register_operand" "=r"))
kono
parents:
diff changeset
2103 (clobber (reg:SI TA_REGNUM))])]
kono
parents:
diff changeset
2104 ""
kono
parents:
diff changeset
2105 {
kono
parents:
diff changeset
2106 if (CASE_VECTOR_PC_RELATIVE)
kono
parents:
diff changeset
2107 return nds32_output_casesi_pc_relative (operands);
kono
parents:
diff changeset
2108 else
kono
parents:
diff changeset
2109 return nds32_output_casesi (operands);
kono
parents:
diff changeset
2110 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2111 [(set_attr "type" "branch")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2112 (set (attr "length")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2113 (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2114 (const_int 28)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2115 (const_int 20)))])
111
kono
parents:
diff changeset
2116
kono
parents:
diff changeset
2117 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
2118
kono
parents:
diff changeset
2119 ;; Performance Extension
kono
parents:
diff changeset
2120
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2121 ; If -fwrapv option is issued, GCC expects there will be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2122 ; signed overflow situation. So the ABS(INT_MIN) is still INT_MIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2123 ; (e.g. ABS(0x80000000)=0x80000000).
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2124 ; However, the hardware ABS instruction of nds32 target
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2125 ; always performs saturation: abs 0x80000000 -> 0x7fffffff.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2126 ; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2127 (define_insn "abssi2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2128 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2129 (abs:SI (match_operand:SI 1 "register_operand" " r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2130 "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2131 "abs\t%0, %1"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2132 [(set_attr "type" "alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2133 (set_attr "length" "4")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2134
111
kono
parents:
diff changeset
2135 (define_insn "clzsi2"
kono
parents:
diff changeset
2136 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
2137 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2138 "TARGET_EXT_PERF"
111
kono
parents:
diff changeset
2139 "clz\t%0, %1"
kono
parents:
diff changeset
2140 [(set_attr "type" "alu")
kono
parents:
diff changeset
2141 (set_attr "length" "4")])
kono
parents:
diff changeset
2142
kono
parents:
diff changeset
2143 (define_insn "smaxsi3"
kono
parents:
diff changeset
2144 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
2145 (smax:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
2146 (match_operand:SI 2 "register_operand" " r")))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2147 "TARGET_EXT_PERF"
111
kono
parents:
diff changeset
2148 "max\t%0, %1, %2"
kono
parents:
diff changeset
2149 [(set_attr "type" "alu")
kono
parents:
diff changeset
2150 (set_attr "length" "4")])
kono
parents:
diff changeset
2151
kono
parents:
diff changeset
2152 (define_insn "sminsi3"
kono
parents:
diff changeset
2153 [(set (match_operand:SI 0 "register_operand" "=r")
kono
parents:
diff changeset
2154 (smin:SI (match_operand:SI 1 "register_operand" " r")
kono
parents:
diff changeset
2155 (match_operand:SI 2 "register_operand" " r")))]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2156 "TARGET_EXT_PERF"
111
kono
parents:
diff changeset
2157 "min\t%0, %1, %2"
kono
parents:
diff changeset
2158 [(set_attr "type" "alu")
kono
parents:
diff changeset
2159 (set_attr "length" "4")])
kono
parents:
diff changeset
2160
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2161 (define_insn "btst"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2162 [(set (match_operand:SI 0 "register_operand" "= r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2163 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
111
kono
parents:
diff changeset
2164 (const_int 1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2165 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2166 "TARGET_EXT_PERF"
111
kono
parents:
diff changeset
2167 "btst\t%0, %1, %2"
kono
parents:
diff changeset
2168 [(set_attr "type" "alu")
kono
parents:
diff changeset
2169 (set_attr "length" "4")])
kono
parents:
diff changeset
2170
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2171 (define_insn "ave"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2172 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2173 (truncate:SI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2174 (ashiftrt:DI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2175 (plus:DI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2176 (plus:DI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2177 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2178 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2179 (const_int 1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2180 (const_int 1))))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2181 "TARGET_EXT_PERF"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2182 "ave\t%0, %1, %2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2183 [(set_attr "type" "alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2184 (set_attr "length" "4")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2185
111
kono
parents:
diff changeset
2186 ;; ----------------------------------------------------------------------------
kono
parents:
diff changeset
2187
kono
parents:
diff changeset
2188 ;; Pseudo NOPs
kono
parents:
diff changeset
2189
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2190 (define_insn "relax_group"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2191 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2192 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2193 ".relax_hint %0"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2194 [(set_attr "length" "0")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2195 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2196
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2197 ;; Output .omit_fp_begin for fp-as-gp optimization.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2198 ;; Also we have to set $fp register.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2199 (define_insn "omit_fp_begin"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2200 [(set (match_operand:SI 0 "register_operand" "=x")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2201 (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_OMIT_FP_BEGIN))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2202 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2203 "! -----\;.omit_fp_begin\;la\t$fp,_FP_BASE_\;! -----"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2204 [(set_attr "length" "8")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2205 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2206
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2207 ;; Output .omit_fp_end for fp-as-gp optimization.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2208 ;; Claim that we have to use $fp register.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2209 (define_insn "omit_fp_end"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2210 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "x")] UNSPEC_VOLATILE_OMIT_FP_END)]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2211 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2212 "! -----\;.omit_fp_end\;! -----"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2213 [(set_attr "length" "0")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2214 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2215
111
kono
parents:
diff changeset
2216 (define_insn "pop25return"
kono
parents:
diff changeset
2217 [(return)
kono
parents:
diff changeset
2218 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
kono
parents:
diff changeset
2219 ""
kono
parents:
diff changeset
2220 "! return for pop 25"
kono
parents:
diff changeset
2221 [(set_attr "length" "0")]
kono
parents:
diff changeset
2222 )
kono
parents:
diff changeset
2223
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2224 ;; Add pc
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2225 (define_insn "add_pc"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2226 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2227 (plus:SI (match_operand:SI 1 "register_operand" "0")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2228 (pc)))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2229 "TARGET_LINUX_ABI || flag_pic"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2230 "add5.pc\t%0"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2231 [(set_attr "type" "alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2232 (set_attr "length" "4")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2233 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2234
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2235 (define_expand "bswapsi2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2236 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2237 (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2238 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2239 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2240 emit_insn (gen_unspec_wsbh (operands[0], operands[1]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2241 emit_insn (gen_rotrsi3 (operands[0], operands[0], GEN_INT (16)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2242 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2243 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2244
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2245 (define_insn "bswaphi2"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2246 [(set (match_operand:HI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2247 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2248 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2249 "wsbh\t%0, %1"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2250 [(set_attr "type" "alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2251 (set_attr "length" "4")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2252 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2253
111
kono
parents:
diff changeset
2254 ;; ----------------------------------------------------------------------------
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2255
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2256 ;; Patterns for exception handling
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2257
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2258 (define_expand "eh_return"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2259 [(use (match_operand 0 "general_operand"))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2260 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2261 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2262 emit_insn (gen_nds32_eh_return (operands[0]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2263 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2264 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2265
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2266 (define_insn_and_split "nds32_eh_return"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2267 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_EH_RETURN)]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2268 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2269 "#"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2270 "reload_completed"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2271 [(const_int 0)]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2272 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2273 rtx place;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2274 rtx addr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2275
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2276 /* The operands[0] is the handler address. We need to assign it
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2277 to return address rtx so that we can jump to exception handler
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2278 when returning from current function. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2279
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2280 if (cfun->machine->lp_size == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2281 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2282 /* If $lp is not saved in the stack frame, we can take $lp directly. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2283 place = gen_rtx_REG (SImode, LP_REGNUM);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2284 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2285 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2286 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2287 /* Otherwise, we need to locate the stack slot of return address.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2288 The return address is generally saved in [$fp-4] location.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2289 However, DSE (dead store elimination) does not detect an alias
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2290 between [$fp-x] and [$sp+y]. This can result in a store to save
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2291 $lp introduced by builtin_eh_return() being incorrectly deleted
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2292 if it is based on $fp. The solution we take here is to compute
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2293 the offset relative to stack pointer and then use $sp to access
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2294 location so that the alias can be detected.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2295 FIXME: What if the immediate value "offset" is too large to be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2296 fit in a single addi instruction? */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2297 HOST_WIDE_INT offset;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2298
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2299 offset = (cfun->machine->fp_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2300 + cfun->machine->gp_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2301 + cfun->machine->lp_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2302 + cfun->machine->callee_saved_gpr_regs_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2303 + cfun->machine->callee_saved_area_gpr_padding_bytes
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2304 + cfun->machine->callee_saved_fpr_regs_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2305 + cfun->machine->eh_return_data_regs_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2306 + cfun->machine->local_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2307 + cfun->machine->out_args_size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2308
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2309 addr = plus_constant (Pmode, stack_pointer_rtx, offset - 4);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2310 place = gen_frame_mem (SImode, addr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2311 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2312
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2313 emit_move_insn (place, operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2314 DONE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2315 })
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2316
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2317 ;; ----------------------------------------------------------------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2318
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2319 ;; Patterns for TLS.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2320 ;; The following two tls patterns don't be expanded directly because the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2321 ;; intermediate value may be spilled into the stack. As a result, it is
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2322 ;; hard to analyze the define-use chain in the relax_opt pass.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2323
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2324
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2325 ;; There is a unspec operand to record RELAX_GROUP number because each
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2326 ;; emitted instruction need a relax_hint above it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2327 (define_insn "tls_desc"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2328 [(set (reg:SI 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2329 (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2330 (const_int 1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2331 (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2332 (use (reg:SI GP_REGNUM))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2333 (clobber (reg:SI LP_REGNUM))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2334 (clobber (reg:SI TA_REGNUM))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2335 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2336 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2337 return nds32_output_tls_desc (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2338 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2339 [(set_attr "length" "20")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2340 (set_attr "type" "branch")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2341 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2342
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2343 ;; There is a unspec operand to record RELAX_GROUP number because each
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2344 ;; emitted instruction need a relax_hint above it.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2345 (define_insn "tls_ie"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2346 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2347 (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2348 (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2349 (use (reg:SI GP_REGNUM))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2350 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2351 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2352 return nds32_output_tls_ie (operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2353 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2354 [(set (attr "length") (if_then_else (match_test "flag_pic")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2355 (const_int 12)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2356 (const_int 8)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2357 (set_attr "type" "misc")]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2358 )
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2359
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2360 ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2361 (define_insn "addsi3_32bit"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2362 [(set (match_operand:SI 0 "register_operand" "=r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2363 (unspec:SI [(match_operand:SI 1 "register_operand" "%r")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2364 (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2365 ""
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2366 "add\t%0, %1, %2";
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2367 [(set_attr "type" "alu")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2368 (set_attr "length" "4")
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2369 (set_attr "feature" "v1")])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2370
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2371 ;; ----------------------------------------------------------------------------