1 |
6 |
jlechner |
; intrinsics support generator support routines.
|
2 |
|
|
;
|
3 |
|
|
; This entire file is deeply littered with mep-specific logic. You have
|
4 |
|
|
; been warned.
|
5 |
|
|
;
|
6 |
|
|
; Copyright (C) 2000, 2001, 2002, 2003, 2009 Red Hat, Inc.
|
7 |
|
|
; This file is part of CGEN.
|
8 |
|
|
|
9 |
|
|
; String containing copyright text.
|
10 |
|
|
; String containing text defining the package we're generating code for.
|
11 |
|
|
|
12 |
|
|
; include aliases
|
13 |
|
|
|
14 |
|
|
;; Shortcuts for commonly-used functions.
|
15 |
|
|
" ";; HELPER FUNCTIONS
|
16 |
|
|
|
17 |
|
|
;; True if FN returns the same value for FIRST and SECOND.
|
18 |
|
|
;; True if predicate FN holds for both FIRST and SECOND.
|
19 |
|
|
|
20 |
|
|
;; True if FN holds for one element of LIST.
|
21 |
|
|
;; True if LIST1 and LIST2 are the same length and (FN X Y) holds for
|
22 |
|
|
;; each (X Y) in the zipped list.
|
23 |
|
|
;; Use (SETTER ELEM INDEX) to assign some number INDEX to each element
|
24 |
|
|
;; ELEM of LIST. BASE is the index of the first element; other elements
|
25 |
|
|
;; are numbered incrementally. Return the first unused index value.
|
26 |
|
|
|
27 |
|
|
;; Sort list ELEMS with partial order FN, where (FN X Y) is true iff X "<=" Y.
|
28 |
|
|
;; Generate preprocessor macro names, suitable for use as bitmasks.
|
29 |
|
|
"_";; Return an inclusive OR of every bitmask member in NAMES.
|
30 |
|
|
"0""|";; Assign values to every bitmask in NAMES.
|
31 |
|
|
"#define "" ""\n""\n";; Convert ISA symbol ISA into a target-frobbed string
|
32 |
|
|
|
33 |
|
|
;; ----------------------
|
34 |
|
|
;; How many spaces to indent the next line.
|
35 |
|
|
;; End the current line and indent the new one.
|
36 |
|
|
|
37 |
|
|
", "",";; Execute BODY so that every call to LINE-BREAK will indent by
|
38 |
|
|
;; INDENT more spaces than it does now.
|
39 |
|
|
|
40 |
|
|
;; will indent to the end of the prefix. Write SUFFIX afterwards.
|
41 |
|
|
;;
|
42 |
|
|
;; This function should only be called at the start of a new line.
|
43 |
|
|
|
44 |
|
|
;; to separate the elements.
|
45 |
|
|
;; Like WRITE-LIST, but write DUMMY if the list is empty.
|
46 |
|
|
;; MACROS
|
47 |
|
|
|
48 |
|
|
;; little macro for making assoc tables with nice names
|
49 |
|
|
;; Make a very simple structure interface. NAME is the structure's name
|
50 |
|
|
;; and FIELDS is a list of its fields.
|
51 |
|
|
;;
|
52 |
|
|
;; (make-struct foo (f1 f2 f3 ...))
|
53 |
|
|
;;
|
54 |
|
|
|
55 |
|
|
;;
|
56 |
|
|
;; (foo:make f1 f2 f3 ...)
|
57 |
|
|
;; Create a new object with the given values for fields F1, F2, F3...
|
58 |
|
|
;;
|
59 |
|
|
;; (foo:f1 object)
|
60 |
|
|
;; Return the value of OBJECT's F1 field, or #f if OBJECT itself is #f.
|
61 |
|
|
|
62 |
|
|
;; (foo:set-f1! object value)
|
63 |
|
|
;; Set OBJECT's F1 field to VALUE.
|
64 |
|
|
;;
|
65 |
|
|
;; ... and likewise for the other fields. Each structure is represented
|
66 |
|
|
;; as a vector of its elements.
|
67 |
|
|
;; MEP-SPECIFIC DETAILS
|
68 |
|
|
;; --------------------
|
69 |
|
|
;; Predicates for recognizing coprocessor register set hardware names.
|
70 |
|
|
|
71 |
|
|
;;
|
72 |
|
|
;; At the moment, we do this by looking at the hardware's name as a
|
73 |
|
|
;; string; it would be more graceful to handle this with an attribute.
|
74 |
|
|
;;
|
75 |
|
|
;; Older MeP .cpu files call the coprocessor register sets h-cr,
|
76 |
|
|
;; h-cr64, and h-ccr. Newer versions of a2cgen suffix the hardware
|
77 |
|
|
;; names for the coprocessor's registers with the name of the
|
78 |
|
|
;; coprocessor, and the me_module number. So, for example, if
|
79 |
|
|
;; me_module 3 has an rhcop coprocessor, its register sets will be
|
80 |
|
|
;; called h-cr64-rhcop-3, h-cr-rhcop-3, and h-ccr-rhcop-3.
|
81 |
|
|
|
82 |
|
|
;; PREFIX. PREFIX is a string, like "h-cr"; the returned predicate
|
83 |
|
|
;; will return true if its argument is the symbol whose name is
|
84 |
|
|
;; PREFIX, (e.g. 'h-cr), or any symbol whose name begins with PREFIX
|
85 |
|
|
|
86 |
|
|
;; Precompute some stuff.
|
87 |
|
|
"-""h-cr64""h-cr""h-ccr";; Return the gcc rtl mode that should be used for operand OP.
|
88 |
|
|
;; Return #f to use the default, target-independent choice.
|
89 |
|
|
"SI""SF""DI""SI""SI";; Return the list of arguments for an intrinsic function. ARGUMENTS is
|
90 |
|
|
;; a list of the operands found in the instruction's syntax string, in the
|
91 |
|
|
;; order they appear. OUTPUT-OPERANDS is a list of all the instruction's
|
92 |
|
|
;; output operands (no particular order). Both lists contain md-operands.
|
93 |
|
|
;;
|
94 |
|
|
;; Normally ARGUMENTS itself is the correct return value, but we
|
95 |
|
|
;; need a couple of MeP-specific hacks:
|
96 |
|
|
;;
|
97 |
|
|
;; - Instructions that write to r0 do not make r0 a syntactic
|
98 |
|
|
;; operand. Instead, they embed "\\$0" in the syntax string.
|
99 |
|
|
;; Cope with this by adding $0 to the beginning of the list
|
100 |
|
|
;; if written.
|
101 |
|
|
;;
|
102 |
|
|
;; - $spr and $tpr can appear in the syntax string but are
|
103 |
|
|
|
104 |
|
|
;; Convert the given cgen ISA name into its gcc equivalent.
|
105 |
|
|
;; cgen names such as 'ext_core<X>' and 'ext_cop<X>_YY' become 'ext<X>'.
|
106 |
|
|
"ext_cop""ext""ext_core""ext";; Apply FN once for each ISA. The first argument to FN is a user-readable
|
107 |
|
|
|
108 |
|
|
;; returned by frob-isa-name.
|
109 |
|
|
"ext";; Return the number of the first register belonging to the given
|
110 |
|
|
;; hardware element.
|
111 |
|
|
; core registers
|
112 |
|
|
; control registers
|
113 |
|
|
|
114 |
|
|
; 64-bit coprocessor registers (same)
|
115 |
|
|
; coprocessor control registers
|
116 |
|
|
;; Return the constraint string for register operand OP.
|
117 |
|
|
"z""h";; hi
|
118 |
|
|
"l";; lo
|
119 |
|
|
;; "tiny" registers, in the range 0..7
|
120 |
|
|
"t""r"; core registers
|
121 |
|
|
"c"; control registers
|
122 |
|
|
|
123 |
|
|
; 64-bit coprocessor registers
|
124 |
|
|
"em""x""y"; coprocessor control registers
|
125 |
|
|
"r";; The first hard register available to the intrinsics generator.
|
126 |
|
|
|
127 |
|
|
;; into groups, each representing a particular form of code generation.
|
128 |
|
|
;; In the MeP case, we have one group for __vliw functions and one group
|
129 |
|
|
|
130 |
|
|
;; True if INSN belongs to GROUP, where GROUP is a membmer of TARGET:GROUPS.
|
131 |
|
|
;; Convert an intrinsic's cgen name into the name of its builtin function.
|
132 |
|
|
|
133 |
|
|
;; attributes. In each case INSN is a cgen instruction (not an md-insn).
|
134 |
|
|
"yes""no""ext_core""core""cop""0""core";; Return the define_insn attributes for INSN as a list of (NAME . VALUE)
|
135 |
|
|
;; pairs.
|
136 |
|
|
|
137 |
|
|
;; to record how long the intruction is.
|
138 |
|
|
"\n"" /* The length of the instruction, in bytes. */\n"" int length;\n";; Initialize the fields described above.
|
139 |
|
|
;; Use WELL-KNOWN-INTRINSIC to define the names of builtins that
|
140 |
|
|
|
141 |
|
|
"3""i""i3""cadd""csub""cand""cor""cnor""cxor""csll""csrl""csra""cmov""cpmov""cmovi""cmov1""cmov2""cmovc1""cmovc2""cmovh1""cmovh2""cneg""cmula0""xmula0""cextuh""cextub""cexth""cextb""fmovs""fadds""TARGET_FMAX""fsubs""TARGET_FMAX""fmuls""TARGET_FMAX""fdivs""TARGET_FMAX""fsqrts""TARGET_FMAX""fabss""TARGET_FMAX""fnegs""TARGET_FMAX""ftruncws""TARGET_FMAX""fcvtsw""TARGET_FMAX""fcmpus""TARGET_FMAX""fcmpues""TARGET_FMAX""fcmpuls""TARGET_FMAX""fcmpules""TARGET_FMAX""fcmpes""TARGET_FMAX""fcmplis""TARGET_FMAX""fcmpleis""TARGET_FMAX";; INTRINSIC OPERANDS
|
142 |
|
|
;; ------------------
|
143 |
|
|
;;
|
144 |
|
|
|
145 |
|
|
;; These objects refer back to normal cgen operands but add the extra
|
146 |
|
|
;; information needed for intrinsics support. Each MD-OPERAND belongs
|
147 |
|
|
;; to exactly one MD-INSN.
|
148 |
|
|
;;
|
149 |
|
|
;; OP is the cgen operand
|
150 |
|
|
;;
|
151 |
|
|
;; IFIELD-VALUE is the constant value that the instruction assigns
|
152 |
|
|
|
153 |
|
|
;;
|
154 |
|
|
;; ARG-INDEX is the position of this operand in the intrinsic's
|
155 |
|
|
;; argument list, or #f if the operand is not an argument.
|
156 |
|
|
;;
|
157 |
|
|
;; READ-INDEX is the match_operand number assigned to this operand
|
158 |
|
|
;; when it appears in a right-hand context. The value is #f if we
|
159 |
|
|
;; never generate such a match_operand, either because the operand
|
160 |
|
|
;; is a strict lvalue or because ARG-INDEX is #f.
|
161 |
|
|
;;
|
162 |
|
|
|
163 |
|
|
;;
|
164 |
|
|
;; MODE is the operand's gcc mode (SI, etc.).
|
165 |
|
|
;; Helper functions to extract commonly-used fields from the
|
166 |
|
|
;; underlying cgen operand.
|
167 |
|
|
;; Functions to access well-known operand attributes.
|
168 |
|
|
;; Return true if operand OP represents the program counter.
|
169 |
|
|
;; Return true if operand OP must be mapped to a label. This is only
|
170 |
|
|
|
171 |
|
|
;; Return true if OP is an immediate operand.
|
172 |
|
|
;; Return true if operand OP is an index into a register file. gcc will
|
173 |
|
|
;; convert them into REG rtxes.
|
174 |
|
|
;; If operand OP is a fixed hard register, return the number GCC assigns
|
175 |
|
|
;; to it, otherwise return #f.
|
176 |
|
|
|
177 |
|
|
;; Guess the gcc rtl mode for operand OP. First see whether it uses
|
178 |
|
|
;; a known hardware element, then try the CDATA attribute.
|
179 |
|
|
|
180 |
|
|
;; If OP accepts only CONST_INTs, return the lowest value it accepts.
|
181 |
|
|
;; Likewise the highest value + 1.
|
182 |
|
|
;; Return the name of an immediate predicate for operand OP, assuming
|
183 |
|
|
;; that OP should accept only CONST_INTs. We define these predicates
|
184 |
|
|
;; in the gcc include file.
|
185 |
|
|
"cgen_""_""a""_immediate";; Return the match_operand predicate for operand OP.
|
186 |
|
|
"memory_operand""immediate_operand""nonimmediate_operand""general_operand";; Return the gcc rtx for non-argument operand OP.
|
187 |
|
|
"(mem:"" (scratch:SI))""(reg:"" "")""bad intrinsic operand \"""\": need constant or ifield indexed register, got ";; Return the constraint string for operand OP. LVALUE? is true if the
|
188 |
|
|
;; operand is appearing in a left-hand context. For read-write operands,
|
189 |
|
|
;; the rvalue operand should have a numerical constraint giving the
|
190 |
|
|
;; number of the lvalue.
|
191 |
|
|
"";; Return the rtl pattern for operand OP. CONTEXT is LHS if the operand
|
192 |
|
|
;; is being used as an lvalue, RHS if it is being used as an rvalue in the
|
193 |
|
|
;; first set of a pattern and RHS-COPY if it is being used as an rvalue
|
194 |
|
|
;; in subsequent sets.
|
195 |
|
|
"(pc)""(match_dup "")""(match_operand:"" "" \"""\" \"""=""""\")";; GCC INSTRUCTION PATTERNS
|
196 |
|
|
;; ------------------------
|
197 |
|
|
;;
|
198 |
|
|
;; If we need to generate a define_insn pattern for a particular cgen
|
199 |
|
|
|
200 |
|
|
;; is associated with a (shared) INTRINSIC object.
|
201 |
|
|
;;
|
202 |
|
|
;; MD-NAME is the name of the define_insn pattern
|
203 |
|
|
;;
|
204 |
|
|
;; INDEX is a unique number given to this instruction. Instructions
|
205 |
|
|
;; are numbered according to their position in the .md output file,
|
206 |
|
|
;; the first instruction having index 0.
|
207 |
|
|
;;
|
208 |
|
|
;; INTRINSIC is the intrinsic object to which this instruction belongs.
|
209 |
|
|
;;
|
210 |
|
|
;; CGEN-INSN is the underlying cgen insn.
|
211 |
|
|
;;
|
212 |
|
|
;; SYNTAX is the output of syntax-break-out with cgen operands
|
213 |
|
|
;; converted to md-operands.
|
214 |
|
|
;;
|
215 |
|
|
;; ARGUMENTS is a list of the operands that act as formal arguments
|
216 |
|
|
;; to the intrinsic function. Usually this is the same as SYNTAX
|
217 |
|
|
;; with strings removed, but there can be target-specific reasons
|
218 |
|
|
;; for using a different argument list.
|
219 |
|
|
;;
|
220 |
|
|
;; INPUTS is a list of the operands that appear in a right-hand
|
221 |
|
|
;; context within the define_insn pattern. If a member of this
|
222 |
|
|
;; list is also in ARGUMENTS, it will have a valid READ-INDEX.
|
223 |
|
|
;;
|
224 |
|
|
;; OUTPUTS is like INPUTS except that it lists the operands that
|
225 |
|
|
;; appear in a left-hand context. Argument operands in this list
|
226 |
|
|
;; will have a valid WRITE-INDEX.
|
227 |
|
|
;;
|
228 |
|
|
;; OPERANDS is a concatenation of OUTPUTS and INPUTS.
|
229 |
|
|
;;
|
230 |
|
|
;; CPTYPE is the type to use for coprocessor operands (like V4HI)
|
231 |
|
|
|
232 |
|
|
|
233 |
|
|
;; Return the name of the underlying cgen insn, mostly used for
|
234 |
|
|
;; error reporting.
|
235 |
|
|
|
236 |
|
|
;; important effects that are not described by its gcc rtx pattern.
|
237 |
|
|
;; This is true for any instruction with the VOLATILE attribute,
|
238 |
|
|
;; any instruction without output operands (including those with
|
239 |
|
|
;; no semantics at all) and any instruction that reads from or
|
240 |
|
|
;; writes to a REGNUM operand.
|
241 |
|
|
;; Return the list of ISAs that implement INSN. Ignore those that
|
242 |
|
|
;; were excluded on the command line.
|
243 |
|
|
;; The full list of instruction groups. As well target-specific groups,
|
244 |
|
|
;; this includes "known-code", meaning that the instruction uses a specific
|
245 |
|
|
;; rtl code instead of an unspec.
|
246 |
|
|
;; Return the list of groups to which INSN belongs.
|
247 |
|
|
;; Partial ordering of syntax elements. Return true if ELEM1 and ELEM2
|
248 |
|
|
|
249 |
|
|
;; are that:
|
250 |
|
|
;;
|
251 |
|
|
;; - Identical syntax strings are compatible.
|
252 |
|
|
;;
|
253 |
|
|
;; - Immediate operands are compatible if the range of one is contained
|
254 |
|
|
;; within the range of the other.
|
255 |
|
|
;;
|
256 |
|
|
;; - Other types of operand are compatible if they use the same
|
257 |
|
|
;; hardware element and have the same length.
|
258 |
|
|
;; Helper functions for comparing lists of operands or lists of syntax
|
259 |
|
|
;; pieces using the above ordering.
|
260 |
|
|
;; INTRINSICS
|
261 |
|
|
;; ----------
|
262 |
|
|
;;
|
263 |
|
|
;; Intrinsics have two names, the one that appears in the cgen file
|
264 |
|
|
;; and the one that is given to the builtin function. The former is
|
265 |
|
|
;; its "cgen name" and is only relevant during the analysis phase.
|
266 |
|
|
|
267 |
|
|
;; NAME is the name of the intrinsic's builtin function. It is
|
268 |
|
|
;; generated from the cgen name by TARGET:BUILTIN-NAME.
|
269 |
|
|
;;
|
270 |
|
|
|
271 |
|
|
;;
|
272 |
|
|
;; UNSPEC is the unspec number to use for the right hand side of the
|
273 |
|
|
;; first SET pattern. Add 2 for each subsequent output (so that real
|
274 |
|
|
;; and shadow registers can use different unspec numbers).
|
275 |
|
|
;;
|
276 |
|
|
;; HOOK is the gcc-hook object associated with this intrinsic,
|
277 |
|
|
;; or #f if none.
|
278 |
|
|
;;
|
279 |
|
|
;; ISAS maps ISA names to the most general implementation of the
|
280 |
|
|
;; intrinsic for that ISA. Used for error checking.
|
281 |
|
|
|
282 |
|
|
;; Return the maximum of HIGHEST and the length of insn property PROPERTY
|
283 |
|
|
;; for any implementation of INSTRINSIC. PROPERTY can the something
|
284 |
|
|
;; like MD-INSN:INPUTS or MD-INSN:OUTPUTS.
|
285 |
|
|
;; GLOBAL VARIABLES
|
286 |
|
|
;; ----------------
|
287 |
|
|
;; Maps cgen intrinsic names to intrinsic objects.
|
288 |
|
|
;; The list of all intrinsics. After the analysis phase, this list
|
289 |
|
|
;; is in index order.
|
290 |
|
|
;; The list of all instructions, in the order they appear in the .md file.
|
291 |
|
|
;; When two instructions are compatible, but one is more general than
|
292 |
|
|
;; the other, the more general one will come after the less general one.
|
293 |
|
|
;; Maps fixed hard registers onto shadow global registers.
|
294 |
|
|
;; Create an intrinsic with the given cgen name and gcc hook. Add it to
|
295 |
|
|
;; INTRINSICS and INTRINSIC-TABLE.
|
296 |
|
|
;; Return a shadow version of hard register REG.
|
297 |
|
|
;; WELL-KNOWN INTRINSICS
|
298 |
|
|
;; ---------------------
|
299 |
|
|
;; gcc might have a special use for certain intrinsics. Such intrinsics
|
300 |
|
|
;; have a GCC-HOOK structure attached.
|
301 |
|
|
;;
|
302 |
|
|
;; RTL-CODE is an rtl code that can be used in the define_insn
|
303 |
|
|
;; pattern instead of usual unspec or unspec_volatile. Usually
|
304 |
|
|
;; the field is an arithmetic or logic code, but it can also be:
|
305 |
|
|
;;
|
306 |
|
|
;; - 'set': the intrinsic implements a move of some sort.
|
307 |
|
|
|
308 |
|
|
;; - #f: use unspecs as normal.
|
309 |
|
|
;;
|
310 |
|
|
;; CONDITION is a condition that must be true for the RTL-CODE
|
311 |
|
|
;; version of the instruction to be available.
|
312 |
|
|
;;
|
313 |
|
|
;; UNSPEC-VERSION is a version of the same intrinsic that has no
|
314 |
|
|
|
315 |
|
|
;; of the same instrinsic, one with a specific rtl-code and one
|
316 |
|
|
;; with a general unspec. The former will allow more optimisations
|
317 |
|
|
|
318 |
|
|
;; Declare a well-known intrinsic with the given cgen name and
|
319 |
|
|
|
320 |
|
|
;; ANALYSIS PHASE
|
321 |
|
|
;; --------------
|
322 |
|
|
;; The next available unspec number.
|
323 |
|
|
;; Given cgen instruction INSN, return the cgen name of its intrinsic.
|
324 |
|
|
"";; Look up an intrinsic by its cgen name. Create a new intrinsic
|
325 |
|
|
;; if the name hasn't been used yet.
|
326 |
|
|
;; If instruction INSN assigns to a constant value to OP's field,
|
327 |
|
|
|
328 |
|
|
;; Create an md-insn from the given cgen instruction and add it to MD-INSNS.
|
329 |
|
|
;; Create a new md-operand for OP.
|
330 |
|
|
;; Find an md-operand for OP, create a new one if we
|
331 |
|
|
;; haven't seen it before.
|
332 |
|
|
;; A partial order on md-operands. Sort them by their position
|
333 |
|
|
;; in the argument list, putting non-argument operands last.
|
334 |
|
|
;;
|
335 |
|
|
;; This ordering is needed when non-commutative intrinsics
|
336 |
|
|
;; use a specific gcc rtl code. For example, if we have
|
337 |
|
|
;; an intrinsic:
|
338 |
|
|
|
339 |
|
|
;; sub (op0, op1, op2)
|
340 |
|
|
;;
|
341 |
|
|
;; which is known to do subtraction, we might use the MINUS
|
342 |
|
|
;; rtl code in the define_insn pattern. op1 must then be
|
343 |
|
|
;; the first input operand and op2 must be the second:
|
344 |
|
|
;;
|
345 |
|
|
;; (set op0 (minus op1 op2))
|
346 |
|
|
;; Create a version of the broken-out syntax in which
|
347 |
|
|
;; each cgen operand is replaced by an md-operand.
|
348 |
|
|
;; All relevant outputs.
|
349 |
|
|
|
350 |
|
|
;; a list of operands. Usually this is taken directly from
|
351 |
|
|
;; the assembler syntax, but allow machine-specific hacks
|
352 |
|
|
;; to modify the list.
|
353 |
|
|
;; The operands that we know to be inputs. For tidiness' sake,
|
354 |
|
|
;; remove (pc), which was no real meaning inside an unspec or
|
355 |
|
|
;; unspec_volatile.
|
356 |
|
|
;; If an argument has not been classified as an input
|
357 |
|
|
;; or an output, treat it as an input. This helps us to
|
358 |
|
|
;; deal with insns whose semantics have not been given.
|
359 |
|
|
;; Allow an intrinsic to specify a type for coprocessor
|
360 |
|
|
|
361 |
|
|
;; Number each argument operand according to its position in the list.
|
362 |
|
|
;; Sort the inputs and outputs as described above.
|
363 |
|
|
|
364 |
|
|
;; have lower numbers than inputs.
|
365 |
|
|
;; Assign a mode to each operand. If we have an output operand,
|
366 |
|
|
;; use its mode for all immediate operands. This is mainly for
|
367 |
|
|
;; intrinsics which use rtl codes like 'plus': the source operands
|
368 |
|
|
;; are then expected to have the same mode as the destination.
|
369 |
|
|
|
370 |
|
|
;; intrinsic structure accordingly. Insns are passed to this function
|
371 |
|
|
;; in .md file order.
|
372 |
|
|
;; We haven't yet seen an implementation of this intrinsic for ISA.
|
373 |
|
|
;; The intrinsic has already been implemented for ISA.
|
374 |
|
|
;; Check whether INSN is at least as general as the bellwether
|
375 |
|
|
;; implementation. If it isn't, report an error, otherwise
|
376 |
|
|
;; use INSN as the new bellwether.
|
377 |
|
|
;; This is temporarily disabled as some IVC2 intrinsics *do* have the
|
378 |
|
|
;; same actual signature and operands, but different bit encodings
|
379 |
|
|
;; depending on the slot. This different syntax makes them not match.
|
380 |
|
|
;; (if (not (md-insn:syntax<=? bellwether insn))
|
381 |
|
|
;; (error (sa "instructions \"" (md-insn:cgen-name insn)
|
382 |
|
|
;; "\" and \"" (md-insn:cgen-name bellwether)
|
383 |
|
|
|
384 |
|
|
;; (intrinsic:name intrinsic)
|
385 |
|
|
;; "\" but do not have a compatible syntax")))
|
386 |
|
|
;; (if (not (md-insn:operands<=? bellwether insn))
|
387 |
|
|
|
388 |
|
|
;; "\" and \"" (md-insn:cgen-name bellwether)
|
389 |
|
|
;; "\" are both mapped to intrinsic \""
|
390 |
|
|
;; (intrinsic:name intrinsic)
|
391 |
|
|
;; "\" but do not have compatible semantics")))
|
392 |
|
|
|
393 |
|
|
"--unused--""--reserved--""--syscall--";; Set up global variables, if we haven't already.
|
394 |
|
|
"Analyzing intrinsics...\n";; Set up the global lists.
|
395 |
|
|
"cgen_intrinsic_""cgen_intrinsic_unspec_";; Tell each object what position it has in its respective list.
|
396 |
|
|
;; Check whether the mapping of instructions to intrinsics is OK.
|
397 |
|
|
;; Assign unspec numbers to each intrinsic.
|
398 |
|
|
;; ITERATION FUNCTIONS
|
399 |
|
|
;; -------------------
|
400 |
|
|
|
401 |
|
|
;; -------------
|
402 |
|
|
;; Write the output template for INSN's define_insn.
|
403 |
|
|
;; ??? Still MeP-specific.
|
404 |
|
|
"$tp""$sp""%""%l""%"" ""\\\\t";; Write the inputs to INSN, wrapped in an unspec, unspec_volatile,
|
405 |
|
|
|
406 |
|
|
;; the wrapper's rtl-code, such as "" or ":SI". UNSPEC is the unspec
|
407 |
|
|
;; number to use, if an unspec is needed, and CONTEXT is as for
|
408 |
|
|
|
409 |
|
|
"(unspec_volatile""(unspec"" [""(const_int 0)""] "")""(and"" "")""(not"" "")""("" "")";; Write a "(set ...)" pattern for the given output. CONTEXT is RHS
|
410 |
|
|
;; for the first output and RHS-COPY for the rest. UNSPEC is an unspec
|
411 |
|
|
|
412 |
|
|
"(set "")""(if_then_else "")""(eq "")""""(const_int 0)""(match_dup "")""(pc)"":";; If this instruction is used for expanding intrinsics, and if the
|
413 |
|
|
;; output is a fixed register that is not mapped to an intrinsic
|
414 |
|
|
;; argument, treat the instruction as setting a global register.
|
415 |
|
|
;; This isn't necessary for volatile instructions since gcc will
|
416 |
|
|
;; not try to second-guess what they do.
|
417 |
|
|
|
418 |
|
|
"\n\n(define_insn \"""\"\n"" [""]""";; C predicate.
|
419 |
|
|
" \"CGEN_ENABLE_INSN_P ("")"" && ("")""\"\n";; assembly syntax
|
420 |
|
|
" \"""\"\n";; attributes
|
421 |
|
|
" [""]""(set_attr \"""\" \"""\")"")\n""\n\n"";; DO NOT EDIT: This file is automatically generated by CGEN.\n"";; Any changes you make will be discarded when it is next regenerated.\n""\n\n""Generating .md file...\n";; Define the immediate predicates.
|
422 |
|
|
"(define_predicate \"""\"\n"" (and (match_code \"const_int\")\n"" (match_test \"(INTVAL (op) & "") == 0\n"" && INTVAL (op) >= ""\n"" && INTVAL (op) < ""\")))\n""\n""\n""";; GCC SOURCE CODE GENERATOR
|
423 |
|
|
;; -------------------------
|
424 |
|
|
;; Maps the names of immediate predicates to an example of an operand
|
425 |
|
|
;; which needs it.
|
426 |
|
|
;; If OP is an immediate predicate, make sure that it has an entry
|
427 |
|
|
;; in IMMEDIATE-PREDICATES.
|
428 |
|
|
"cgen_regnum_operand_type_V8QI""cgen_regnum_operand_type_V4HI""cgen_regnum_operand_type_V2SI""cgen_regnum_operand_type_V8UQI""cgen_regnum_operand_type_V4UHI""cgen_regnum_operand_type_V2USI""cgen_regnum_operand_type_VECTOR""cgen_regnum_operand_type_CP_DATA_BUS_INT""cgen_regnum_operand_type_DI""cgen_regnum_operand_type_SI""cgen_regnum_operand_type_POINTER""cgen_regnum_operand_type_LABEL""cgen_regnum_operand_type_LONG""cgen_regnum_operand_type_ULONG""cgen_regnum_operand_type_SHORT""cgen_regnum_operand_type_USHORT""cgen_regnum_operand_type_CHAR""cgen_regnum_operand_type_UCHAR""cgen_regnum_operand_type_DEFAULT";; Write out the cgen_insn initialiser for INSN.
|
429 |
|
|
" { "" }""ISA""GROUP""CODE_FOR_""1""0""{ "" }""0""{ "" }""{ "", ""{ 0, 0"", "", ""1""0"" }""{ 0, 0, cgen_regnum_operand_type_DEFAULT, 0}"; i.e., mep-intrin.h
|
430 |
|
|
|
431 |
|
|
"#define FIRST_SHADOW_REGISTER ""\n""#define LAST_SHADOW_REGISTER ""\n""#define FIXED_SHADOW_REGISTERS \\\n ""1""\n""#define CALL_USED_SHADOW_REGISTERS FIXED_SHADOW_REGISTERS\n""#define SHADOW_REG_ALLOC_ORDER \\\n ""\n""#define SHADOW_REGISTER_NAMES \\\n ""\"$shadow""\"""\n\n";; Declare the index values for well-known intrinsics.
|
432 |
|
|
"\n\n#ifndef __MEP__\n""enum {\n"" "" = ""\n};\n""#endif /* ! defined (__MEP__) */\n";; Define the structure used to describe intrinsic insns.
|
433 |
|
|
"\n\n""enum cgen_regnum_operand_type {\n"" cgen_regnum_operand_type_POINTER, /* long * */\n"" cgen_regnum_operand_type_LABEL, /* void * */\n"" cgen_regnum_operand_type_LONG, /* long */\n"" cgen_regnum_operand_type_ULONG, /* unsigned long */\n"" cgen_regnum_operand_type_SHORT, /* short */\n"" cgen_regnum_operand_type_USHORT, /* unsigned short */\n"" cgen_regnum_operand_type_CHAR, /* char */\n"" cgen_regnum_operand_type_UCHAR, /* unsigned char */\n"" cgen_regnum_operand_type_SI, /* __cop long */\n"" cgen_regnum_operand_type_DI, /* __cop long long */\n"" cgen_regnum_operand_type_CP_DATA_BUS_INT, /* cp_data_bus_int */\n"" cgen_regnum_operand_type_VECTOR, /* opaque vector type */\n"" cgen_regnum_operand_type_V8QI, /* V8QI vector type */\n"" cgen_regnum_operand_type_V4HI, /* V4HI vector type */\n"" cgen_regnum_operand_type_V2SI, /* V2SI vector type */\n"" cgen_regnum_operand_type_V8UQI, /* V8UQI vector type */\n"" cgen_regnum_operand_type_V4UHI, /* V4UHI vector type */\n"" cgen_regnum_operand_type_V2USI, /* V2USI vector type */\n"" cgen_regnum_operand_type_DEFAULT = cgen_regnum_operand_type_LONG\n""};\n""\n""struct cgen_regnum_operand {\n"" /* The number of addressable registers, 0 for non-regnum operands. */\n"" unsigned char count;\n""\n"" /* The first register. */\n"" unsigned char base;\n""\n"" /* The type of the operand. */\n"" enum cgen_regnum_operand_type type;\n""\n"" /* Is it passed by reference? */\n"" int reference_p;\n""};\n\n""struct cgen_insn {\n"" /* An index into cgen_intrinsics[]. */\n"" unsigned int intrinsic;\n""\n"" /* A bitmask of the ISAs which include this instruction. */\n"" unsigned int isas;\n""\n"" /* A bitmask of the target-specific groups to which this instruction\n"" belongs. */\n"" unsigned int groups;\n""\n"" /* The insn_code for this instruction. */\n"" int icode;\n""\n"" /* The number of arguments to the intrinsic function. */\n"" unsigned int num_args;\n""\n"" /* If true, the first argument is the return value. */\n"" unsigned int cret_p;\n""\n"" /* Maps operand numbers to argument numbers. */\n"" unsigned int op_mapping[10];\n""\n"" /* Array of regnum properties, indexed by argument number. */\n"" struct cgen_regnum_operand regnums[10];\n""};\n";; Declare the arrays that we define later.
|
434 |
|
|
"\n""extern const struct cgen_insn cgen_insns[];\n""extern const char *const cgen_intrinsics[];\n";; Macro used by the .md file.
|
435 |
|
|
"\n""/* Is the instruction described by cgen_insns[INDEX] enabled? */\n""#define CGEN_ENABLE_INSN_P(INDEX) \\\n"" ((CGEN_CURRENT_ISAS & cgen_insns[INDEX].isas) != 0 \\\n"" && (CGEN_CURRENT_GROUP & cgen_insns[INDEX].groups) != 0)\n\n""ISA""GROUP""#endif\n""#ifdef WANT_GCC_DEFINITIONS\n";; Create an array describing the range and alignment of immediate
|
436 |
|
|
;; predicates.
|
437 |
|
|
|
438 |
|
|
"const char *const cgen_intrinsics[] = {\n"" \"""\"""\n};\n\n";; Create an array describing each .md file instruction.
|
439 |
|
|
"const struct cgen_insn cgen_insns[] = {\n""\n};\n""#endif\n";; PROTOTYPE GENERATOR
|
440 |
|
|
;; -------------------
|
441 |
|
|
"long *""void *""long""unsigned long""short""unsigned short""char""unsigned char";;(logit 0 "op " (md-operand:cdata op) " cptype " cptype "\n")
|
442 |
|
|
|
443 |
|
|
"\n\n""/* DO NOT EDIT: This file is automatically generated by CGEN.\n"" Any changes you make will be discarded when it is next regenerated.\n""*/\n\n""/* GCC defines these internally, as follows... \n";
|
444 |
|
|
"#if __MEP_CONFIG_CP_DATA_BUS_WIDTH == 64\n"" typedef long long cp_data_bus_int;\n""#else\n"" typedef long cp_data_bus_int;\n""#endif\n""typedef char cp_v8qi __attribute__((vector_size(8)));\n""typedef unsigned char cp_v8uqi __attribute__((vector_size(8)));\n""typedef short cp_v4hi __attribute__((vector_size(8)));\n""typedef unsigned short cp_v4uhi __attribute__((vector_size(8)));\n""typedef int cp_v2si __attribute__((vector_size(8)));\n""typedef unsigned int cp_v2usi __attribute__((vector_size(8)));\n""*/\n\n""Generating prototype file...\n""\n// ""\n""void"" "" ("", "");""volatile""// "" ""\n""";; The rest of this file has not been converted to use the INTRINSICS
|
445 |
|
|
;; attribute. The code isn't used at the moment anyway.
|
446 |
|
|
"\n""""7""&&lab""0x"""""" + 1""p""l""ul""s""us""c""uc""cpdbi""l"""", ""x""y""z""t""w""--unused--""--reserved--"" ("");\n"
|