Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

1181 rinda
30 KiB

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