progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / base / asm-common.h
CommitLineData
1a0c09c4
MW
1/// -*- mode: asm; asm-comment-char: ?/ -*-
2///
08b868da 3/// Common definitions for asesembler source files
1a0c09c4
MW
4///
5/// (c) 2015 Straylight/Edgeware
6///
7
8///----- Licensing notice ---------------------------------------------------
9///
10/// This file is part of Catacomb.
11///
12/// Catacomb is free software; you can redistribute it and/or modify
13/// it under the terms of the GNU Library General Public License as
14/// published by the Free Software Foundation; either version 2 of the
15/// License, or (at your option) any later version.
16///
17/// Catacomb is distributed in the hope that it will be useful,
18/// but WITHOUT ANY WARRANTY; without even the implied warranty of
19/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20/// GNU Library General Public License for more details.
21///
22/// You should have received a copy of the GNU Library General Public
23/// License along with Catacomb; if not, write to the Free
24/// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25/// MA 02111-1307, USA.
26
8ce88ea5
MW
27#ifndef CATACOMB_ASM_COMMON_H
28#define CATACOMB_ASM_COMMON_H
29
1a0c09c4
MW
30///--------------------------------------------------------------------------
31/// General definitions.
32
898f32b3
MW
33// Preprocessor hacks.
34#define STRINGY(x) _STRINGY(x, y)
35#define _STRINGY(x) #x
36#define GLUE(x, y) _GLUE(x, y)
37#define _GLUE(x, y) x##y
38#define _EMPTY
39
f8e509a9
MW
40// Some useful variables.
41 .L$_subsec = 0
42
43// Literal pools done the hard way.
44#define _LIT .text .L$_subsec + 1
45#define _ENDLIT .text .L$_subsec
6c54cbd3 46#define _LTORG .L$_subsec = .L$_subsec + 2; .text .L$_subsec
f8e509a9 47
1a517bb3
MW
48// Announcing an internal function.
49#define INTFUNC(name) \
1a0c09c4 50 TYPE_FUNC(name); \
8a1aa284 51 .macro ENDFUNC; _ENDFUNC(name); .endm; \
0923a413 52 .L$_prologue_p = 0; .L$_frameptr_p = 0; \
1a0c09c4 53 FUNC_PREHOOK(name); \
1a517bb3 54name: \
1a0c09c4
MW
55 FUNC_POSTHOOK(name)
56
1a517bb3
MW
57// Announcing an external function.
58#define FUNC(name) \
59 .globl F(name); \
60INTFUNC(F(name))
61
1a0c09c4
MW
62// Marking the end of a function.
63#define _ENDFUNC(name) \
0923a413
MW
64 .if ~ .L$_prologue_p; .error "Missing `endprologue'"; .endif; \
65 .if .L$_frameptr_p; .purgem dropfp; .endif; \
1a0c09c4
MW
66 .purgem ENDFUNC; \
67 SIZE_OBJ(name); \
f8e509a9 68 ENDFUNC_HOOK(name); \
6c54cbd3 69 _LTORG
1a0c09c4 70
8ae4c946
MW
71// Make a helper function, if necessary.
72#define AUXFN(name) \
73 .ifndef .L$_auxfn_def.name; \
74 .text 7128; \
75 .macro _ENDAUXFN; _ENDAUXFN_TAIL(name); .endm; \
76 FUNC_PREHOOK(name); \
77name:
78#define _ENDAUXFN_TAIL(name) \
79 .purgem _ENDAUXFN; \
80 .text .L$_subsec; \
81 .L$_auxfn_def.name = 1
82#define ENDAUXFN _ENDAUXFN; .endif
83
1a0c09c4
MW
84///--------------------------------------------------------------------------
85/// ELF-specific hacking.
86
87#if __ELF__
88
148c3643
MW
89// Section types.
90#if CPUFAM_ARMEL
91# define _SECTTY(ty) %ty
92#else
93# define _SECTTY(ty) @ty
94#endif
95
b0c2da14
MW
96// Section selection.
97#define RODATA .section .rodata, "a", _SECTTY(progbits)
98
5336ba54 99// Additional symbol metadata.
1a0c09c4 100#define TYPE_FUNC(name) .type name, STT_FUNC
6ae7b854 101#define TYPE_OBJ(name) .type name, STT_OBJECT
1a0c09c4
MW
102#define SIZE_OBJ(name) .size name, . - name
103
f2fb936a
MW
104// Special arrangements for position-independent code.
105#if __PIC__ || __PIE__
106# define WANT_PIC 1
107#endif
108
67e71236
MW
109// Don't make the stack executable by default.
110#ifndef FORCE_EXECUTABLE_STACK
111 .pushsection .note.GNU-stack, "", _SECTTY(progbits)
112 .popsection
113#endif
114
1a0c09c4
MW
115#endif
116
117///--------------------------------------------------------------------------
0f23f75f
MW
118/// Windows-specific hacking.
119
120#if ABI_WIN
1a0c09c4 121
5336ba54 122// Function names need decorating on 32-bit i386.
1a0c09c4 123#if CPUFAM_X86
0f23f75f
MW
124# define F(name) _##name
125#endif
126
b0c2da14
MW
127// Section selection.
128#define RODATA .section .rdata, "dr"
129
0f23f75f
MW
130#endif
131
132///--------------------------------------------------------------------------
133/// x86- and amd64-specific hacking.
134///
135/// It's (slightly) easier to deal with both of these in one go.
136
137#if CPUFAM_X86 || CPUFAM_AMD64
1a0c09c4 138
2cb17e02
MW
139// Word size.
140#if CPUFAM_X86
141# define WORDSZ 4
142#endif
143#if CPUFAM_AMD64
144# define WORDSZ 8
145#endif
146
1a0c09c4
MW
147// Set the function hooks.
148#define FUNC_PREHOOK(_) .balign 16
149
f71dd54d
MW
150// On Windows, arrange to install stack-unwinding data.
151#if CPUFAM_AMD64 && ABI_WIN
152# define FUNC_POSTHOOK(name) .seh_proc name
153# define ENDFUNC_HOOK(_) .seh_endproc
154// Procedures are expected to invoke `.seh_setframe' if necessary, and
155// `.seh_pushreg' and friends, and `.seh_endprologue'.
156#endif
157
0923a413
MW
158#if __ELF__
159# define FUNC_POSTHOOK(_) .cfi_startproc
160# define ENDFUNC_HOOK(_) .cfi_endproc
161#endif
162
1a0c09c4
MW
163// Don't use the wretched AT&T syntax. It's festooned with pointless
164// punctuation, and all of the data movement is backwards. Ugh!
165 .intel_syntax noprefix
166
167// Call external subroutine at ADDR, possibly via PLT.
8a1aa284 168.macro callext addr
1a0c09c4
MW
169#if WANT_PIC
170 call \addr@PLT
171#else
172 call \addr
173#endif
8a1aa284 174.endm
1a0c09c4
MW
175
176// Do I need to arrange a spare GOT register?
177#if WANT_PIC && CPUFAM_X86
178# define NEED_GOT 1
179#endif
180#define GOTREG ebx // Not needed in AMD64 so don't care.
181
182// Maybe load GOT address into GOT.
8a1aa284 183.macro ldgot got=GOTREG
0f23f75f 184#if WANT_PIC && CPUFAM_X86
8ae4c946 185 AUXFN(_ldgot.\got)
1a0c09c4
MW
186 mov \got, [esp]
187 ret
8ae4c946
MW
188 ENDAUXFN
189 call _ldgot.\got
190 add \got, offset _GLOBAL_OFFSET_TABLE_
1a0c09c4 191#endif
8a1aa284 192.endm
1a0c09c4
MW
193
194// Load address of external symbol ADDR into REG, maybe using GOT.
8a1aa284 195.macro leaext reg, addr, got=GOTREG
1a0c09c4 196#if WANT_PIC
0f23f75f 197# if CPUFAM_X86
1a0c09c4 198 mov \reg, [\got + \addr@GOT]
0f23f75f
MW
199# endif
200# if CPUFAM_AMD64
201 mov \reg, \addr@GOTPCREL[rip]
202# endif
1a0c09c4 203#else
0f23f75f 204# if CPUFAM_X86
1a0c09c4 205 mov \reg, offset \addr
0f23f75f
MW
206# endif
207# if CPUFAM_AMD64
208 lea \reg, \addr[rip]
209# endif
1a0c09c4 210#endif
8a1aa284 211.endm
1a0c09c4
MW
212
213// Address expression (possibly using a base register, and a displacement)
214// referring to ADDR, which is within our module, maybe using GOT.
215#define INTADDR(...) INTADDR__0(__VA_ARGS__, GOTREG, dummy)
216#define INTADDR__0(addr, got, ...) INTADDR__1(addr, got)
0f23f75f
MW
217#if CPUFAM_AMD64
218# define INTADDR__1(addr, got) addr + rip
219#elif WANT_PIC
1a0c09c4
MW
220# define INTADDR__1(addr, got) got + addr@GOTOFF
221#else
222# define INTADDR__1(addr, got) addr
223#endif
224
981a9e5d 225// Permutations for SIMD instructions. SHUF(D, C, B, A) is an immediate,
a117c06f
MW
226// suitable for use in `pshufd' or `shufpd', which copies element A
227// (0 <= A < 4) of the source to element 0 of the destination, element B to
228// element 1, element C to element 2, and element D to element 3.
981a9e5d 229#define SHUF(d, c, b, a) (64*(d) + 16*(c) + 4*(b) + (a))
a13b5730 230
43ea7558
MW
231// Map register names to their individual pieces.
232
233// Apply decoration decor to (internal) register name reg of type ty.
234//
235// See `R_...' for internal register names. Decorations are as follows.
236//
237// b low byte (e.g., `al', `r8b')
238// h high byte (e.g., `ah')
239// w word (e.g., `ax', `r8w')
240// d doubleword (e.g., `eax', `r8d')
241// q quadword (e.g., `rax', `r8')
242// r whole register (doubleword on x86, quadword on amd64)
243//
244// And types are as follows.
245//
246// abcd the four traditional registers `a', `b', `c', `d'
247// xp the four pointer registers `si', `di', `bp', `sp'
248// ip the instruction pointer `ip'
249// rn the AMD64 numbered registers `r8'--`r15'
250#define _DECOR(ty, decor, reg) _DECOR_##ty##_##decor(reg)
251
252// Internal macros: _DECOR_ty_decor(reg) applies decoration decor to
253// (internal) register name reg of type ty.
254
255#define _DECOR_abcd_b(reg) reg##l
256#define _DECOR_abcd_h(reg) reg##h
257#define _DECOR_abcd_w(reg) reg##x
258#define _DECOR_abcd_d(reg) e##reg##x
259#if CPUFAM_AMD64
260# define _DECOR_abcd_q(reg) r##reg##x
261#endif
262
43ea7558
MW
263#define _DECOR_xp_w(reg) reg
264#define _DECOR_xp_d(reg) e##reg
265#if CPUFAM_AMD64
a105615f 266# define _DECOR_xp_b(reg) reg##l
43ea7558
MW
267# define _DECOR_xp_q(reg) r##reg
268#endif
269
270#define _DECOR_ip_w(reg) reg
271#define _DECOR_ip_d(reg) e##reg
272#if CPUFAM_AMD64
273# define _DECOR_ip_q(reg) r##reg
274#endif
275
276#if CPUFAM_AMD64
277# define _DECOR_rn_b(reg) reg##b
278# define _DECOR_rn_w(reg) reg##w
279# define _DECOR_rn_d(reg) reg##d
280# define _DECOR_rn_q(reg) reg
281# define _DECOR_rn_r(reg) reg
282#endif
283
005cd277
MW
284#define _DECOR_mem_b(addr) byte ptr addr
285#define _DECOR_mem_w(addr) word ptr addr
286#define _DECOR_mem_d(addr) dword ptr addr
287#if CPUFAM_AMD64
288# define _DECOR_mem_q(addr) qword ptr addr
289#endif
290
7e251005
MW
291#define _DECOR_imm_b(imm) byte imm
292#define _DECOR_imm_w(imm) word imm
293#define _DECOR_imm_d(imm) dword imm
294#if CPUFAM_AMD64
295# define _DECOR_imm_q(imm) qword imm
296#endif
297
43ea7558
MW
298#if CPUFAM_X86
299# define _DECOR_abcd_r(reg) e##reg##x
300# define _DECOR_xp_r(reg) e##reg
301# define _DECOR_ip_r(reg) e##reg
3c0490d1 302# define _DECOR_mem_r(addr) dword ptr addr
7e251005 303# define _DECOR_imm_r(imm) dword imm
43ea7558
MW
304#endif
305#if CPUFAM_AMD64
306# define _DECOR_abcd_r(reg) r##reg##x
307# define _DECOR_xp_r(reg) r##reg
308# define _DECOR_ip_r(reg) r##reg
3c0490d1 309# define _DECOR_mem_r(addr) qword ptr addr
7e251005 310# define _DECOR_imm_r(imm) qword imm
43ea7558
MW
311#endif
312
43ea7558
MW
313// R_r(decor) applies decoration decor to register r, which is an internal
314// register name. The internal register names are: `ip', `a', `b', `c', `d',
315// `si', `di', `bp', `sp', `r8'--`r15'.
4ff9d579 316#define R_nil(decor) nil
43ea7558
MW
317#define R_ip(decor) _DECOR(ip, decor, ip)
318#define R_a(decor) _DECOR(abcd, decor, a)
319#define R_b(decor) _DECOR(abcd, decor, b)
320#define R_c(decor) _DECOR(abcd, decor, c)
321#define R_d(decor) _DECOR(abcd, decor, d)
322#define R_si(decor) _DECOR(xp, decor, si)
323#define R_di(decor) _DECOR(xp, decor, di)
324#define R_bp(decor) _DECOR(xp, decor, bp)
325#define R_sp(decor) _DECOR(xp, decor, sp)
326#if CPUFAM_AMD64
327# define R_r8(decor) _DECOR(rn, decor, r8)
328# define R_r9(decor) _DECOR(rn, decor, r9)
329# define R_r10(decor) _DECOR(rn, decor, r10)
330# define R_r11(decor) _DECOR(rn, decor, r11)
331# define R_r12(decor) _DECOR(rn, decor, r12)
332# define R_r13(decor) _DECOR(rn, decor, r13)
333# define R_r14(decor) _DECOR(rn, decor, r14)
334# define R_r15(decor) _DECOR(rn, decor, r15)
335#endif
336
337// Refer to an in-memory datum of the type implied by decor residing at
338// address addr (which should supply its own square-brackets).
339#define MEM(decor, addr) _DECOR(mem, decor, addr)
340
7e251005
MW
341// Refer to an immediate datum of the type implied by decor.
342#define IMM(decor, imm) _DECOR(mem, decor, imm)
343
43ea7558
MW
344// Applies decoration decor to assembler-level register name reg.
345#define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor)
346
347// Internal macros: _REGFORM_r(decor) applies decoration decor to an
348// assembler-level register name, in place of any decoration that register
349// name has already.
350
4ff9d579
MW
351#define _REGFORM_nil(decor) R_nil(decor)
352
43ea7558
MW
353#define _REGFORM_ip(decor) R_ip(decor)
354#define _REGFORM_eip(decor) R_ip(decor)
355
356#define _REGFORM_a(decor) R_a(decor)
357#define _REGFORM_al(decor) R_a(decor)
358#define _REGFORM_ah(decor) R_a(decor)
359#define _REGFORM_ax(decor) R_a(decor)
360#define _REGFORM_eax(decor) R_a(decor)
361
362#define _REGFORM_b(decor) R_b(decor)
363#define _REGFORM_bl(decor) R_b(decor)
364#define _REGFORM_bh(decor) R_b(decor)
365#define _REGFORM_bx(decor) R_b(decor)
366#define _REGFORM_ebx(decor) R_b(decor)
367
368#define _REGFORM_c(decor) R_c(decor)
369#define _REGFORM_cl(decor) R_c(decor)
370#define _REGFORM_ch(decor) R_c(decor)
371#define _REGFORM_cx(decor) R_c(decor)
372#define _REGFORM_ecx(decor) R_c(decor)
373
374#define _REGFORM_d(decor) R_d(decor)
375#define _REGFORM_dl(decor) R_d(decor)
376#define _REGFORM_dh(decor) R_d(decor)
377#define _REGFORM_dx(decor) R_d(decor)
378#define _REGFORM_edx(decor) R_d(decor)
379
380#define _REGFORM_si(decor) R_si(decor)
381#define _REGFORM_sil(decor) R_si(decor)
382#define _REGFORM_esi(decor) R_si(decor)
383
384#define _REGFORM_di(decor) R_di(decor)
385#define _REGFORM_dil(decor) R_di(decor)
386#define _REGFORM_edi(decor) R_di(decor)
387
388#define _REGFORM_bp(decor) R_bp(decor)
389#define _REGFORM_bpl(decor) R_bp(decor)
390#define _REGFORM_ebp(decor) R_bp(decor)
391
392#define _REGFORM_sp(decor) R_sp(decor)
393#define _REGFORM_spl(decor) R_sp(decor)
394#define _REGFORM_esp(decor) R_sp(decor)
395
396#if CPUFAM_AMD64
397
398# define _REGFORM_rip(decor) R_ip(decor)
399# define _REGFORM_rsp(decor) R_sp(decor)
400# define _REGFORM_rbp(decor) R_bp(decor)
401# define _REGFORM_rdi(decor) R_di(decor)
402# define _REGFORM_rsi(decor) R_si(decor)
403# define _REGFORM_rdx(decor) R_d(decor)
404# define _REGFORM_rcx(decor) R_c(decor)
405# define _REGFORM_rbx(decor) R_b(decor)
406# define _REGFORM_rax(decor) R_a(decor)
407
408# define _REGFORM_r8(decor) R_r8(decor)
409# define _REGFORM_r8b(decor) R_r8(decor)
410# define _REGFORM_r8w(decor) R_r8(decor)
411# define _REGFORM_r8d(decor) R_r8(decor)
412
413# define _REGFORM_r9(decor) R_r9(decor)
414# define _REGFORM_r9b(decor) R_r9(decor)
415# define _REGFORM_r9w(decor) R_r9(decor)
416# define _REGFORM_r9d(decor) R_r9(decor)
417
418# define _REGFORM_r10(decor) R_r10(decor)
419# define _REGFORM_r10b(decor) R_r10(decor)
420# define _REGFORM_r10w(decor) R_r10(decor)
421# define _REGFORM_r10d(decor) R_r10(decor)
422
423# define _REGFORM_r11(decor) R_r11(decor)
424# define _REGFORM_r11b(decor) R_r11(decor)
425# define _REGFORM_r11w(decor) R_r11(decor)
426# define _REGFORM_r11d(decor) R_r11(decor)
427
428# define _REGFORM_r12(decor) R_r12(decor)
429# define _REGFORM_r12b(decor) R_r12(decor)
430# define _REGFORM_r12w(decor) R_r12(decor)
431# define _REGFORM_r12d(decor) R_r12(decor)
432
433# define _REGFORM_r13(decor) R_r13(decor)
434# define _REGFORM_r13b(decor) R_r13(decor)
435# define _REGFORM_r13w(decor) R_r13(decor)
436# define _REGFORM_r13d(decor) R_r13(decor)
437
438# define _REGFORM_r14(decor) R_r14(decor)
439# define _REGFORM_r14b(decor) R_r14(decor)
440# define _REGFORM_r14w(decor) R_r14(decor)
441# define _REGFORM_r14d(decor) R_r14(decor)
442
443# define _REGFORM_r15(decor) R_r15(decor)
444# define _REGFORM_r15b(decor) R_r15(decor)
445# define _REGFORM_r15w(decor) R_r15(decor)
446# define _REGFORM_r15d(decor) R_r15(decor)
447
448#endif
449
450// Macros for converting register names.
451#define BYTE(reg) _REGFORM(reg, b)
452#define HIBYTE(reg) _REGFORM(reg, h)
453#define WORD(reg) _REGFORM(reg, w)
454#define DWORD(reg) _REGFORM(reg, d)
455#if CPUFAM_AMD64
456# define QWORD(reg) _REGFORM(reg, q)
457#endif
458#define WHOLE(reg) _REGFORM(reg, r)
459
a90d420c
MW
460// Macros for some common registers.
461#define AX R_a(r)
462#define BX R_b(r)
463#define CX R_c(r)
464#define DX R_d(r)
465#define SI R_si(r)
466#define DI R_di(r)
467#define BP R_bp(r)
468#define SP R_sp(r)
469
0923a413 470// Stack management and unwinding.
a90d420c 471.macro setfp fp=BP, offset=0
0923a413 472 .if \offset == 0
a90d420c 473 mov \fp, SP
0923a413
MW
474#if __ELF__
475 .cfi_def_cfa_register \fp
476#endif
477#if ABI_WIN && CPUFAM_AMD64
478 .seh_setframe \fp, 0
479#endif
480 .else
a90d420c 481 lea \fp, [SP + \offset]
0923a413
MW
482#if __ELF__
483 .cfi_def_cfa_register \fp
484 .cfi_adjust_cfa_offset -\offset
485#endif
486#if ABI_WIN && CPUFAM_AMD64
487 .seh_setframe \fp, \offset
488#endif
489 .endif
490 .L$_frameptr_p = -1
491 .macro dropfp; _dropfp \fp, \offset; .endm
492.endm
493
cdc153a5 494.macro _dropfp fp, offset=0
0923a413 495 .if \offset == 0
a90d420c 496 mov SP, \fp
0923a413 497#if __ELF__
a90d420c 498 .cfi_def_cfa_register SP
0923a413
MW
499#endif
500 .else
a90d420c 501 lea SP, [\fp - \offset]
0923a413 502#if __ELF__
a90d420c 503 .cfi_def_cfa_register SP
0923a413
MW
504 .cfi_adjust_cfa_offset +\offset
505#endif
506 .endif
507 .L$_frameptr_p = 0
508 .purgem dropfp
509.endm
510
511.macro stalloc n
a90d420c 512 sub SP, \n
0923a413
MW
513#if __ELF__
514 .cfi_adjust_cfa_offset +\n
515#endif
516#if ABI_WIN && CPUFAM_AMD64
517 .seh_stackalloc \n
518#endif
519.endm
520
521.macro stfree n
a90d420c 522 add SP, \n
0923a413
MW
523#if __ELF__
524 .cfi_adjust_cfa_offset -\n
525#endif
526.endm
527
528.macro pushreg r
529 push \r
530#if __ELF__
531 .cfi_adjust_cfa_offset +WORDSZ
532 .cfi_rel_offset \r, 0
533#endif
534#if ABI_WIN && CPUFAM_AMD64
535 .seh_pushreg \r
536#endif
537.endm
538
539.macro popreg r
540 pop \r
541#if __ELF__
542 .cfi_adjust_cfa_offset -WORDSZ
543 .cfi_restore \r
544#endif
545.endm
546
547.macro savexmm r, offset
a90d420c 548 movdqa [SP + \offset], \r
0923a413
MW
549#if ABI_WIN && CPUFAM_AMD64
550 .seh_savexmm \r, \offset
551#endif
552.endm
553
554.macro rstrxmm r, offset
a90d420c 555 movdqa \r, [SP + \offset]
0923a413
MW
556.endm
557
558.macro endprologue
559#if ABI_WIN && CPUFAM_AMD64
560 .seh_endprologue
561#endif
562 .L$_prologue_p = -1
563.endm
564
1a0c09c4
MW
565#endif
566
567///--------------------------------------------------------------------------
61bd904b
MW
568/// ARM-specific hacking.
569
59d86860 570#if CPUFAM_ARMEL
61bd904b 571
9f6eb05d
MW
572// ARM/Thumb mode things. Use ARM by default.
573#define ARM .arm; .L$_pcoff = 8
574#define THUMB .thumb; .L$_pcoff = 4
575 ARM
576
61bd904b 577// Set the function hooks.
0923a413
MW
578#define FUNC_PREHOOK(_) .balign 4; .fnstart
579#define ENDFUNC_HOOK(_) .fnend; .ltorg
61bd904b
MW
580
581// Call external subroutine at ADDR, possibly via PLT.
8a1aa284 582.macro callext addr, cond=
61bd904b
MW
583#if WANT_PIC
584 bl\cond \addr(PLT)
585#else
586 bl\cond \addr
587#endif
8a1aa284 588.endm
61bd904b
MW
589
590// Do I need to arrange a spare GOT register?
591#if WANT_PIC
592# define NEED_GOT 1
593#endif
594#define GOTREG r9
595
596// Maybe load GOT address into GOT.
8a1aa284 597.macro ldgot cond=, got=GOTREG
61bd904b 598#if WANT_PIC
adca2a18
MW
599 ldr\cond \got, .L$_ldgot$\@
600.L$_ldgot_pc$\@:
2d03a881 601 add\cond \got, pc, \got
8a1aa284 602 _LIT
adca2a18
MW
603 .balign 4
604.L$_ldgot$\@:
9f6eb05d 605 .word _GLOBAL_OFFSET_TABLE_ - .L$_ldgot_pc$\@ - .L$_pcoff
8a1aa284 606 _ENDLIT
61bd904b 607#endif
8a1aa284 608.endm
61bd904b
MW
609
610// Load address of external symbol ADDR into REG, maybe using GOT.
8a1aa284 611.macro leaext reg, addr, cond=, got=GOTREG
61bd904b 612#if WANT_PIC
adca2a18 613 ldr\cond \reg, .L$_leaext$\@
2d03a881 614 ldr\cond \reg, [\got, \reg]
8a1aa284 615 _LIT
adca2a18
MW
616 .balign 4
617.L$_leaext$\@:
618 .word \addr(GOT)
8a1aa284 619 _ENDLIT
61bd904b 620#else
2d03a881 621 ldr\cond \reg, =\addr
61bd904b 622#endif
8a1aa284 623.endm
61bd904b 624
0c53ac58 625// Load address of external symbol ADDR into REG directly.
8a1aa284 626.macro leaextq reg, addr, cond=
0c53ac58
MW
627#if WANT_PIC
628 ldr\cond \reg, .L$_leaextq$\@
629.L$_leaextq_pc$\@:
b6db2017 630 .if .L$_pcoff == 8
0c53ac58 631 ldr\cond \reg, [pc, \reg]
b6db2017 632 .else
9f6eb05d
MW
633 add\cond \reg, pc
634 ldr\cond \reg, [\reg]
b6db2017 635 .endif
8a1aa284 636 _LIT
0c53ac58
MW
637 .balign 4
638.L$_leaextq$\@:
9f6eb05d 639 .word \addr(GOT_PREL) + (. - .L$_leaextq_pc$\@ - .L$_pcoff)
8a1aa284 640 _ENDLIT
0c53ac58
MW
641#else
642 ldr\cond \reg, =\addr
643#endif
8a1aa284 644.endm
0c53ac58 645
1a031196
MW
646.macro vzero vz=q15
647 // Set VZ (default q15) to zero.
648 vmov.u32 \vz, #0
649.endm
650
651.macro vshl128 vd, vn, nbit, vz=q15
652 // Set VD to VN shifted left by NBIT. Assume VZ (default q15) is
653 // all-bits-zero. NBIT must be a multiple of 8.
654 .if \nbit&3 != 0
655 .error "shift quantity must be whole number of bytes"
656 .endif
657 vext.8 \vd, \vz, \vn, #16 - (\nbit >> 3)
658.endm
659
660.macro vshr128 vd, vn, nbit, vz=q15
661 // Set VD to VN shifted right by NBIT. Assume VZ (default q15) is
662 // all-bits-zero. NBIT must be a multiple of 8.
663 .if \nbit&3 != 0
664 .error "shift quantity must be whole number of bytes"
665 .endif
666 vext.8 \vd, \vn, \vz, #\nbit >> 3
667.endm
668
43ea7558
MW
669// Apply decoration decor to register name reg.
670#define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor)
671
672// Internal macros: `_REGFORM_r(decor)' applies decoration decor to register
673// name r.
674
4ff9d579
MW
675#define _REGFORM_nil(decor) nil
676
43ea7558
MW
677#define _REGFORM_s0(decor) _DECOR(s, decor, 0)
678#define _REGFORM_s1(decor) _DECOR(s, decor, 1)
679#define _REGFORM_s2(decor) _DECOR(s, decor, 2)
680#define _REGFORM_s3(decor) _DECOR(s, decor, 3)
681#define _REGFORM_s4(decor) _DECOR(s, decor, 4)
682#define _REGFORM_s5(decor) _DECOR(s, decor, 5)
683#define _REGFORM_s6(decor) _DECOR(s, decor, 6)
684#define _REGFORM_s7(decor) _DECOR(s, decor, 7)
685#define _REGFORM_s8(decor) _DECOR(s, decor, 8)
686#define _REGFORM_s9(decor) _DECOR(s, decor, 9)
687#define _REGFORM_s10(decor) _DECOR(s, decor, 10)
688#define _REGFORM_s11(decor) _DECOR(s, decor, 11)
689#define _REGFORM_s12(decor) _DECOR(s, decor, 12)
690#define _REGFORM_s13(decor) _DECOR(s, decor, 13)
691#define _REGFORM_s14(decor) _DECOR(s, decor, 14)
692#define _REGFORM_s15(decor) _DECOR(s, decor, 15)
693#define _REGFORM_s16(decor) _DECOR(s, decor, 16)
694#define _REGFORM_s17(decor) _DECOR(s, decor, 17)
695#define _REGFORM_s18(decor) _DECOR(s, decor, 18)
696#define _REGFORM_s19(decor) _DECOR(s, decor, 19)
697#define _REGFORM_s20(decor) _DECOR(s, decor, 20)
698#define _REGFORM_s21(decor) _DECOR(s, decor, 21)
699#define _REGFORM_s22(decor) _DECOR(s, decor, 22)
700#define _REGFORM_s23(decor) _DECOR(s, decor, 23)
701#define _REGFORM_s24(decor) _DECOR(s, decor, 24)
702#define _REGFORM_s25(decor) _DECOR(s, decor, 25)
703#define _REGFORM_s26(decor) _DECOR(s, decor, 26)
704#define _REGFORM_s27(decor) _DECOR(s, decor, 27)
705#define _REGFORM_s28(decor) _DECOR(s, decor, 28)
706#define _REGFORM_s29(decor) _DECOR(s, decor, 29)
707#define _REGFORM_s30(decor) _DECOR(s, decor, 30)
708#define _REGFORM_s31(decor) _DECOR(s, decor, 31)
709
710#define _REGFORM_d0(decor) _DECOR(d, decor, 0)
711#define _REGFORM_d1(decor) _DECOR(d, decor, 1)
712#define _REGFORM_d2(decor) _DECOR(d, decor, 2)
713#define _REGFORM_d3(decor) _DECOR(d, decor, 3)
714#define _REGFORM_d4(decor) _DECOR(d, decor, 4)
715#define _REGFORM_d5(decor) _DECOR(d, decor, 5)
716#define _REGFORM_d6(decor) _DECOR(d, decor, 6)
717#define _REGFORM_d7(decor) _DECOR(d, decor, 7)
718#define _REGFORM_d8(decor) _DECOR(d, decor, 8)
719#define _REGFORM_d9(decor) _DECOR(d, decor, 9)
720#define _REGFORM_d10(decor) _DECOR(d, decor, 10)
721#define _REGFORM_d11(decor) _DECOR(d, decor, 11)
722#define _REGFORM_d12(decor) _DECOR(d, decor, 12)
723#define _REGFORM_d13(decor) _DECOR(d, decor, 13)
724#define _REGFORM_d14(decor) _DECOR(d, decor, 14)
725#define _REGFORM_d15(decor) _DECOR(d, decor, 15)
726#define _REGFORM_d16(decor) _DECOR(d, decor, 16)
727#define _REGFORM_d17(decor) _DECOR(d, decor, 17)
728#define _REGFORM_d18(decor) _DECOR(d, decor, 18)
729#define _REGFORM_d19(decor) _DECOR(d, decor, 19)
730#define _REGFORM_d20(decor) _DECOR(d, decor, 20)
731#define _REGFORM_d21(decor) _DECOR(d, decor, 21)
732#define _REGFORM_d22(decor) _DECOR(d, decor, 22)
733#define _REGFORM_d23(decor) _DECOR(d, decor, 23)
734#define _REGFORM_d24(decor) _DECOR(d, decor, 24)
735#define _REGFORM_d25(decor) _DECOR(d, decor, 25)
736#define _REGFORM_d26(decor) _DECOR(d, decor, 26)
737#define _REGFORM_d27(decor) _DECOR(d, decor, 27)
738#define _REGFORM_d28(decor) _DECOR(d, decor, 28)
739#define _REGFORM_d29(decor) _DECOR(d, decor, 29)
740#define _REGFORM_d30(decor) _DECOR(d, decor, 30)
741#define _REGFORM_d31(decor) _DECOR(d, decor, 31)
742
743#define _REGFORM_q0(decor) _DECOR(q, decor, 0)
744#define _REGFORM_q1(decor) _DECOR(q, decor, 1)
745#define _REGFORM_q2(decor) _DECOR(q, decor, 2)
746#define _REGFORM_q3(decor) _DECOR(q, decor, 3)
747#define _REGFORM_q4(decor) _DECOR(q, decor, 4)
748#define _REGFORM_q5(decor) _DECOR(q, decor, 5)
749#define _REGFORM_q6(decor) _DECOR(q, decor, 6)
750#define _REGFORM_q7(decor) _DECOR(q, decor, 7)
751#define _REGFORM_q8(decor) _DECOR(q, decor, 8)
752#define _REGFORM_q9(decor) _DECOR(q, decor, 9)
753#define _REGFORM_q10(decor) _DECOR(q, decor, 10)
754#define _REGFORM_q11(decor) _DECOR(q, decor, 11)
755#define _REGFORM_q12(decor) _DECOR(q, decor, 12)
756#define _REGFORM_q13(decor) _DECOR(q, decor, 13)
757#define _REGFORM_q14(decor) _DECOR(q, decor, 14)
758#define _REGFORM_q15(decor) _DECOR(q, decor, 15)
759
760// `_LOPART(n)' and `_HIPART(n)' return the numbers of the register halves of
761// register n, i.e., 2*n and 2*n + 1 respectively.
762#define _LOPART(n) _GLUE(_LOPART_, n)
763#define _HIPART(n) _GLUE(_HIPART_, n)
764
765// Internal macros: `_LOPART_n' and `_HIPART_n' return the numbers of the
766// register halves of register n, i.e., 2*n and 2*n + 1 respectively.
767
768#define _LOPART_0 0
769#define _HIPART_0 1
770#define _LOPART_1 2
771#define _HIPART_1 3
772#define _LOPART_2 4
773#define _HIPART_2 5
774#define _LOPART_3 6
775#define _HIPART_3 7
776#define _LOPART_4 8
777#define _HIPART_4 9
778#define _LOPART_5 10
779#define _HIPART_5 11
780#define _LOPART_6 12
781#define _HIPART_6 13
782#define _LOPART_7 14
783#define _HIPART_7 15
784#define _LOPART_8 16
785#define _HIPART_8 17
786#define _LOPART_9 18
787#define _HIPART_9 19
788#define _LOPART_10 20
789#define _HIPART_10 21
790#define _LOPART_11 22
791#define _HIPART_11 23
792#define _LOPART_12 24
793#define _HIPART_12 25
794#define _LOPART_13 26
795#define _HIPART_13 27
796#define _LOPART_14 28
797#define _HIPART_14 29
798#define _LOPART_15 30
799#define _HIPART_15 31
800
801// Return the register number of the pair containing register n, i.e.,
802// floor(n/2).
803#define _PAIR(n) _GLUE(_PAIR_, n)
804
805// Internal macros: `_PAIR_n' returns the register number of the pair
806// containing register n, i.e., floor(n/2).
807#define _PAIR_0 0
808#define _PAIR_1 0
809#define _PAIR_2 1
810#define _PAIR_3 1
811#define _PAIR_4 2
812#define _PAIR_5 2
813#define _PAIR_6 3
814#define _PAIR_7 3
815#define _PAIR_8 4
816#define _PAIR_9 4
817#define _PAIR_10 5
818#define _PAIR_11 5
819#define _PAIR_12 6
820#define _PAIR_13 6
821#define _PAIR_14 7
822#define _PAIR_15 7
823#define _PAIR_16 8
824#define _PAIR_17 8
825#define _PAIR_18 9
826#define _PAIR_19 9
827#define _PAIR_20 10
828#define _PAIR_21 10
829#define _PAIR_22 11
830#define _PAIR_23 11
831#define _PAIR_24 12
832#define _PAIR_25 12
833#define _PAIR_26 13
834#define _PAIR_27 13
835#define _PAIR_28 14
836#define _PAIR_29 14
837#define _PAIR_30 15
838#define _PAIR_31 15
839
840// Apply decoration decor to register number n of type ty. Decorations are
841// as follows.
842//
843// decor types meaning
844// Q s, d the NEON qN register containing this one
845// D s the NEON dN register containing this one
846// D0 q the low 64-bit half of this one
847// D1 q the high 64-bit half of this one
848// S0 d, q the first 32-bit piece of this one
849// S1 d, q the second 32-bit piece of this one
850// S2 q the third 32-bit piece of this one
851// S3 q the fourth 32-bit piece of this one
852// Bn q the nth byte of this register, as a scalar
853// Hn q the nth halfword of this register, as a scalar
854// Wn q the nth word of this register, as a scalar
855#define _DECOR(ty, decor, n) _DECOR_##ty##_##decor(n)
856
857// Internal macros: `_DECOR_ty_decor(n)' applies decoration decor to register
858// number n of type ty.
859
860#define _DECOR_s_Q(n) GLUE(q, _PAIR(_PAIR(n)))
861#define _DECOR_s_D(n) GLUE(d, _PAIR(n))
862
863#define _DECOR_d_Q(n) GLUE(q, _PAIR(n))
864#define _DECOR_d_S0(n) GLUE(s, _LOPART(n))
865#define _DECOR_d_S1(n) GLUE(s, _LOPART(n))
866
867#define _DECOR_q_D0(n) GLUE(d, _LOPART(n))
868#define _DECOR_q_D1(n) GLUE(d, _HIPART(n))
869#define _DECOR_q_S0(n) GLUE(s, _LOPART(_LOPART(n)))
870#define _DECOR_q_S1(n) GLUE(s, _HIPART(_LOPART(n)))
871#define _DECOR_q_S2(n) GLUE(s, _LOPART(_HIPART(n)))
872#define _DECOR_q_S3(n) GLUE(s, _HIPART(_HIPART(n)))
873#define _DECOR_q_W0(n) GLUE(d, _LOPART(n))[0]
874#define _DECOR_q_W1(n) GLUE(d, _LOPART(n))[1]
875#define _DECOR_q_W2(n) GLUE(d, _HIPART(n))[0]
876#define _DECOR_q_W3(n) GLUE(d, _HIPART(n))[1]
877#define _DECOR_q_H0(n) GLUE(d, _LOPART(n))[0]
878#define _DECOR_q_H1(n) GLUE(d, _LOPART(n))[1]
879#define _DECOR_q_H2(n) GLUE(d, _LOPART(n))[2]
880#define _DECOR_q_H3(n) GLUE(d, _LOPART(n))[3]
881#define _DECOR_q_H4(n) GLUE(d, _HIPART(n))[0]
882#define _DECOR_q_H5(n) GLUE(d, _HIPART(n))[1]
883#define _DECOR_q_H6(n) GLUE(d, _HIPART(n))[2]
884#define _DECOR_q_H7(n) GLUE(d, _HIPART(n))[3]
885#define _DECOR_q_B0(n) GLUE(d, _LOPART(n))[0]
886#define _DECOR_q_B1(n) GLUE(d, _LOPART(n))[1]
887#define _DECOR_q_B2(n) GLUE(d, _LOPART(n))[2]
888#define _DECOR_q_B3(n) GLUE(d, _LOPART(n))[3]
889#define _DECOR_q_B4(n) GLUE(d, _LOPART(n))[4]
890#define _DECOR_q_B5(n) GLUE(d, _LOPART(n))[5]
891#define _DECOR_q_B6(n) GLUE(d, _LOPART(n))[6]
892#define _DECOR_q_B7(n) GLUE(d, _LOPART(n))[7]
893#define _DECOR_q_B8(n) GLUE(d, _HIPART(n))[0]
894#define _DECOR_q_B9(n) GLUE(d, _HIPART(n))[1]
895#define _DECOR_q_B10(n) GLUE(d, _HIPART(n))[2]
896#define _DECOR_q_B11(n) GLUE(d, _HIPART(n))[3]
897#define _DECOR_q_B12(n) GLUE(d, _HIPART(n))[4]
898#define _DECOR_q_B13(n) GLUE(d, _HIPART(n))[5]
899#define _DECOR_q_B14(n) GLUE(d, _HIPART(n))[6]
900#define _DECOR_q_B15(n) GLUE(d, _HIPART(n))[7]
901
902// Macros for navigating the NEON register hierarchy.
903#define S0(reg) _REGFORM(reg, S0)
904#define S1(reg) _REGFORM(reg, S1)
905#define S2(reg) _REGFORM(reg, S2)
906#define S3(reg) _REGFORM(reg, S3)
907#define D(reg) _REGFORM(reg, D)
908#define D0(reg) _REGFORM(reg, D0)
909#define D1(reg) _REGFORM(reg, D1)
910#define Q(reg) _REGFORM(reg, Q)
911
912// Macros for indexing quadword registers.
913#define QB(reg, i) _REGFORM(reg, B##i)
914#define QH(reg, i) _REGFORM(reg, H##i)
915#define QW(reg, i) _REGFORM(reg, W##i)
916
917// Macros for converting vldm/vstm ranges.
918#define QQ(qlo, qhi) D0(qlo)-D1(qhi)
919
0923a413 920// Stack management and unwinding.
42c44b27 921.macro setfp fp=r11, offset=0
0923a413
MW
922 .if \offset == 0
923 mov \fp, sp
924 .setfp \fp, sp
925 .else
926 add \fp, sp, #\offset
927 .setfp \fp, sp, #\offset
928 .endif
929 .macro dropfp; _dropfp \fp, \offset; .endm
930 .L$_frameptr_p = -1
931.endm
932
cdc153a5 933.macro _dropfp fp, offset=0
0923a413
MW
934 .if \offset == 0
935 mov sp, \fp
936 .else
937 sub sp, \fp, #\offset
938 .endif
939 .purgem dropfp
940 .L$_frameptr_p = 0
941.endm
942
943.macro stalloc n
944 sub sp, sp, #\n
945 .pad #\n
946.endm
947
948.macro stfree n
949 add sp, sp, #\n
950 .pad #-\n
951.endm
952
953.macro pushreg rr:vararg
1f1fd884 954 push {\rr}
0923a413
MW
955 .save {\rr}
956.endm
957
958.macro popreg rr:vararg
1f1fd884 959 pop {\rr}
0923a413
MW
960.endm
961
962.macro pushvfp rr:vararg
963 vstmdb sp!, {\rr}
964 .vsave {\rr}
965.endm
966
967.macro popvfp rr:vararg
968 vldmia sp!, {\rr}
969.endm
970
971.macro endprologue
972.endm
973
974// No need for prologue markers on ARM.
975#define FUNC_POSTHOOK(_) .L$_prologue_p = -1
976
61bd904b
MW
977#endif
978
979///--------------------------------------------------------------------------
e492db88
MW
980/// AArch64-specific hacking.
981
982#if CPUFAM_ARM64
983
984// Set the function hooks.
985#define FUNC_PREHOOK(_) .balign 4
986#define FUNC_POSTHOOK(_) .cfi_startproc; .L$_prologue_p = -1
987#define ENDFUNC_HOOK(_) .cfi_endproc
988
989// Call external subroutine at ADDR, possibly via PLT.
990.macro callext addr
991 bl \addr
992.endm
993
994// Load address of external symbol ADDR into REG.
995.macro leaext reg, addr
996#if WANT_PIC
997 adrp \reg, :got:\addr
998 ldr \reg, [\reg, #:got_lo12:\addr]
999#else
1000 adrp \reg, \addr
1001 add \reg, \reg, #:lo12:\addr
1002#endif
1003.endm
1004
1a031196
MW
1005.macro vzero vz=v31
1006 // Set VZ (default v31) to zero.
1007 dup \vz\().4s, wzr
1008.endm
1009
1010.macro vshl128 vd, vn, nbit, vz=v31
1011 // Set VD to VN shifted left by NBIT. Assume VZ (default v31) is
1012 // all-bits-zero. NBIT must be a multiple of 8.
1013 .if \nbit&3 != 0
1014 .error "shift quantity must be whole number of bytes"
1015 .endif
1016 ext \vd\().16b, \vz\().16b, \vn\().16b, #16 - (\nbit >> 3)
1017.endm
1018
1019.macro vshr128 vd, vn, nbit, vz=v31
1020 // Set VD to VN shifted right by NBIT. Assume VZ (default v31) is
1021 // all-bits-zero. NBIT must be a multiple of 8.
1022 .if \nbit&3 != 0
1023 .error "shift quantity must be whole number of bytes"
1024 .endif
1025 ext \vd\().16b, \vn\().16b, \vz\().16b, #\nbit >> 3
1026.endm
1027
e492db88 1028// Stack management and unwinding.
42c44b27 1029.macro setfp fp=x29, offset=0
e492db88
MW
1030 // If you're just going through the motions with a fixed-size stack frame,
1031 // then you want to say `add x29, sp, #OFFSET' directly, which will avoid
1032 // pointlessly restoring sp later.
1033 .if \offset == 0
1034 mov \fp, sp
1035 .cfi_def_cfa_register \fp
1036 .else
1037 add \fp, sp, #\offset
1038 .cfi_def_cfa_register \fp
1039 .cfi_adjust_cfa_offset -\offset
1040 .endif
1041 .macro dropfp; _dropfp \fp, \offset; .endm
1042 .L$_frameptr_p = -1
1043.endm
1044
cdc153a5 1045.macro _dropfp fp, offset=0
e492db88
MW
1046 .if \offset == 0
1047 mov sp, \fp
1048 .cfi_def_cfa_register sp
1049 .else
1050 sub sp, \fp, #\offset
1051 .cfi_def_cfa_register sp
1052 .cfi_adjust_cfa_offset +\offset
1053 .endif
1054 .purgem dropfp
1055 .L$_frameptr_p = 0
1056.endm
1057
1058.macro stalloc n
1059 sub sp, sp, #\n
1060 .cfi_adjust_cfa_offset +\n
1061.endm
1062
1063.macro stfree n
1064 add sp, sp, #\n
1065 .cfi_adjust_cfa_offset -\n
1066.endm
1067
4bf3072e
MW
1068.macro pushreg x, y=nil
1069 .ifeqs "\y", "nil"
e492db88
MW
1070 str \x, [sp, #-16]!
1071 .cfi_adjust_cfa_offset +16
1072 .cfi_rel_offset \x, 0
1073 .else
1074 stp \x, \y, [sp, #-16]!
1075 .cfi_adjust_cfa_offset +16
1076 .cfi_rel_offset \x, 0
1077 .cfi_rel_offset \y, 8
1078 .endif
1079.endm
1080
4bf3072e
MW
1081.macro popreg x, y=nil
1082 .ifeqs "\y", "nil"
e492db88
MW
1083 ldr \x, [sp], #16
1084 .cfi_restore \x
1085 .cfi_adjust_cfa_offset -16
1086 .else
1087 ldp \x, \y, [sp], #16
1088 .cfi_restore \x
1089 .cfi_restore \y
1090 .cfi_adjust_cfa_offset -16
1091 .endif
1092.endm
1093
4bf3072e
MW
1094.macro savereg x, y, z=nil
1095 .ifeqs "\z", "nil"
1096 str \x, [sp, \y]
e492db88
MW
1097 .cfi_rel_offset \x, \y
1098 .else
1099 stp \x, \y, [sp, #\z]
1100 .cfi_rel_offset \x, \z
1101 .cfi_rel_offset \y, \z + 8
1102 .endif
1103.endm
1104
4bf3072e
MW
1105.macro rstrreg x, y, z=nil
1106 .ifeqs "\z", "nil"
1107 ldr \x, [sp, \y]
e492db88
MW
1108 .cfi_restore \x
1109 .else
1110 ldp \x, \y, [sp, #\z]
1111 .cfi_restore \x
1112 .cfi_restore \y
1113 .endif
1114.endm
1115
1116.macro endprologue
1117.endm
1118
5f49478b
MW
1119// cmov RD, RN, CC: set RD to RN if CC is satisfied, otherwise do nothing
1120.macro cmov rd, rn, cc
1121 csel \rd, \rn, \rd, \cc
1122.endm
1123
483edf69
MW
1124// Notational improvement: write `csel.CC' etc., rather than `csel ..., CC'.
1125#define _COND(_) \
1126 _(eq) _(ne) _(cs) _(cc) _(vs) _(vc) _(mi) _(pl) \
1127 _(ge) _(lt) _(gt) _(le) _(hi) _(ls) _(al) _(nv) \
1128 _(hs) _(lo)
1129#define _INST(_) \
1130 _(ccmp) _(ccmn) \
5f49478b 1131 _(csel) _(cmov) \
483edf69
MW
1132 _(csinc) _(cinc) _(cset) \
1133 _(csneg) _(cneg) \
1134 _(csinv) _(cinv) _(csetm)
1135#define _CONDVAR(cc) _definstvar cc;
1136#define _INSTVARS(inst) \
1137 .macro _definstvar cc; \
1138 .macro inst.\cc args:vararg; inst \args, \cc; .endm; \
1139 .endm; \
1140 _COND(_CONDVAR); \
1141 .purgem _definstvar;
1142 _INST(_INSTVARS)
1143#undef _COND
1144#undef _INST
1145#undef _CONDVAR
1146#undef _INSTVARS
1147
1148// Flag bits for `ccmp' and friends.
1149#define CCMP_N 8
1150#define CCMP_Z 4
1151#define CCMP_C 2
1152#define CCMP_V 1
1153
1154// Flag settings for satisfying conditions.
1155#define CCMP_MI CCMP_N
1156#define CCMP_PL 0
1157#define CCMP_EQ CCMP_Z
1158#define CCMP_NE 0
1159#define CCMP_CS CCMP_C
1160#define CCMP_HS CCMP_C
1161#define CCMP_CC 0
1162#define CCMP_LO 0
1163#define CCMP_VS CCMP_V
1164#define CCMP_VC 0
1165#define CCMP_HI CCMP_C
1166#define CCMP_LS 0
1167#define CCMP_LT CCMP_N
1168#define CCMP_GE 0
1169#define CCMP_LE CCMP_N
1170#define CCMP_GT 0
1171
e492db88
MW
1172#endif
1173
1174///--------------------------------------------------------------------------
1a0c09c4
MW
1175/// Final stuff.
1176
1177// Default values for the various hooks.
1178#ifndef FUNC_PREHOOK
1e5664a6 1179# define FUNC_PREHOOK(_)
1a0c09c4
MW
1180#endif
1181#ifndef FUNC_POSTHOOK
1e5664a6 1182# define FUNC_POSTHOOK(_)
1a0c09c4
MW
1183#endif
1184#ifndef ENDFUNC_HOOK
1e5664a6 1185# define ENDFUNC_HOOK(_)
1a0c09c4
MW
1186#endif
1187
b0c2da14
MW
1188// Section selection.
1189#ifndef TEXT
1190# define TEXT .text .L$_subsec
1191#endif
1192#ifndef RODATA
1193# define RODATA TEXT
1194#endif
1195#ifndef DATA
1196# define DATA .data
1197#endif
1198
1199// Symbol decoration.
1a0c09c4 1200#ifndef F
772740dd
MW
1201# ifdef SYM_USCORE
1202# define F(name) _##name
1203# else
1204# define F(name) name
1205# endif
1a0c09c4
MW
1206#endif
1207
1208#ifndef TYPE_FUNC
1209# define TYPE_FUNC(name)
1210#endif
6ae7b854
MW
1211#ifndef TYPE_OBJ
1212# define TYPE_OBJ(name)
1213#endif
1a0c09c4
MW
1214#ifndef SIZE_OBJ
1215# define SIZE_OBJ(name)
1216#endif
1217
1218///----- That's all, folks --------------------------------------------------
8ce88ea5
MW
1219
1220#endif