progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / base / asm-common.h
index e8f6445..9257d76 100644 (file)
 #define _ENDLIT .text .L$_subsec
 #define _LTORG .L$_subsec = .L$_subsec + 2; .text .L$_subsec
 
-// ELF section types.
-#if __ELF__
-#  if CPUFAM_ARMEL
-#    define _SECTTY(ty) %ty
-#  else
-#    define _SECTTY(ty) @ty
-#  endif
-#endif
-
-// Section selection.
-#define TEXT .text .L$_subsec
-#if ABI_WIN
-#  define RODATA .section .rdata, "dr"
-#elif __ELF__
-#  define RODATA .section .rodata, "a", _SECTTY(progbits)
-#else
-#  define RODATA TEXT
-#endif
-#define DATA .data
-
 // Announcing an internal function.
 #define INTFUNC(name)                                                  \
        TYPE_FUNC(name);                                                \
@@ -106,14 +86,32 @@ name:
 
 #if __ELF__
 
-#if __PIC__ || __PIE__
-#  define WANT_PIC 1
+// Section types.
+#if CPUFAM_ARMEL
+#  define _SECTTY(ty) %ty
+#else
+#  define _SECTTY(ty) @ty
 #endif
 
-#define TYPE_FUNC(name) .type name, STT_FUNC
+// Section selection.
+#define RODATA .section .rodata, "a", _SECTTY(progbits)
 
+// Additional symbol metadata.
+#define TYPE_FUNC(name) .type name, STT_FUNC
+#define TYPE_OBJ(name) .type name, STT_OBJECT
 #define SIZE_OBJ(name) .size name, . - name
 
+// Special arrangements for position-independent code.
+#if __PIC__ || __PIE__
+#  define WANT_PIC 1
+#endif
+
+// Don't make the stack executable by default.
+#ifndef FORCE_EXECUTABLE_STACK
+       .pushsection .note.GNU-stack, "", _SECTTY(progbits)
+       .popsection
+#endif
+
 #endif
 
 ///--------------------------------------------------------------------------
@@ -121,10 +119,14 @@ name:
 
 #if ABI_WIN
 
+// Function names need decorating on 32-bit i386.
 #if CPUFAM_X86
 #  define F(name) _##name
 #endif
 
+// Section selection.
+#define RODATA .section .rdata, "dr"
+
 #endif
 
 ///--------------------------------------------------------------------------
@@ -220,11 +222,11 @@ name:
 #  define INTADDR__1(addr, got) addr
 #endif
 
-// Permutations for SIMD instructions.  SHUF(A, B, C, D) is an immediate,
+// Permutations for SIMD instructions.  SHUF(D, C, B, A) is an immediate,
 // suitable for use in `pshufd' or `shufpd', which copies element A
 // (0 <= A < 4) of the source to element 0 of the destination, element B to
 // element 1, element C to element 2, and element D to element 3.
-#define SHUF(a, b, c, d) ((a) + 4*(b) + 16*(c) + 64*(d))
+#define SHUF(d, c, b, a) (64*(d) + 16*(c) + 4*(b) + (a))
 
 // Map register names to their individual pieces.
 
@@ -311,6 +313,7 @@ name:
 // R_r(decor) applies decoration decor to register r, which is an internal
 // register name.  The internal register names are: `ip', `a', `b', `c', `d',
 // `si', `di', `bp', `sp', `r8'--`r15'.
+#define R_nil(decor) nil
 #define R_ip(decor) _DECOR(ip, decor, ip)
 #define R_a(decor) _DECOR(abcd, decor, a)
 #define R_b(decor) _DECOR(abcd, decor, b)
@@ -345,6 +348,8 @@ name:
 // assembler-level register name, in place of any decoration that register
 // name has already.
 
+#define _REGFORM_nil(decor) R_nil(decor)
+
 #define _REGFORM_ip(decor) R_ip(decor)
 #define _REGFORM_eip(decor) R_ip(decor)
 
@@ -452,10 +457,20 @@ name:
 #endif
 #define WHOLE(reg) _REGFORM(reg, r)
 
+// Macros for some common registers.
+#define AX R_a(r)
+#define BX R_b(r)
+#define CX R_c(r)
+#define DX R_d(r)
+#define SI R_si(r)
+#define DI R_di(r)
+#define BP R_bp(r)
+#define SP R_sp(r)
+
 // Stack management and unwinding.
-.macro setfp   fp=R_bp(r), offset=0
+.macro setfp   fp=BP, offset=0
   .if \offset == 0
-       mov     \fp, R_sp(r)
+       mov     \fp, SP
 #if __ELF__
          .cfi_def_cfa_register \fp
 #endif
@@ -463,7 +478,7 @@ name:
          .seh_setframe \fp, 0
 #endif
   .else
-       lea     \fp, [R_sp(r) + \offset]
+       lea     \fp, [SP + \offset]
 #if __ELF__
          .cfi_def_cfa_register \fp
          .cfi_adjust_cfa_offset -\offset
@@ -478,14 +493,14 @@ name:
 
 .macro _dropfp fp, offset=0
   .if \offset == 0
-       mov     R_sp(r), \fp
+       mov     SP, \fp
 #if __ELF__
-         .cfi_def_cfa_register R_sp(r)
+         .cfi_def_cfa_register SP
 #endif
   .else
