FIX BUILD (with GHC 6.2.x): System.Directory.Internals is no more
[ghc-hetmet.git] / rts / gmp / mpn / x86 / x86-defs.m4
1 divert(-1)
2
3 dnl  m4 macros for x86 assembler.
4
5
6 dnl  Copyright (C) 1999, 2000 Free Software Foundation, Inc.
7 dnl 
8 dnl  This file is part of the GNU MP Library.
9 dnl
10 dnl  The GNU MP Library is free software; you can redistribute it and/or
11 dnl  modify it under the terms of the GNU Lesser General Public License as
12 dnl  published by the Free Software Foundation; either version 2.1 of the
13 dnl  License, or (at your option) any later version.
14 dnl
15 dnl  The GNU MP Library is distributed in the hope that it will be useful,
16 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 dnl  Lesser General Public License for more details.
19 dnl
20 dnl  You should have received a copy of the GNU Lesser General Public
21 dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
22 dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
23 dnl  Suite 330, Boston, MA 02111-1307, USA.
24
25
26 dnl  Notes:
27 dnl
28 dnl  m4 isn't perfect for processing BSD style x86 assembler code, the main
29 dnl  problems are,
30 dnl
31 dnl  1. Doing define(foo,123) and then using foo in an addressing mode like
32 dnl     foo(%ebx) expands as a macro rather than a constant.  This is worked
33 dnl     around by using deflit() from asm-defs.m4, instead of define().
34 dnl
35 dnl  2. Immediates in macro definitions need a space or `' to stop the $
36 dnl     looking like a macro parameter.  For example,
37 dnl
38 dnl             define(foo, `mov $ 123, %eax')
39 dnl
40 dnl     This is only a problem in macro definitions, not in ordinary text,
41 dnl     nor in macro parameters like text passed to forloop() or ifdef().
42
43
44 deflit(BYTES_PER_MP_LIMB, 4)
45
46
47 dnl  --------------------------------------------------------------------------
48 dnl  Replacement PROLOGUE/EPILOGUE with more sophisticated error checking.
49 dnl  Nesting and overlapping not allowed.
50 dnl
51
52
53 dnl  Usage: PROLOGUE(functionname)
54 dnl
55 dnl  Generate a function prologue.  functionname gets GSYM_PREFIX added.
56 dnl  Examples,
57 dnl
58 dnl         PROLOGUE(mpn_add_n)
59 dnl         PROLOGUE(somefun)
60
61 define(`PROLOGUE',
62 m4_assert_numargs(1)
63 m4_assert_defined(`PROLOGUE_cpu')
64 `ifdef(`PROLOGUE_current_function',
65 `m4_error(`PROLOGUE'(`PROLOGUE_current_function') needs an `EPILOGUE'() before `PROLOGUE'($1)
66 )')dnl
67 m4_file_seen()dnl
68 define(`PROLOGUE_current_function',`$1')dnl
69 PROLOGUE_cpu(GSYM_PREFIX`'$1)')
70
71
72 dnl  Usage: EPILOGUE()
73 dnl
74 dnl  Notice the function name is passed to EPILOGUE_cpu(), letting it use $1
75 dnl  instead of the long PROLOGUE_current_function symbol.
76
77 define(`EPILOGUE',
78 m4_assert_numargs(0)
79 m4_assert_defined(`EPILOGUE_cpu')
80 `ifdef(`PROLOGUE_current_function',,
81 `m4_error(`EPILOGUE'() with no `PROLOGUE'()
82 )')dnl
83 EPILOGUE_cpu(GSYM_PREFIX`'PROLOGUE_current_function)`'dnl
84 undefine(`PROLOGUE_current_function')')
85
86 m4wrap_prepend(
87 `ifdef(`PROLOGUE_current_function',
88 `m4_error(`EPILOGUE() for PROLOGUE('PROLOGUE_current_function`) never seen
89 ')')')
90
91
92 dnl  Usage: PROLOGUE_assert_inside()
93 dnl
94 dnl  Use this unquoted on a line on its own at the start of a macro
95 dnl  definition to add some code to check the macro is only used inside a
96 dnl  PROLOGUE/EPILOGUE pair, and that hence PROLOGUE_current_function is
97 dnl  defined.
98
99 define(PROLOGUE_assert_inside,
100 m4_assert_numargs(0)
101 ``PROLOGUE_assert_inside_internal'(m4_doublequote($`'0))`dnl '')
102
103 define(PROLOGUE_assert_inside_internal,
104 m4_assert_numargs(1)
105 `ifdef(`PROLOGUE_current_function',,
106 `m4_error(`$1 used outside a PROLOGUE / EPILOGUE pair
107 ')')')
108
109
110 dnl  Usage: L(labelname)
111 dnl         LF(functionname,labelname)
112 dnl
113 dnl  Generate a local label in the current or given function.  For LF(),
114 dnl  functionname gets GSYM_PREFIX added, the same as with PROLOGUE().
115 dnl
116 dnl  For example, in a function mpn_add_n (and with MPN_PREFIX __gmpn),
117 dnl
118 dnl         L(bar)          => L__gmpn_add_n__bar
119 dnl         LF(somefun,bar) => Lsomefun__bar
120 dnl
121 dnl  The funtion name and label name get two underscores between them rather
122 dnl  than one to guard against clashing with a separate external symbol that
123 dnl  happened to be called functionname_labelname.  (Though this would only
124 dnl  happen if the local label prefix is is empty.)  Underscores are used so
125 dnl  the whole label will still be a valid C identifier and so can be easily
126 dnl  used in gdb.
127
128 dnl  LSYM_PREFIX can be L$, so defn() is used to prevent L expanding as the
129 dnl  L macro and making an infinite recursion.
130 define(LF,
131 m4_assert_numargs(2)
132 m4_assert_defined(`LSYM_PREFIX')
133 `defn(`LSYM_PREFIX')GSYM_PREFIX`'$1`'__$2')
134
135 define(`L',
136 m4_assert_numargs(1)
137 PROLOGUE_assert_inside()
138 `LF(PROLOGUE_current_function,`$1')')
139
140
141 dnl  Called: PROLOGUE_cpu(gsym)
142 dnl          EPILOGUE_cpu(gsym)
143
144 define(PROLOGUE_cpu,
145 m4_assert_numargs(1)
146         `GLOBL  $1
147         TYPE($1,`function')
148 $1:')
149
150 define(EPILOGUE_cpu,
151 m4_assert_numargs(1)
152 `       SIZE($1,.-$1)')
153
154
155
156 dnl  --------------------------------------------------------------------------
157 dnl  Various x86 macros.
158 dnl
159
160
161 dnl  Usage: ALIGN_OFFSET(bytes,offset)
162 dnl
163 dnl  Align to `offset' away from a multiple of `bytes'.
164 dnl
165 dnl  This is useful for testing, for example align to something very strict
166 dnl  and see what effect offsets from it have, "ALIGN_OFFSET(256,32)".
167 dnl
168 dnl  Generally you wouldn't execute across the padding, but it's done with
169 dnl  nop's so it'll work.
170
171 define(ALIGN_OFFSET,
172 m4_assert_numargs(2)
173 `ALIGN($1)
174 forloop(`i',1,$2,`      nop
175 ')')
176
177
178 dnl  Usage: defframe(name,offset)
179 dnl
180 dnl  Make a definition like the following with which to access a parameter
181 dnl  or variable on the stack.
182 dnl
183 dnl         define(name,`FRAME+offset(%esp)')
184 dnl
185 dnl  Actually m4_empty_if_zero(FRAME+offset) is used, which will save one
186 dnl  byte if FRAME+offset is zero, by putting (%esp) rather than 0(%esp).
187 dnl  Use define(`defframe_empty_if_zero_disabled',1) if for some reason the
188 dnl  zero offset is wanted.
189 dnl
190 dnl  The new macro also gets a check that when it's used FRAME is actually
191 dnl  defined, and that the final %esp offset isn't negative, which would
192 dnl  mean an attempt to access something below the current %esp.
193 dnl
194 dnl  deflit() is used rather than a plain define(), so the new macro won't
195 dnl  delete any following parenthesized expression.  name(%edi) will come
196 dnl  out say as 16(%esp)(%edi).  This isn't valid assembler and should
197 dnl  provoke an error, which is better than silently giving just 16(%esp).
198 dnl
199 dnl  See README.family for more on the suggested way to access the stack
200 dnl  frame.
201
202 define(defframe,
203 m4_assert_numargs(2)
204 `deflit(`$1',
205 m4_assert_defined(`FRAME')
206 `defframe_check_notbelow(`$1',$2,FRAME)dnl
207 defframe_empty_if_zero(FRAME+($2))(%esp)')')
208
209 dnl  Called: defframe_empty_if_zero(expression)
210 define(defframe_empty_if_zero,
211 `ifelse(defframe_empty_if_zero_disabled,1,
212 `eval($1)',
213 `m4_empty_if_zero($1)')')
214
215 dnl  Called: defframe_check_notbelow(`name',offset,FRAME)
216 define(defframe_check_notbelow,
217 m4_assert_numargs(3)
218 `ifelse(eval(($3)+($2)<0),1,
219 `m4_error(`$1 at frame offset $2 used when FRAME is only $3 bytes
220 ')')')
221
222
223 dnl  Usage: FRAME_pushl()
224 dnl         FRAME_popl()
225 dnl         FRAME_addl_esp(n)
226 dnl         FRAME_subl_esp(n)
227 dnl
228 dnl  Adjust FRAME appropriately for a pushl or popl, or for an addl or subl
229 dnl  %esp of n bytes.
230 dnl
231 dnl  Using these macros is completely optional.  Sometimes it makes more
232 dnl  sense to put explicit deflit(`FRAME',N) forms, especially when there's
233 dnl  jumps and different sequences of FRAME values need to be used in
234 dnl  different places.
235
236 define(FRAME_pushl,
237 m4_assert_numargs(0)
238 m4_assert_defined(`FRAME')
239 `deflit(`FRAME',eval(FRAME+4))')
240
241 define(FRAME_popl,
242 m4_assert_numargs(0)
243 m4_assert_defined(`FRAME')
244 `deflit(`FRAME',eval(FRAME-4))')
245
246 define(FRAME_addl_esp,
247 m4_assert_numargs(1)
248 m4_assert_defined(`FRAME')
249 `deflit(`FRAME',eval(FRAME-($1)))')
250
251 define(FRAME_subl_esp,
252 m4_assert_numargs(1)
253 m4_assert_defined(`FRAME')
254 `deflit(`FRAME',eval(FRAME+($1)))')
255
256
257 dnl  Usage: defframe_pushl(name)
258 dnl
259 dnl  Do a combination of a FRAME_pushl() and a defframe() to name the stack
260 dnl  location just pushed.  This should come after a pushl instruction.
261 dnl  Putting it on the same line works and avoids lengthening the code.  For
262 dnl  example,
263 dnl
264 dnl         pushl   %eax     defframe_pushl(VAR_COUNTER)
265 dnl
266 dnl  Notice the defframe() is done with an unquoted -FRAME thus giving its
267 dnl  current value without tracking future changes.
268
269 define(defframe_pushl,
270 `FRAME_pushl()defframe(`$1',-FRAME)')
271
272
273 dnl  --------------------------------------------------------------------------
274 dnl  Assembler instruction macros.
275 dnl
276
277
278 dnl  Usage: emms_or_femms
279 dnl         femms_available_p
280 dnl
281 dnl  femms_available_p expands to 1 or 0 according to whether the AMD 3DNow
282 dnl  femms instruction is available.  emms_or_femms expands to femms if
283 dnl  available, or emms if not.
284 dnl
285 dnl  emms_or_femms is meant for use in the K6 directory where plain K6
286 dnl  (without femms) and K6-2 and K6-3 (with a slightly faster femms) are
287 dnl  supported together.
288 dnl
289 dnl  On K7 femms is no longer faster and is just an alias for emms, so plain
290 dnl  emms may as well be used.
291
292 define(femms_available_p,
293 m4_assert_numargs(-1)
294 `m4_ifdef_anyof_p(
295         `HAVE_TARGET_CPU_k62',
296         `HAVE_TARGET_CPU_k63',
297         `HAVE_TARGET_CPU_athlon')')
298
299 define(emms_or_femms,
300 m4_assert_numargs(-1)
301 `ifelse(femms_available_p,1,`femms',`emms')')
302
303
304 dnl  Usage: femms
305 dnl
306 dnl  The gas 2.9.1 that comes with FreeBSD 3.4 doesn't support femms, so the
307 dnl  following is a replacement using .byte.
308 dnl
309 dnl  If femms isn't available, an emms is generated instead, for convenience
310 dnl  when testing on a machine without femms.
311
312 define(femms,
313 m4_assert_numargs(-1)
314 `ifelse(femms_available_p,1,
315 `.byte  15,14   C AMD 3DNow femms',
316 `emms`'dnl
317 m4_warning(`warning, using emms in place of femms, use for testing only
318 ')')')
319
320
321 dnl  Usage: jadcl0(op)
322 dnl
323 dnl  Issue a jnc/incl as a substitute for adcl $0,op.  This isn't an exact
324 dnl  replacement, since it doesn't set the flags like adcl does.
325 dnl
326 dnl  This finds a use in K6 mpn_addmul_1, mpn_submul_1, mpn_mul_basecase and
327 dnl  mpn_sqr_basecase because on K6 an adcl is slow, the branch
328 dnl  misprediction penalty is small, and the multiply algorithm used leads
329 dnl  to a carry bit on average only 1/4 of the time.
330 dnl
331 dnl  jadcl0_disabled can be set to 1 to instead issue an ordinary adcl for
332 dnl  comparison.  For example,
333 dnl
334 dnl             define(`jadcl0_disabled',1)
335 dnl
336 dnl  When using a register operand, eg. "jadcl0(%edx)", the jnc/incl code is
337 dnl  the same size as an adcl.  This makes it possible to use the exact same
338 dnl  computed jump code when testing the relative speed of jnc/incl and adcl
339 dnl  with jadcl0_disabled.
340
341 define(jadcl0,
342 m4_assert_numargs(1)
343 `ifelse(jadcl0_disabled,1,
344         `adcl   $`'0, $1',
345         `jnc    1f
346         incl    $1
347 1:dnl')')
348
349
350 dnl  Usage: cmov_available_p
351 dnl
352 dnl  Expand to 1 if cmov is available, 0 if not.
353
354 define(cmov_available_p,
355 `m4_ifdef_anyof_p(
356         `HAVE_TARGET_CPU_pentiumpro',
357         `HAVE_TARGET_CPU_pentium2',
358         `HAVE_TARGET_CPU_pentium3',
359         `HAVE_TARGET_CPU_athlon')')
360
361
362 dnl  Usage: x86_lookup(target, key,value, key,value, ...)
363 dnl         x86_lookup_p(target, key,value, key,value, ...)
364 dnl
365 dnl  Look for `target' among the `key' parameters.
366 dnl
367 dnl  x86_lookup expands to the corresponding `value', or generates an error
368 dnl  if `target' isn't found.
369 dnl
370 dnl  x86_lookup_p expands to 1 if `target' is found, or 0 if not.
371
372 define(x86_lookup,
373 `ifelse(eval($#<3),1,
374 `m4_error(`unrecognised part of x86 instruction: $1
375 ')',
376 `ifelse(`$1',`$2', `$3',
377 `x86_lookup(`$1',shift(shift(shift($@))))')')')
378
379 define(x86_lookup_p,
380 `ifelse(eval($#<3),1, `0',
381 `ifelse(`$1',`$2',    `1',
382 `x86_lookup_p(`$1',shift(shift(shift($@))))')')')
383
384
385 dnl  Usage: x86_opcode_reg32(reg)
386 dnl         x86_opcode_reg32_p(reg)
387 dnl
388 dnl  x86_opcode_reg32 expands to the standard 3 bit encoding for the given
389 dnl  32-bit register, eg. `%ebp' turns into 5.
390 dnl
391 dnl  x86_opcode_reg32_p expands to 1 if reg is a valid 32-bit register, or 0
392 dnl  if not.
393
394 define(x86_opcode_reg32,
395 m4_assert_numargs(1)
396 `x86_lookup(`$1',x86_opcode_reg32_list)')
397
398 define(x86_opcode_reg32_p,
399 m4_assert_onearg()
400 `x86_lookup_p(`$1',x86_opcode_reg32_list)')
401
402 define(x86_opcode_reg32_list,
403 ``%eax',0,
404 `%ecx',1,
405 `%edx',2,
406 `%ebx',3,
407 `%esp',4,
408 `%ebp',5,
409 `%esi',6,
410 `%edi',7')
411
412
413 dnl  Usage: x86_opcode_tttn(cond)
414 dnl
415 dnl  Expand to the 4-bit "tttn" field value for the given x86 branch
416 dnl  condition (like `c', `ae', etc).
417
418 define(x86_opcode_tttn,
419 m4_assert_numargs(1)
420 `x86_lookup(`$1',x86_opcode_ttn_list)')
421
422 define(x86_opcode_tttn_list,
423 ``o',  0,
424 `no',  1,
425 `b',   2, `c',  2, `nae',2,
426 `nb',  3, `nc', 3, `ae', 3,
427 `e',   4, `z',  4,
428 `ne',  5, `nz', 5,
429 `be',  6, `na', 6,
430 `nbe', 7, `a',  7,
431 `s',   8,
432 `ns',  9,
433 `p',  10, `pe', 10, `npo',10,
434 `np', 11, `npe',11, `po', 11,
435 `l',  12, `nge',12,
436 `nl', 13, `ge', 13,
437 `le', 14, `ng', 14,
438 `nle',15, `g',  15')
439
440
441 dnl  Usage: cmovCC(srcreg,dstreg)
442 dnl
443 dnl  Generate a cmov instruction if the target supports cmov, or simulate it
444 dnl  with a conditional jump if not (the latter being meant only for
445 dnl  testing).  For example,
446 dnl
447 dnl         cmovz(  %eax, %ebx)
448 dnl
449 dnl  cmov instructions are generated using .byte sequences, since only
450 dnl  recent versions of gas know cmov.
451 dnl
452 dnl  The source operand can only be a plain register.  (m4 code implementing
453 dnl  full memory addressing modes exists, believe it or not, but isn't
454 dnl  currently needed and isn't included.)
455 dnl
456 dnl  All the standard conditions are defined.  Attempting to use one without
457 dnl  the macro parentheses, such as just "cmovbe %eax, %ebx", will provoke
458 dnl  an error.  This ensures the necessary .byte sequences aren't
459 dnl  accidentally missed.
460
461 dnl  Called: define_cmov_many(cond,tttn,cond,tttn,...)
462 define(define_cmov_many,
463 `ifelse(m4_length(`$1'),0,,
464 `define_cmov(`$1',`$2')define_cmov_many(shift(shift($@)))')')
465
466 dnl  Called: define_cmov(cond,tttn)
467 define(define_cmov,
468 m4_assert_numargs(2)
469 `define(`cmov$1',
470 m4_instruction_wrapper()
471 m4_assert_numargs(2)
472 `cmov_internal'(m4_doublequote($`'0),``$1',`$2'',dnl
473 m4_doublequote($`'1),m4_doublequote($`'2)))')
474
475 define_cmov_many(x86_opcode_tttn_list)
476
477
478 dnl  Called: cmov_internal(name,cond,tttn,src,dst)
479 define(cmov_internal,
480 m4_assert_numargs(5)
481 `ifelse(cmov_available_p,1,
482 `cmov_bytes_tttn(`$1',`$3',`$4',`$5')',
483 `m4_warning(`warning, simulating cmov with jump, use for testing only
484 ')cmov_simulate(`$2',`$4',`$5')')')
485
486 dnl  Called: cmov_simulate(cond,src,dst)
487 dnl  If this is going to be used with memory operands for the source it will
488 dnl  need to be changed to do a fetch even if the condition is false, so as
489 dnl  to trigger exceptions the same way a real cmov does.
490 define(cmov_simulate,
491 m4_assert_numargs(3)
492         `j$1    1f      C cmov$1 $2, $3
493         jmp     2f
494 1:      movl    $2, $3
495 2:')
496
497 dnl  Called: cmov_bytes_tttn(name,tttn,src,dst)
498 define(cmov_bytes_tttn,
499 m4_assert_numargs(4)
500 `.byte  dnl
501 15, dnl
502 eval(64+$2), dnl
503 eval(192+8*x86_opcode_reg32(`$4')+x86_opcode_reg32(`$3')) dnl
504         C `$1 $3, $4'')
505
506
507 dnl  Usage: loop_or_decljnz label
508 dnl
509 dnl  Generate either a "loop" instruction or a "decl %ecx / jnz", whichever
510 dnl  is better.  "loop" is better on K6 and probably on 386, on other chips
511 dnl  separate decl/jnz is better.
512 dnl
513 dnl  This macro is just for mpn/x86/divrem_1.asm and mpn/x86/mod_1.asm where
514 dnl  this loop_or_decljnz variation is enough to let the code be shared by
515 dnl  all chips.
516
517 define(loop_or_decljnz,
518 `ifelse(loop_is_better_p,1,
519         `loop',
520         `decl   %ecx
521         jnz')')
522
523 define(loop_is_better_p,
524 `m4_ifdef_anyof_p(`HAVE_TARGET_CPU_k6',
525                   `HAVE_TARGET_CPU_k62',
526                   `HAVE_TARGET_CPU_k63',
527                   `HAVE_TARGET_CPU_i386')')
528
529
530 dnl  Usage: Zdisp(inst,op,op,op)
531 dnl
532 dnl  Generate explicit .byte sequences if necessary to force a byte-sized
533 dnl  zero displacement on an instruction.  For example,
534 dnl
535 dnl         Zdisp(  movl,   0,(%esi), %eax)
536 dnl
537 dnl  expands to
538 dnl
539 dnl                 .byte   139,70,0  C movl 0(%esi), %eax
540 dnl
541 dnl  If the displacement given isn't 0, then normal assembler code is
542 dnl  generated.  For example,
543 dnl
544 dnl         Zdisp(  movl,   4,(%esi), %eax)
545 dnl
546 dnl  expands to
547 dnl
548 dnl                 movl    4(%esi), %eax
549 dnl
550 dnl  This means a single Zdisp() form can be used with an expression for the
551 dnl  displacement, and .byte will be used only if necessary.  The
552 dnl  displacement argument is eval()ed.
553 dnl
554 dnl  Because there aren't many places a 0(reg) form is wanted, Zdisp is
555 dnl  implemented with a table of instructions and encodings.  A new entry is
556 dnl  needed for any different operation or registers.
557
558 define(Zdisp,
559 `define(`Zdisp_found',0)dnl
560 Zdisp_match( movl, %eax, 0,(%edi), `137,71,0',    $@)`'dnl
561 Zdisp_match( movl, %ebx, 0,(%edi), `137,95,0',    $@)`'dnl
562 Zdisp_match( movl, %esi, 0,(%edi), `137,119,0',   $@)`'dnl
563 Zdisp_match( movl, 0,(%ebx), %eax, `139,67,0',    $@)`'dnl
564 Zdisp_match( movl, 0,(%ebx), %esi, `139,115,0',   $@)`'dnl
565 Zdisp_match( movl, 0,(%esi), %eax, `139,70,0',    $@)`'dnl
566 Zdisp_match( movl, 0,(%esi,%ecx,4), %eax, `0x8b,0x44,0x8e,0x00',      $@)`'dnl
567 Zdisp_match( addl, %ebx, 0,(%edi), `1,95,0',      $@)`'dnl
568 Zdisp_match( addl, %ecx, 0,(%edi), `1,79,0',      $@)`'dnl
569 Zdisp_match( addl, %esi, 0,(%edi), `1,119,0',     $@)`'dnl
570 Zdisp_match( subl, %ecx, 0,(%edi), `41,79,0',     $@)`'dnl
571 Zdisp_match( adcl, 0,(%edx), %esi, `19,114,0',    $@)`'dnl
572 Zdisp_match( sbbl, 0,(%edx), %esi, `27,114,0',    $@)`'dnl
573 Zdisp_match( movq, 0,(%eax,%ecx,8), %mm0, `0x0f,0x6f,0x44,0xc8,0x00', $@)`'dnl
574 Zdisp_match( movq, 0,(%ebx,%eax,4), %mm0, `0x0f,0x6f,0x44,0x83,0x00', $@)`'dnl
575 Zdisp_match( movq, 0,(%ebx,%eax,4), %mm2, `0x0f,0x6f,0x54,0x83,0x00', $@)`'dnl
576 Zdisp_match( movq, 0,(%esi),        %mm0, `15,111,70,0',     $@)`'dnl
577 Zdisp_match( movq, %mm0,        0,(%edi), `15,127,71,0',     $@)`'dnl
578 Zdisp_match( movq, %mm2, 0,(%ecx,%eax,4), `0x0f,0x7f,0x54,0x81,0x00', $@)`'dnl
579 Zdisp_match( movq, %mm2, 0,(%edx,%eax,4), `0x0f,0x7f,0x54,0x82,0x00', $@)`'dnl
580 Zdisp_match( movq, %mm0, 0,(%edx,%ecx,8), `0x0f,0x7f,0x44,0xca,0x00', $@)`'dnl
581 Zdisp_match( movd, 0,(%eax,%ecx,8), %mm1, `0x0f,0x6e,0x4c,0xc8,0x00', $@)`'dnl
582 Zdisp_match( movd, 0,(%edx,%ecx,8), %mm0, `0x0f,0x6e,0x44,0xca,0x00', $@)`'dnl
583 Zdisp_match( movd, %mm0, 0,(%eax,%ecx,4), `0x0f,0x7e,0x44,0x88,0x00', $@)`'dnl
584 Zdisp_match( movd, %mm0, 0,(%ecx,%eax,4), `0x0f,0x7e,0x44,0x81,0x00', $@)`'dnl
585 Zdisp_match( movd, %mm2, 0,(%ecx,%eax,4), `0x0f,0x7e,0x54,0x81,0x00', $@)`'dnl
586 ifelse(Zdisp_found,0,
587 `m4_error(`unrecognised instruction in Zdisp: $1 $2 $3 $4
588 ')')')
589
590 define(Zdisp_match,
591 `ifelse(eval(m4_stringequal_p(`$1',`$6')
592         && m4_stringequal_p(`$2',0)
593         && m4_stringequal_p(`$3',`$8')
594         && m4_stringequal_p(`$4',`$9')),1,
595 `define(`Zdisp_found',1)dnl
596 ifelse(eval(`$7'),0,
597 `       .byte   $5  C `$1 0$3, $4'',
598 `       $6      $7$8, $9')',
599
600 `ifelse(eval(m4_stringequal_p(`$1',`$6')
601         && m4_stringequal_p(`$2',`$7')
602         && m4_stringequal_p(`$3',0)
603         && m4_stringequal_p(`$4',`$9')),1,
604 `define(`Zdisp_found',1)dnl
605 ifelse(eval(`$8'),0,
606 `       .byte   $5  C `$1 $2, 0$4'',
607 `       $6      $7, $8$9')')')')
608
609
610 dnl  Usage: shldl(count,src,dst)
611 dnl         shrdl(count,src,dst)
612 dnl         shldw(count,src,dst)
613 dnl         shrdw(count,src,dst)
614 dnl
615 dnl  Generate a double-shift instruction, possibly omitting a %cl count
616 dnl  parameter if that's what the assembler requires, as indicated by
617 dnl  WANT_SHLDL_CL in config.m4.  For example,
618 dnl
619 dnl         shldl(  %cl, %eax, %ebx)
620 dnl
621 dnl  turns into either
622 dnl
623 dnl         shldl   %cl, %eax, %ebx
624 dnl  or
625 dnl         shldl   %eax, %ebx
626 dnl
627 dnl  Immediate counts are always passed through unchanged.  For example,
628 dnl
629 dnl         shrdl(  $2, %esi, %edi)
630 dnl  becomes
631 dnl         shrdl   $2, %esi, %edi
632 dnl
633 dnl
634 dnl  If you forget to use the macro form "shldl( ...)" and instead write
635 dnl  just a plain "shldl ...", an error results.  This ensures the necessary
636 dnl  variant treatment of %cl isn't accidentally bypassed.
637
638 define(define_shd_instruction,
639 `define($1,
640 m4_instruction_wrapper()
641 m4_assert_numargs(3)
642 `shd_instruction'(m4_doublequote($`'0),m4_doublequote($`'1),dnl
643 m4_doublequote($`'2),m4_doublequote($`'3)))')
644
645 dnl  Effectively: define(shldl,`shd_instruction(`$0',`$1',`$2',`$3')') etc
646 define_shd_instruction(shldl)
647 define_shd_instruction(shrdl)
648 define_shd_instruction(shldw)
649 define_shd_instruction(shrdw)
650
651 dnl  Called: shd_instruction(op,count,src,dst)
652 define(shd_instruction,
653 m4_assert_numargs(4)
654 m4_assert_defined(`WANT_SHLDL_CL')
655 `ifelse(eval(m4_stringequal_p(`$2',`%cl') && !WANT_SHLDL_CL),1,
656 ``$1'   `$3', `$4'',
657 ``$1'   `$2', `$3', `$4'')')
658
659
660 dnl  Usage: ASSERT(cond, instructions)
661 dnl
662 dnl  If WANT_ASSERT is 1, output the given instructions and expect the given
663 dnl  flags condition to then be satisfied.  For example,
664 dnl
665 dnl         ASSERT(ne, `cmpl %eax, %ebx')
666 dnl
667 dnl  The instructions can be omitted to just assert a flags condition with
668 dnl  no extra calculation.  For example,
669 dnl
670 dnl         ASSERT(nc)
671 dnl
672 dnl  When `instructions' is not empty, a pushf/popf is added to preserve the
673 dnl  flags, but the instructions themselves must preserve any registers that
674 dnl  matter.  FRAME is adjusted for the push and pop, so the instructions
675 dnl  given can use defframe() stack variables.
676
677 define(ASSERT,
678 m4_assert_numargs_range(1,2)
679 `ifelse(WANT_ASSERT,1,
680         `C ASSERT
681 ifelse(`$2',,,` pushf   ifdef(`FRAME',`FRAME_pushl()')')
682         $2
683         j`$1'   1f
684         ud2     C assertion failed
685 1:
686 ifelse(`$2',,,` popf    ifdef(`FRAME',`FRAME_popl()')')
687 ')')
688
689
690 dnl  Usage: movl_text_address(label,register)
691 dnl
692 dnl  Get the address of a text segment label, using either a plain movl or a
693 dnl  position-independent calculation, as necessary.  For example,
694 dnl
695 dnl         movl_code_address(L(foo),%eax)
696 dnl
697 dnl  This macro is only meant for use in ASSERT()s or when testing, since
698 dnl  the PIC sequence it generates will want to be done with a ret balancing
699 dnl  the call on CPUs with return address branch predition.
700 dnl
701 dnl  The addl generated here has a backward reference to 1b, and so won't
702 dnl  suffer from the two forwards references bug in old gas (described in
703 dnl  mpn/x86/README.family).
704
705 define(movl_text_address,
706 `ifdef(`PIC',
707         `call   1f
708 1:      popl    $2      C %eip
709         addl    `$'$1-1b, $2',
710         `movl   `$'$1, $2')')
711
712
713 divert`'dnl