-       lea     R_sp(r), [\fp - \offset]
+       lea     SP, [\fp - \offset]
 #if __ELF__
-         .cfi_def_cfa_register R_sp(r)
+         .cfi_def_cfa_register SP
          .cfi_adjust_cfa_offset +\offset
 #endif
   .endif
@@ -494,7 +509,7 @@ name:
 .endm
 
 .macro stalloc n
-       sub     R_sp(r), \n
+       sub     SP, \n
 #if __ELF__
          .cfi_adjust_cfa_offset +\n
 #endif
@@ -504,7 +519,7 @@ name:
 .endm
 
 .macro stfree  n
-       add     R_sp(r), \n
+       add     SP, \n
 #if __ELF__
          .cfi_adjust_cfa_offset -\n
 #endif
@@ -530,14 +545,14 @@ name:
 .endm
 
 .macro savexmm r, offset
-       movdqa  [R_sp(r) + \offset], \r
+       movdqa  [SP + \offset], \r
 #if ABI_WIN && CPUFAM_AMD64
          .seh_savexmm \r, \offset
 #endif
 .endm
 
 .macro rstrxmm r, offset
-       movdqa  \r, [R_sp(r) + \offset]
+       movdqa  \r, [SP + \offset]
 .endm
 
 .macro endprologue
@@ -657,6 +672,8 @@ name:
 // Internal macros: `_REGFORM_r(decor)' applies decoration decor to register
 // name r.
 
+#define _REGFORM_nil(decor) nil
+
 #define _REGFORM_s0(decor) _DECOR(s, decor, 0)
 #define _REGFORM_s1(decor) _DECOR(s, decor, 1)
 #define _REGFORM_s2(decor) _DECOR(s, decor, 2)
@@ -1099,6 +1116,59 @@ name:
 .macro endprologue
 .endm
 
+// cmov RD, RN, CC: set RD to RN if CC is satisfied, otherwise do nothing
+.macro cmov    rd, rn, cc
+       csel    \rd, \rn, \rd, \cc
+.endm
+
+// Notational improvement: write `csel.CC' etc., rather than `csel ..., CC'.
+#define _COND(_)                                                       \
+       _(eq) _(ne) _(cs) _(cc) _(vs) _(vc) _(mi) _(pl)                 \
+       _(ge) _(lt) _(gt) _(le) _(hi) _(ls) _(al) _(nv)                 \
+       _(hs) _(lo)
+#define _INST(_)                                                       \
+       _(ccmp) _(ccmn)                                                 \
+       _(csel) _(cmov)                                                 \
+       _(csinc) _(cinc) _(cset)                                        \
+       _(csneg) _(cneg)                                                \
+       _(csinv) _(cinv) _(csetm)
+#define _CONDVAR(cc) _definstvar cc;
+#define _INSTVARS(inst)                                                        \
+       .macro _definstvar cc;                                          \
+         .macro inst.\cc args:vararg; inst \args, \cc; .endm;          \
+       .endm;                                                          \
+       _COND(_CONDVAR);                                                \
+       .purgem _definstvar;
+       _INST(_INSTVARS)
+#undef _COND
+#undef _INST
+#undef _CONDVAR
+#undef _INSTVARS
+
+// Flag bits for `ccmp' and friends.
+#define CCMP_N 8
+#define CCMP_Z 4
+#define CCMP_C 2
+#define CCMP_V 1
+
+// Flag settings for satisfying conditions.
+#define CCMP_MI CCMP_N
+#define CCMP_PL 0
+#define CCMP_EQ CCMP_Z
+#define CCMP_NE 0
+#define CCMP_CS CCMP_C
+#define CCMP_HS CCMP_C
+#define CCMP_CC 0
+#define CCMP_LO 0
+#define CCMP_VS CCMP_V
+#define CCMP_VC 0
+#define CCMP_HI CCMP_C
+#define CCMP_LS 0
+#define CCMP_LT CCMP_N
+#define CCMP_GE 0
+#define CCMP_LE CCMP_N
+#define CCMP_GT 0
+
 #endif
 
 ///--------------------------------------------------------------------------
@@ -1115,23 +1185,36 @@ name:
 #  define ENDFUNC_HOOK(_)
 #endif
 
+// Section selection.
+#ifndef TEXT
+#  define TEXT .text .L$_subsec
+#endif
+#ifndef RODATA
+#  define RODATA TEXT
+#endif
+#ifndef DATA
+#  define DATA .data
+#endif
+
+// Symbol decoration.
 #ifndef F
-#  define F(name) name
+#  ifdef SYM_USCORE
+#    define F(name) _##name
+#  else
+#    define F(name) name
+#  endif
 #endif
 
 #ifndef TYPE_FUNC
 #  define TYPE_FUNC(name)
 #endif
-
+#ifndef TYPE_OBJ
+#  define TYPE_OBJ(name)
+#endif
 #ifndef SIZE_OBJ
 #  define SIZE_OBJ(name)
 #endif
 
-#if __ELF__ && !defined(WANT_EXECUTABLE_STACK)
-       .pushsection .note.GNU-stack, "", _SECTTY(progbits)
-       .popsection
-#endif
-
 ///----- That's all, folks --------------------------------------------------
 
 #endif