feat: multi-user system, bug fixes, security & performance fixes, and more

This commit is contained in:
2026-03-14 13:28:46 +01:00
parent 576ad34f95
commit 261b536041
389 changed files with 231853 additions and 591 deletions
+318
View File
@@ -0,0 +1,318 @@
/*
* Syscall.hpp
* MontaukOS syscall definitions for userspace programs
* Copyright (c) 2025 Daniel Hammer
*/
#pragma once
#include <cstdint>
#include <cstddef>
namespace Montauk {
// Syscall numbers
static constexpr uint64_t SYS_EXIT = 0;
static constexpr uint64_t SYS_YIELD = 1;
static constexpr uint64_t SYS_SLEEP_MS = 2;
static constexpr uint64_t SYS_GETPID = 3;
static constexpr uint64_t SYS_PRINT = 4;
static constexpr uint64_t SYS_PUTCHAR = 5;
static constexpr uint64_t SYS_OPEN = 6;
static constexpr uint64_t SYS_READ = 7;
static constexpr uint64_t SYS_GETSIZE = 8;
static constexpr uint64_t SYS_CLOSE = 9;
static constexpr uint64_t SYS_READDIR = 10;
static constexpr uint64_t SYS_ALLOC = 11;
static constexpr uint64_t SYS_FREE = 12;
static constexpr uint64_t SYS_GETTICKS = 13;
static constexpr uint64_t SYS_GETMILLISECONDS = 14;
static constexpr uint64_t SYS_GETINFO = 15;
static constexpr uint64_t SYS_ISKEYAVAILABLE = 16;
static constexpr uint64_t SYS_GETKEY = 17;
static constexpr uint64_t SYS_GETCHAR = 18;
static constexpr uint64_t SYS_PING = 19;
static constexpr uint64_t SYS_SPAWN = 20;
static constexpr uint64_t SYS_FBINFO = 21;
static constexpr uint64_t SYS_FBMAP = 22;
static constexpr uint64_t SYS_WAITPID = 23;
static constexpr uint64_t SYS_TERMSIZE = 24;
static constexpr uint64_t SYS_GETARGS = 25;
static constexpr uint64_t SYS_RESET = 26;
static constexpr uint64_t SYS_SHUTDOWN = 27;
static constexpr uint64_t SYS_GETTIME = 28;
static constexpr uint64_t SYS_SOCKET = 29;
static constexpr uint64_t SYS_CONNECT = 30;
static constexpr uint64_t SYS_BIND = 31;
static constexpr uint64_t SYS_LISTEN = 32;
static constexpr uint64_t SYS_ACCEPT = 33;
static constexpr uint64_t SYS_SEND = 34;
static constexpr uint64_t SYS_RECV = 35;
static constexpr uint64_t SYS_CLOSESOCK = 36;
static constexpr uint64_t SYS_GETNETCFG = 37;
static constexpr uint64_t SYS_SETNETCFG = 38;
static constexpr uint64_t SYS_SENDTO = 39;
static constexpr uint64_t SYS_RECVFROM = 40;
static constexpr uint64_t SYS_FWRITE = 41;
static constexpr uint64_t SYS_FCREATE = 42;
static constexpr uint64_t SYS_FDELETE = 77;
static constexpr uint64_t SYS_FMKDIR = 78;
static constexpr uint64_t SYS_DRIVELIST = 79;
static constexpr uint64_t SYS_TERMSCALE = 43;
static constexpr uint64_t SYS_RESOLVE = 44;
static constexpr uint64_t SYS_GETRANDOM = 45;
static constexpr uint64_t SYS_KLOG = 46;
static constexpr uint64_t SYS_MOUSESTATE = 47;
static constexpr uint64_t SYS_SETMOUSEBOUNDS = 48;
static constexpr uint64_t SYS_SPAWN_REDIR = 49;
static constexpr uint64_t SYS_CHILDIO_READ = 50;
static constexpr uint64_t SYS_CHILDIO_WRITE = 51;
static constexpr uint64_t SYS_CHILDIO_WRITEKEY = 52;
static constexpr uint64_t SYS_CHILDIO_SETTERMSZ = 53;
// Window server syscalls
static constexpr uint64_t SYS_WINCREATE = 54;
static constexpr uint64_t SYS_WINDESTROY = 55;
static constexpr uint64_t SYS_WINPRESENT = 56;
static constexpr uint64_t SYS_WINPOLL = 57;
static constexpr uint64_t SYS_WINENUM = 58;
static constexpr uint64_t SYS_WINMAP = 59;
static constexpr uint64_t SYS_WINSENDEVENT = 60;
static constexpr uint64_t SYS_WINRESIZE = 64;
static constexpr uint64_t SYS_WINSETSCALE = 65;
static constexpr uint64_t SYS_WINGETSCALE = 66;
static constexpr uint64_t SYS_WINSETCURSOR = 68;
// Process management syscalls
static constexpr uint64_t SYS_PROCLIST = 61;
static constexpr uint64_t SYS_KILL = 62;
static constexpr uint64_t SYS_DEVLIST = 63;
static constexpr uint64_t SYS_DISKINFO = 69;
// Kernel introspection syscalls
static constexpr uint64_t SYS_MEMSTATS = 67;
// Storage / partition syscalls
static constexpr uint64_t SYS_PARTLIST = 70;
static constexpr uint64_t SYS_DISKREAD = 71;
static constexpr uint64_t SYS_DISKWRITE = 72;
static constexpr uint64_t SYS_GPTINIT = 73;
static constexpr uint64_t SYS_GPTADD = 74;
static constexpr uint64_t SYS_FSMOUNT = 75;
static constexpr uint64_t SYS_FSFORMAT = 76;
// Audio syscalls
static constexpr uint64_t SYS_AUDIOOPEN = 80;
static constexpr uint64_t SYS_AUDIOCLOSE = 81;
static constexpr uint64_t SYS_AUDIOWRITE = 82;
static constexpr uint64_t SYS_AUDIOCTL = 83;
// Bluetooth syscalls
static constexpr uint64_t SYS_BTSCAN = 84;
static constexpr uint64_t SYS_BTCONNECT = 85;
static constexpr uint64_t SYS_BTDISCONNECT = 86;
static constexpr uint64_t SYS_BTLIST = 87;
static constexpr uint64_t SYS_BTINFO = 88;
// Audio control commands (for SYS_AUDIOCTL)
static constexpr int AUDIO_CTL_SET_VOLUME = 0;
static constexpr int AUDIO_CTL_GET_VOLUME = 1;
static constexpr int AUDIO_CTL_GET_POS = 2;
static constexpr int AUDIO_CTL_PAUSE = 3;
static constexpr int AUDIO_CTL_GET_OUTPUT = 4; // 0=HDA, 1=Bluetooth
static constexpr int AUDIO_CTL_SET_OUTPUT = 5; // Switch audio output
static constexpr int AUDIO_CTL_BT_STATUS = 6; // Get Bluetooth connection status
static constexpr int SOCK_TCP = 1;
static constexpr int SOCK_UDP = 2;
struct NetCfg {
uint32_t ipAddress; // network byte order
uint32_t subnetMask; // network byte order
uint32_t gateway; // network byte order
uint8_t macAddress[6];
uint8_t _pad[2];
uint32_t dnsServer; // network byte order
};
struct DateTime {
uint16_t Year;
uint8_t Month;
uint8_t Day;
uint8_t Hour;
uint8_t Minute;
uint8_t Second;
};
struct FbInfo {
uint64_t width;
uint64_t height;
uint64_t pitch; // bytes per scanline
uint64_t bpp; // bits per pixel (32)
uint64_t userAddr; // filled by SYS_FBMAP (0 until mapped)
};
struct SysInfo {
char osName[32];
char osVersion[32];
uint32_t apiVersion;
uint32_t maxProcesses;
};
struct KeyEvent {
uint8_t scancode;
char ascii;
bool pressed;
bool shift;
bool ctrl;
bool alt;
};
struct MouseState {
int32_t x;
int32_t y;
int32_t scrollDelta;
uint8_t buttons;
};
// Window server shared types
struct WinEvent {
uint8_t type; // 0=key, 1=mouse, 2=resize, 3=close, 4=scale
uint8_t _pad[3];
union {
KeyEvent key;
struct { int32_t x, y, scroll; uint8_t buttons, prev_buttons; } mouse;
struct { int32_t w, h; } resize;
struct { int32_t scale; } scale;
};
};
struct WinInfo {
int32_t id;
int32_t ownerPid;
char title[64];
int32_t width, height;
uint8_t dirty;
uint8_t cursor; // 0=arrow, 1=resize_h, 2=resize_v
uint8_t _pad2[2];
};
struct WinCreateResult {
int32_t id; // -1 on failure
uint32_t _pad;
uint64_t pixelVa; // VA of pixel buffer in caller's address space
};
struct DevInfo {
uint8_t category; // 0=CPU, 1=Interrupt, 2=Timer, 3=Input, 4=USB, 5=Network, 6=Display, 7=Storage, 8=PCI
uint8_t _pad[3];
char name[48];
char detail[48];
};
struct DiskInfo {
uint8_t port; // block device index
uint8_t type; // 0=none, 1=SATA, 2=SATAPI, 3=NVMe
uint8_t sataGen; // SATA gen (1/2/3)
uint8_t _pad0;
uint64_t sectorCount; // Total user-addressable sectors
uint16_t sectorSizeLog; // Logical sector size (bytes)
uint16_t sectorSizePhys; // Physical sector size (bytes)
uint16_t rpm; // 0=unknown, 1=SSD, else RPM
uint16_t ncqDepth; // 0 if no NCQ
uint8_t supportsLba48;
uint8_t supportsNcq;
uint8_t supportsTrim;
uint8_t supportsSmart;
uint8_t supportsWriteCache;
uint8_t supportsReadAhead;
uint8_t _pad1[2];
char model[41];
char serial[21];
char firmware[9];
char _pad2[1];
};
struct PartGuid {
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
};
struct PartInfo {
int32_t blockDev; // block device index
uint32_t _pad0;
uint64_t startLba;
uint64_t endLba;
uint64_t sectorCount;
PartGuid typeGuid;
PartGuid uniqueGuid;
uint64_t attributes;
char name[72]; // ASCII partition name
char typeName[24]; // human-readable type name
};
struct GptAddParams {
int32_t blockDev;
uint32_t _pad0;
uint64_t startLba; // 0 = auto (fill largest free region)
uint64_t endLba; // 0 = auto
PartGuid typeGuid;
char name[72];
};
// Filesystem type IDs for SYS_FSFORMAT
static constexpr int FS_TYPE_FAT32 = 1;
static constexpr int FS_TYPE_EXT2 = 2;
struct FsFormatParams {
int32_t partIndex; // global partition index
int32_t fsType; // FS_TYPE_FAT32, etc.
char label[32]; // volume label
};
// Bluetooth scan result (returned by SYS_BTSCAN)
struct BtScanResult {
uint8_t bdAddr[6];
uint8_t _pad[2];
uint32_t classOfDevice;
int8_t rssi;
uint8_t _pad2[3];
char name[64];
};
// Bluetooth connected device info (returned by SYS_BTLIST)
struct BtDevInfo {
uint8_t bdAddr[6];
uint8_t connected;
uint8_t encrypted;
uint16_t handle;
uint8_t linkType;
uint8_t _pad;
};
// Bluetooth adapter info (returned by SYS_BTINFO)
struct BtAdapterInfo {
uint8_t bdAddr[6];
uint8_t initialized;
uint8_t scanning;
char name[64];
};
struct ProcInfo {
int32_t pid;
int32_t parentPid;
uint8_t state; // 0=Free, 1=Ready, 2=Running, 3=Terminated
uint8_t _pad[3];
char name[64];
uint64_t heapUsed; // heapNext - UserHeapBase (bytes)
};
struct MemStats {
uint64_t totalBytes;
uint64_t freeBytes;
uint64_t usedBytes;
uint64_t pageSize;
};
}
+81
View File
@@ -0,0 +1,81 @@
/* Copyright (C) 2012-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _X86GPRINTRIN_H_INCLUDED
# error "Never use <adxintrin.h> directly; include <x86gprintrin.h> instead."
#endif
#ifndef _ADXINTRIN_H_INCLUDED
#define _ADXINTRIN_H_INCLUDED
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_subborrow_u32 (unsigned char __CF, unsigned int __X,
unsigned int __Y, unsigned int *__P)
{
return __builtin_ia32_sbb_u32 (__CF, __X, __Y, __P);
}
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_addcarry_u32 (unsigned char __CF, unsigned int __X,
unsigned int __Y, unsigned int *__P)
{
return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
}
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_addcarryx_u32 (unsigned char __CF, unsigned int __X,
unsigned int __Y, unsigned int *__P)
{
return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
}
#ifdef __x86_64__
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_subborrow_u64 (unsigned char __CF, unsigned long long __X,
unsigned long long __Y, unsigned long long *__P)
{
return __builtin_ia32_sbb_u64 (__CF, __X, __Y, __P);
}
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_addcarry_u64 (unsigned char __CF, unsigned long long __X,
unsigned long long __Y, unsigned long long *__P)
{
return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P);
}
extern __inline unsigned char
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_addcarryx_u64 (unsigned char __CF, unsigned long long __X,
unsigned long long __Y, unsigned long long *__P)
{
return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P);
}
#endif
#endif /* _ADXINTRIN_H_INCLUDED */
+94
View File
@@ -0,0 +1,94 @@
// <algorithm> -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file include/algorithm
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_ALGORITHM
#define _GLIBCXX_ALGORITHM 1
#pragma GCC system_header
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#if __cplusplus > 201703L
# include <bits/ranges_algo.h>
#endif
#define __glibcxx_want_clamp
#define __glibcxx_want_constexpr_algorithms
#define __glibcxx_want_freestanding_algorithm
#define __glibcxx_want_parallel_algorithm
#define __glibcxx_want_ranges_contains
#define __glibcxx_want_ranges_find_last
#define __glibcxx_want_ranges_fold
#define __glibcxx_want_robust_nonmodifying_seq_ops
#define __glibcxx_want_sample
#define __glibcxx_want_shift
#include <bits/version.h>
#if __cpp_lib_parallel_algorithm // C++ >= 17 && HOSTED
// Parallel STL algorithms
# if _PSTL_EXECUTION_POLICIES_DEFINED
// If <execution> has already been included, pull in implementations
# include <pstl/glue_algorithm_impl.h>
# else
// Otherwise just pull in forward declarations
# include <pstl/glue_algorithm_defs.h>
# define _PSTL_ALGORITHM_FORWARD_DECLARED 1
# endif
#endif
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithm>
#endif
#endif /* _GLIBCXX_ALGORITHM */
+93
View File
@@ -0,0 +1,93 @@
/* Copyright (C) 2007-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Implemented from the specification included in the AMD Programmers
Manual Update, version 2.x */
#ifndef _AMMINTRIN_H_INCLUDED
#define _AMMINTRIN_H_INCLUDED
/* We need definitions from the SSE3, SSE2 and SSE header files*/
#include <pmmintrin.h>
#ifndef __SSE4A__
#pragma GCC push_options
#pragma GCC target("sse4a")
#define __DISABLE_SSE4A__
#endif /* __SSE4A__ */
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_stream_sd (double * __P, __m128d __Y)
{
__builtin_ia32_movntsd (__P, (__v2df) __Y);
}
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_stream_ss (float * __P, __m128 __Y)
{
__builtin_ia32_movntss (__P, (__v4sf) __Y);
}
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extract_si64 (__m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_extrq ((__v2di) __X, (__v16qi) __Y);
}
#ifdef __OPTIMIZE__
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_extracti_si64 (__m128i __X, unsigned const int __I, unsigned const int __L)
{
return (__m128i) __builtin_ia32_extrqi ((__v2di) __X, __I, __L);
}
#else
#define _mm_extracti_si64(X, I, L) \
((__m128i) __builtin_ia32_extrqi ((__v2di)(__m128i)(X), \
(unsigned int)(I), (unsigned int)(L)))
#endif
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_insert_si64 (__m128i __X,__m128i __Y)
{
return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y);
}
#ifdef __OPTIMIZE__
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_inserti_si64(__m128i __X, __m128i __Y, unsigned const int __I, unsigned const int __L)
{
return (__m128i) __builtin_ia32_insertqi ((__v2di)__X, (__v2di)__Y, __I, __L);
}
#else
#define _mm_inserti_si64(X, Y, I, L) \
((__m128i) __builtin_ia32_insertqi ((__v2di)(__m128i)(X), \
(__v2di)(__m128i)(Y), \
(unsigned int)(I), (unsigned int)(L)))
#endif
#ifdef __DISABLE_SSE4A__
#undef __DISABLE_SSE4A__
#pragma GCC pop_options
#endif /* __DISABLE_SSE4A__ */
#endif /* _AMMINTRIN_H_INCLUDED */
+52
View File
@@ -0,0 +1,52 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <amxbf16intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AMXBF16INTRIN_H_INCLUDED
#define _AMXBF16INTRIN_H_INCLUDED
#if !defined(__AMX_BF16__)
#pragma GCC push_options
#pragma GCC target("amx-bf16")
#define __DISABLE_AMX_BF16__
#endif /* __AMX_BF16__ */
#if defined(__x86_64__)
#define _tile_dpbf16ps_internal(dst,src1,src2) \
__asm__ volatile\
("{tdpbf16ps\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|tdpbf16ps\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::)
#define _tile_dpbf16ps(dst,src1,src2) \
_tile_dpbf16ps_internal (dst, src1, src2)
#endif
#ifdef __DISABLE_AMX_BF16__
#undef __DISABLE_AMX_BF16__
#pragma GCC pop_options
#endif /* __DISABLE_AMX_BF16__ */
#endif /* _AMXBF16INTRIN_H_INCLUDED */
@@ -0,0 +1,59 @@
/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <amxcomplexintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AMXCOMPLEXINTRIN_H_INCLUDED
#define _AMXCOMPLEXINTRIN_H_INCLUDED
#if !defined(__AMX_COMPLEX__)
#pragma GCC push_options
#pragma GCC target("amx-complex")
#define __DISABLE_AMX_COMPLEX__
#endif /* __AMX_COMPLEX__ */
#if defined(__x86_64__)
#define _tile_cmmimfp16ps_internal(src1_dst,src2,src3) \
__asm__ volatile\
("{tcmmimfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmimfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::)
#define _tile_cmmrlfp16ps_internal(src1_dst,src2,src3) \
__asm__ volatile\
("{tcmmrlfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmrlfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::)
#define _tile_cmmimfp16ps(src1_dst,src2,src3) \
_tile_cmmimfp16ps_internal (src1_dst, src2, src3)
#define _tile_cmmrlfp16ps(src1_dst,src2,src3) \
_tile_cmmrlfp16ps_internal (src1_dst, src2, src3)
#endif
#ifdef __DISABLE_AMX_COMPLEX__
#undef __DISABLE_AMX_COMPLEX__
#pragma GCC pop_options
#endif /* __DISABLE_AMX_COMPLEX__ */
#endif /* _AMXCOMPLEXINTRIN_H_INCLUDED */
+46
View File
@@ -0,0 +1,46 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <amxfp16intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AMXFP16INTRIN_H_INCLUDED
#define _AMXFP16INTRIN_H_INCLUDED
#if defined(__x86_64__)
#define _tile_dpfp16ps_internal(dst,src1,src2) \
__asm__ volatile \
("{tdpfp16ps\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|tdpfp16ps\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::)
#define _tile_dpfp16ps(dst,src1,src2) \
_tile_dpfp16ps_internal (dst,src1,src2)
#endif
#ifdef __DISABLE_AMX_FP16__
#undef __DISABLE_AMX_FP16__
#pragma GCC pop_options
#endif /* __DISABLE_AMX_FP16__ */
#endif /* _AMXFP16INTRIN_H_INCLUDED */
+61
View File
@@ -0,0 +1,61 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <amxint8intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AMXINT8INTRIN_H_INCLUDED
#define _AMXINT8INTRIN_H_INCLUDED
#if !defined(__AMX_INT8__)
#pragma GCC push_options
#pragma GCC target("amx-int8")
#define __DISABLE_AMX_INT8__
#endif /* __AMX_INT8__ */
#if defined(__x86_64__)
#define _tile_int8_dp_internal(name,dst,src1,src2) \
__asm__ volatile \
("{"#name"\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|"#name"\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::)
#define _tile_dpbssd(dst,src1,src2) \
_tile_int8_dp_internal (tdpbssd, dst, src1, src2)
#define _tile_dpbsud(dst,src1,src2) \
_tile_int8_dp_internal (tdpbsud, dst, src1, src2)
#define _tile_dpbusd(dst,src1,src2) \
_tile_int8_dp_internal (tdpbusd, dst, src1, src2)
#define _tile_dpbuud(dst,src1,src2) \
_tile_int8_dp_internal (tdpbuud, dst, src1, src2)
#endif
#ifdef __DISABLE_AMX_INT8__
#undef __DISABLE_AMX_INT8__
#pragma GCC pop_options
#endif /* __DISABLE_AMX_INT8__ */
#endif /* _AMXINT8INTRIN_H_INCLUDED */
+98
View File
@@ -0,0 +1,98 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <amxtileintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AMXTILEINTRIN_H_INCLUDED
#define _AMXTILEINTRIN_H_INCLUDED
#if !defined(__AMX_TILE__)
#pragma GCC push_options
#pragma GCC target("amx-tile")
#define __DISABLE_AMX_TILE__
#endif /* __AMX_TILE__ */
#if defined(__x86_64__)
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_tile_loadconfig (const void *__config)
{
__builtin_ia32_ldtilecfg (__config);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_tile_storeconfig (void *__config)
{
__builtin_ia32_sttilecfg (__config);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_tile_release (void)
{
__asm__ volatile ("tilerelease" ::);
}
#define _tile_loadd(dst,base,stride) \
_tile_loadd_internal (dst, base, stride)
#define _tile_loadd_internal(dst,base,stride) \
__asm__ volatile \
("{tileloadd\t(%0,%1,1), %%tmm"#dst"|tileloadd\t%%tmm"#dst", [%0+%1*1]}" \
:: "r" ((const void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride)))
#define _tile_stream_loadd(dst,base,stride) \
_tile_stream_loadd_internal (dst, base, stride)
#define _tile_stream_loadd_internal(dst,base,stride) \
__asm__ volatile \
("{tileloaddt1\t(%0,%1,1), %%tmm"#dst"|tileloaddt1\t%%tmm"#dst", [%0+%1*1]}" \
:: "r" ((const void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride)))
#define _tile_stored(dst,base,stride) \
_tile_stored_internal (dst, base, stride)
#define _tile_stored_internal(src,base,stride) \
__asm__ volatile \
("{tilestored\t%%tmm"#src", (%0,%1,1)|tilestored\t[%0+%1*1], %%tmm"#src"}" \
:: "r" ((void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride)) \
: "memory")
#define _tile_zero(dst) \
_tile_zero_internal (dst)
#define _tile_zero_internal(dst) \
__asm__ volatile \
("tilezero\t%%tmm"#dst ::)
#endif
#ifdef __DISABLE_AMX_TILE__
#undef __DISABLE_AMX_TILE__
#pragma GCC pop_options
#endif /* __DISABLE_AMX_TILE__ */
#endif /* _AMXTILEINTRIN_H_INCLUDED */
+519
View File
@@ -0,0 +1,519 @@
// <array> -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/array
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_ARRAY
#define _GLIBCXX_ARRAY 1
#pragma GCC system_header
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <compare>
#include <initializer_list>
#include <type_traits>
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/range_access.h> // std::begin, std::end etc.
#include <bits/utility.h> // std::index_sequence, std::tuple_size
#include <debug/assertions.h>
#define __glibcxx_want_array_constexpr
#define __glibcxx_want_freestanding_array
#define __glibcxx_want_nonmember_container_access
#define __glibcxx_want_to_array
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, size_t _Nm>
struct __array_traits
{
using _Type = _Tp[_Nm];
using _Is_swappable = __is_swappable<_Tp>;
using _Is_nothrow_swappable = __is_nothrow_swappable<_Tp>;
};
template<typename _Tp>
struct __array_traits<_Tp, 0>
{
// Empty type used instead of _Tp[0] for std::array<_Tp, 0>.
struct _Type
{
// Indexing is undefined.
__attribute__((__always_inline__,__noreturn__))
_Tp& operator[](size_t) const noexcept { __builtin_trap(); }
// Conversion to a pointer produces a null pointer.
__attribute__((__always_inline__))
constexpr explicit operator _Tp*() const noexcept { return nullptr; }
};
using _Is_swappable = true_type;
using _Is_nothrow_swappable = true_type;
};
/**
* @brief A standard container for storing a fixed size sequence of elements.
*
* @ingroup sequences
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and a
* <a href="tables.html#67">sequence</a>.
*
* Sets support random access iterators.
*
* @tparam Tp Type of element. Required to be a complete type.
* @tparam Nm Number of elements.
*/
template<typename _Tp, std::size_t _Nm>
struct array
{
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// Support for zero-sized arrays mandatory.
typename __array_traits<_Tp, _Nm>::_Type _M_elems;
// No explicit construct/copy/destroy for aggregate type.
// DR 776.
_GLIBCXX20_CONSTEXPR void
fill(const value_type& __u)
{ std::fill_n(begin(), size(), __u); }
_GLIBCXX20_CONSTEXPR void
swap(array& __other)
noexcept(__array_traits<_Tp, _Nm>::_Is_nothrow_swappable::value)
{ std::swap_ranges(begin(), end(), __other.begin()); }
// Iterators.
[[__gnu__::__const__, __nodiscard__]]
_GLIBCXX17_CONSTEXPR iterator
begin() noexcept
{ return iterator(data()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_iterator
begin() const noexcept
{ return const_iterator(data()); }
[[__gnu__::__const__, __nodiscard__]]
_GLIBCXX17_CONSTEXPR iterator
end() noexcept
{ return iterator(data() + _Nm); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_iterator
end() const noexcept
{ return const_iterator(data() + _Nm); }
[[__gnu__::__const__, __nodiscard__]]
_GLIBCXX17_CONSTEXPR reverse_iterator
rbegin() noexcept
{ return reverse_iterator(end()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rbegin() const noexcept
{ return const_reverse_iterator(end()); }
[[__gnu__::__const__, __nodiscard__]]
_GLIBCXX17_CONSTEXPR reverse_iterator
rend() noexcept
{ return reverse_iterator(begin()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rend() const noexcept
{ return const_reverse_iterator(begin()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_iterator
cbegin() const noexcept
{ return const_iterator(data()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_iterator
cend() const noexcept
{ return const_iterator(data() + _Nm); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(end()); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(begin()); }
// Capacity.
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
constexpr size_type
size() const noexcept { return _Nm; }
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
constexpr size_type
max_size() const noexcept { return _Nm; }
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
constexpr bool
empty() const noexcept { return size() == 0; }
// Element access.
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR reference
operator[](size_type __n) noexcept
{
__glibcxx_requires_subscript(__n);
return _M_elems[__n];
}
[[__nodiscard__]]
constexpr const_reference
operator[](size_type __n) const noexcept
{
#if __cplusplus >= 201402L
__glibcxx_requires_subscript(__n);
#endif
return _M_elems[__n];
}
_GLIBCXX17_CONSTEXPR reference
at(size_type __n)
{
if (__n >= _Nm)
std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
">= _Nm (which is %zu)"),
__n, _Nm);
return _M_elems[__n];
}
constexpr const_reference
at(size_type __n) const
{
// Result of conditional expression must be an lvalue so use
// boolean ? lvalue : (throw-expr, lvalue)
return __n < _Nm ? _M_elems[__n]
: (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
">= _Nm (which is %zu)"),
__n, _Nm),
_M_elems[__n]);
}
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR reference
front() noexcept
{
__glibcxx_requires_nonempty();
return _M_elems[(size_type)0];
}
[[__nodiscard__]]
constexpr const_reference
front() const noexcept
{
#if __cplusplus >= 201402L
__glibcxx_requires_nonempty();
#endif
return _M_elems[(size_type)0];
}
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR reference
back() noexcept
{
__glibcxx_requires_nonempty();
return _M_elems[_Nm - 1];
}
[[__nodiscard__]]
constexpr const_reference
back() const noexcept
{
#if __cplusplus >= 201402L
__glibcxx_requires_nonempty();
#endif
return _M_elems[_Nm - 1];
}
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
_GLIBCXX17_CONSTEXPR pointer
data() noexcept
{ return static_cast<pointer>(_M_elems); }
[[__nodiscard__]]
_GLIBCXX17_CONSTEXPR const_pointer
data() const noexcept
{ return static_cast<const_pointer>(_M_elems); }
};
#if __cpp_deduction_guides >= 201606
template<typename _Tp, typename... _Up>
array(_Tp, _Up...)
-> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
1 + sizeof...(_Up)>;
#endif
// Array comparisons.
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return std::equal(__one.begin(), __one.end(), __two.begin()); }
#if __cpp_lib_three_way_comparison // C++ >= 20 && lib_concepts
template<typename _Tp, size_t _Nm>
[[nodiscard]]
constexpr __detail::__synth3way_t<_Tp>
operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
{
if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
if (!std::__is_constant_evaluated())
{
constexpr size_t __n = _Nm * sizeof(_Tp);
return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
}
for (size_t __i = 0; __i < _Nm; ++__i)
{
auto __c = __detail::__synth3way(__a[__i], __b[__i]);
if (__c != 0)
return __c;
}
return strong_ordering::equal;
}
#else
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one == __two); }
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
{
return std::lexicographical_compare(__a.begin(), __a.end(),
__b.begin(), __b.end());
}
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return __two < __one; }
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one > __two); }
template<typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
_GLIBCXX20_CONSTEXPR
inline bool
operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one < __two); }
#endif // three_way_comparison && concepts
// Specialized algorithms.
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
// Constrained free swap overload, see p0185r1
__enable_if_t<__array_traits<_Tp, _Nm>::_Is_swappable::value>
#else
void
#endif
swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
noexcept(noexcept(__one.swap(__two)))
{ __one.swap(__two); }
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
template<typename _Tp, std::size_t _Nm>
__enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value>
swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
#endif
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
constexpr _Tp&
get(array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return __arr._M_elems[_Int];
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
constexpr _Tp&&
get(array<_Tp, _Nm>&& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return std::move(std::get<_Int>(__arr));
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
constexpr const _Tp&
get(const array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return __arr._M_elems[_Int];
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
[[__nodiscard__]]
constexpr const _Tp&&
get(const array<_Tp, _Nm>&& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return std::move(std::get<_Int>(__arr));
}
#ifdef __cpp_lib_to_array // C++ >= 20 && __cpp_generic_lambdas >= 201707L
template<typename _Tp, size_t _Nm>
[[nodiscard]]
constexpr array<remove_cv_t<_Tp>, _Nm>
to_array(_Tp (&__a)[_Nm])
noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
{
static_assert(!is_array_v<_Tp>);
static_assert(is_constructible_v<_Tp, _Tp&>);
if constexpr (is_constructible_v<_Tp, _Tp&>)
{
if constexpr (is_trivially_copyable_v<_Tp>
&& is_trivially_default_constructible_v<_Tp>
&& is_copy_assignable_v<_Tp>)
{
array<remove_cv_t<_Tp>, _Nm> __arr;
if (!__is_constant_evaluated() && _Nm != 0)
__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
else
for (size_t __i = 0; __i < _Nm; ++__i)
__arr._M_elems[__i] = __a[__i];
return __arr;
}
else
return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }};
}(make_index_sequence<_Nm>{});
}
else
__builtin_unreachable(); // FIXME: see PR c++/91388
}
template<typename _Tp, size_t _Nm>
[[nodiscard]]
constexpr array<remove_cv_t<_Tp>, _Nm>
to_array(_Tp (&&__a)[_Nm])
noexcept(is_nothrow_move_constructible_v<_Tp>)
{
static_assert(!is_array_v<_Tp>);
static_assert(is_move_constructible_v<_Tp>);
if constexpr (is_move_constructible_v<_Tp>)
{
if constexpr (is_trivially_copyable_v<_Tp>
&& is_trivially_default_constructible_v<_Tp>
&& is_copy_assignable_v<_Tp>)
{
array<remove_cv_t<_Tp>, _Nm> __arr;
if (!__is_constant_evaluated() && _Nm != 0)
__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
else
for (size_t __i = 0; __i < _Nm; ++__i)
__arr._M_elems[__i] = __a[__i];
return __arr;
}
else
return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }};
}(make_index_sequence<_Nm>{});
}
else
__builtin_unreachable(); // FIXME: see PR c++/91388
}
#endif // __cpp_lib_to_array
// Tuple interface to class template array.
/// Partial specialization for std::array
template<typename _Tp, size_t _Nm>
struct tuple_size<array<_Tp, _Nm>>
: public integral_constant<size_t, _Nm> { };
/// Partial specialization for std::array
template<size_t _Ind, typename _Tp, size_t _Nm>
struct tuple_element<_Ind, array<_Tp, _Nm>>
{
static_assert(_Ind < _Nm, "array index is in range");
using type = _Tp;
};
#if __cplusplus >= 201703L
template<typename _Tp, size_t _Nm>
inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;
template<typename _Tp, size_t _Nm>
inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
#endif
template<typename _Tp, size_t _Nm>
struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
#endif // _GLIBCXX_ARRAY
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,216 @@
/* Copyright (C) 2015-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx5124fmapsintrin.h> directly; include <x86intrin.h> instead."
#endif
#ifndef _AVX5124FMAPSINTRIN_H_INCLUDED
#define _AVX5124FMAPSINTRIN_H_INCLUDED
#ifndef __AVX5124FMAPS__
#pragma GCC push_options
#pragma GCC target("avx5124fmaps,evex512")
#define __DISABLE_AVX5124FMAPS__
#endif /* __AVX5124FMAPS__ */
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_4fmadd_ps (__m512 __A, __m512 __B, __m512 __C,
__m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fmaddps ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_4fmadd_ps (__m512 __A, __mmask16 __U, __m512 __B,
__m512 __C, __m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fmaddps_mask ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F,
(__v16sf) __A,
(__mmask16) __U);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_4fmadd_ps (__mmask16 __U,
__m512 __A, __m512 __B, __m512 __C,
__m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fmaddps_mask ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F,
(__v16sf) _mm512_setzero_ps (),
(__mmask16) __U);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_4fmadd_ss (__m128 __A, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fmaddss ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_4fmadd_ss (__m128 __A, __mmask8 __U, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fmaddss_mask ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F,
(__v4sf) __A,
(__mmask8) __U);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_4fmadd_ss (__mmask8 __U, __m128 __A, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fmaddss_mask ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F,
(__v4sf) _mm_setzero_ps (),
(__mmask8) __U);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_4fnmadd_ps (__m512 __A, __m512 __B, __m512 __C,
__m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fnmaddps ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_4fnmadd_ps (__m512 __A, __mmask16 __U, __m512 __B,
__m512 __C, __m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fnmaddps_mask ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F,
(__v16sf) __A,
(__mmask16) __U);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_4fnmadd_ps (__mmask16 __U,
__m512 __A, __m512 __B, __m512 __C,
__m512 __D, __m512 __E, __m128 *__F)
{
return (__m512) __builtin_ia32_4fnmaddps_mask ((__v16sf) __B,
(__v16sf) __C,
(__v16sf) __D,
(__v16sf) __E,
(__v16sf) __A,
(const __v4sf *) __F,
(__v16sf) _mm512_setzero_ps (),
(__mmask16) __U);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_4fnmadd_ss (__m128 __A, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fnmaddss ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_4fnmadd_ss (__m128 __A, __mmask8 __U, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fnmaddss_mask ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F,
(__v4sf) __A,
(__mmask8) __U);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_4fnmadd_ss (__mmask8 __U, __m128 __A, __m128 __B, __m128 __C,
__m128 __D, __m128 __E, __m128 *__F)
{
return (__m128) __builtin_ia32_4fnmaddss_mask ((__v4sf) __B,
(__v4sf) __C,
(__v4sf) __D,
(__v4sf) __E,
(__v4sf) __A,
(const __v4sf *) __F,
(__v4sf) _mm_setzero_ps (),
(__mmask8) __U);
}
#ifdef __DISABLE_AVX5124FMAPS__
#undef __DISABLE_AVX5124FMAPS__
#pragma GCC pop_options
#endif /* __DISABLE_AVX5124FMAPS__ */
#endif /* _AVX5124FMAPSINTRIN_H_INCLUDED */
@@ -0,0 +1,132 @@
/* Copyright (C) 2015-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx5124vnniwintrin.h> directly; include <x86intrin.h> instead."
#endif
#ifndef _AVX5124VNNIWINTRIN_H_INCLUDED
#define _AVX5124VNNIWINTRIN_H_INCLUDED
#ifndef __AVX5124VNNIW__
#pragma GCC push_options
#pragma GCC target("avx5124vnniw,evex512")
#define __DISABLE_AVX5124VNNIW__
#endif /* __AVX5124VNNIW__ */
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_4dpwssd_epi32 (__m512i __A, __m512i __B, __m512i __C,
__m512i __D, __m512i __E, __m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssd ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_4dpwssd_epi32 (__m512i __A, __mmask16 __U, __m512i __B,
__m512i __C, __m512i __D, __m512i __E,
__m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssd_mask ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F,
(__v16si) __A,
(__mmask16) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_4dpwssd_epi32 (__mmask16 __U, __m512i __A, __m512i __B,
__m512i __C, __m512i __D, __m512i __E,
__m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssd_mask ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F,
(__v16si) _mm512_setzero_ps (),
(__mmask16) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_4dpwssds_epi32 (__m512i __A, __m512i __B, __m512i __C,
__m512i __D, __m512i __E, __m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssds ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_4dpwssds_epi32 (__m512i __A, __mmask16 __U, __m512i __B,
__m512i __C, __m512i __D, __m512i __E,
__m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssds_mask ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F,
(__v16si) __A,
(__mmask16) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_4dpwssds_epi32 (__mmask16 __U, __m512i __A, __m512i __B,
__m512i __C, __m512i __D, __m512i __E,
__m128i *__F)
{
return (__m512i) __builtin_ia32_vp4dpwssds_mask ((__v16si) __B,
(__v16si) __C,
(__v16si) __D,
(__v16si) __E,
(__v16si) __A,
(const __v4si *) __F,
(__v16si) _mm512_setzero_ps (),
(__mmask16) __U);
}
#ifdef __DISABLE_AVX5124VNNIW__
#undef __DISABLE_AVX5124VNNIW__
#pragma GCC pop_options
#endif /* __DISABLE_AVX5124VNNIW__ */
#endif /* _AVX5124VNNIWINTRIN_H_INCLUDED */
+163
View File
@@ -0,0 +1,163 @@
/* Copyright (C) 2019-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512bf16intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512BF16INTRIN_H_INCLUDED
#define _AVX512BF16INTRIN_H_INCLUDED
#if !defined (__AVX512BF16__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512bf16,no-evex512")
#define __DISABLE_AVX512BF16__
#endif /* __AVX512BF16__ */
/* Convert One BF16 Data to One Single Float Data. */
extern __inline float
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtsbh_ss (__bf16 __A)
{
return __builtin_ia32_cvtbf2sf (__A);
}
#ifdef __DISABLE_AVX512BF16__
#undef __DISABLE_AVX512BF16__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512BF16__ */
#if !defined (__AVX512BF16__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512bf16,evex512")
#define __DISABLE_AVX512BF16_512__
#endif /* __AVX512BF16_512__ */
/* Internal data types for implementing the intrinsics. */
typedef __bf16 __v32bf __attribute__ ((__vector_size__ (64)));
/* The Intel API is flexible enough that we must allow aliasing with other
vector types, and their scalar components. */
typedef __bf16 __m512bh __attribute__ ((__vector_size__ (64), __may_alias__));
/* vcvtne2ps2bf16 */
extern __inline __m512bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_cvtne2ps_pbh (__m512 __A, __m512 __B)
{
return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf(__A, __B);
}
extern __inline __m512bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_cvtne2ps_pbh (__m512bh __A, __mmask32 __B, __m512 __C, __m512 __D)
{
return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf_mask(__C, __D, __A, __B);
}
extern __inline __m512bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_cvtne2ps_pbh (__mmask32 __A, __m512 __B, __m512 __C)
{
return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf_maskz(__B, __C, __A);
}
/* vcvtneps2bf16 */
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_cvtneps_pbh (__m512 __A)
{
return (__m256bh)__builtin_ia32_cvtneps2bf16_v16sf(__A);
}
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_cvtneps_pbh (__m256bh __A, __mmask16 __B, __m512 __C)
{
return (__m256bh)__builtin_ia32_cvtneps2bf16_v16sf_mask(__C, __A, __B);
}
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_cvtneps_pbh (__mmask16 __A, __m512 __B)
{
return (__m256bh)__builtin_ia32_cvtneps2bf16_v16sf_maskz(__B, __A);
}
/* vdpbf16ps */
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_dpbf16_ps (__m512 __A, __m512bh __B, __m512bh __C)
{
return (__m512)__builtin_ia32_dpbf16ps_v16sf(__A, __B, __C);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_dpbf16_ps (__m512 __A, __mmask16 __B, __m512bh __C, __m512bh __D)
{
return (__m512)__builtin_ia32_dpbf16ps_v16sf_mask(__A, __C, __D, __B);
}
extern __inline __m512
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_dpbf16_ps (__mmask16 __A, __m512 __B, __m512bh __C, __m512bh __D)
{
return (__m512)__builtin_ia32_dpbf16ps_v16sf_maskz(__B, __C, __D, __A);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_cvtpbh_ps (__m256bh __A)
{
return (__m512)_mm512_castsi512_ps ((__m512i)_mm512_slli_epi32 (
(__m512i)_mm512_cvtepi16_epi32 ((__m256i)__A), 16));
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_cvtpbh_ps (__mmask16 __U, __m256bh __A)
{
return (__m512)_mm512_castsi512_ps ((__m512i) _mm512_slli_epi32 (
(__m512i)_mm512_maskz_cvtepi16_epi32 (
(__mmask16)__U, (__m256i)__A), 16));
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_cvtpbh_ps (__m512 __S, __mmask16 __U, __m256bh __A)
{
return (__m512)_mm512_castsi512_ps ((__m512i)(_mm512_mask_slli_epi32 (
(__m512i)__S, (__mmask16)__U,
(__m512i)_mm512_cvtepi16_epi32 ((__m256i)__A), 16)));
}
#ifdef __DISABLE_AVX512BF16_512__
#undef __DISABLE_AVX512BF16_512__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512BF16_512__ */
#endif /* _AVX512BF16INTRIN_H_INCLUDED */
@@ -0,0 +1,276 @@
/* Copyright (C) 2019-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512bf16vlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512BF16VLINTRIN_H_INCLUDED
#define _AVX512BF16VLINTRIN_H_INCLUDED
#if !defined(__AVX512VL__) || !defined(__AVX512BF16__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512bf16,avx512vl,no-evex512")
#define __DISABLE_AVX512BF16VL__
#endif /* __AVX512BF16__ */
/* Internal data types for implementing the intrinsics. */
typedef __bf16 __v16bf __attribute__ ((__vector_size__ (32)));
typedef __bf16 __v8bf __attribute__ ((__vector_size__ (16)));
/* The Intel API is flexible enough that we must allow aliasing with other
vector types, and their scalar components. */
typedef __bf16 __m256bh __attribute__ ((__vector_size__ (32), __may_alias__));
typedef __bf16 __m128bh __attribute__ ((__vector_size__ (16), __may_alias__));
typedef __bf16 __bfloat16;
extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_avx512_castsi128_ps(__m128i __A)
{
return (__m128) __A;
}
extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_avx512_castsi256_ps (__m256i __A)
{
return (__m256) __A;
}
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_avx512_slli_epi32 (__m128i __A, int __B)
{
return (__m128i)__builtin_ia32_pslldi128 ((__v4si)__A, __B);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_avx512_slli_epi32 (__m256i __A, int __B)
{
return (__m256i)__builtin_ia32_pslldi256 ((__v8si)__A, __B);
}
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_avx512_cvtepi16_epi32 (__m128i __X)
{
return (__m128i) __builtin_ia32_pmovsxwd128 ((__v8hi)__X);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_avx512_cvtepi16_epi32 (__m128i __X)
{
return (__m256i) __builtin_ia32_pmovsxwd256 ((__v8hi)__X);
}
#define _mm256_cvtneps_pbh(A) \
(__m128bh) __builtin_ia32_cvtneps2bf16_v8sf (A)
#define _mm_cvtneps_pbh(A) \
(__m128bh) __builtin_ia32_cvtneps2bf16_v4sf (A)
/* vcvtne2ps2bf16 */
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtne2ps_pbh (__m256 __A, __m256 __B)
{
return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf(__A, __B);
}
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_cvtne2ps_pbh (__m256bh __A, __mmask16 __B, __m256 __C, __m256 __D)
{
return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf_mask(__C, __D, __A, __B);
}
extern __inline __m256bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_cvtne2ps_pbh (__mmask16 __A, __m256 __B, __m256 __C)
{
return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf_maskz(__B, __C, __A);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtne2ps_pbh (__m128 __A, __m128 __B)
{
return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf(__A, __B);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_cvtne2ps_pbh (__m128bh __A, __mmask8 __B, __m128 __C, __m128 __D)
{
return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf_mask(__C, __D, __A, __B);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_cvtne2ps_pbh (__mmask8 __A, __m128 __B, __m128 __C)
{
return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf_maskz(__B, __C, __A);
}
/* vcvtneps2bf16 */
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_cvtneps_pbh (__m128bh __A, __mmask8 __B, __m256 __C)
{
return (__m128bh)__builtin_ia32_cvtneps2bf16_v8sf_mask(__C, __A, __B);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_cvtneps_pbh (__mmask8 __A, __m256 __B)
{
return (__m128bh)__builtin_ia32_cvtneps2bf16_v8sf_maskz(__B, __A);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_cvtneps_pbh (__m128bh __A, __mmask8 __B, __m128 __C)
{
return (__m128bh)__builtin_ia32_cvtneps2bf16_v4sf_mask(__C, __A, __B);
}
extern __inline __m128bh
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_cvtneps_pbh (__mmask8 __A, __m128 __B)
{
return (__m128bh)__builtin_ia32_cvtneps2bf16_v4sf_maskz(__B, __A);
}
/* vdpbf16ps */
extern __inline __m256
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbf16_ps (__m256 __A, __m256bh __B, __m256bh __C)
{
return (__m256)__builtin_ia32_dpbf16ps_v8sf(__A, __B, __C);
}
extern __inline __m256
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_dpbf16_ps (__m256 __A, __mmask8 __B, __m256bh __C, __m256bh __D)
{
return (__m256)__builtin_ia32_dpbf16ps_v8sf_mask(__A, __C, __D, __B);
}
extern __inline __m256
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_dpbf16_ps (__mmask8 __A, __m256 __B, __m256bh __C, __m256bh __D)
{
return (__m256)__builtin_ia32_dpbf16ps_v8sf_maskz(__B, __C, __D, __A);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbf16_ps (__m128 __A, __m128bh __B, __m128bh __C)
{
return (__m128)__builtin_ia32_dpbf16ps_v4sf(__A, __B, __C);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_dpbf16_ps (__m128 __A, __mmask8 __B, __m128bh __C, __m128bh __D)
{
return (__m128)__builtin_ia32_dpbf16ps_v4sf_mask(__A, __C, __D, __B);
}
extern __inline __m128
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_dpbf16_ps (__mmask8 __A, __m128 __B, __m128bh __C, __m128bh __D)
{
return (__m128)__builtin_ia32_dpbf16ps_v4sf_maskz(__B, __C, __D, __A);
}
extern __inline __bf16
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtness_sbh (float __A)
{
__v4sf __V = {__A, 0, 0, 0};
__v8bf __R = __builtin_ia32_cvtneps2bf16_v4sf_mask ((__v4sf)__V,
(__v8bf)_mm_avx512_undefined_si128 (), (__mmask8)-1);
return __R[0];
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtpbh_ps (__m128bh __A)
{
return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_avx512_slli_epi32 (
(__m128i)_mm_avx512_cvtepi16_epi32 ((__m128i)__A), 16));
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtpbh_ps (__m128bh __A)
{
return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_avx512_slli_epi32 (
(__m256i)_mm256_avx512_cvtepi16_epi32 ((__m128i)__A), 16));
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_cvtpbh_ps (__mmask8 __U, __m128bh __A)
{
return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_avx512_slli_epi32 (
(__m128i)_mm_maskz_cvtepi16_epi32 (
(__mmask8)__U, (__m128i)__A), 16));
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_cvtpbh_ps (__mmask8 __U, __m128bh __A)
{
return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_avx512_slli_epi32 (
(__m256i)_mm256_maskz_cvtepi16_epi32 (
(__mmask8)__U, (__m128i)__A), 16));
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_cvtpbh_ps (__m128 __S, __mmask8 __U, __m128bh __A)
{
return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_mask_slli_epi32 (
(__m128i)__S, (__mmask8)__U, (__m128i)_mm_avx512_cvtepi16_epi32 (
(__m128i)__A), 16));
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_cvtpbh_ps (__m256 __S, __mmask8 __U, __m128bh __A)
{
return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_mask_slli_epi32 (
(__m256i)__S, (__mmask8)__U, (__m256i)_mm256_avx512_cvtepi16_epi32 (
(__m128i)__A), 16));
}
#ifdef __DISABLE_AVX512BF16VL__
#undef __DISABLE_AVX512BF16VL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512BF16VL__ */
#endif /* _AVX512BF16VLINTRIN_H_INCLUDED */
@@ -0,0 +1,111 @@
/* Copyright (C) 2017-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx512bitalgintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512BITALGINTRIN_H_INCLUDED
#define _AVX512BITALGINTRIN_H_INCLUDED
#if !defined (__AVX512BITALG__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512bitalg,evex512")
#define __DISABLE_AVX512BITALG__
#endif /* __AVX512BITALG__ */
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_popcnt_epi8 (__m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountb_v64qi ((__v64qi) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_popcnt_epi16 (__m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_popcnt_epi8 (__m512i __W, __mmask64 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountb_v64qi_mask ((__v64qi) __A,
(__v64qi) __W,
(__mmask64) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_popcnt_epi8 (__mmask64 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountb_v64qi_mask ((__v64qi) __A,
(__v64qi)
_mm512_setzero_si512 (),
(__mmask64) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_popcnt_epi16 (__m512i __W, __mmask32 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountw_v32hi_mask ((__v32hi) __A,
(__v32hi) __W,
(__mmask32) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_popcnt_epi16 (__mmask32 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountw_v32hi_mask ((__v32hi) __A,
(__v32hi)
_mm512_setzero_si512 (),
(__mmask32) __U);
}
extern __inline __mmask64
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_bitshuffle_epi64_mask (__m512i __A, __m512i __B)
{
return (__mmask64) __builtin_ia32_vpshufbitqmb512_mask ((__v64qi) __A,
(__v64qi) __B,
(__mmask64) -1);
}
extern __inline __mmask64
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_bitshuffle_epi64_mask (__mmask64 __M, __m512i __A, __m512i __B)
{
return (__mmask64) __builtin_ia32_vpshufbitqmb512_mask ((__v64qi) __A,
(__v64qi) __B,
(__mmask64) __M);
}
#ifdef __DISABLE_AVX512BITALG__
#undef __DISABLE_AVX512BITALG__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512BITALG__ */
#endif /* _AVX512BITALGINTRIN_H_INCLUDED */
@@ -0,0 +1,180 @@
/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx512bitalgvlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512BITALGVLINTRIN_H_INCLUDED
#define _AVX512BITALGVLINTRIN_H_INCLUDED
#if !defined(__AVX512BITALG__) || !defined(__AVX512VL__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512bitalg,avx512vl,no-evex512")
#define __DISABLE_AVX512BITALGVL__
#endif /* __AVX512BITALGVL__ */
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_popcnt_epi8 (__m256i __W, __mmask32 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A,
(__v32qi) __W,
(__mmask32) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_popcnt_epi8 (__mmask32 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A,
(__v32qi)
_mm256_avx512_setzero_si256 (),
(__mmask32) __U);
}
extern __inline __mmask32
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_bitshuffle_epi64_mask (__m256i __A, __m256i __B)
{
return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A,
(__v32qi) __B,
(__mmask32) -1);
}
extern __inline __mmask32
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_bitshuffle_epi64_mask (__mmask32 __M, __m256i __A, __m256i __B)
{
return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A,
(__v32qi) __B,
(__mmask32) __M);
}
extern __inline __mmask16
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_bitshuffle_epi64_mask (__m128i __A, __m128i __B)
{
return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A,
(__v16qi) __B,
(__mmask16) -1);
}
extern __inline __mmask16
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_bitshuffle_epi64_mask (__mmask16 __M, __m128i __A, __m128i __B)
{
return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A,
(__v16qi) __B,
(__mmask16) __M);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_popcnt_epi8 (__m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountb_v32qi ((__v32qi) __A);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_popcnt_epi16 (__m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountw_v16hi ((__v16hi) __A);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_popcnt_epi8 (__m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountb_v16qi ((__v16qi) __A);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_popcnt_epi16 (__m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountw_v8hi ((__v8hi) __A);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_popcnt_epi16 (__m256i __W, __mmask16 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A,
(__v16hi) __W,
(__mmask16) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_popcnt_epi16 (__mmask16 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A,
(__v16hi)
_mm256_avx512_setzero_si256 (),
(__mmask16) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_popcnt_epi8 (__m128i __W, __mmask16 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A,
(__v16qi) __W,
(__mmask16) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_popcnt_epi8 (__mmask16 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A,
(__v16qi)
_mm_avx512_setzero_si128 (),
(__mmask16) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_popcnt_epi16 (__m128i __W, __mmask8 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A,
(__v8hi) __W,
(__mmask8) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_popcnt_epi16 (__mmask8 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A,
(__v8hi)
_mm_avx512_setzero_si128 (),
(__mmask8) __U);
}
#ifdef __DISABLE_AVX512BITALGVL__
#undef __DISABLE_AVX512BITALGVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512BITALGVL__ */
#endif /* _AVX512BITALGVLINTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
+184
View File
@@ -0,0 +1,184 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512cdintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512CDINTRIN_H_INCLUDED
#define _AVX512CDINTRIN_H_INCLUDED
#ifndef __AVX512CD__
#pragma GCC push_options
#pragma GCC target("avx512cd,evex512")
#define __DISABLE_AVX512CD__
#endif /* __AVX512CD__ */
/* Internal data types for implementing the intrinsics. */
typedef long long __v8di __attribute__ ((__vector_size__ (64)));
typedef int __v16si __attribute__ ((__vector_size__ (64)));
/* The Intel API is flexible enough that we must allow aliasing with other
vector types, and their scalar components. */
typedef long long __m512i __attribute__ ((__vector_size__ (64), __may_alias__));
typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
typedef unsigned char __mmask8;
typedef unsigned short __mmask16;
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_conflict_epi32 (__m512i __A)
{
return (__m512i)
__builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
(__v16si) _mm512_setzero_si512 (),
(__mmask16) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_conflict_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
(__v16si) __W,
(__mmask16) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_conflict_epi32 (__mmask16 __U, __m512i __A)
{
return (__m512i)
__builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
(__v16si) _mm512_setzero_si512 (),
(__mmask16) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_conflict_epi64 (__m512i __A)
{
return (__m512i)
__builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
(__v8di) _mm512_setzero_si512 (),
(__mmask8) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_conflict_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
(__v8di) __W,
(__mmask8) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_conflict_epi64 (__mmask8 __U, __m512i __A)
{
return (__m512i)
__builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
(__v8di) _mm512_setzero_si512 (),
(__mmask8) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_lzcnt_epi64 (__m512i __A)
{
return (__m512i)
__builtin_ia32_vplzcntq_512_mask ((__v8di) __A,
(__v8di) _mm512_setzero_si512 (),
(__mmask8) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_lzcnt_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vplzcntq_512_mask ((__v8di) __A,
(__v8di) __W,
(__mmask8) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_lzcnt_epi64 (__mmask8 __U, __m512i __A)
{
return (__m512i)
__builtin_ia32_vplzcntq_512_mask ((__v8di) __A,
(__v8di) _mm512_setzero_si512 (),
(__mmask8) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_lzcnt_epi32 (__m512i __A)
{
return (__m512i)
__builtin_ia32_vplzcntd_512_mask ((__v16si) __A,
(__v16si) _mm512_setzero_si512 (),
(__mmask16) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_lzcnt_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vplzcntd_512_mask ((__v16si) __A,
(__v16si) __W,
(__mmask16) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_lzcnt_epi32 (__mmask16 __U, __m512i __A)
{
return (__m512i)
__builtin_ia32_vplzcntd_512_mask ((__v16si) __A,
(__v16si) _mm512_setzero_si512 (),
(__mmask16) __U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_broadcastmb_epi64 (__mmask8 __A)
{
return (__m512i) __builtin_ia32_broadcastmb512 (__A);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_broadcastmw_epi32 (__mmask16 __A)
{
return (__m512i) __builtin_ia32_broadcastmw512 (__A);
}
#ifdef __DISABLE_AVX512CD__
#undef __DISABLE_AVX512CD__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512CD__ */
#endif /* _AVX512CDINTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
+536
View File
@@ -0,0 +1,536 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512erintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512ERINTRIN_H_INCLUDED
#define _AVX512ERINTRIN_H_INCLUDED
#ifndef __AVX512ER__
#pragma GCC push_options
#pragma GCC target("avx512er,evex512")
#define __DISABLE_AVX512ER__
#endif /* __AVX512ER__ */
/* Internal data types for implementing the intrinsics. */
typedef double __v8df __attribute__ ((__vector_size__ (64)));
typedef float __v16sf __attribute__ ((__vector_size__ (64)));
/* The Intel API is flexible enough that we must allow aliasing with other
vector types, and their scalar components. */
typedef float __m512 __attribute__ ((__vector_size__ (64), __may_alias__));
typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__));
typedef unsigned char __mmask8;
typedef unsigned short __mmask16;
#ifdef __OPTIMIZE__
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_exp2a23_round_pd (__m512d __A, int __R)
{
return (__m512d) __builtin_ia32_exp2pd_mask ((__v8df) __A,
(__v8df) _mm512_undefined_pd (),
(__mmask8) -1, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_exp2a23_round_pd (__m512d __W, __mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_exp2pd_mask ((__v8df) __A,
(__v8df) __W,
(__mmask8) __U, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_exp2a23_round_pd (__mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_exp2pd_mask ((__v8df) __A,
(__v8df) _mm512_setzero_pd (),
(__mmask8) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_exp2a23_round_ps (__m512 __A, int __R)
{
return (__m512) __builtin_ia32_exp2ps_mask ((__v16sf) __A,
(__v16sf) _mm512_undefined_ps (),
(__mmask16) -1, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_exp2a23_round_ps (__m512 __W, __mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_exp2ps_mask ((__v16sf) __A,
(__v16sf) __W,
(__mmask16) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_exp2a23_round_ps (__mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_exp2ps_mask ((__v16sf) __A,
(__v16sf) _mm512_setzero_ps (),
(__mmask16) __U, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_rcp28_round_pd (__m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rcp28pd_mask ((__v8df) __A,
(__v8df) _mm512_undefined_pd (),
(__mmask8) -1, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_rcp28_round_pd (__m512d __W, __mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rcp28pd_mask ((__v8df) __A,
(__v8df) __W,
(__mmask8) __U, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_rcp28_round_pd (__mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rcp28pd_mask ((__v8df) __A,
(__v8df) _mm512_setzero_pd (),
(__mmask8) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_rcp28_round_ps (__m512 __A, int __R)
{
return (__m512) __builtin_ia32_rcp28ps_mask ((__v16sf) __A,
(__v16sf) _mm512_undefined_ps (),
(__mmask16) -1, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_rcp28_round_ps (__m512 __W, __mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_rcp28ps_mask ((__v16sf) __A,
(__v16sf) __W,
(__mmask16) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_rcp28_round_ps (__mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_rcp28ps_mask ((__v16sf) __A,
(__v16sf) _mm512_setzero_ps (),
(__mmask16) __U, __R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_rcp28_round_sd (__m128d __A, __m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rcp28sd_round ((__v2df) __B,
(__v2df) __A,
__R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_rcp28_round_sd (__m128d __W, __mmask8 __U, __m128d __A,
__m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rcp28sd_mask_round ((__v2df) __B,
(__v2df) __A,
(__v2df) __W,
__U,
__R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_rcp28_round_sd (__mmask8 __U, __m128d __A, __m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rcp28sd_mask_round ((__v2df) __B,
(__v2df) __A,
(__v2df)
_mm_setzero_pd (),
__U,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_rcp28_round_ss (__m128 __A, __m128 __B, int __R)
{
return (__m128) __builtin_ia32_rcp28ss_round ((__v4sf) __B,
(__v4sf) __A,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_rcp28_round_ss (__m128 __W, __mmask8 __U, __m128 __A,
__m128 __B, int __R)
{
return (__m128) __builtin_ia32_rcp28ss_mask_round ((__v4sf) __B,
(__v4sf) __A,
(__v4sf) __W,
__U,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_rcp28_round_ss (__mmask8 __U, __m128 __A, __m128 __B, int __R)
{
return (__m128) __builtin_ia32_rcp28ss_mask_round ((__v4sf) __B,
(__v4sf) __A,
(__v4sf)
_mm_setzero_ps (),
__U,
__R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_rsqrt28_round_pd (__m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rsqrt28pd_mask ((__v8df) __A,
(__v8df) _mm512_undefined_pd (),
(__mmask8) -1, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_rsqrt28_round_pd (__m512d __W, __mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rsqrt28pd_mask ((__v8df) __A,
(__v8df) __W,
(__mmask8) __U, __R);
}
extern __inline __m512d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_rsqrt28_round_pd (__mmask8 __U, __m512d __A, int __R)
{
return (__m512d) __builtin_ia32_rsqrt28pd_mask ((__v8df) __A,
(__v8df) _mm512_setzero_pd (),
(__mmask8) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_rsqrt28_round_ps (__m512 __A, int __R)
{
return (__m512) __builtin_ia32_rsqrt28ps_mask ((__v16sf) __A,
(__v16sf) _mm512_undefined_ps (),
(__mmask16) -1, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_rsqrt28_round_ps (__m512 __W, __mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_rsqrt28ps_mask ((__v16sf) __A,
(__v16sf) __W,
(__mmask16) __U, __R);
}
extern __inline __m512
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_rsqrt28_round_ps (__mmask16 __U, __m512 __A, int __R)
{
return (__m512) __builtin_ia32_rsqrt28ps_mask ((__v16sf) __A,
(__v16sf) _mm512_setzero_ps (),
(__mmask16) __U, __R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_rsqrt28_round_sd (__m128d __A, __m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rsqrt28sd_round ((__v2df) __B,
(__v2df) __A,
__R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_rsqrt28_round_sd (__m128d __W, __mmask8 __U, __m128d __A,
__m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rsqrt28sd_mask_round ((__v2df) __B,
(__v2df) __A,
(__v2df) __W,
__U,
__R);
}
extern __inline __m128d
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_rsqrt28_round_sd (__mmask8 __U, __m128d __A, __m128d __B, int __R)
{
return (__m128d) __builtin_ia32_rsqrt28sd_mask_round ((__v2df) __B,
(__v2df) __A,
(__v2df)
_mm_setzero_pd (),
__U,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_rsqrt28_round_ss (__m128 __A, __m128 __B, int __R)
{
return (__m128) __builtin_ia32_rsqrt28ss_round ((__v4sf) __B,
(__v4sf) __A,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_rsqrt28_round_ss (__m128 __W, __mmask8 __U, __m128 __A,
__m128 __B, int __R)
{
return (__m128) __builtin_ia32_rsqrt28ss_mask_round ((__v4sf) __B,
(__v4sf) __A,
(__v4sf) __W,
__U,
__R);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_rsqrt28_round_ss (__mmask8 __U, __m128 __A, __m128 __B, int __R)
{
return (__m128) __builtin_ia32_rsqrt28ss_mask_round ((__v4sf) __B,
(__v4sf) __A,
(__v4sf)
_mm_setzero_ps (),
__U,
__R);
}
#else
#define _mm512_exp2a23_round_pd(A, C) \
__builtin_ia32_exp2pd_mask(A, (__v8df)_mm512_setzero_pd(), -1, C)
#define _mm512_mask_exp2a23_round_pd(W, U, A, C) \
__builtin_ia32_exp2pd_mask(A, W, U, C)
#define _mm512_maskz_exp2a23_round_pd(U, A, C) \
__builtin_ia32_exp2pd_mask(A, (__v8df)_mm512_setzero_pd(), U, C)
#define _mm512_exp2a23_round_ps(A, C) \
__builtin_ia32_exp2ps_mask(A, (__v16sf)_mm512_setzero_ps(), -1, C)
#define _mm512_mask_exp2a23_round_ps(W, U, A, C) \
__builtin_ia32_exp2ps_mask(A, W, U, C)
#define _mm512_maskz_exp2a23_round_ps(U, A, C) \
__builtin_ia32_exp2ps_mask(A, (__v16sf)_mm512_setzero_ps(), U, C)
#define _mm512_rcp28_round_pd(A, C) \
__builtin_ia32_rcp28pd_mask(A, (__v8df)_mm512_setzero_pd(), -1, C)
#define _mm512_mask_rcp28_round_pd(W, U, A, C) \
__builtin_ia32_rcp28pd_mask(A, W, U, C)
#define _mm512_maskz_rcp28_round_pd(U, A, C) \
__builtin_ia32_rcp28pd_mask(A, (__v8df)_mm512_setzero_pd(), U, C)
#define _mm512_rcp28_round_ps(A, C) \
__builtin_ia32_rcp28ps_mask(A, (__v16sf)_mm512_setzero_ps(), -1, C)
#define _mm512_mask_rcp28_round_ps(W, U, A, C) \
__builtin_ia32_rcp28ps_mask(A, W, U, C)
#define _mm512_maskz_rcp28_round_ps(U, A, C) \
__builtin_ia32_rcp28ps_mask(A, (__v16sf)_mm512_setzero_ps(), U, C)
#define _mm512_rsqrt28_round_pd(A, C) \
__builtin_ia32_rsqrt28pd_mask(A, (__v8df)_mm512_setzero_pd(), -1, C)
#define _mm512_mask_rsqrt28_round_pd(W, U, A, C) \
__builtin_ia32_rsqrt28pd_mask(A, W, U, C)
#define _mm512_maskz_rsqrt28_round_pd(U, A, C) \
__builtin_ia32_rsqrt28pd_mask(A, (__v8df)_mm512_setzero_pd(), U, C)
#define _mm512_rsqrt28_round_ps(A, C) \
__builtin_ia32_rsqrt28ps_mask(A, (__v16sf)_mm512_setzero_ps(), -1, C)
#define _mm512_mask_rsqrt28_round_ps(W, U, A, C) \
__builtin_ia32_rsqrt28ps_mask(A, W, U, C)
#define _mm512_maskz_rsqrt28_round_ps(U, A, C) \
__builtin_ia32_rsqrt28ps_mask(A, (__v16sf)_mm512_setzero_ps(), U, C)
#define _mm_rcp28_round_sd(A, B, R) \
__builtin_ia32_rcp28sd_round(A, B, R)
#define _mm_mask_rcp28_round_sd(W, U, A, B, R) \
__builtin_ia32_rcp28sd_mask_round ((A), (B), (W), (U), (R))
#define _mm_maskz_rcp28_round_sd(U, A, B, R) \
__builtin_ia32_rcp28sd_mask_round ((A), (B), (__v2df) _mm_setzero_pd (), \
(U), (R))
#define _mm_rcp28_round_ss(A, B, R) \
__builtin_ia32_rcp28ss_round(A, B, R)
#define _mm_mask_rcp28_round_ss(W, U, A, B, R) \
__builtin_ia32_rcp28ss_mask_round ((A), (B), (W), (U), (R))
#define _mm_maskz_rcp28_round_ss(U, A, B, R) \
__builtin_ia32_rcp28ss_mask_round ((A), (B), (__v4sf) _mm_setzero_ps (), \
(U), (R))
#define _mm_rsqrt28_round_sd(A, B, R) \
__builtin_ia32_rsqrt28sd_round(A, B, R)
#define _mm_mask_rsqrt28_round_sd(W, U, A, B, R) \
__builtin_ia32_rsqrt28sd_mask_round ((A), (B), (W), (U), (R))
#define _mm_maskz_rsqrt28_round_sd(U, A, B, R) \
__builtin_ia32_rsqrt28sd_mask_round ((A), (B), (__v2df) _mm_setzero_pd (),\
(U), (R))
#define _mm_rsqrt28_round_ss(A, B, R) \
__builtin_ia32_rsqrt28ss_round(A, B, R)
#define _mm_mask_rsqrt28_round_ss(W, U, A, B, R) \
__builtin_ia32_rsqrt28ss_mask_round ((A), (B), (W), (U), (R))
#define _mm_maskz_rsqrt28_round_ss(U, A, B, R) \
__builtin_ia32_rsqrt28ss_mask_round ((A), (B), (__v4sf) _mm_setzero_ps (),\
(U), (R))
#endif
#define _mm_mask_rcp28_sd(W, U, A, B)\
_mm_mask_rcp28_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_maskz_rcp28_sd(U, A, B)\
_mm_maskz_rcp28_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_mask_rcp28_ss(W, U, A, B)\
_mm_mask_rcp28_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_maskz_rcp28_ss(U, A, B)\
_mm_maskz_rcp28_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_mask_rsqrt28_sd(W, U, A, B)\
_mm_mask_rsqrt28_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_maskz_rsqrt28_sd(U, A, B)\
_mm_maskz_rsqrt28_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_mask_rsqrt28_ss(W, U, A, B)\
_mm_mask_rsqrt28_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm_maskz_rsqrt28_ss(U, A, B)\
_mm_maskz_rsqrt28_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION)
#define _mm512_exp2a23_pd(A) \
_mm512_exp2a23_round_pd(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_exp2a23_pd(W, U, A) \
_mm512_mask_exp2a23_round_pd(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_exp2a23_pd(U, A) \
_mm512_maskz_exp2a23_round_pd(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_exp2a23_ps(A) \
_mm512_exp2a23_round_ps(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_exp2a23_ps(W, U, A) \
_mm512_mask_exp2a23_round_ps(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_exp2a23_ps(U, A) \
_mm512_maskz_exp2a23_round_ps(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_rcp28_pd(A) \
_mm512_rcp28_round_pd(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_rcp28_pd(W, U, A) \
_mm512_mask_rcp28_round_pd(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_rcp28_pd(U, A) \
_mm512_maskz_rcp28_round_pd(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_rcp28_ps(A) \
_mm512_rcp28_round_ps(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_rcp28_ps(W, U, A) \
_mm512_mask_rcp28_round_ps(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_rcp28_ps(U, A) \
_mm512_maskz_rcp28_round_ps(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_rsqrt28_pd(A) \
_mm512_rsqrt28_round_pd(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_rsqrt28_pd(W, U, A) \
_mm512_mask_rsqrt28_round_pd(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_rsqrt28_pd(U, A) \
_mm512_maskz_rsqrt28_round_pd(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_rsqrt28_ps(A) \
_mm512_rsqrt28_round_ps(A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_mask_rsqrt28_ps(W, U, A) \
_mm512_mask_rsqrt28_round_ps(W, U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm512_maskz_rsqrt28_ps(U, A) \
_mm512_maskz_rsqrt28_round_ps(U, A, _MM_FROUND_CUR_DIRECTION)
#define _mm_rcp28_sd(A, B) \
__builtin_ia32_rcp28sd_round(B, A, _MM_FROUND_CUR_DIRECTION)
#define _mm_rcp28_ss(A, B) \
__builtin_ia32_rcp28ss_round(B, A, _MM_FROUND_CUR_DIRECTION)
#define _mm_rsqrt28_sd(A, B) \
__builtin_ia32_rsqrt28sd_round(B, A, _MM_FROUND_CUR_DIRECTION)
#define _mm_rsqrt28_ss(A, B) \
__builtin_ia32_rsqrt28ss_round(B, A, _MM_FROUND_CUR_DIRECTION)
#ifdef __DISABLE_AVX512ER__
#undef __DISABLE_AVX512ER__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512ER__ */
#endif /* _AVX512ERINTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+104
View File
@@ -0,0 +1,104 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512ifmaintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512IFMAINTRIN_H_INCLUDED
#define _AVX512IFMAINTRIN_H_INCLUDED
#if !defined (__AVX512IFMA__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512ifma,evex512")
#define __DISABLE_AVX512IFMA__
#endif /* __AVX512IFMA__ */
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_madd52lo_epu64 (__m512i __X, __m512i __Y, __m512i __Z)
{
return (__m512i) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X,
(__v8di) __Y,
(__v8di) __Z,
(__mmask8) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_madd52hi_epu64 (__m512i __X, __m512i __Y, __m512i __Z)
{
return (__m512i) __builtin_ia32_vpmadd52huq512_mask ((__v8di) __X,
(__v8di) __Y,
(__v8di) __Z,
(__mmask8) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_madd52lo_epu64 (__m512i __W, __mmask8 __M, __m512i __X,
__m512i __Y)
{
return (__m512i) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __W,
(__v8di) __X,
(__v8di) __Y,
(__mmask8) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_madd52hi_epu64 (__m512i __W, __mmask8 __M, __m512i __X,
__m512i __Y)
{
return (__m512i) __builtin_ia32_vpmadd52huq512_mask ((__v8di) __W,
(__v8di) __X,
(__v8di) __Y,
(__mmask8) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_madd52lo_epu64 (__mmask8 __M, __m512i __X, __m512i __Y, __m512i __Z)
{
return (__m512i) __builtin_ia32_vpmadd52luq512_maskz ((__v8di) __X,
(__v8di) __Y,
(__v8di) __Z,
(__mmask8) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_madd52hi_epu64 (__mmask8 __M, __m512i __X, __m512i __Y, __m512i __Z)
{
return (__m512i) __builtin_ia32_vpmadd52huq512_maskz ((__v8di) __X,
(__v8di) __Y,
(__v8di) __Z,
(__mmask8) __M);
}
#ifdef __DISABLE_AVX512IFMA__
#undef __DISABLE_AVX512IFMA__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512IFMA__ */
#endif /* _AVX512IFMAINTRIN_H_INCLUDED */
@@ -0,0 +1,145 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512ifmavlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512IFMAVLINTRIN_H_INCLUDED
#define _AVX512IFMAVLINTRIN_H_INCLUDED
#if !defined(__AVX512VL__) || !defined(__AVX512IFMA__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512ifma,avx512vl,no-evex512")
#define __DISABLE_AVX512IFMAVL__
#endif /* __AVX512IFMAVL__ */
#define _mm_madd52lo_epu64(A, B, C) \
((__m128i) __builtin_ia32_vpmadd52luq128 ((__v2di) (A), \
(__v2di) (B), \
(__v2di) (C)))
#define _mm_madd52hi_epu64(A, B, C) \
((__m128i) __builtin_ia32_vpmadd52huq128 ((__v2di) (A), \
(__v2di) (B), \
(__v2di) (C)))
#define _mm256_madd52lo_epu64(A, B, C) \
((__m256i) __builtin_ia32_vpmadd52luq256 ((__v4di) (A), \
(__v4di) (B), \
(__v4di) (C)))
#define _mm256_madd52hi_epu64(A, B, C) \
((__m256i) __builtin_ia32_vpmadd52huq256 ((__v4di) (A), \
(__v4di) (B), \
(__v4di) (C)))
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_madd52lo_epu64 (__m128i __W, __mmask8 __M, __m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_vpmadd52luq128_mask ((__v2di) __W,
(__v2di) __X,
(__v2di) __Y,
(__mmask8) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_madd52hi_epu64 (__m128i __W, __mmask8 __M, __m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_vpmadd52huq128_mask ((__v2di) __W,
(__v2di) __X,
(__v2di) __Y,
(__mmask8) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_madd52lo_epu64 (__m256i __W, __mmask8 __M, __m256i __X,
__m256i __Y)
{
return (__m256i) __builtin_ia32_vpmadd52luq256_mask ((__v4di) __W,
(__v4di) __X,
(__v4di) __Y,
(__mmask8) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_madd52hi_epu64 (__m256i __W, __mmask8 __M, __m256i __X,
__m256i __Y)
{
return (__m256i) __builtin_ia32_vpmadd52huq256_mask ((__v4di) __W,
(__v4di) __X,
(__v4di) __Y,
(__mmask8) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_madd52lo_epu64 (__mmask8 __M, __m128i __X, __m128i __Y, __m128i __Z)
{
return (__m128i) __builtin_ia32_vpmadd52luq128_maskz ((__v2di) __X,
(__v2di) __Y,
(__v2di) __Z,
(__mmask8) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_madd52hi_epu64 (__mmask8 __M, __m128i __X, __m128i __Y, __m128i __Z)
{
return (__m128i) __builtin_ia32_vpmadd52huq128_maskz ((__v2di) __X,
(__v2di) __Y,
(__v2di) __Z,
(__mmask8) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_madd52lo_epu64 (__mmask8 __M, __m256i __X, __m256i __Y, __m256i __Z)
{
return (__m256i) __builtin_ia32_vpmadd52luq256_maskz ((__v4di) __X,
(__v4di) __Y,
(__v4di) __Z,
(__mmask8) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_madd52hi_epu64 (__mmask8 __M, __m256i __X, __m256i __Y, __m256i __Z)
{
return (__m256i) __builtin_ia32_vpmadd52huq256_maskz ((__v4di) __X,
(__v4di) __Y,
(__v4di) __Z,
(__mmask8) __M);
}
#ifdef __DISABLE_AVX512IFMAVL__
#undef __DISABLE_AVX512IFMAVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512IFMAVL__ */
#endif /* _AVX512IFMAVLINTRIN_H_INCLUDED */
+269
View File
@@ -0,0 +1,269 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512pfintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512PFINTRIN_H_INCLUDED
#define _AVX512PFINTRIN_H_INCLUDED
#ifndef __AVX512PF__
#pragma GCC push_options
#pragma GCC target("avx512pf,evex512")
#define __DISABLE_AVX512PF__
#endif /* __AVX512PF__ */
/* Internal data types for implementing the intrinsics. */
typedef long long __v8di __attribute__ ((__vector_size__ (64)));
typedef int __v16si __attribute__ ((__vector_size__ (64)));
/* The Intel API is flexible enough that we must allow aliasing with other
vector types, and their scalar components. */
typedef long long __m512i __attribute__ ((__vector_size__ (64), __may_alias__));
typedef unsigned char __mmask8;
typedef unsigned short __mmask16;
#ifdef __OPTIMIZE__
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i32gather_pd (__m256i __index, void const *__addr,
int __scale, int __hint)
{
__builtin_ia32_gatherpfdpd ((__mmask8) 0xFF, (__v8si) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i32gather_ps (__m512i __index, void const *__addr,
int __scale, int __hint)
{
__builtin_ia32_gatherpfdps ((__mmask16) 0xFFFF, (__v16si) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i32gather_pd (__m256i __index, __mmask8 __mask,
void const *__addr, int __scale, int __hint)
{
__builtin_ia32_gatherpfdpd (__mask, (__v8si) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i32gather_ps (__m512i __index, __mmask16 __mask,
void const *__addr, int __scale, int __hint)
{
__builtin_ia32_gatherpfdps (__mask, (__v16si) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i64gather_pd (__m512i __index, void const *__addr,
int __scale, int __hint)
{
__builtin_ia32_gatherpfqpd ((__mmask8) 0xFF, (__v8di) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i64gather_ps (__m512i __index, void const *__addr,
int __scale, int __hint)
{
__builtin_ia32_gatherpfqps ((__mmask8) 0xFF, (__v8di) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i64gather_pd (__m512i __index, __mmask8 __mask,
void const *__addr, int __scale, int __hint)
{
__builtin_ia32_gatherpfqpd (__mask, (__v8di) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i64gather_ps (__m512i __index, __mmask8 __mask,
void const *__addr, int __scale, int __hint)
{
__builtin_ia32_gatherpfqps (__mask, (__v8di) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i32scatter_pd (void *__addr, __m256i __index, int __scale,
int __hint)
{
__builtin_ia32_scatterpfdpd ((__mmask8) 0xFF, (__v8si) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i32scatter_ps (void *__addr, __m512i __index, int __scale,
int __hint)
{
__builtin_ia32_scatterpfdps ((__mmask16) 0xFFFF, (__v16si) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i32scatter_pd (void *__addr, __mmask8 __mask,
__m256i __index, int __scale, int __hint)
{
__builtin_ia32_scatterpfdpd (__mask, (__v8si) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i32scatter_ps (void *__addr, __mmask16 __mask,
__m512i __index, int __scale, int __hint)
{
__builtin_ia32_scatterpfdps (__mask, (__v16si) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i64scatter_pd (void *__addr, __m512i __index, int __scale,
int __hint)
{
__builtin_ia32_scatterpfqpd ((__mmask8) 0xFF, (__v8di) __index,__addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_prefetch_i64scatter_ps (void *__addr, __m512i __index, int __scale,
int __hint)
{
__builtin_ia32_scatterpfqps ((__mmask8) 0xFF, (__v8di) __index, __addr,
__scale, __hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i64scatter_pd (void *__addr, __mmask8 __mask,
__m512i __index, int __scale, int __hint)
{
__builtin_ia32_scatterpfqpd (__mask, (__v8di) __index, __addr, __scale,
__hint);
}
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_prefetch_i64scatter_ps (void *__addr, __mmask8 __mask,
__m512i __index, int __scale, int __hint)
{
__builtin_ia32_scatterpfqps (__mask, (__v8di) __index, __addr, __scale,
__hint);
}
#else
#define _mm512_prefetch_i32gather_pd(INDEX, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfdpd ((__mmask8)0xFF, (__v8si)(__m256i) (INDEX), \
(void const *) (ADDR), (int) (SCALE), \
(int) (HINT))
#define _mm512_prefetch_i32gather_ps(INDEX, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfdps ((__mmask16)0xFFFF, (__v16si)(__m512i) (INDEX), \
(void const *) (ADDR), (int) (SCALE), \
(int) (HINT))
#define _mm512_mask_prefetch_i32gather_pd(INDEX, MASK, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfdpd ((__mmask8) (MASK), (__v8si)(__m256i) (INDEX), \
(void const *) (ADDR), (int) (SCALE), \
(int) (HINT))
#define _mm512_mask_prefetch_i32gather_ps(INDEX, MASK, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfdps ((__mmask16) (MASK), (__v16si)(__m512i) (INDEX),\
(void const *) (ADDR), (int) (SCALE), \
(int) (HINT))
#define _mm512_prefetch_i64gather_pd(INDEX, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfqpd ((__mmask8)0xFF, (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_prefetch_i64gather_ps(INDEX, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfqps ((__mmask8)0xFF, (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i64gather_pd(INDEX, MASK, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfqpd ((__mmask8) (MASK), (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i64gather_ps(INDEX, MASK, ADDR, SCALE, HINT) \
__builtin_ia32_gatherpfqps ((__mmask8) (MASK), (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_prefetch_i32scatter_pd(ADDR, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfdpd ((__mmask8)0xFF, (__v8si)(__m256i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_prefetch_i32scatter_ps(ADDR, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfdps ((__mmask16)0xFFFF, (__v16si)(__m512i) (INDEX),\
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i32scatter_pd(ADDR, MASK, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfdpd ((__mmask8) (MASK), (__v8si)(__m256i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i32scatter_ps(ADDR, MASK, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfdps ((__mmask16) (MASK), \
(__v16si)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_prefetch_i64scatter_pd(ADDR, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfqpd ((__mmask8)0xFF, (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_prefetch_i64scatter_ps(ADDR, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfqps ((__mmask8)0xFF, (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i64scatter_pd(ADDR, MASK, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfqpd ((__mmask8) (MASK), (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#define _mm512_mask_prefetch_i64scatter_ps(ADDR, MASK, INDEX, SCALE, HINT) \
__builtin_ia32_scatterpfqps ((__mmask8) (MASK), (__v8di)(__m512i) (INDEX), \
(void *) (ADDR), (int) (SCALE), (int) (HINT))
#endif
#ifdef __DISABLE_AVX512PF__
#undef __DISABLE_AVX512PF__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512PF__ */
#endif /* _AVX512PFINTRIN_H_INCLUDED */
@@ -0,0 +1,545 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vbmi2intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef __AVX512VBMI2INTRIN_H_INCLUDED
#define __AVX512VBMI2INTRIN_H_INCLUDED
#if !defined(__AVX512VBMI2__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vbmi2,evex512")
#define __DISABLE_AVX512VBMI2__
#endif /* __AVX512VBMI2__ */
#ifdef __OPTIMIZE__
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdi_epi16 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshrd_v32hi ((__v32hi)__A, (__v32hi) __B,
__C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdi_epi32 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshrd_v16si ((__v16si)__A, (__v16si) __B,
__C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdi_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshrd_v16si_mask ((__v16si)__C,
(__v16si) __D, __E, (__v16si) __A, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdi_epi32 (__mmask16 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshrd_v16si_mask ((__v16si)__B,
(__v16si) __C, __D, (__v16si) _mm512_setzero_si512 (), (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdi_epi64 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshrd_v8di ((__v8di)__A, (__v8di) __B, __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdi_epi64 (__m512i __A, __mmask8 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshrd_v8di_mask ((__v8di)__C, (__v8di) __D,
__E, (__v8di) __A, (__mmask8)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdi_epi64 (__mmask8 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshrd_v8di_mask ((__v8di)__B, (__v8di) __C,
__D, (__v8di) _mm512_setzero_si512 (), (__mmask8)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldi_epi16 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshld_v32hi ((__v32hi)__A, (__v32hi) __B,
__C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldi_epi32 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshld_v16si ((__v16si)__A, (__v16si) __B,
__C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldi_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshld_v16si_mask ((__v16si)__C,
(__v16si) __D, __E, (__v16si) __A, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldi_epi32 (__mmask16 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshld_v16si_mask ((__v16si)__B,
(__v16si) __C, __D, (__v16si) _mm512_setzero_si512 (), (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldi_epi64 (__m512i __A, __m512i __B, int __C)
{
return (__m512i) __builtin_ia32_vpshld_v8di ((__v8di)__A, (__v8di) __B, __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldi_epi64 (__m512i __A, __mmask8 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshld_v8di_mask ((__v8di)__C, (__v8di) __D,
__E, (__v8di) __A, (__mmask8)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldi_epi64 (__mmask8 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshld_v8di_mask ((__v8di)__B, (__v8di) __C,
__D, (__v8di) _mm512_setzero_si512 (), (__mmask8)__A);
}
#else
#define _mm512_shrdi_epi16(A, B, C) \
((__m512i) __builtin_ia32_vpshrd_v32hi ((__v32hi)(__m512i)(A), \
(__v32hi)(__m512i)(B),(int)(C)))
#define _mm512_shrdi_epi32(A, B, C) \
((__m512i) __builtin_ia32_vpshrd_v16si ((__v16si)(__m512i)(A), \
(__v16si)(__m512i)(B),(int)(C)))
#define _mm512_mask_shrdi_epi32(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshrd_v16si_mask ((__v16si)(__m512i)(C), \
(__v16si)(__m512i)(D), \
(int)(E), \
(__v16si)(__m512i)(A), \
(__mmask16)(B)))
#define _mm512_maskz_shrdi_epi32(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshrd_v16si_mask ((__v16si)(__m512i)(B), \
(__v16si)(__m512i)(C),(int)(D), \
(__v16si)(__m512i)_mm512_setzero_si512 (), \
(__mmask16)(A)))
#define _mm512_shrdi_epi64(A, B, C) \
((__m512i) __builtin_ia32_vpshrd_v8di ((__v8di)(__m512i)(A), \
(__v8di)(__m512i)(B),(int)(C)))
#define _mm512_mask_shrdi_epi64(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshrd_v8di_mask ((__v8di)(__m512i)(C), \
(__v8di)(__m512i)(D), (int)(E), \
(__v8di)(__m512i)(A), \
(__mmask8)(B)))
#define _mm512_maskz_shrdi_epi64(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshrd_v8di_mask ((__v8di)(__m512i)(B), \
(__v8di)(__m512i)(C),(int)(D), \
(__v8di)(__m512i)_mm512_setzero_si512 (), \
(__mmask8)(A)))
#define _mm512_shldi_epi16(A, B, C) \
((__m512i) __builtin_ia32_vpshld_v32hi ((__v32hi)(__m512i)(A), \
(__v32hi)(__m512i)(B),(int)(C)))
#define _mm512_shldi_epi32(A, B, C) \
((__m512i) __builtin_ia32_vpshld_v16si ((__v16si)(__m512i)(A), \
(__v16si)(__m512i)(B),(int)(C)))
#define _mm512_mask_shldi_epi32(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshld_v16si_mask ((__v16si)(__m512i)(C), \
(__v16si)(__m512i)(D), \
(int)(E), \
(__v16si)(__m512i)(A), \
(__mmask16)(B)))
#define _mm512_maskz_shldi_epi32(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshld_v16si_mask ((__v16si)(__m512i)(B), \
(__v16si)(__m512i)(C),(int)(D), \
(__v16si)(__m512i)_mm512_setzero_si512 (), \
(__mmask16)(A)))
#define _mm512_shldi_epi64(A, B, C) \
((__m512i) __builtin_ia32_vpshld_v8di ((__v8di)(__m512i)(A), \
(__v8di)(__m512i)(B), (int)(C)))
#define _mm512_mask_shldi_epi64(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshld_v8di_mask ((__v8di)(__m512i)(C), \
(__v8di)(__m512i)(D), (int)(E), \
(__v8di)(__m512i)(A), \
(__mmask8)(B)))
#define _mm512_maskz_shldi_epi64(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshld_v8di_mask ((__v8di)(__m512i)(B), \
(__v8di)(__m512i)(C),(int)(D), \
(__v8di)(__m512i)_mm512_setzero_si512 (), \
(__mmask8)(A)))
#endif
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdv_epi16 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshrdv_v32hi ((__v32hi)__A, (__v32hi) __B,
(__v32hi) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdv_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshrdv_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdv_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdv_epi32 (__mmask16 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shrdv_epi64 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshrdv_v8di ((__v8di)__A, (__v8di) __B,
(__v8di) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdv_epi64 (__m512i __A, __mmask8 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v8di_mask ((__v8di)__A, (__v8di) __C,
(__v8di) __D, (__mmask8)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdv_epi64 (__mmask8 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v8di_maskz ((__v8di)__B, (__v8di) __C,
(__v8di) __D, (__mmask8)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldv_epi16 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshldv_v32hi ((__v32hi)__A, (__v32hi) __B,
(__v32hi) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldv_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshldv_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldv_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldv_epi32 (__mmask16 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_shldv_epi64 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpshldv_v8di ((__v8di)__A, (__v8di) __B,
(__v8di) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldv_epi64 (__m512i __A, __mmask8 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v8di_mask ((__v8di)__A, (__v8di) __C,
(__v8di) __D, (__mmask8)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldv_epi64 (__mmask8 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v8di_maskz ((__v8di)__B, (__v8di) __C,
(__v8di) __D, (__mmask8)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_compress_epi8 (__m512i __A, __mmask64 __B, __m512i __C)
{
return (__m512i) __builtin_ia32_compressqi512_mask ((__v64qi)__C,
(__v64qi)__A, (__mmask64)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_compress_epi8 (__mmask64 __A, __m512i __B)
{
return (__m512i) __builtin_ia32_compressqi512_mask ((__v64qi)__B,
(__v64qi)_mm512_setzero_si512 (), (__mmask64)__A);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_compressstoreu_epi8 (void * __A, __mmask64 __B, __m512i __C)
{
__builtin_ia32_compressstoreuqi512_mask ((__v64qi *) __A, (__v64qi) __C,
(__mmask64) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_compress_epi16 (__m512i __A, __mmask32 __B, __m512i __C)
{
return (__m512i) __builtin_ia32_compresshi512_mask ((__v32hi)__C,
(__v32hi)__A, (__mmask32)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_compress_epi16 (__mmask32 __A, __m512i __B)
{
return (__m512i) __builtin_ia32_compresshi512_mask ((__v32hi)__B,
(__v32hi)_mm512_setzero_si512 (), (__mmask32)__A);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_compressstoreu_epi16 (void * __A, __mmask32 __B, __m512i __C)
{
__builtin_ia32_compressstoreuhi512_mask ((__v32hi *) __A, (__v32hi) __C,
(__mmask32) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_expand_epi8 (__m512i __A, __mmask64 __B, __m512i __C)
{
return (__m512i) __builtin_ia32_expandqi512_mask ((__v64qi) __C,
(__v64qi) __A,
(__mmask64) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_expand_epi8 (__mmask64 __A, __m512i __B)
{
return (__m512i) __builtin_ia32_expandqi512_maskz ((__v64qi) __B,
(__v64qi) _mm512_setzero_si512 (), (__mmask64) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_expandloadu_epi8 (__m512i __A, __mmask64 __B, const void * __C)
{
return (__m512i) __builtin_ia32_expandloadqi512_mask ((const __v64qi *) __C,
(__v64qi) __A, (__mmask64) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_expandloadu_epi8 (__mmask64 __A, const void * __B)
{
return (__m512i) __builtin_ia32_expandloadqi512_maskz ((const __v64qi *) __B,
(__v64qi) _mm512_setzero_si512 (), (__mmask64) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_expand_epi16 (__m512i __A, __mmask32 __B, __m512i __C)
{
return (__m512i) __builtin_ia32_expandhi512_mask ((__v32hi) __C,
(__v32hi) __A,
(__mmask32) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_expand_epi16 (__mmask32 __A, __m512i __B)
{
return (__m512i) __builtin_ia32_expandhi512_maskz ((__v32hi) __B,
(__v32hi) _mm512_setzero_si512 (), (__mmask32) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_expandloadu_epi16 (__m512i __A, __mmask32 __B, const void * __C)
{
return (__m512i) __builtin_ia32_expandloadhi512_mask ((const __v32hi *) __C,
(__v32hi) __A, (__mmask32) __B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_expandloadu_epi16 (__mmask32 __A, const void * __B)
{
return (__m512i) __builtin_ia32_expandloadhi512_maskz ((const __v32hi *) __B,
(__v32hi) _mm512_setzero_si512 (), (__mmask32) __A);
}
#ifdef __OPTIMIZE__
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdi_epi16 (__m512i __A, __mmask32 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshrd_v32hi_mask ((__v32hi)__C,
(__v32hi) __D, __E, (__v32hi) __A, (__mmask32)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdi_epi16 (__mmask32 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshrd_v32hi_mask ((__v32hi)__B,
(__v32hi) __C, __D, (__v32hi) _mm512_setzero_si512 (), (__mmask32)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldi_epi16 (__m512i __A, __mmask32 __B, __m512i __C, __m512i __D,
int __E)
{
return (__m512i)__builtin_ia32_vpshld_v32hi_mask ((__v32hi)__C,
(__v32hi) __D, __E, (__v32hi) __A, (__mmask32)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldi_epi16 (__mmask32 __A, __m512i __B, __m512i __C, int __D)
{
return (__m512i)__builtin_ia32_vpshld_v32hi_mask ((__v32hi)__B,
(__v32hi) __C, __D, (__v32hi) _mm512_setzero_si512 (), (__mmask32)__A);
}
#else
#define _mm512_mask_shrdi_epi16(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshrd_v32hi_mask ((__v32hi)(__m512i)(C), \
(__v32hi)(__m512i)(D), \
(int)(E), \
(__v32hi)(__m512i)(A), \
(__mmask32)(B)))
#define _mm512_maskz_shrdi_epi16(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshrd_v32hi_mask ((__v32hi)(__m512i)(B), \
(__v32hi)(__m512i)(C),(int)(D), \
(__v32hi)(__m512i)_mm512_setzero_si512 (), \
(__mmask32)(A)))
#define _mm512_mask_shldi_epi16(A, B, C, D, E) \
((__m512i) __builtin_ia32_vpshld_v32hi_mask ((__v32hi)(__m512i)(C), \
(__v32hi)(__m512i)(D), \
(int)(E), \
(__v32hi)(__m512i)(A), \
(__mmask32)(B)))
#define _mm512_maskz_shldi_epi16(A, B, C, D) \
((__m512i) \
__builtin_ia32_vpshld_v32hi_mask ((__v32hi)(__m512i)(B), \
(__v32hi)(__m512i)(C),(int)(D), \
(__v32hi)(__m512i)_mm512_setzero_si512 (), \
(__mmask32)(A)))
#endif
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shrdv_epi16 (__m512i __A, __mmask32 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v32hi_mask ((__v32hi)__A,
(__v32hi) __C, (__v32hi) __D, (__mmask32)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shrdv_epi16 (__mmask32 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshrdv_v32hi_maskz ((__v32hi)__B,
(__v32hi) __C, (__v32hi) __D, (__mmask32)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_shldv_epi16 (__m512i __A, __mmask32 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v32hi_mask ((__v32hi)__A,
(__v32hi) __C, (__v32hi) __D, (__mmask32)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_shldv_epi16 (__mmask32 __A, __m512i __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpshldv_v32hi_maskz ((__v32hi)__B,
(__v32hi) __C, (__v32hi) __D, (__mmask32)__A);
}
#ifdef __DISABLE_AVX512VBMI2__
#undef __DISABLE_AVX512VBMI2__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VBMI2__ */
#endif /* __AVX512VBMI2INTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
+158
View File
@@ -0,0 +1,158 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vbmiintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VBMIINTRIN_H_INCLUDED
#define _AVX512VBMIINTRIN_H_INCLUDED
#if !defined (__AVX512VBMI__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vbmi,evex512")
#define __DISABLE_AVX512VBMI__
#endif /* __AVX512VBMI__ */
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_multishift_epi64_epi8 (__m512i __W, __mmask64 __M, __m512i __X, __m512i __Y)
{
return (__m512i) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X,
(__v64qi) __Y,
(__v64qi) __W,
(__mmask64) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_multishift_epi64_epi8 (__mmask64 __M, __m512i __X, __m512i __Y)
{
return (__m512i) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X,
(__v64qi) __Y,
(__v64qi)
_mm512_setzero_si512 (),
(__mmask64) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_multishift_epi64_epi8 (__m512i __X, __m512i __Y)
{
return (__m512i) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X,
(__v64qi) __Y,
(__v64qi)
_mm512_undefined_epi32 (),
(__mmask64) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_permutexvar_epi8 (__m512i __A, __m512i __B)
{
return (__m512i) __builtin_ia32_permvarqi512_mask ((__v64qi) __B,
(__v64qi) __A,
(__v64qi)
_mm512_undefined_epi32 (),
(__mmask64) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_permutexvar_epi8 (__mmask64 __M, __m512i __A,
__m512i __B)
{
return (__m512i) __builtin_ia32_permvarqi512_mask ((__v64qi) __B,
(__v64qi) __A,
(__v64qi)
_mm512_setzero_si512(),
(__mmask64) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_permutexvar_epi8 (__m512i __W, __mmask64 __M, __m512i __A,
__m512i __B)
{
return (__m512i) __builtin_ia32_permvarqi512_mask ((__v64qi) __B,
(__v64qi) __A,
(__v64qi) __W,
(__mmask64) __M);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_permutex2var_epi8 (__m512i __A, __m512i __I, __m512i __B)
{
return (__m512i) __builtin_ia32_vpermt2varqi512_mask ((__v64qi) __I
/* idx */ ,
(__v64qi) __A,
(__v64qi) __B,
(__mmask64) -1);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_permutex2var_epi8 (__m512i __A, __mmask64 __U,
__m512i __I, __m512i __B)
{
return (__m512i) __builtin_ia32_vpermt2varqi512_mask ((__v64qi) __I
/* idx */ ,
(__v64qi) __A,
(__v64qi) __B,
(__mmask64)
__U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask2_permutex2var_epi8 (__m512i __A, __m512i __I,
__mmask64 __U, __m512i __B)
{
return (__m512i) __builtin_ia32_vpermi2varqi512_mask ((__v64qi) __A,
(__v64qi) __I
/* idx */ ,
(__v64qi) __B,
(__mmask64)
__U);
}
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_permutex2var_epi8 (__mmask64 __U, __m512i __A,
__m512i __I, __m512i __B)
{
return (__m512i) __builtin_ia32_vpermt2varqi512_maskz ((__v64qi) __I
/* idx */ ,
(__v64qi) __A,
(__v64qi) __B,
(__mmask64)
__U);
}
#ifdef __DISABLE_AVX512VBMI__
#undef __DISABLE_AVX512VBMI__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VBMI__ */
#endif /* _AVX512VBMIINTRIN_H_INCLUDED */
@@ -0,0 +1,273 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vbmivlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VBMIVLINTRIN_H_INCLUDED
#define _AVX512VBMIVLINTRIN_H_INCLUDED
#if !defined(__AVX512VL__) || !defined(__AVX512VBMI__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vbmi,avx512vl,no-evex512")
#define __DISABLE_AVX512VBMIVL__
#endif /* __AVX512VBMIVL__ */
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_multishift_epi64_epi8 (__m256i __W, __mmask32 __M, __m256i __X, __m256i __Y)
{
return (__m256i) __builtin_ia32_vpmultishiftqb256_mask ((__v32qi) __X,
(__v32qi) __Y,
(__v32qi) __W,
(__mmask32) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_multishift_epi64_epi8 (__mmask32 __M, __m256i __X, __m256i __Y)
{
return (__m256i) __builtin_ia32_vpmultishiftqb256_mask ((__v32qi) __X,
(__v32qi) __Y,
(__v32qi)
_mm256_avx512_setzero_si256 (),
(__mmask32) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_multishift_epi64_epi8 (__m256i __X, __m256i __Y)
{
return (__m256i) __builtin_ia32_vpmultishiftqb256_mask ((__v32qi) __X,
(__v32qi) __Y,
(__v32qi)
_mm256_avx512_undefined_si256 (),
(__mmask32) -1);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_multishift_epi64_epi8 (__m128i __W, __mmask16 __M, __m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_vpmultishiftqb128_mask ((__v16qi) __X,
(__v16qi) __Y,
(__v16qi) __W,
(__mmask16) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_multishift_epi64_epi8 (__mmask16 __M, __m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_vpmultishiftqb128_mask ((__v16qi) __X,
(__v16qi) __Y,
(__v16qi)
_mm_avx512_setzero_si128 (),
(__mmask16) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_multishift_epi64_epi8 (__m128i __X, __m128i __Y)
{
return (__m128i) __builtin_ia32_vpmultishiftqb128_mask ((__v16qi) __X,
(__v16qi) __Y,
(__v16qi)
_mm_avx512_undefined_si128 (),
(__mmask16) -1);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_permutexvar_epi8 (__m256i __A, __m256i __B)
{
return (__m256i) __builtin_ia32_permvarqi256_mask ((__v32qi) __B,
(__v32qi) __A,
(__v32qi)
_mm256_avx512_undefined_si256 (),
(__mmask32) -1);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_permutexvar_epi8 (__mmask32 __M, __m256i __A,
__m256i __B)
{
return (__m256i) __builtin_ia32_permvarqi256_mask ((__v32qi) __B,
(__v32qi) __A,
(__v32qi)
_mm256_avx512_setzero_si256 (),
(__mmask32) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_permutexvar_epi8 (__m256i __W, __mmask32 __M, __m256i __A,
__m256i __B)
{
return (__m256i) __builtin_ia32_permvarqi256_mask ((__v32qi) __B,
(__v32qi) __A,
(__v32qi) __W,
(__mmask32) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_permutexvar_epi8 (__m128i __A, __m128i __B)
{
return (__m128i) __builtin_ia32_permvarqi128_mask ((__v16qi) __B,
(__v16qi) __A,
(__v16qi)
_mm_avx512_undefined_si128 (),
(__mmask16) -1);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_permutexvar_epi8 (__mmask16 __M, __m128i __A, __m128i __B)
{
return (__m128i) __builtin_ia32_permvarqi128_mask ((__v16qi) __B,
(__v16qi) __A,
(__v16qi)
_mm_avx512_setzero_si128 (),
(__mmask16) __M);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_permutexvar_epi8 (__m128i __W, __mmask16 __M, __m128i __A,
__m128i __B)
{
return (__m128i) __builtin_ia32_permvarqi128_mask ((__v16qi) __B,
(__v16qi) __A,
(__v16qi) __W,
(__mmask16) __M);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_permutex2var_epi8 (__m256i __A, __m256i __I, __m256i __B)
{
return (__m256i) __builtin_ia32_vpermt2varqi256_mask ((__v32qi) __I
/* idx */ ,
(__v32qi) __A,
(__v32qi) __B,
(__mmask32) -1);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_permutex2var_epi8 (__m256i __A, __mmask32 __U,
__m256i __I, __m256i __B)
{
return (__m256i) __builtin_ia32_vpermt2varqi256_mask ((__v32qi) __I
/* idx */ ,
(__v32qi) __A,
(__v32qi) __B,
(__mmask32)
__U);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask2_permutex2var_epi8 (__m256i __A, __m256i __I,
__mmask32 __U, __m256i __B)
{
return (__m256i) __builtin_ia32_vpermi2varqi256_mask ((__v32qi) __A,
(__v32qi) __I
/* idx */ ,
(__v32qi) __B,
(__mmask32)
__U);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_permutex2var_epi8 (__mmask32 __U, __m256i __A,
__m256i __I, __m256i __B)
{
return (__m256i) __builtin_ia32_vpermt2varqi256_maskz ((__v32qi) __I
/* idx */ ,
(__v32qi) __A,
(__v32qi) __B,
(__mmask32)
__U);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_permutex2var_epi8 (__m128i __A, __m128i __I, __m128i __B)
{
return (__m128i) __builtin_ia32_vpermt2varqi128_mask ((__v16qi) __I
/* idx */ ,
(__v16qi) __A,
(__v16qi) __B,
(__mmask16) -1);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_permutex2var_epi8 (__m128i __A, __mmask16 __U, __m128i __I,
__m128i __B)
{
return (__m128i) __builtin_ia32_vpermt2varqi128_mask ((__v16qi) __I
/* idx */ ,
(__v16qi) __A,
(__v16qi) __B,
(__mmask16)
__U);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask2_permutex2var_epi8 (__m128i __A, __m128i __I, __mmask16 __U,
__m128i __B)
{
return (__m128i) __builtin_ia32_vpermi2varqi128_mask ((__v16qi) __A,
(__v16qi) __I
/* idx */ ,
(__v16qi) __B,
(__mmask16)
__U);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_permutex2var_epi8 (__mmask16 __U, __m128i __A, __m128i __I,
__m128i __B)
{
return (__m128i) __builtin_ia32_vpermt2varqi128_maskz ((__v16qi) __I
/* idx */ ,
(__v16qi) __A,
(__v16qi) __B,
(__mmask16)
__U);
}
#ifdef __DISABLE_AVX512VBMIVL__
#undef __DISABLE_AVX512VBMIVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VBMIVL__ */
#endif /* _AVX512VBMIVLINTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+144
View File
@@ -0,0 +1,144 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vnniintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef __AVX512VNNIINTRIN_H_INCLUDED
#define __AVX512VNNIINTRIN_H_INCLUDED
#if !defined(__AVX512VNNI__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vnni,evex512")
#define __DISABLE_AVX512VNNI__
#endif /* __AVX512VNNI__ */
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_dpbusd_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_dpbusd_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpdpbusd_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_dpbusd_epi32 (__mmask16 __A, __m512i __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpbusd_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_dpbusds_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpdpbusds_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_dpbusds_epi32 (__m512i __A, __mmask16 __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpbusds_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_dpbusds_epi32 (__mmask16 __A, __m512i __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpbusds_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_dpwssd_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpdpwssd_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_dpwssd_epi32 (__m512i __A, __mmask16 __B, __m512i __C, __m512i __D)
{
return (__m512i)__builtin_ia32_vpdpwssd_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_dpwssd_epi32 (__mmask16 __A, __m512i __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpwssd_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_dpwssds_epi32 (__m512i __A, __m512i __B, __m512i __C)
{
return (__m512i) __builtin_ia32_vpdpwssds_v16si ((__v16si)__A, (__v16si) __B,
(__v16si) __C);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_dpwssds_epi32 (__m512i __A, __mmask16 __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpwssds_v16si_mask ((__v16si)__A,
(__v16si) __C, (__v16si) __D, (__mmask16)__B);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_dpwssds_epi32 (__mmask16 __A, __m512i __B, __m512i __C,
__m512i __D)
{
return (__m512i)__builtin_ia32_vpdpwssds_v16si_maskz ((__v16si)__B,
(__v16si) __C, (__v16si) __D, (__mmask16)__A);
}
#ifdef __DISABLE_AVX512VNNI__
#undef __DISABLE_AVX512VNNI__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VNNI__ */
#endif /* __AVX512VNNIINTRIN_H_INCLUDED */
@@ -0,0 +1,210 @@
/* Copyright (C) 2013-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vnnivlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VNNIVLINTRIN_H_INCLUDED
#define _AVX512VNNIVLINTRIN_H_INCLUDED
#if !defined(__AVX512VL__) || !defined(__AVX512VNNI__) || defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vnni,avx512vl,no-evex512")
#define __DISABLE_AVX512VNNIVL__
#endif /* __AVX512VNNIVL__ */
#define _mm256_dpbusd_epi32(A, B, C) \
((__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si) (A), \
(__v8si) (B), \
(__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_dpbusd_epi32 (__m256i __A, __mmask8 __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpbusd_v8si_mask ((__v8si)__A, (__v8si) __C,
(__v8si) __D, (__mmask8)__B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_dpbusd_epi32 (__mmask8 __A, __m256i __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpbusd_v8si_maskz ((__v8si)__B,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
#define _mm_dpbusd_epi32(A, B, C) \
((__m128i) __builtin_ia32_vpdpbusd_v4si ((__v4si) (A), \
(__v4si) (B), \
(__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_dpbusd_epi32 (__m128i __A, __mmask8 __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpbusd_v4si_mask ((__v4si)__A, (__v4si) __C,
(__v4si) __D, (__mmask8)__B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_dpbusd_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpbusd_v4si_maskz ((__v4si)__B,
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
#define _mm256_dpbusds_epi32(A, B, C) \
((__m256i) __builtin_ia32_vpdpbusds_v8si ((__v8si) (A), \
(__v8si) (B), \
(__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_dpbusds_epi32 (__m256i __A, __mmask8 __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpbusds_v8si_mask ((__v8si)__A,
(__v8si) __C, (__v8si) __D, (__mmask8)__B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_dpbusds_epi32 (__mmask8 __A, __m256i __B, __m256i __C,
__m256i __D)
{
return (__m256i)__builtin_ia32_vpdpbusds_v8si_maskz ((__v8si)__B,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
#define _mm_dpbusds_epi32(A, B, C) \
((__m128i) __builtin_ia32_vpdpbusds_v4si ((__v4si) (A), \
(__v4si) (B), \
(__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_dpbusds_epi32 (__m128i __A, __mmask8 __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpbusds_v4si_mask ((__v4si)__A,
(__v4si) __C, (__v4si) __D, (__mmask8)__B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_dpbusds_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpbusds_v4si_maskz ((__v4si)__B,
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
#define _mm256_dpwssd_epi32(A, B, C) \
((__m256i) __builtin_ia32_vpdpwssd_v8si ((__v8si) (A), \
(__v8si) (B), \
(__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_dpwssd_epi32 (__m256i __A, __mmask8 __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpwssd_v8si_mask ((__v8si)__A, (__v8si) __C,
(__v8si) __D, (__mmask8)__B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_dpwssd_epi32 (__mmask8 __A, __m256i __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpwssd_v8si_maskz ((__v8si)__B,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
#define _mm_dpwssd_epi32(A, B, C) \
((__m128i) __builtin_ia32_vpdpwssd_v4si ((__v4si) (A), \
(__v4si) (B), \
(__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_dpwssd_epi32 (__m128i __A, __mmask8 __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpwssd_v4si_mask ((__v4si)__A, (__v4si) __C,
(__v4si) __D, (__mmask8)__B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_dpwssd_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpwssd_v4si_maskz ((__v4si)__B,
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
#define _mm256_dpwssds_epi32(A, B, C) \
((__m256i) __builtin_ia32_vpdpwssds_v8si ((__v8si) (A), \
(__v8si) (B), \
(__v8si) (C)))
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_dpwssds_epi32 (__m256i __A, __mmask8 __B, __m256i __C, __m256i __D)
{
return (__m256i)__builtin_ia32_vpdpwssds_v8si_mask ((__v8si)__A,
(__v8si) __C, (__v8si) __D, (__mmask8)__B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_dpwssds_epi32 (__mmask8 __A, __m256i __B, __m256i __C,
__m256i __D)
{
return (__m256i)__builtin_ia32_vpdpwssds_v8si_maskz ((__v8si)__B,
(__v8si) __C, (__v8si) __D, (__mmask8)__A);
}
#define _mm_dpwssds_epi32(A, B, C) \
((__m128i) __builtin_ia32_vpdpwssds_v4si ((__v4si) (A), \
(__v4si) (B), \
(__v4si) (C)))
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_dpwssds_epi32 (__m128i __A, __mmask8 __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpwssds_v4si_mask ((__v4si)__A,
(__v4si) __C, (__v4si) __D, (__mmask8)__B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_dpwssds_epi32 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D)
{
return (__m128i)__builtin_ia32_vpdpwssds_v4si_maskz ((__v4si)__B,
(__v4si) __C, (__v4si) __D, (__mmask8)__A);
}
#ifdef __DISABLE_AVX512VNNIVL__
#undef __DISABLE_AVX512VNNIVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VNNIVL__ */
#endif /* __DISABLE_AVX512VNNIVL__ */
@@ -0,0 +1,58 @@
/* Copyright (C) 2019-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vp2intersectintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VP2INTERSECTINTRIN_H_INCLUDED
#define _AVX512VP2INTERSECTINTRIN_H_INCLUDED
#if !defined(__AVX512VP2INTERSECT__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vp2intersect,evex512")
#define __DISABLE_AVX512VP2INTERSECT__
#endif /* __AVX512VP2INTERSECT__ */
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_2intersect_epi32 (__m512i __A, __m512i __B, __mmask16 *__U,
__mmask16 *__M)
{
__builtin_ia32_2intersectd512 (__U, __M, (__v16si) __A, (__v16si) __B);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_2intersect_epi64 (__m512i __A, __m512i __B, __mmask8 *__U,
__mmask8 *__M)
{
__builtin_ia32_2intersectq512 (__U, __M, (__v8di) __A, (__v8di) __B);
}
#ifdef __DISABLE_AVX512VP2INTERSECT__
#undef __DISABLE_AVX512VP2INTERSECT__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VP2INTERSECT__ */
#endif /* _AVX512VP2INTERSECTINTRIN_H_INCLUDED */
@@ -0,0 +1,73 @@
/* Copyright (C) 2019-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <avx512vp2intersectintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VP2INTERSECTVLINTRIN_H_INCLUDED
#define _AVX512VP2INTERSECTVLINTRIN_H_INCLUDED
#if !defined(__AVX512VP2INTERSECT__) || !defined(__AVX512VL__) \
|| defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vp2intersect,avx512vl,no-evex512")
#define __DISABLE_AVX512VP2INTERSECTVL__
#endif /* __AVX512VP2INTERSECTVL__ */
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_2intersect_epi32 (__m128i __A, __m128i __B, __mmask8 *__U, __mmask8 *__M)
{
__builtin_ia32_2intersectd128 (__U, __M, (__v4si) __A, (__v4si) __B);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_2intersect_epi32 (__m256i __A, __m256i __B, __mmask8 *__U,
__mmask8 *__M)
{
__builtin_ia32_2intersectd256 (__U, __M, (__v8si) __A, (__v8si) __B);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_2intersect_epi64 (__m128i __A, __m128i __B, __mmask8 *__U, __mmask8 *__M)
{
__builtin_ia32_2intersectq128 (__U, __M, (__v2di) __A, (__v2di) __B);
}
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_2intersect_epi64 (__m256i __A, __m256i __B, __mmask8 *__U,
__mmask8 *__M)
{
__builtin_ia32_2intersectq256 (__U, __M, (__v4di) __A, (__v4di) __B);
}
#ifdef __DISABLE_AVX512VP2INTERSECTVL__
#undef __DISABLE_AVX512VP2INTERSECTVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VP2INTERSECTVL__ */
#endif /* _AVX512VP2INTERSECTVLINTRIN_H_INCLUDED */
@@ -0,0 +1,94 @@
/* Copyright (C) 2017-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx512vpopcntdqintrin.h> directly; include <x86intrin.h> instead."
#endif
#ifndef _AVX512VPOPCNTDQINTRIN_H_INCLUDED
#define _AVX512VPOPCNTDQINTRIN_H_INCLUDED
#if !defined (__AVX512VPOPCNTDQ__) || !defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vpopcntdq,evex512")
#define __DISABLE_AVX512VPOPCNTDQ__
#endif /* __AVX512VPOPCNTDQ__ */
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_popcnt_epi32 (__m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountd_v16si ((__v16si) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_popcnt_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountd_v16si_mask ((__v16si) __A,
(__v16si) __W,
(__mmask16) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_popcnt_epi32 (__mmask16 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountd_v16si_mask ((__v16si) __A,
(__v16si)
_mm512_setzero_si512 (),
(__mmask16) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_popcnt_epi64 (__m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountq_v8di ((__v8di) __A);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_popcnt_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountq_v8di_mask ((__v8di) __A,
(__v8di) __W,
(__mmask8) __U);
}
extern __inline __m512i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm512_maskz_popcnt_epi64 (__mmask8 __U, __m512i __A)
{
return (__m512i) __builtin_ia32_vpopcountq_v8di_mask ((__v8di) __A,
(__v8di)
_mm512_setzero_si512 (),
(__mmask8) __U);
}
#ifdef __DISABLE_AVX512VPOPCNTDQ__
#undef __DISABLE_AVX512VPOPCNTDQ__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VPOPCNTDQ__ */
#endif /* _AVX512VPOPCNTDQINTRIN_H_INCLUDED */
@@ -0,0 +1,147 @@
/* Copyright (C) 2017-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
# error "Never use <avx512vpopcntdqvlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVX512VPOPCNTDQVLINTRIN_H_INCLUDED
#define _AVX512VPOPCNTDQVLINTRIN_H_INCLUDED
#if !defined(__AVX512VPOPCNTDQ__) || !defined(__AVX512VL__) \
|| defined (__EVEX512__)
#pragma GCC push_options
#pragma GCC target("avx512vpopcntdq,avx512vl,no-evex512")
#define __DISABLE_AVX512VPOPCNTDQVL__
#endif /* __AVX512VPOPCNTDQVL__ */
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_popcnt_epi32 (__m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountd_v4si ((__v4si) __A);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_popcnt_epi32 (__m128i __W, __mmask16 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountd_v4si_mask ((__v4si) __A,
(__v4si) __W,
(__mmask16) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_popcnt_epi32 (__mmask16 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountd_v4si_mask ((__v4si) __A,
(__v4si)
_mm_avx512_setzero_si128 (),
(__mmask16) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_popcnt_epi32 (__m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountd_v8si ((__v8si) __A);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_popcnt_epi32 (__m256i __W, __mmask16 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountd_v8si_mask ((__v8si) __A,
(__v8si) __W,
(__mmask16) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_popcnt_epi32 (__mmask16 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountd_v8si_mask ((__v8si) __A,
(__v8si)
_mm256_avx512_setzero_si256 (),
(__mmask16) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_popcnt_epi64 (__m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountq_v2di ((__v2di) __A);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_popcnt_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountq_v2di_mask ((__v2di) __A,
(__v2di) __W,
(__mmask8) __U);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_maskz_popcnt_epi64 (__mmask8 __U, __m128i __A)
{
return (__m128i) __builtin_ia32_vpopcountq_v2di_mask ((__v2di) __A,
(__v2di)
_mm_avx512_setzero_si128 (),
(__mmask8) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_popcnt_epi64 (__m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountq_v4di ((__v4di) __A);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_popcnt_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountq_v4di_mask ((__v4di) __A,
(__v4di) __W,
(__mmask8) __U);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_maskz_popcnt_epi64 (__mmask8 __U, __m256i __A)
{
return (__m256i) __builtin_ia32_vpopcountq_v4di_mask ((__v4di) __A,
(__v4di)
_mm256_avx512_setzero_si256 (),
(__mmask8) __U);
}
#ifdef __DISABLE_AVX512VPOPCNTDQVL__
#undef __DISABLE_AVX512VPOPCNTDQVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVX512VPOPCNTDQVL__ */
#endif /* _AVX512VPOPCNTDQVLINTRIN_H_INCLUDED */
+78
View File
@@ -0,0 +1,78 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avxifmaintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVXIFMAINTRIN_H_INCLUDED
#define _AVXIFMAINTRIN_H_INCLUDED
#ifndef __AVXIFMA__
#pragma GCC push_options
#pragma GCC target("avxifma")
#define __DISABLE_AVXIFMA__
#endif /* __AVXIFMA__ */
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_madd52lo_avx_epu64 (__m128i __X, __m128i __Y, __m128i __Z)
{
return (__m128i) __builtin_ia32_vpmadd52luq128 ((__v2di) __X,
(__v2di) __Y,
(__v2di) __Z);
}
extern __inline __m128i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_madd52hi_avx_epu64 (__m128i __X, __m128i __Y, __m128i __Z)
{
return (__m128i) __builtin_ia32_vpmadd52huq128 ((__v2di) __X,
(__v2di) __Y,
(__v2di) __Z);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_madd52lo_avx_epu64 (__m256i __X, __m256i __Y, __m256i __Z)
{
return (__m256i) __builtin_ia32_vpmadd52luq256 ((__v4di) __X,
(__v4di) __Y,
(__v4di) __Z);
}
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_madd52hi_avx_epu64 (__m256i __X, __m256i __Y, __m256i __Z)
{
return (__m256i) __builtin_ia32_vpmadd52huq256 ((__v4di) __X,
(__v4di) __Y,
(__v4di) __Z);
}
#ifdef __DISABLE_AVXIFMA__
#undef __DISABLE_AVXIFMA__
#pragma GCC pop_options
#endif /* __DISABLE_AVXIFMA__ */
#endif /* _AVXIFMAINTRIN_H_INCLUDED */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,140 @@
/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avxneconvertintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVXNECONVERTINTRIN_H_INCLUDED
#define _AVXNECONVERTINTRIN_H_INCLUDED
#ifndef __AVXNECONVERT__
#pragma GCC push_options
#pragma GCC target ("avxneconvert")
#define __DISABLE_AVXNECONVERT__
#endif /* __AVXNECONVERT__ */
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_bcstnebf16_ps (const void *__P)
{
return (__m128) __builtin_ia32_vbcstnebf162ps128 ((const __bf16 *) __P);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_bcstnebf16_ps (const void *__P)
{
return (__m256) __builtin_ia32_vbcstnebf162ps256 ((const __bf16 *) __P);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_bcstnesh_ps (const void *__P)
{
return (__m128) __builtin_ia32_vbcstnesh2ps128 ((const _Float16 *) __P);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_bcstnesh_ps (const void *__P)
{
return (__m256) __builtin_ia32_vbcstnesh2ps256 ((const _Float16 *) __P);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtneebf16_ps (const __m128bh *__A)
{
return (__m128) __builtin_ia32_vcvtneebf162ps128 ((const __v8bf *) __A);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtneebf16_ps (const __m256bh *__A)
{
return (__m256) __builtin_ia32_vcvtneebf162ps256 ((const __v16bf *) __A);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtneeph_ps (const __m128h *__A)
{
return (__m128) __builtin_ia32_vcvtneeph2ps128 ((const __v8hf *) __A);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtneeph_ps (const __m256h *__A)
{
return (__m256) __builtin_ia32_vcvtneeph2ps256 ((const __v16hf *) __A);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtneobf16_ps (const __m128bh *__A)
{
return (__m128) __builtin_ia32_vcvtneobf162ps128 ((const __v8bf *) __A);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtneobf16_ps (const __m256bh *__A)
{
return (__m256) __builtin_ia32_vcvtneobf162ps256 ((const __v16bf *) __A);
}
extern __inline __m128
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtneoph_ps (const __m128h *__A)
{
return (__m128) __builtin_ia32_vcvtneoph2ps128 ((const __v8hf *) __A);
}
extern __inline __m256
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtneoph_ps (const __m256h *__A)
{
return (__m256) __builtin_ia32_vcvtneoph2ps256 ((const __v16hf *) __A);
}
extern __inline __m128bh
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_cvtneps_avx_pbh (__m128 __A)
{
return (__m128bh) __builtin_ia32_cvtneps2bf16_v4sf (__A);
}
extern __inline __m128bh
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_cvtneps_avx_pbh (__m256 __A)
{
return (__m128bh) __builtin_ia32_cvtneps2bf16_v8sf (__A);
}
#ifdef __DISABLE_AVXNECONVERT__
#undef __DISABLE_AVXNECONVERT__
#pragma GCC pop_options
#endif /* __DISABLE_AVXNECONVERT__ */
#endif /* _AVXNECONVERTINTRIN_H_INCLUDED */
@@ -0,0 +1,138 @@
/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <avxvnniint16intrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVXVNNIINT16INTRIN_H_INCLUDED
#define _AVXVNNIINT16INTRIN_H_INCLUDED
#if !defined(__AVXVNNIINT16__)
#pragma GCC push_options
#pragma GCC target("avxvnniint16")
#define __DISABLE_AVXVNNIINT16__
#endif /* __AVXVNNIINT16__ */
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwsud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwsuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwusd_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwusd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwusds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwusds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwuud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwuuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpwuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwsud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwsuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwusd_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwusd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwusds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwusds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwuud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwuuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpwuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
#ifdef __DISABLE_AVXVNNIINT16__
#undef __DISABLE_AVXVNNIINT16__
#pragma GCC pop_options
#endif /* __DISABLE_AVXVNNIINT16__ */
#endif /* __AVXVNNIINT16INTRIN_H_INCLUDED */
@@ -0,0 +1,138 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if !defined _IMMINTRIN_H_INCLUDED
#error "Never use <avxvnniint8vlintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVXVNNIINT8INTRIN_H_INCLUDED
#define _AVXVNNIINT8INTRIN_H_INCLUDED
#if !defined(__AVXVNNIINT8__)
#pragma GCC push_options
#pragma GCC target("avxvnniint8")
#define __DISABLE_AVXVNNIINT8__
#endif /* __AVXVNNIINT8__ */
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbssd_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbssd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbssds_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbssds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbsud_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbsuds_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbuud_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbuuds_epi32 (__m128i __W, __m128i __A, __m128i __B)
{
return (__m128i)
__builtin_ia32_vpdpbuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbssd_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbssd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbssds_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbssds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbsud_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbsuds_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbuud_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbuuds_epi32 (__m256i __W, __m256i __A, __m256i __B)
{
return (__m256i)
__builtin_ia32_vpdpbuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B);
}
#ifdef __DISABLE_AVXVNNIINT8__
#undef __DISABLE_AVXVNNIINT8__
#pragma GCC pop_options
#endif /* __DISABLE_AVXVNNIINT8__ */
#endif /* __AVXVNNIINT8INTRIN_H_INCLUDED */
+113
View File
@@ -0,0 +1,113 @@
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _IMMINTRIN_H_INCLUDED
#error "Never use <avxvnniintrin.h> directly; include <immintrin.h> instead."
#endif
#ifndef _AVXVNNIINTRIN_H_INCLUDED
#define _AVXVNNIINTRIN_H_INCLUDED
#if !defined(__AVXVNNI__)
#pragma GCC push_options
#pragma GCC target("avxvnni")
#define __DISABLE_AVXVNNIVL__
#endif /* __AVXVNNIVL__ */
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbusd_avx_epi32(__m256i __A, __m256i __B, __m256i __C)
{
return (__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si) __A,
(__v8si) __B,
(__v8si) __C);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbusd_avx_epi32(__m128i __A, __m128i __B, __m128i __C)
{
return (__m128i) __builtin_ia32_vpdpbusd_v4si ((__v4si) __A,
(__v4si) __B,
(__v4si) __C);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpbusds_avx_epi32(__m256i __A, __m256i __B, __m256i __C)
{
return (__m256i) __builtin_ia32_vpdpbusds_v8si ((__v8si) __A,
(__v8si) __B,
(__v8si) __C);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpbusds_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
{
return (__m128i) __builtin_ia32_vpdpbusds_v4si ((__v4si) __A,
(__v4si) __B,
(__v4si) __C);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwssd_avx_epi32(__m256i __A,__m256i __B,__m256i __C)
{
return (__m256i) __builtin_ia32_vpdpwssd_v8si ((__v8si) __A,
(__v8si) __B,
(__v8si) __C);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwssd_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
{
return (__m128i) __builtin_ia32_vpdpwssd_v4si ((__v4si) __A,
(__v4si) __B,
(__v4si) __C);
}
extern __inline __m256i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_dpwssds_avx_epi32(__m256i __A,__m256i __B,__m256i __C)
{
return (__m256i) __builtin_ia32_vpdpwssds_v8si ((__v8si) __A,
(__v8si) __B,
(__v8si) __C);
}
extern __inline __m128i
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_dpwssds_avx_epi32(__m128i __A,__m128i __B,__m128i __C)
{
return (__m128i) __builtin_ia32_vpdpwssds_v4si ((__v4si) __A,
(__v4si) __B,
(__v4si) __C);
}
#ifdef __DISABLE_AVXVNNIVL__
#undef __DISABLE_AVXVNNIVL__
#pragma GCC pop_options
#endif /* __DISABLE_AVXVNNIVL__ */
#endif /* _AVXVNNIINTRIN_H_INCLUDED */
@@ -0,0 +1,343 @@
// auto_ptr implementation -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file backward/auto_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _BACKWARD_AUTO_PTR_H
#define _BACKWARD_AUTO_PTR_H 1
#include <bits/c++config.h>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* A wrapper class to provide auto_ptr with reference semantics.
* For example, an auto_ptr can be assigned (or constructed from)
* the result of a function which returns an auto_ptr by value.
*
* All the auto_ptr_ref stuff should happen behind the scenes.
*/
template<typename _Tp1>
struct auto_ptr_ref
{
_Tp1* _M_ptr;
explicit
auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }
} _GLIBCXX11_DEPRECATED;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/**
* @brief A simple smart pointer providing strict ownership semantics.
*
* The Standard says:
* <pre>
* An @c auto_ptr owns the object it holds a pointer to. Copying
* an @c auto_ptr copies the pointer and transfers ownership to the
* destination. If more than one @c auto_ptr owns the same object
* at the same time the behavior of the program is undefined.
*
* The uses of @c auto_ptr include providing temporary
* exception-safety for dynamically allocated memory, passing
* ownership of dynamically allocated memory to a function, and
* returning dynamically allocated memory from a function. @c
* auto_ptr does not meet the CopyConstructible and Assignable
* requirements for Standard Library <a
* href="tables.html#65">container</a> elements and thus
* instantiating a Standard Library container with an @c auto_ptr
* results in undefined behavior.
* </pre>
* Quoted from [20.4.5]/3.
*
* Good examples of what can and cannot be done with auto_ptr can
* be found in the libstdc++ testsuite.
*
* _GLIBCXX_RESOLVE_LIB_DEFECTS
* 127. auto_ptr<> conversion issues
* These resolutions have all been incorporated.
*
* @headerfile memory
* @deprecated Deprecated in C++11, no longer in the standard since C++17.
* Use `unique_ptr` instead.
*/
template<typename _Tp>
class auto_ptr
{
private:
_Tp* _M_ptr;
public:
/// The pointed-to type.
typedef _Tp element_type;
/**
* @brief An %auto_ptr is usually constructed from a raw pointer.
* @param __p A pointer (defaults to NULL).
*
* This object now @e owns the object pointed to by @a __p.
*/
explicit
auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
/**
* @brief An %auto_ptr can be constructed from another %auto_ptr.
* @param __a Another %auto_ptr of the same type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership.
*/
auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
/**
* @brief An %auto_ptr can be constructed from another %auto_ptr.
* @param __a Another %auto_ptr of a different but related type.
*
* A pointer-to-Tp1 must be convertible to a
* pointer-to-Tp/element_type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership.
*/
template<typename _Tp1>
auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
/**
* @brief %auto_ptr assignment operator.
* @param __a Another %auto_ptr of the same type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership. The object that this one @e
* used to own and track has been deleted.
*/
auto_ptr&
operator=(auto_ptr& __a) throw()
{
reset(__a.release());
return *this;
}
/**
* @brief %auto_ptr assignment operator.
* @param __a Another %auto_ptr of a different but related type.
*
* A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership. The object that this one @e
* used to own and track has been deleted.
*/
template<typename _Tp1>
auto_ptr&
operator=(auto_ptr<_Tp1>& __a) throw()
{
reset(__a.release());
return *this;
}
/**
* When the %auto_ptr goes out of scope, the object it owns is
* deleted. If it no longer owns anything (i.e., @c get() is
* @c NULL), then this has no effect.
*
* The C++ standard says there is supposed to be an empty throw
* specification here, but omitting it is standard conforming. Its
* presence can be detected only if _Tp::~_Tp() throws, but this is
* prohibited. [17.4.3.6]/2
*/
~auto_ptr() { delete _M_ptr; }
/**
* @brief Smart pointer dereferencing.
*
* If this %auto_ptr no longer owns anything, then this
* operation will crash. (For a smart pointer, <em>no longer owns
* anything</em> is the same as being a null pointer, and you know
* what happens when you dereference one of those...)
*/
element_type&
operator*() const throw()
{
__glibcxx_assert(_M_ptr != 0);
return *_M_ptr;
}
/**
* @brief Smart pointer dereferencing.
*
* This returns the pointer itself, which the language then will
* automatically cause to be dereferenced.
*/
element_type*
operator->() const throw()
{
__glibcxx_assert(_M_ptr != 0);
return _M_ptr;
}
/**
* @brief Bypassing the smart pointer.
* @return The raw pointer being managed.
*
* You can get a copy of the pointer that this object owns, for
* situations such as passing to a function which only accepts
* a raw pointer.
*
* @note This %auto_ptr still owns the memory.
*/
element_type*
get() const throw() { return _M_ptr; }
/**
* @brief Bypassing the smart pointer.
* @return The raw pointer being managed.
*
* You can get a copy of the pointer that this object owns, for
* situations such as passing to a function which only accepts
* a raw pointer.
*
* @note This %auto_ptr no longer owns the memory. When this object
* goes out of scope, nothing will happen.
*/
element_type*
release() throw()
{
element_type* __tmp = _M_ptr;
_M_ptr = 0;
return __tmp;
}
/**
* @brief Forcibly deletes the managed object.
* @param __p A pointer (defaults to NULL).
*
* This object now @e owns the object pointed to by @a __p. The
* previous object has been deleted.
*/
void
reset(element_type* __p = 0) throw()
{
if (__p != _M_ptr)
{
delete _M_ptr;
_M_ptr = __p;
}
}
/**
* @brief Automatic conversions
*
* These operations are supposed to convert an %auto_ptr into and from
* an auto_ptr_ref automatically as needed. This would allow
* constructs such as
* @code
* auto_ptr<Derived> func_returning_auto_ptr(.....);
* ...
* auto_ptr<Base> ptr = func_returning_auto_ptr(.....);
* @endcode
*
* But it doesn't work, and won't be fixed. For further details see
* http://cplusplus.github.io/LWG/lwg-closed.html#463
*/
auto_ptr(auto_ptr_ref<element_type> __ref) throw()
: _M_ptr(__ref._M_ptr) { }
auto_ptr&
operator=(auto_ptr_ref<element_type> __ref) throw()
{
if (__ref._M_ptr != this->get())
{
delete _M_ptr;
_M_ptr = __ref._M_ptr;
}
return *this;
}
template<typename _Tp1>
operator auto_ptr_ref<_Tp1>() throw()
{ return auto_ptr_ref<_Tp1>(this->release()); }
template<typename _Tp1>
operator auto_ptr<_Tp1>() throw()
{ return auto_ptr<_Tp1>(this->release()); }
} _GLIBCXX11_DEPRECATED_SUGGEST("std::unique_ptr");
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 541. shared_ptr template assignment and void
template<>
class auto_ptr<void>
{
public:
typedef void element_type;
} _GLIBCXX11_DEPRECATED;
#if __cplusplus >= 201103L
#if _GLIBCXX_HOSTED
template<_Lock_policy _Lp>
template<typename _Tp>
inline
__shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r)
: _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
{ __r.release(); }
template<typename _Tp, _Lock_policy _Lp>
template<typename _Tp1, typename>
inline
__shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r)
: _M_ptr(__r.get()), _M_refcount()
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
static_assert( sizeof(_Tp1) > 0, "incomplete type" );
_Tp1* __tmp = __r.get();
_M_refcount = __shared_count<_Lp>(std::move(__r));
_M_enable_shared_from_this_with(__tmp);
}
template<typename _Tp>
template<typename _Tp1, typename>
inline
shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
#endif // HOSTED
template<typename _Tp, typename _Dp>
template<typename _Up, typename>
inline
unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept
: _M_t(__u.release(), deleter_type()) { }
#endif // C++11
#pragma GCC diagnostic pop
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _BACKWARD_AUTO_PTR_H */
+184
View File
@@ -0,0 +1,184 @@
// Functor implementations -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file backward/binders.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _BACKWARD_BINDERS_H
#define _BACKWARD_BINDERS_H 1
// Suppress deprecated warning for this file.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.6 binders
/** @defgroup binders Binder Classes
* @ingroup functors
*
* Binders turn functions/functors with two arguments into functors
* with a single argument, storing an argument to be applied later.
* For example, a variable @c B of type @c binder1st is constructed
* from a functor @c f and an argument @c x. Later, B's @c
* operator() is called with a single argument @c y. The return
* value is the value of @c f(x,y). @c B can be @a called with
* various arguments (y1, y2, ...) and will in turn call @c
* f(x,y1), @c f(x,y2), ...
*
* The function @c bind1st is provided to save some typing. It takes the
* function and an argument as parameters, and returns an instance of
* @c binder1st.
*
* The type @c binder2nd and its creator function @c bind2nd do the same
* thing, but the stored argument is passed as the second parameter instead
* of the first, e.g., @c bind2nd(std::minus<float>(),1.3) will create a
* functor whose @c operator() accepts a floating-point number, subtracts
* 1.3 from it, and returns the result. (If @c bind1st had been used,
* the functor would perform <em>1.3 - x</em> instead.
*
* Creator-wrapper functions like @c bind1st are intended to be used in
* calling algorithms. Their return values will be temporary objects.
* (The goal is to not require you to type names like
* @c std::binder1st<std::plus<int>> for declaring a variable to hold the
* return value from @c bind1st(std::plus<int>(),5).
*
* These become more useful when combined with the composition functions.
*
* These functions are deprecated in C++11 and can be replaced by
* @c std::bind (or @c std::tr1::bind) which is more powerful and flexible,
* supporting functions with any number of arguments. Uses of @c bind1st
* can be replaced by @c std::bind(f, x, std::placeholders::_1) and
* @c bind2nd by @c std::bind(f, std::placeholders::_1, x).
* @{
*/
/// One of the @link binders binder functors@endlink.
template<typename _Operation>
class binder1st
: public unary_function<typename _Operation::second_argument_type,
typename _Operation::result_type>
{
protected:
_Operation op;
typename _Operation::first_argument_type value;
public:
binder1st(const _Operation& __x,
const typename _Operation::first_argument_type& __y)
: op(__x), value(__y) { }
typename _Operation::result_type
operator()(const typename _Operation::second_argument_type& __x) const
{ return op(value, __x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::second_argument_type& __x) const
{ return op(value, __x); }
} _GLIBCXX11_DEPRECATED_SUGGEST("std::bind");
/// One of the @link binders binder functors@endlink.
template<typename _Operation, typename _Tp>
_GLIBCXX11_DEPRECATED_SUGGEST("std::bind")
inline binder1st<_Operation>
bind1st(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::first_argument_type _Arg1_type;
return binder1st<_Operation>(__fn, _Arg1_type(__x));
}
/// One of the @link binders binder functors@endlink.
template<typename _Operation>
class binder2nd
: public unary_function<typename _Operation::first_argument_type,
typename _Operation::result_type>
{
protected:
_Operation op;
typename _Operation::second_argument_type value;
public:
binder2nd(const _Operation& __x,
const typename _Operation::second_argument_type& __y)
: op(__x), value(__y) { }
typename _Operation::result_type
operator()(const typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
} _GLIBCXX11_DEPRECATED_SUGGEST("std::bind");
/// One of the @link binders binder functors@endlink.
template<typename _Operation, typename _Tp>
_GLIBCXX11_DEPRECATED_SUGGEST("std::bind")
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
/** @} */
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#pragma GCC diagnostic pop
#endif /* _BACKWARD_BINDERS_H */
+183
View File
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_H__
#define BR_BEARSSL_H__
#include <stddef.h>
#include <stdint.h>
/** \mainpage BearSSL API
*
* # API Layout
*
* The functions and structures defined by the BearSSL API are located
* in various header files:
*
* | Header file | Elements |
* | :-------------- | :------------------------------------------------ |
* | bearssl_hash.h | Hash functions |
* | bearssl_hmac.h | HMAC |
* | bearssl_kdf.h | Key Derivation Functions |
* | bearssl_rand.h | Pseudorandom byte generators |
* | bearssl_prf.h | PRF implementations (for SSL/TLS) |
* | bearssl_block.h | Symmetric encryption |
* | bearssl_aead.h | AEAD algorithms (combined encryption + MAC) |
* | bearssl_rsa.h | RSA encryption and signatures |
* | bearssl_ec.h | Elliptic curves support (including ECDSA) |
* | bearssl_ssl.h | SSL/TLS engine interface |
* | bearssl_x509.h | X.509 certificate decoding and validation |
* | bearssl_pem.h | Base64/PEM decoding support functions |
*
* Applications using BearSSL are supposed to simply include `bearssl.h`
* as follows:
*
* #include <bearssl.h>
*
* The `bearssl.h` file itself includes all the other header files. It is
* possible to include specific header files, but it has no practical
* advantage for the application. The API is separated into separate
* header files only for documentation convenience.
*
*
* # Conventions
*
* ## MUST and SHALL
*
* In all descriptions, the usual "MUST", "SHALL", "MAY",... terminology
* is used. Failure to meet requirements expressed with a "MUST" or
* "SHALL" implies undefined behaviour, which means that segmentation
* faults, buffer overflows, and other similar adverse events, may occur.
*
* In general, BearSSL is not very forgiving of programming errors, and
* does not include much failsafes or error reporting when the problem
* does not arise from external transient conditions, and can be fixed
* only in the application code. This is done so in order to make the
* total code footprint lighter.
*
*
* ## `NULL` values
*
* Function parameters with a pointer type shall not be `NULL` unless
* explicitly authorised by the documentation. As an exception, when
* the pointer aims at a sequence of bytes and is accompanied with
* a length parameter, and the length is zero (meaning that there is
* no byte at all to retrieve), then the pointer may be `NULL` even if
* not explicitly allowed.
*
*
* ## Memory Allocation
*
* BearSSL does not perform dynamic memory allocation. This implies that
* for any functionality that requires a non-transient state, the caller
* is responsible for allocating the relevant context structure. Such
* allocation can be done in any appropriate area, including static data
* segments, the heap, and the stack, provided that proper alignment is
* respected. The header files define these context structures
* (including size and contents), so the C compiler should handle
* alignment automatically.
*
* Since there is no dynamic resource allocation, there is also nothing to
* release. When the calling code is done with a BearSSL feature, it
* may simple release the context structures it allocated itself, with
* no "close function" to call. If the context structures were allocated
* on the stack (as local variables), then even that release operation is
* implicit.
*
*
* ## Structure Contents
*
* Except when explicitly indicated, structure contents are opaque: they
* are included in the header files so that calling code may know the
* structure sizes and alignment requirements, but callers SHALL NOT
* access individual fields directly. For fields that are supposed to
* be read from or written to, the API defines accessor functions (the
* simplest of these accessor functions are defined as `static inline`
* functions, and the C compiler will optimise them away).
*
*
* # API Usage
*
* BearSSL usage for running a SSL/TLS client or server is described
* on the [BearSSL Web site](https://www.bearssl.org/api1.html). The
* BearSSL source archive also comes with sample code.
*/
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#include "bearssl_kdf.h"
#include "bearssl_rand.h"
#include "bearssl_prf.h"
#include "bearssl_block.h"
#include "bearssl_aead.h"
#include "bearssl_rsa.h"
#include "bearssl_ec.h"
#include "bearssl_ssl.h"
#include "bearssl_x509.h"
#include "bearssl_pem.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Type for a configuration option.
*
* A "configuration option" is a value that is selected when the BearSSL
* library itself is compiled. Most options are boolean; their value is
* then either 1 (option is enabled) or 0 (option is disabled). Some
* values have other integer values. Option names correspond to macro
* names. Some of the options can be explicitly set in the internal
* `"config.h"` file.
*/
typedef struct {
/** \brief Configurable option name. */
const char *name;
/** \brief Configurable option value. */
long value;
} br_config_option;
/** \brief Get configuration report.
*
* This function returns compiled configuration options, each as a
* 'long' value. Names match internal macro names, in particular those
* that can be set in the `"config.h"` inner file. For boolean options,
* the numerical value is 1 if enabled, 0 if disabled. For maximum
* key sizes, values are expressed in bits.
*
* The returned array is terminated by an entry whose `name` is `NULL`.
*
* \return the configuration report.
*/
const br_config_option *br_get_config(void);
/* ======================================================================= */
/** \brief Version feature: support for time callback. */
#define BR_FEATURE_X509_TIME_CALLBACK 1
#ifdef __cplusplus
}
#endif
#endif
+183
View File
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_H__
#define BR_BEARSSL_H__
#include <stddef.h>
#include <stdint.h>
/** \mainpage BearSSL API
*
* # API Layout
*
* The functions and structures defined by the BearSSL API are located
* in various header files:
*
* | Header file | Elements |
* | :-------------- | :------------------------------------------------ |
* | bearssl_hash.h | Hash functions |
* | bearssl_hmac.h | HMAC |
* | bearssl_kdf.h | Key Derivation Functions |
* | bearssl_rand.h | Pseudorandom byte generators |
* | bearssl_prf.h | PRF implementations (for SSL/TLS) |
* | bearssl_block.h | Symmetric encryption |
* | bearssl_aead.h | AEAD algorithms (combined encryption + MAC) |
* | bearssl_rsa.h | RSA encryption and signatures |
* | bearssl_ec.h | Elliptic curves support (including ECDSA) |
* | bearssl_ssl.h | SSL/TLS engine interface |
* | bearssl_x509.h | X.509 certificate decoding and validation |
* | bearssl_pem.h | Base64/PEM decoding support functions |
*
* Applications using BearSSL are supposed to simply include `bearssl.h`
* as follows:
*
* #include <bearssl.h>
*
* The `bearssl.h` file itself includes all the other header files. It is
* possible to include specific header files, but it has no practical
* advantage for the application. The API is separated into separate
* header files only for documentation convenience.
*
*
* # Conventions
*
* ## MUST and SHALL
*
* In all descriptions, the usual "MUST", "SHALL", "MAY",... terminology
* is used. Failure to meet requirements expressed with a "MUST" or
* "SHALL" implies undefined behaviour, which means that segmentation
* faults, buffer overflows, and other similar adverse events, may occur.
*
* In general, BearSSL is not very forgiving of programming errors, and
* does not include much failsafes or error reporting when the problem
* does not arise from external transient conditions, and can be fixed
* only in the application code. This is done so in order to make the
* total code footprint lighter.
*
*
* ## `NULL` values
*
* Function parameters with a pointer type shall not be `NULL` unless
* explicitly authorised by the documentation. As an exception, when
* the pointer aims at a sequence of bytes and is accompanied with
* a length parameter, and the length is zero (meaning that there is
* no byte at all to retrieve), then the pointer may be `NULL` even if
* not explicitly allowed.
*
*
* ## Memory Allocation
*
* BearSSL does not perform dynamic memory allocation. This implies that
* for any functionality that requires a non-transient state, the caller
* is responsible for allocating the relevant context structure. Such
* allocation can be done in any appropriate area, including static data
* segments, the heap, and the stack, provided that proper alignment is
* respected. The header files define these context structures
* (including size and contents), so the C compiler should handle
* alignment automatically.
*
* Since there is no dynamic resource allocation, there is also nothing to
* release. When the calling code is done with a BearSSL feature, it
* may simple release the context structures it allocated itself, with
* no "close function" to call. If the context structures were allocated
* on the stack (as local variables), then even that release operation is
* implicit.
*
*
* ## Structure Contents
*
* Except when explicitly indicated, structure contents are opaque: they
* are included in the header files so that calling code may know the
* structure sizes and alignment requirements, but callers SHALL NOT
* access individual fields directly. For fields that are supposed to
* be read from or written to, the API defines accessor functions (the
* simplest of these accessor functions are defined as `static inline`
* functions, and the C compiler will optimise them away).
*
*
* # API Usage
*
* BearSSL usage for running a SSL/TLS client or server is described
* on the [BearSSL Web site](https://www.bearssl.org/api1.html). The
* BearSSL source archive also comes with sample code.
*/
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#include "bearssl_kdf.h"
#include "bearssl_rand.h"
#include "bearssl_prf.h"
#include "bearssl_block.h"
#include "bearssl_aead.h"
#include "bearssl_rsa.h"
#include "bearssl_ec.h"
#include "bearssl_ssl.h"
#include "bearssl_x509.h"
#include "bearssl_pem.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Type for a configuration option.
*
* A "configuration option" is a value that is selected when the BearSSL
* library itself is compiled. Most options are boolean; their value is
* then either 1 (option is enabled) or 0 (option is disabled). Some
* values have other integer values. Option names correspond to macro
* names. Some of the options can be explicitly set in the internal
* `"config.h"` file.
*/
typedef struct {
/** \brief Configurable option name. */
const char *name;
/** \brief Configurable option value. */
long value;
} br_config_option;
/** \brief Get configuration report.
*
* This function returns compiled configuration options, each as a
* 'long' value. Names match internal macro names, in particular those
* that can be set in the `"config.h"` inner file. For boolean options,
* the numerical value is 1 if enabled, 0 if disabled. For maximum
* key sizes, values are expressed in bits.
*
* The returned array is terminated by an entry whose `name` is `NULL`.
*
* \return the configuration report.
*/
const br_config_option *br_get_config(void);
/* ======================================================================= */
/** \brief Version feature: support for time callback. */
#define BR_FEATURE_X509_TIME_CALLBACK 1
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,967 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_EC_H__
#define BR_BEARSSL_EC_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_rand.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_ec.h
*
* # Elliptic Curves
*
* This file documents the EC implementations provided with BearSSL, and
* ECDSA.
*
* ## Elliptic Curve API
*
* Only "named curves" are supported. Each EC implementation supports
* one or several named curves, identified by symbolic identifiers.
* These identifiers are small integers, that correspond to the values
* registered by the
* [IANA](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8).
*
* Since all currently defined elliptic curve identifiers are in the 0..31
* range, it is convenient to encode support of some curves in a 32-bit
* word, such that bit x corresponds to curve of identifier x.
*
* An EC implementation is incarnated by a `br_ec_impl` instance, that
* offers the following fields:
*
* - `supported_curves`
*
* A 32-bit word that documents the identifiers of the curves supported
* by this implementation.
*
* - `generator()`
*
* Callback method that returns a pointer to the conventional generator
* point for that curve.
*
* - `order()`
*
* Callback method that returns a pointer to the subgroup order for
* that curve. That value uses unsigned big-endian encoding.
*
* - `xoff()`
*
* Callback method that returns the offset and length of the X
* coordinate in an encoded point.
*
* - `mul()`
*
* Multiply a curve point with an integer.
*
* - `mulgen()`
*
* Multiply the curve generator with an integer. This may be faster
* than the generic `mul()`.
*
* - `muladd()`
*
* Multiply two curve points by two integers, and return the sum of
* the two products.
*
* All curve points are represented in uncompressed format. The `mul()`
* and `muladd()` methods take care to validate that the provided points
* are really part of the relevant curve subgroup.
*
* For all point multiplication functions, the following holds:
*
* - Functions validate that the provided points are valid members
* of the relevant curve subgroup. An error is reported if that is
* not the case.
*
* - Processing is constant-time, even if the point operands are not
* valid. This holds for both the source and resulting points, and
* the multipliers (integers). Only the byte length of the provided
* multiplier arrays (not their actual value length in bits) may
* leak through timing-based side channels.
*
* - The multipliers (integers) MUST be lower than the subgroup order.
* If this property is not met, then the result is indeterminate,
* but an error value is not necessarily returned.
*
*
* ## ECDSA
*
* ECDSA signatures have two standard formats, called "raw" and "asn1".
* Internally, such a signature is a pair of modular integers `(r,s)`.
* The "raw" format is the concatenation of the unsigned big-endian
* encodings of these two integers, possibly left-padded with zeros so
* that they have the same encoded length. The "asn1" format is the
* DER encoding of an ASN.1 structure that contains the two integer
* values:
*
* ECDSASignature ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* In general, in all of X.509 and SSL/TLS, the "asn1" format is used.
* BearSSL offers ECDSA implementations for both formats; conversion
* functions between the two formats are also provided. Conversion of a
* "raw" format signature into "asn1" may enlarge a signature by no more
* than 9 bytes for all supported curves; conversely, conversion of an
* "asn1" signature to "raw" may expand the signature but the "raw"
* length will never be more than twice the length of the "asn1" length
* (and usually it will be shorter).
*
* Note that for a given signature, the "raw" format is not fully
* deterministic, in that it does not enforce a minimal common length.
*/
/*
* Standard curve ID. These ID are equal to the assigned numerical
* identifiers assigned to these curves for TLS:
* http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
*/
/** \brief Identifier for named curve sect163k1. */
#define BR_EC_sect163k1 1
/** \brief Identifier for named curve sect163r1. */
#define BR_EC_sect163r1 2
/** \brief Identifier for named curve sect163r2. */
#define BR_EC_sect163r2 3
/** \brief Identifier for named curve sect193r1. */
#define BR_EC_sect193r1 4
/** \brief Identifier for named curve sect193r2. */
#define BR_EC_sect193r2 5
/** \brief Identifier for named curve sect233k1. */
#define BR_EC_sect233k1 6
/** \brief Identifier for named curve sect233r1. */
#define BR_EC_sect233r1 7
/** \brief Identifier for named curve sect239k1. */
#define BR_EC_sect239k1 8
/** \brief Identifier for named curve sect283k1. */
#define BR_EC_sect283k1 9
/** \brief Identifier for named curve sect283r1. */
#define BR_EC_sect283r1 10
/** \brief Identifier for named curve sect409k1. */
#define BR_EC_sect409k1 11
/** \brief Identifier for named curve sect409r1. */
#define BR_EC_sect409r1 12
/** \brief Identifier for named curve sect571k1. */
#define BR_EC_sect571k1 13
/** \brief Identifier for named curve sect571r1. */
#define BR_EC_sect571r1 14
/** \brief Identifier for named curve secp160k1. */
#define BR_EC_secp160k1 15
/** \brief Identifier for named curve secp160r1. */
#define BR_EC_secp160r1 16
/** \brief Identifier for named curve secp160r2. */
#define BR_EC_secp160r2 17
/** \brief Identifier for named curve secp192k1. */
#define BR_EC_secp192k1 18
/** \brief Identifier for named curve secp192r1. */
#define BR_EC_secp192r1 19
/** \brief Identifier for named curve secp224k1. */
#define BR_EC_secp224k1 20
/** \brief Identifier for named curve secp224r1. */
#define BR_EC_secp224r1 21
/** \brief Identifier for named curve secp256k1. */
#define BR_EC_secp256k1 22
/** \brief Identifier for named curve secp256r1. */
#define BR_EC_secp256r1 23
/** \brief Identifier for named curve secp384r1. */
#define BR_EC_secp384r1 24
/** \brief Identifier for named curve secp521r1. */
#define BR_EC_secp521r1 25
/** \brief Identifier for named curve brainpoolP256r1. */
#define BR_EC_brainpoolP256r1 26
/** \brief Identifier for named curve brainpoolP384r1. */
#define BR_EC_brainpoolP384r1 27
/** \brief Identifier for named curve brainpoolP512r1. */
#define BR_EC_brainpoolP512r1 28
/** \brief Identifier for named curve Curve25519. */
#define BR_EC_curve25519 29
/** \brief Identifier for named curve Curve448. */
#define BR_EC_curve448 30
/**
* \brief Structure for an EC public key.
*/
typedef struct {
/** \brief Identifier for the curve used by this key. */
int curve;
/** \brief Public curve point (uncompressed format). */
unsigned char *q;
/** \brief Length of public curve point (in bytes). */
size_t qlen;
} br_ec_public_key;
/**
* \brief Structure for an EC private key.
*
* The private key is an integer modulo the curve subgroup order. The
* encoding below tolerates extra leading zeros. In general, it is
* recommended that the private key has the same length as the curve
* subgroup order.
*/
typedef struct {
/** \brief Identifier for the curve used by this key. */
int curve;
/** \brief Private key (integer, unsigned big-endian encoding). */
unsigned char *x;
/** \brief Private key length (in bytes). */
size_t xlen;
} br_ec_private_key;
/**
* \brief Type for an EC implementation.
*/
typedef struct {
/**
* \brief Supported curves.
*
* This word is a bitfield: bit `x` is set if the curve of ID `x`
* is supported. E.g. an implementation supporting both NIST P-256
* (secp256r1, ID 23) and NIST P-384 (secp384r1, ID 24) will have
* value `0x01800000` in this field.
*/
uint32_t supported_curves;
/**
* \brief Get the conventional generator.
*
* This function returns the conventional generator (encoded
* curve point) for the specified curve. This function MUST NOT
* be called if the curve is not supported.
*
* \param curve curve identifier.
* \param len receiver for the encoded generator length (in bytes).
* \return the encoded generator.
*/
const unsigned char *(*generator)(int curve, size_t *len);
/**
* \brief Get the subgroup order.
*
* This function returns the order of the subgroup generated by
* the conventional generator, for the specified curve. Unsigned
* big-endian encoding is used. This function MUST NOT be called
* if the curve is not supported.
*
* \param curve curve identifier.
* \param len receiver for the encoded order length (in bytes).
* \return the encoded order.
*/
const unsigned char *(*order)(int curve, size_t *len);
/**
* \brief Get the offset and length for the X coordinate.
*
* This function returns the offset and length (in bytes) of
* the X coordinate in an encoded non-zero point.
*
* \param curve curve identifier.
* \param len receiver for the X coordinate length (in bytes).
* \return the offset for the X coordinate (in bytes).
*/
size_t (*xoff)(int curve, size_t *len);
/**
* \brief Multiply a curve point by an integer.
*
* The source point is provided in array `G` (of size `Glen` bytes);
* the multiplication result is written over it. The multiplier
* `x` (of size `xlen` bytes) uses unsigned big-endian encoding.
*
* Rules:
*
* - The specified curve MUST be supported.
*
* - The source point must be a valid point on the relevant curve
* subgroup (and not the "point at infinity" either). If this is
* not the case, then this function returns an error (0).
*
* - The multiplier integer MUST be non-zero and less than the
* curve subgroup order. If this property does not hold, then
* the result is indeterminate and an error code is not
* guaranteed.
*
* Returned value is 1 on success, 0 on error. On error, the
* contents of `G` are indeterminate.
*
* \param G point to multiply.
* \param Glen length of the encoded point (in bytes).
* \param x multiplier (unsigned big-endian).
* \param xlen multiplier length (in bytes).
* \param curve curve identifier.
* \return 1 on success, 0 on error.
*/
uint32_t (*mul)(unsigned char *G, size_t Glen,
const unsigned char *x, size_t xlen, int curve);
/**
* \brief Multiply the generator by an integer.
*
* The multiplier MUST be non-zero and less than the curve
* subgroup order. Results are indeterminate if this property
* does not hold.
*
* \param R output buffer for the point.
* \param x multiplier (unsigned big-endian).
* \param xlen multiplier length (in bytes).
* \param curve curve identifier.
* \return encoded result point length (in bytes).
*/
size_t (*mulgen)(unsigned char *R,
const unsigned char *x, size_t xlen, int curve);
/**
* \brief Multiply two points by two integers and add the
* results.
*
* The point `x*A + y*B` is computed and written back in the `A`
* array.
*
* Rules:
*
* - The specified curve MUST be supported.
*
* - The source points (`A` and `B`) must be valid points on
* the relevant curve subgroup (and not the "point at
* infinity" either). If this is not the case, then this
* function returns an error (0).
*
* - If the `B` pointer is `NULL`, then the conventional
* subgroup generator is used. With some implementations,
* this may be faster than providing a pointer to the
* generator.
*
* - The multiplier integers (`x` and `y`) MUST be non-zero
* and less than the curve subgroup order. If either integer
* is zero, then an error is reported, but if one of them is
* not lower than the subgroup order, then the result is
* indeterminate and an error code is not guaranteed.
*
* - If the final result is the point at infinity, then an
* error is returned.
*
* Returned value is 1 on success, 0 on error. On error, the
* contents of `A` are indeterminate.
*
* \param A first point to multiply.
* \param B second point to multiply (`NULL` for the generator).
* \param len common length of the encoded points (in bytes).
* \param x multiplier for `A` (unsigned big-endian).
* \param xlen length of multiplier for `A` (in bytes).
* \param y multiplier for `A` (unsigned big-endian).
* \param ylen length of multiplier for `A` (in bytes).
* \param curve curve identifier.
* \return 1 on success, 0 on error.
*/
uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len,
const unsigned char *x, size_t xlen,
const unsigned char *y, size_t ylen, int curve);
} br_ec_impl;
/**
* \brief EC implementation "i31".
*
* This implementation internally uses generic code for modular integers,
* with a representation as sequences of 31-bit words. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i31;
/**
* \brief EC implementation "i15".
*
* This implementation internally uses generic code for modular integers,
* with a representation as sequences of 15-bit words. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i15;
/**
* \brief EC implementation "m15" for P-256.
*
* This implementation uses specialised code for curve secp256r1 (also
* known as NIST P-256), with optional Karatsuba decomposition, and fast
* modular reduction thanks to the field modulus special format. Only
* 32-bit multiplications are used (with 32-bit results, not 64-bit).
*/
extern const br_ec_impl br_ec_p256_m15;
/**
* \brief EC implementation "m31" for P-256.
*
* This implementation uses specialised code for curve secp256r1 (also
* known as NIST P-256), relying on multiplications of 31-bit values
* (MUL31).
*/
extern const br_ec_impl br_ec_p256_m31;
/**
* \brief EC implementation "m62" (specialised code) for P-256.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_p256_m62_get()` to dynamically obtain a pointer
* to that implementation.
*/
extern const br_ec_impl br_ec_p256_m62;
/**
* \brief Get the "m62" implementation of P-256, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_p256_m62_get(void);
/**
* \brief EC implementation "m64" (specialised code) for P-256.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_p256_m64_get()` to dynamically obtain a pointer
* to that implementation.
*/
extern const br_ec_impl br_ec_p256_m64;
/**
* \brief Get the "m64" implementation of P-256, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_p256_m64_get(void);
/**
* \brief EC implementation "i15" (generic code) for Curve25519.
*
* This implementation uses the generic code for modular integers (with
* 15-bit words) to support Curve25519. Due to the specificities of the
* curve definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_i15;
/**
* \brief EC implementation "i31" (generic code) for Curve25519.
*
* This implementation uses the generic code for modular integers (with
* 31-bit words) to support Curve25519. Due to the specificities of the
* curve definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_i31;
/**
* \brief EC implementation "m15" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 15 bits. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m15;
/**
* \brief EC implementation "m31" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 31 bits. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m31;
/**
* \brief EC implementation "m62" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 62 bits, with a 124-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_c25519_m62_get()` to dynamically obtain a pointer
* to that implementation. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m62;
/**
* \brief Get the "m62" implementation of Curve25519, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_c25519_m62_get(void);
/**
* \brief EC implementation "m64" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_c25519_m64_get()` to dynamically obtain a pointer
* to that implementation. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m64;
/**
* \brief Get the "m64" implementation of Curve25519, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_c25519_m64_get(void);
/**
* \brief Aggregate EC implementation "m15".
*
* This implementation is a wrapper for:
*
* - `br_ec_c25519_m15` for Curve25519
* - `br_ec_p256_m15` for NIST P-256
* - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512)
*/
extern const br_ec_impl br_ec_all_m15;
/**
* \brief Aggregate EC implementation "m31".
*
* This implementation is a wrapper for:
*
* - `br_ec_c25519_m31` for Curve25519
* - `br_ec_p256_m31` for NIST P-256
* - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512)
*/
extern const br_ec_impl br_ec_all_m31;
/**
* \brief Get the "default" EC implementation for the current system.
*
* This returns a pointer to the preferred implementation on the
* current system.
*
* \return the default EC implementation.
*/
const br_ec_impl *br_ec_get_default(void);
/**
* \brief Convert a signature from "raw" to "asn1".
*
* Conversion is done "in place" and the new length is returned.
* Conversion may enlarge the signature, but by no more than 9 bytes at
* most. On error, 0 is returned (error conditions include an odd raw
* signature length, or an oversized integer).
*
* \param sig signature to convert.
* \param sig_len signature length (in bytes).
* \return the new signature length, or 0 on error.
*/
size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len);
/**
* \brief Convert a signature from "asn1" to "raw".
*
* Conversion is done "in place" and the new length is returned.
* Conversion may enlarge the signature, but the new signature length
* will be less than twice the source length at most. On error, 0 is
* returned (error conditions include an invalid ASN.1 structure or an
* oversized integer).
*
* \param sig signature to convert.
* \param sig_len signature length (in bytes).
* \return the new signature length, or 0 on error.
*/
size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len);
/**
* \brief Type for an ECDSA signer function.
*
* A pointer to the EC implementation is provided. The hash value is
* assumed to have the length inferred from the designated hash function
* class.
*
* Signature is written in the buffer pointed to by `sig`, and the length
* (in bytes) is returned. On error, nothing is written in the buffer,
* and 0 is returned. This function returns 0 if the specified curve is
* not supported by the provided EC implementation.
*
* The signature format is either "raw" or "asn1", depending on the
* implementation; maximum length is predictable from the implemented
* curve:
*
* | curve | raw | asn1 |
* | :--------- | --: | ---: |
* | NIST P-256 | 64 | 72 |
* | NIST P-384 | 96 | 104 |
* | NIST P-521 | 132 | 139 |
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief Type for an ECDSA signature verification function.
*
* A pointer to the EC implementation is provided. The hashed value,
* computed over the purportedly signed data, is also provided with
* its length.
*
* The signature format is either "raw" or "asn1", depending on the
* implementation.
*
* Returned value is 1 on success (valid signature), 0 on error. This
* function returns 0 if the specified curve is not supported by the
* provided EC implementation.
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature generator, "i31" implementation, "asn1" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature generator, "i31" implementation, "raw" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature verifier, "i31" implementation, "asn1" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature verifier, "i31" implementation, "raw" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature generator, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature generator, "i15" implementation, "raw" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature verifier, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature verifier, "i15" implementation, "raw" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief Get "default" ECDSA implementation (signer, asn1 format).
*
* This returns the preferred implementation of ECDSA signature generation
* ("asn1" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void);
/**
* \brief Get "default" ECDSA implementation (signer, raw format).
*
* This returns the preferred implementation of ECDSA signature generation
* ("raw" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_sign br_ecdsa_sign_raw_get_default(void);
/**
* \brief Get "default" ECDSA implementation (verifier, asn1 format).
*
* This returns the preferred implementation of ECDSA signature verification
* ("asn1" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void);
/**
* \brief Get "default" ECDSA implementation (verifier, raw format).
*
* This returns the preferred implementation of ECDSA signature verification
* ("raw" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void);
/**
* \brief Maximum size for EC private key element buffer.
*
* This is the largest number of bytes that `br_ec_keygen()` may need or
* ever return.
*/
#define BR_EC_KBUF_PRIV_MAX_SIZE 72
/**
* \brief Maximum size for EC public key element buffer.
*
* This is the largest number of bytes that `br_ec_compute_public()` may
* need or ever return.
*/
#define BR_EC_KBUF_PUB_MAX_SIZE 145
/**
* \brief Generate a new EC private key.
*
* If the specified `curve` is not supported by the elliptic curve
* implementation (`impl`), then this function returns zero.
*
* The `sk` structure fields are set to the new private key data. In
* particular, `sk.x` is made to point to the provided key buffer (`kbuf`),
* in which the actual private key data is written. That buffer is assumed
* to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum
* size for all supported curves.
*
* The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then
* the private key is not actually generated, and `sk` may also be `NULL`;
* the minimum length for `kbuf` is still computed and returned.
*
* If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is
* still generated and stored in `kbuf`.
*
* \param rng_ctx source PRNG context (already initialized).
* \param impl the elliptic curve implementation.
* \param sk the private key structure to fill, or `NULL`.
* \param kbuf the key element buffer, or `NULL`.
* \param curve the curve identifier.
* \return the key data length (in bytes), or zero.
*/
size_t br_ec_keygen(const br_prng_class **rng_ctx,
const br_ec_impl *impl, br_ec_private_key *sk,
void *kbuf, int curve);
/**
* \brief Compute EC public key from EC private key.
*
* This function uses the provided elliptic curve implementation (`impl`)
* to compute the public key corresponding to the private key held in `sk`.
* The public key point is written into `kbuf`, which is then linked from
* the `*pk` structure. The size of the public key point, i.e. the number
* of bytes used in `kbuf`, is returned.
*
* If `kbuf` is `NULL`, then the public key point is NOT computed, and
* the public key structure `*pk` is unmodified (`pk` may be `NULL` in
* that case). The size of the public key point is still returned.
*
* If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key
* point is computed and stored in `kbuf`, and its size is returned.
*
* If the curve used by the private key is not supported by the curve
* implementation, then this function returns zero.
*
* The private key MUST be valid. An off-range private key value is not
* necessarily detected, and leads to unpredictable results.
*
* \param impl the elliptic curve implementation.
* \param pk the public key structure to fill (or `NULL`).
* \param kbuf the public key point buffer (or `NULL`).
* \param sk the source private key.
* \return the public key point length (in bytes), or zero.
*/
size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk,
void *kbuf, const br_ec_private_key *sk);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,241 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_HMAC_H__
#define BR_BEARSSL_HMAC_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_hmac.h
*
* # HMAC
*
* HMAC is initialized with a key and an underlying hash function; it
* then fills a "key context". That context contains the processed
* key.
*
* With the key context, a HMAC context can be initialized to process
* the input bytes and obtain the MAC output. The key context is not
* modified during that process, and can be reused.
*
* IMPORTANT: HMAC shall be used only with functions that have the
* following properties:
*
* - hash output size does not exceed 64 bytes;
* - hash internal state size does not exceed 64 bytes;
* - internal block length is a power of 2 between 16 and 256 bytes.
*/
/**
* \brief HMAC key context.
*
* The HMAC key context is initialised with a hash function implementation
* and a secret key. Contents are opaque (callers should not access them
* directly). The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
const br_hash_class *dig_vtable;
unsigned char ksi[64], kso[64];
#endif
} br_hmac_key_context;
/**
* \brief HMAC key context initialisation.
*
* Initialise the key context with the provided key, using the hash function
* identified by `digest_vtable`. This supports arbitrary key lengths.
*
* \param kc HMAC key context to initialise.
* \param digest_vtable pointer to the hash function implementation vtable.
* \param key pointer to the HMAC secret key.
* \param key_len HMAC secret key length (in bytes).
*/
void br_hmac_key_init(br_hmac_key_context *kc,
const br_hash_class *digest_vtable, const void *key, size_t key_len);
/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC key context.
*
* \param kc HMAC key context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_key_get_digest(
const br_hmac_key_context *kc)
{
return kc->dig_vtable;
}
/**
* \brief HMAC computation context.
*
* The HMAC computation context maintains the state for a single HMAC
* computation. It is modified as input bytes are injected. The context
* is caller-allocated and has no release function since it does not
* dynamically allocate external resources. Its contents are opaque.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
br_hash_compat_context dig;
unsigned char kso[64];
size_t out_len;
#endif
} br_hmac_context;
/**
* \brief HMAC computation initialisation.
*
* Initialise a HMAC context with a key context. The key context is
* unmodified. Relevant data from the key context is immediately copied;
* the key context can thus be independently reused, modified or released
* without impacting this HMAC computation.
*
* An explicit output length can be specified; the actual output length
* will be the minimum of that value and the natural HMAC output length.
* If `out_len` is 0, then the natural HMAC output length is selected. The
* "natural output length" is the output length of the underlying hash
* function.
*
* \param ctx HMAC context to initialise.
* \param kc HMAC key context (already initialised with the key).
* \param out_len HMAC output length (0 to select "natural length").
*/
void br_hmac_init(br_hmac_context *ctx,
const br_hmac_key_context *kc, size_t out_len);
/**
* \brief Get the HMAC output size.
*
* The HMAC output size is the number of bytes that will actually be
* produced with `br_hmac_out()` with the provided context. This function
* MUST NOT be called on a non-initialised HMAC computation context.
* The returned value is the minimum of the HMAC natural length (output
* size of the underlying hash function) and the `out_len` parameter which
* was used with the last `br_hmac_init()` call on that context (if the
* initialisation `out_len` parameter was 0, then this function will
* return the HMAC natural length).
*
* \param ctx the (already initialised) HMAC computation context.
* \return the HMAC actual output size.
*/
static inline size_t
br_hmac_size(br_hmac_context *ctx)
{
return ctx->out_len;
}
/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC context.
*
* \param hc HMAC context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_get_digest(
const br_hmac_context *hc)
{
return hc->dig.vtable;
}
/**
* \brief Inject some bytes in HMAC.
*
* The provided `len` bytes are injected as extra input in the HMAC
* computation incarnated by the `ctx` HMAC context. It is acceptable
* that `len` is zero, in which case `data` is ignored (and may be
* `NULL`) and this function does nothing.
*/
void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len);
/**
* \brief Compute the HMAC output.
*
* The destination buffer MUST be large enough to accommodate the result;
* its length is at most the "natural length" of HMAC (i.e. the output
* length of the underlying hash function). The context is NOT modified;
* further bytes may be processed. Thus, "partial HMAC" values can be
* efficiently obtained.
*
* Returned value is the output length (in bytes).
*
* \param ctx HMAC computation context.
* \param out destination buffer for the HMAC output.
* \return the produced value length (in bytes).
*/
size_t br_hmac_out(const br_hmac_context *ctx, void *out);
/**
* \brief Constant-time HMAC computation.
*
* This function compute the HMAC output in constant time. Some extra
* input bytes are processed, then the output is computed. The extra
* input consists in the `len` bytes pointed to by `data`. The `len`
* parameter must lie between `min_len` and `max_len` (inclusive);
* `max_len` bytes are actually read from `data`. Computing time (and
* memory access pattern) will not depend upon the data byte contents or
* the value of `len`.
*
* The output is written in the `out` buffer, that MUST be large enough
* to receive it.
*
* The difference `max_len - min_len` MUST be less than 2<sup>30</sup>
* (i.e. about one gigabyte).
*
* This function computes the output properly only if the underlying
* hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256,
* SHA-384 or SHA-512).
*
* The provided context is NOT modified.
*
* \param ctx the (already initialised) HMAC computation context.
* \param data the extra input bytes.
* \param len the extra input length (in bytes).
* \param min_len minimum extra input length (in bytes).
* \param max_len maximum extra input length (in bytes).
* \param out destination buffer for the HMAC output.
* \return the produced value length (in bytes).
*/
size_t br_hmac_outCT(const br_hmac_context *ctx,
const void *data, size_t len, size_t min_len, size_t max_len,
void *out);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,284 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_KDF_H__
#define BR_BEARSSL_KDF_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_kdf.h
*
* # Key Derivation Functions
*
* KDF are functions that takes a variable length input, and provide a
* variable length output, meant to be used to derive subkeys from a
* master key.
*
* ## HKDF
*
* HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869).
* It is based on HMAC, itself using an underlying hash function. Any
* hash function can be used, as long as it is compatible with the rules
* for the HMAC implementation (i.e. output size is 64 bytes or less, hash
* internal state size is 64 bytes or less, and the internal block length is
* a power of 2 between 16 and 256 bytes). HKDF has two phases:
*
* - HKDF-Extract: the input data in ingested, along with a "salt" value.
*
* - HKDF-Expand: the output is produced, from the result of processing
* the input and salt, and using an extra non-secret parameter called
* "info".
*
* The "salt" and "info" strings are non-secret and can be empty. Their role
* is normally to bind the input and output, respectively, to conventional
* identifiers that qualifu them within the used protocol or application.
*
* The implementation defined in this file uses the following functions:
*
* - `br_hkdf_init()`: initialize an HKDF context, with a hash function,
* and the salt. This starts the HKDF-Extract process.
*
* - `br_hkdf_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_hkdf_flip()`: end the HKDF-Extract process, and start the
* HKDF-Expand process.
*
* - `br_hkdf_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
* For correct HKDF processing, the same "info" string must be
* provided for each call.
*
* Note that the HKDF total output size (the number of bytes that
* HKDF-Expand is willing to produce) is limited: if the hash output size
* is _n_ bytes, then the maximum output size is _255*n_.
*
* ## SHAKE
*
* SHAKE is defined in
* [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final)
* under two versions: SHAKE128 and SHAKE256, offering an alleged
* "security level" of 128 and 256 bits, respectively (SHAKE128 is
* about 20 to 25% faster than SHAKE256). SHAKE internally relies on
* the Keccak family of sponge functions, not on any externally provided
* hash function. Contrary to HKDF, SHAKE does not have a concept of
* either a "salt" or an "info" string. The API consists in four
* functions:
*
* - `br_shake_init()`: initialize a SHAKE context for a given
* security level.
*
* - `br_shake_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_shake_flip()`: end the data injection process, and start the
* data production process.
*
* - `br_shake_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
*/
/**
* \brief HKDF context.
*
* The HKDF context is initialized with a hash function implementation
* and a salt value. Contents are opaque (callers should not access them
* directly). The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
union {
br_hmac_context hmac_ctx;
br_hmac_key_context prk_ctx;
} u;
unsigned char buf[64];
size_t ptr;
size_t dig_len;
unsigned chunk_num;
#endif
} br_hkdf_context;
/**
* \brief HKDF context initialization.
*
* The underlying hash function and salt value are provided. Arbitrary
* salt lengths can be used.
*
* HKDF makes a difference between a salt of length zero, and an
* absent salt (the latter being equivalent to a salt consisting of
* bytes of value zero, of the same length as the hash function output).
* If `salt_len` is zero, then this function assumes that the salt is
* present but of length zero. To specify an _absent_ salt, use
* `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored).
*
* \param hc HKDF context to initialise.
* \param digest_vtable pointer to the hash function implementation vtable.
* \param salt HKDF-Extract salt.
* \param salt_len HKDF-Extract salt length (in bytes).
*/
void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable,
const void *salt, size_t salt_len);
/**
* \brief The special "absent salt" value for HKDF.
*/
#define BR_HKDF_NO_SALT (&br_hkdf_no_salt)
#ifndef BR_DOXYGEN_IGNORE
extern const unsigned char br_hkdf_no_salt;
#endif
/**
* \brief HKDF input injection (HKDF-Extract).
*
* This function injects some more input bytes ("key material") into
* HKDF. This function may be called several times, after `br_hkdf_init()`
* but before `br_hkdf_flip()`.
*
* \param hc HKDF context.
* \param ikm extra input bytes.
* \param ikm_len number of extra input bytes.
*/
void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len);
/**
* \brief HKDF switch to the HKDF-Expand phase.
*
* This call terminates the HKDF-Extract process (input injection), and
* starts the HKDF-Expand process (output production).
*
* \param hc HKDF context.
*/
void br_hkdf_flip(br_hkdf_context *hc);
/**
* \brief HKDF output production (HKDF-Expand).
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_hkdf_flip()`.
*
* Returned value is the number of actually produced bytes. The total
* output length is limited to 255 times the output length of the
* underlying hash function.
*
* \param hc HKDF context.
* \param info application specific information string.
* \param info_len application specific information string length (in bytes).
* \param out destination buffer for the HKDF output.
* \param out_len the length of the requested output (in bytes).
* \return the produced output length (in bytes).
*/
size_t br_hkdf_produce(br_hkdf_context *hc,
const void *info, size_t info_len, void *out, size_t out_len);
/**
* \brief SHAKE context.
*
* The HKDF context is initialized with a "security level". The internal
* notion is called "capacity"; the capacity is twice the security level
* (for instance, SHAKE128 has capacity 256).
*
* The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
unsigned char dbuf[200];
size_t dptr;
size_t rate;
uint64_t A[25];
#endif
} br_shake_context;
/**
* \brief SHAKE context initialization.
*
* The context is initialized for the provided "security level".
* Internally, this sets the "capacity" to twice the security level;
* thus, for SHAKE128, the `security_level` parameter should be 128,
* which corresponds to a 256-bit capacity.
*
* Allowed security levels are all multiples of 32, from 32 to 768,
* inclusive. Larger security levels imply lower performance; levels
* beyond 256 bits don't make much sense. Standard levels are 128
* and 256 bits (for SHAKE128 and SHAKE256, respectively).
*
* \param sc SHAKE context to initialise.
* \param security_level security level (in bits).
*/
void br_shake_init(br_shake_context *sc, int security_level);
/**
* \brief SHAKE input injection.
*
* This function injects some more input bytes ("key material") into
* SHAKE. This function may be called several times, after `br_shake_init()`
* but before `br_shake_flip()`.
*
* \param sc SHAKE context.
* \param data extra input bytes.
* \param len number of extra input bytes.
*/
void br_shake_inject(br_shake_context *sc, const void *data, size_t len);
/**
* \brief SHAKE switch to production phase.
*
* This call terminates the input injection process, and starts the
* output production process.
*
* \param sc SHAKE context.
*/
void br_shake_flip(br_shake_context *hc);
/**
* \brief SHAKE output production.
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_shake_flip()`.
*
* There is no practical limit to the number of bytes that may be produced.
*
* \param sc SHAKE context.
* \param out destination buffer for the SHAKE output.
* \param len the length of the requested output (in bytes).
*/
void br_shake_produce(br_shake_context *sc, void *out, size_t len);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,294 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_PEM_H__
#define BR_BEARSSL_PEM_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_pem.h
*
* # PEM Support
*
* PEM is a traditional encoding layer use to store binary objects (in
* particular X.509 certificates, and private keys) in text files. While
* the acronym comes from an old, defunct standard ("Privacy Enhanced
* Mail"), the format has been reused, with some variations, by many
* systems, and is a _de facto_ standard, even though it is not, actually,
* specified in all clarity anywhere.
*
* ## Format Details
*
* BearSSL contains a generic, streamed PEM decoder, which handles the
* following format:
*
* - The input source (a sequence of bytes) is assumed to be the
* encoding of a text file in an ASCII-compatible charset. This
* includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each
* line ends on a newline character (U+000A LINE FEED). The
* U+000D CARRIAGE RETURN characters are ignored, so the code
* accepts both Windows-style and Unix-style line endings.
*
* - Each object begins with a banner that occurs at the start of
* a line; the first banner characters are "`-----BEGIN `" (five
* dashes, the word "BEGIN", and a space). The banner matching is
* not case-sensitive.
*
* - The _object name_ consists in the characters that follow the
* banner start sequence, up to the end of the line, but without
* trailing dashes (in "normal" PEM, there are five trailing
* dashes, but this implementation is not picky about these dashes).
* The BearSSL decoder normalises the name characters to uppercase
* (for ASCII letters only) and accepts names up to 127 characters.
*
* - The object ends with a banner that again occurs at the start of
* a line, and starts with "`-----END `" (again case-insensitive).
*
* - Between that start and end banner, only Base64 data shall occur.
* Base64 converts each sequence of three bytes into four
* characters; the four characters are ASCII letters, digits, "`+`"
* or "`-`" signs, and one or two "`=`" signs may occur in the last
* quartet. Whitespace is ignored (whitespace is any ASCII character
* of code 32 or less, so control characters are whitespace) and
* lines may have arbitrary length; the only restriction is that the
* four characters of a quartet must appear on the same line (no
* line break inside a quartet).
*
* - A single file may contain more than one PEM object. Bytes that
* occur between objects are ignored.
*
*
* ## PEM Decoder API
*
* The PEM decoder offers a state-machine API. The caller allocates a
* decoder context, then injects source bytes. Source bytes are pushed
* with `br_pem_decoder_push()`. The decoder stops accepting bytes when
* it reaches an "event", which is either the start of an object, the
* end of an object, or a decoding error within an object.
*
* The `br_pem_decoder_event()` function is used to obtain the current
* event; it also clears it, thus allowing the decoder to accept more
* bytes. When a object start event is raised, the decoder context
* offers the found object name (normalised to ASCII uppercase).
*
* When an object is reached, the caller must set an appropriate callback
* function, which will receive (by chunks) the decoded object data.
*
* Since the decoder context makes no dynamic allocation, it requires
* no explicit deallocation.
*/
/**
* \brief PEM decoder context.
*
* Contents are opaque (they should not be accessed directly).
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
const unsigned char *hbuf;
size_t hlen;
void (*dest)(void *dest_ctx, const void *src, size_t len);
void *dest_ctx;
unsigned char event;
char name[128];
unsigned char buf[255];
size_t ptr;
#endif
} br_pem_decoder_context;
/**
* \brief Initialise a PEM decoder structure.
*
* \param ctx decoder context to initialise.
*/
void br_pem_decoder_init(br_pem_decoder_context *ctx);
/**
* \brief Push some bytes into the decoder.
*
* Returned value is the number of bytes actually consumed; this may be
* less than the number of provided bytes if an event is raised. When an
* event is raised, it must be read (with `br_pem_decoder_event()`);
* until the event is read, this function will return 0.
*
* \param ctx decoder context.
* \param data new data bytes.
* \param len number of new data bytes.
* \return the number of bytes actually received (may be less than `len`).
*/
size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
const void *data, size_t len);
/**
* \brief Set the receiver for decoded data.
*
* When an object is entered, the provided function (with opaque context
* pointer) will be called repeatedly with successive chunks of decoded
* data for that object. If `dest` is set to 0, then decoded data is
* simply ignored. The receiver can be set at any time, but, in practice,
* it should be called immediately after receiving a "start of object"
* event.
*
* \param ctx decoder context.
* \param dest callback for receiving decoded data.
* \param dest_ctx opaque context pointer for the `dest` callback.
*/
static inline void
br_pem_decoder_setdest(br_pem_decoder_context *ctx,
void (*dest)(void *dest_ctx, const void *src, size_t len),
void *dest_ctx)
{
ctx->dest = dest;
ctx->dest_ctx = dest_ctx;
}
/**
* \brief Get the last event.
*
* If an event was raised, then this function returns the event value, and
* also clears it, thereby allowing the decoder to proceed. If no event
* was raised since the last call to `br_pem_decoder_event()`, then this
* function returns 0.
*
* \param ctx decoder context.
* \return the raised event, or 0.
*/
int br_pem_decoder_event(br_pem_decoder_context *ctx);
/**
* \brief Event: start of object.
*
* This event is raised when the start of a new object has been detected.
* The object name (normalised to uppercase) can be accessed with
* `br_pem_decoder_name()`.
*/
#define BR_PEM_BEGIN_OBJ 1
/**
* \brief Event: end of object.
*
* This event is raised when the end of the current object is reached
* (normally, i.e. with no decoding error).
*/
#define BR_PEM_END_OBJ 2
/**
* \brief Event: decoding error.
*
* This event is raised when decoding fails within an object.
* This formally closes the current object and brings the decoder back
* to the "out of any object" state. The offending line in the source
* is consumed.
*/
#define BR_PEM_ERROR 3
/**
* \brief Get the name of the encountered object.
*
* The encountered object name is defined only when the "start of object"
* event is raised. That name is normalised to uppercase (for ASCII letters
* only) and does not include trailing dashes.
*
* \param ctx decoder context.
* \return the current object name.
*/
static inline const char *
br_pem_decoder_name(br_pem_decoder_context *ctx)
{
return ctx->name;
}
/**
* \brief Encode an object in PEM.
*
* This function encodes the provided binary object (`data`, of length `len`
* bytes) into PEM. The `banner` text will be included in the header and
* footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header).
*
* The length (in characters) of the PEM output is returned; that length
* does NOT include the terminating zero, that this function nevertheless
* adds. If using the returned value for allocation purposes, the allocated
* buffer size MUST be at least one byte larger than the returned size.
*
* If `dest` is `NULL`, then the encoding does not happen; however, the
* length of the encoded object is still computed and returned.
*
* The `data` pointer may be `NULL` only if `len` is zero (when encoding
* an object of length zero, which is not very useful), or when `dest`
* is `NULL` (in that case, source data bytes are ignored).
*
* Some `flags` can be specified to alter the encoding behaviour:
*
* - If `BR_PEM_LINE64` is set, then line-breaking will occur after
* every 64 characters of output, instead of the default of 76.
*
* - If `BR_PEM_CRLF` is set, then end-of-line sequence will use
* CR+LF instead of a single LF.
*
* The `data` and `dest` buffers may overlap, in which case the source
* binary data is destroyed in the process. Note that the PEM-encoded output
* is always larger than the source binary.
*
* \param dest the destination buffer (or `NULL`).
* \param data the source buffer (can be `NULL` in some cases).
* \param len the source length (in bytes).
* \param banner the PEM banner expression.
* \param flags the behavioural flags.
* \return the PEM object length (in characters), EXCLUDING the final zero.
*/
size_t br_pem_encode(void *dest, const void *data, size_t len,
const char *banner, unsigned flags);
/**
* \brief PEM encoding flag: split lines at 64 characters.
*/
#define BR_PEM_LINE64 0x0001
/**
* \brief PEM encoding flag: use CR+LF line endings.
*/
#define BR_PEM_CRLF 0x0002
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,150 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_PRF_H__
#define BR_BEARSSL_PRF_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_prf.h
*
* # The TLS PRF
*
* The "PRF" is the pseudorandom function used internally during the
* SSL/TLS handshake, notably to expand negotiated shared secrets into
* the symmetric encryption keys that will be used to process the
* application data.
*
* TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This
* is implemented by the `br_tls10_prf()` function.
*
* TLS 1.2 redefines the PRF, using an explicit hash function. The
* `br_tls12_sha256_prf()` and `br_tls12_sha384_prf()` functions apply that
* PRF with, respectively, SHA-256 and SHA-384. Most standard cipher suites
* rely on the SHA-256 based PRF, but some use SHA-384.
*
* The PRF always uses as input three parameters: a "secret" (some
* bytes), a "label" (ASCII string), and a "seed" (again some bytes). An
* arbitrary output length can be produced. The "seed" is provided as an
* arbitrary number of binary chunks, that gets internally concatenated.
*/
/**
* \brief Type for a seed chunk.
*
* Each chunk may have an arbitrary length, and may be empty (no byte at
* all). If the chunk length is zero, then the pointer to the chunk data
* may be `NULL`.
*/
typedef struct {
/**
* \brief Pointer to the chunk data.
*/
const void *data;
/**
* \brief Chunk length (in bytes).
*/
size_t len;
} br_tls_prf_seed_chunk;
/**
* \brief PRF implementation for TLS 1.0 and 1.1.
*
* This PRF is the one specified by TLS 1.0 and 1.1. It internally uses
* MD5 and SHA-1.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls10_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* \brief PRF implementation for TLS 1.2, with SHA-256.
*
* This PRF is the one specified by TLS 1.2, when the underlying hash
* function is SHA-256.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls12_sha256_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* \brief PRF implementation for TLS 1.2, with SHA-384.
*
* This PRF is the one specified by TLS 1.2, when the underlying hash
* function is SHA-384.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls12_sha384_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* brief A convenient type name for a PRF implementation.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
typedef void (*br_tls_prf_impl)(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,397 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_RAND_H__
#define BR_BEARSSL_RAND_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_block.h"
#include "bearssl_hash.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_rand.h
*
* # Pseudo-Random Generators
*
* A PRNG is a state-based engine that outputs pseudo-random bytes on
* demand. It is initialized with an initial seed, and additional seed
* bytes can be added afterwards. Bytes produced depend on the seeds and
* also on the exact sequence of calls (including sizes requested for
* each call).
*
*
* ## Procedural and OOP API
*
* For the PRNG of name "`xxx`", two API are provided. The _procedural_
* API defined a context structure `br_xxx_context` and three functions:
*
* - `br_xxx_init()`
*
* Initialise the context with an initial seed.
*
* - `br_xxx_generate()`
*
* Produce some pseudo-random bytes.
*
* - `br_xxx_update()`
*
* Inject some additional seed.
*
* The initialisation function sets the first context field (`vtable`)
* to a pointer to the vtable that supports the OOP API. The OOP API
* provides access to the same functions through function pointers,
* named `init()`, `generate()` and `update()`.
*
* Note that the context initialisation method may accept additional
* parameters, provided as a 'const void *' pointer at API level. These
* additional parameters depend on the implemented PRNG.
*
*
* ## HMAC_DRBG
*
* HMAC_DRBG is defined in [NIST SP 800-90A Revision
* 1](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf).
* It uses HMAC repeatedly, over some configurable underlying hash
* function. In BearSSL, it is implemented under the "`hmac_drbg`" name.
* The "extra parameters" pointer for context initialisation should be
* set to a pointer to the vtable for the underlying hash function (e.g.
* pointer to `br_sha256_vtable` to use HMAC_DRBG with SHA-256).
*
* According to the NIST standard, each request shall produce up to
* 2<sup>19</sup> bits (i.e. 64 kB of data); moreover, the context shall
* be reseeded at least once every 2<sup>48</sup> requests. This
* implementation does not maintain the reseed counter (the threshold is
* too high to be reached in practice) and does not object to producing
* more than 64 kB in a single request; thus, the code cannot fail,
* which corresponds to the fact that the API has no room for error
* codes. However, this implies that requesting more than 64 kB in one
* `generate()` request, or making more than 2<sup>48</sup> requests
* without reseeding, is formally out of NIST specification. There is
* no currently known security penalty for exceeding the NIST limits,
* and, in any case, HMAC_DRBG usage in implementing SSL/TLS always
* stays much below these thresholds.
*
*
* ## AESCTR_DRBG
*
* AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is
* meant to be used only in situations where you are desperate for
* speed, and have an hardware-optimized AES/CTR implementation. Whether
* this will yield perceptible improvements depends on what you use the
* pseudorandom bytes for, and how many you want; for instance, RSA key
* pair generation uses a substantial amount of randomness, and using
* AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key
* generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz).
*
* Internally, it uses CTR mode with successive counter values, starting
* at zero (counter value expressed over 128 bits, big-endian convention).
* The counter is not allowed to reach 32768; thus, every 32768*16 bytes
* at most, the `update()` function is run (on an empty seed, if none is
* provided). The `update()` function computes the new AES-128 key by
* applying a custom hash function to the concatenation of a state-dependent
* word (encryption of an all-one block with the current key) and the new
* seed. The custom hash function uses Hirose's construction over AES-256;
* see the comments in `aesctr_drbg.c` for details.
*
* This DRBG does not follow an existing standard, and thus should be
* considered as inadequate for production use until it has been properly
* analysed.
*/
/**
* \brief Class type for PRNG implementations.
*
* A `br_prng_class` instance references the methods implementing a PRNG.
* Constant instances of this structure are defined for each implemented
* PRNG. Such instances are also called "vtables".
*/
typedef struct br_prng_class_ br_prng_class;
struct br_prng_class_ {
/**
* \brief Size (in bytes) of the context structure appropriate for
* running this PRNG.
*/
size_t context_size;
/**
* \brief Initialisation method.
*
* The context to initialise is provided as a pointer to its
* first field (the vtable pointer); this function sets that
* first field to a pointer to the vtable.
*
* The extra parameters depend on the implementation; each
* implementation defines what kind of extra parameters it
* expects (if any).
*
* Requirements on the initial seed depend on the implemented
* PRNG.
*
* \param ctx PRNG context to initialise.
* \param params extra parameters for the PRNG.
* \param seed initial seed.
* \param seed_len initial seed length (in bytes).
*/
void (*init)(const br_prng_class **ctx, const void *params,
const void *seed, size_t seed_len);
/**
* \brief Random bytes generation.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly.
*
* \param ctx PRNG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void (*generate)(const br_prng_class **ctx, void *out, size_t len);
/**
* \brief Inject additional seed bytes.
*
* The provided seed bytes are added into the PRNG internal
* entropy pool.
*
* \param ctx PRNG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void (*update)(const br_prng_class **ctx,
const void *seed, size_t seed_len);
};
/**
* \brief Context for HMAC_DRBG.
*
* The context contents are opaque, except the first field, which
* supports OOP.
*/
typedef struct {
/**
* \brief Pointer to the vtable.
*
* This field is set with the initialisation method/function.
*/
const br_prng_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
unsigned char K[64];
unsigned char V[64];
const br_hash_class *digest_class;
#endif
} br_hmac_drbg_context;
/**
* \brief Statically allocated, constant vtable for HMAC_DRBG.
*/
extern const br_prng_class br_hmac_drbg_vtable;
/**
* \brief HMAC_DRBG initialisation.
*
* The context to initialise is provided as a pointer to its first field
* (the vtable pointer); this function sets that first field to a
* pointer to the vtable.
*
* The `seed` value is what is called, in NIST terminology, the
* concatenation of the "seed", "nonce" and "personalization string", in
* that order.
*
* The `digest_class` parameter defines the underlying hash function.
* Formally, the NIST standard specifies that the hash function shall
* be only SHA-1 or one of the SHA-2 functions. This implementation also
* works with any other implemented hash function (such as MD5), but
* this is non-standard and therefore not recommended.
*
* \param ctx HMAC_DRBG context to initialise.
* \param digest_class vtable for the underlying hash function.
* \param seed initial seed.
* \param seed_len initial seed length (in bytes).
*/
void br_hmac_drbg_init(br_hmac_drbg_context *ctx,
const br_hash_class *digest_class, const void *seed, size_t seed_len);
/**
* \brief Random bytes generation with HMAC_DRBG.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly. Formally, requesting
* more than 65536 bytes in one request falls out of specification
* limits (but it won't fail).
*
* \param ctx HMAC_DRBG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len);
/**
* \brief Inject additional seed bytes in HMAC_DRBG.
*
* The provided seed bytes are added into the HMAC_DRBG internal
* entropy pool. The process does not _replace_ existing entropy,
* thus pushing non-random bytes (i.e. bytes which are known to the
* attackers) does not degrade the overall quality of generated bytes.
*
* \param ctx HMAC_DRBG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void br_hmac_drbg_update(br_hmac_drbg_context *ctx,
const void *seed, size_t seed_len);
/**
* \brief Get the hash function implementation used by a given instance of
* HMAC_DRBG.
*
* This calls MUST NOT be performed on a context which was not
* previously initialised.
*
* \param ctx HMAC_DRBG context.
* \return the hash function vtable.
*/
static inline const br_hash_class *
br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx)
{
return ctx->digest_class;
}
/**
* \brief Type for a provider of entropy seeds.
*
* A "seeder" is a function that is able to obtain random values from
* some source and inject them as entropy seed in a PRNG. A seeder
* shall guarantee that the total entropy of the injected seed is large
* enough to seed a PRNG for purposes of cryptographic key generation
* (i.e. at least 128 bits).
*
* A seeder may report a failure to obtain adequate entropy. Seeders
* shall endeavour to fix themselves transient errors by trying again;
* thus, callers may consider reported errors as permanent.
*
* \param ctx PRNG context to seed.
* \return 1 on success, 0 on error.
*/
typedef int (*br_prng_seeder)(const br_prng_class **ctx);
/**
* \brief Get a seeder backed by the operating system or hardware.
*
* Get a seeder that feeds on RNG facilities provided by the current
* operating system or hardware. If no such facility is known, then 0
* is returned.
*
* If `name` is not `NULL`, then `*name` is set to a symbolic string
* that identifies the seeder implementation. If no seeder is returned
* and `name` is not `NULL`, then `*name` is set to a pointer to the
* constant string `"none"`.
*
* \param name receiver for seeder name, or `NULL`.
* \return the system seeder, if available, or 0.
*/
br_prng_seeder br_prng_seeder_system(const char **name);
/**
* \brief Context for AESCTR_DRBG.
*
* The context contents are opaque, except the first field, which
* supports OOP.
*/
typedef struct {
/**
* \brief Pointer to the vtable.
*
* This field is set with the initialisation method/function.
*/
const br_prng_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
br_aes_gen_ctr_keys sk;
uint32_t cc;
#endif
} br_aesctr_drbg_context;
/**
* \brief Statically allocated, constant vtable for AESCTR_DRBG.
*/
extern const br_prng_class br_aesctr_drbg_vtable;
/**
* \brief AESCTR_DRBG initialisation.
*
* The context to initialise is provided as a pointer to its first field
* (the vtable pointer); this function sets that first field to a
* pointer to the vtable.
*
* The internal AES key is first set to the all-zero key; then, the
* `br_aesctr_drbg_update()` function is called with the provided `seed`.
* The call is performed even if the seed length (`seed_len`) is zero.
*
* The `aesctr` parameter defines the underlying AES/CTR implementation.
*
* \param ctx AESCTR_DRBG context to initialise.
* \param aesctr vtable for the AES/CTR implementation.
* \param seed initial seed (can be `NULL` if `seed_len` is zero).
* \param seed_len initial seed length (in bytes).
*/
void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx,
const br_block_ctr_class *aesctr, const void *seed, size_t seed_len);
/**
* \brief Random bytes generation with AESCTR_DRBG.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly.
*
* \param ctx AESCTR_DRBG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx,
void *out, size_t len);
/**
* \brief Inject additional seed bytes in AESCTR_DRBG.
*
* The provided seed bytes are added into the AESCTR_DRBG internal
* entropy pool. The process does not _replace_ existing entropy,
* thus pushing non-random bytes (i.e. bytes which are known to the
* attackers) does not degrade the overall quality of generated bytes.
*
* \param ctx AESCTR_DRBG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx,
const void *seed, size_t seed_len);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+967
View File
@@ -0,0 +1,967 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_EC_H__
#define BR_BEARSSL_EC_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_rand.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_ec.h
*
* # Elliptic Curves
*
* This file documents the EC implementations provided with BearSSL, and
* ECDSA.
*
* ## Elliptic Curve API
*
* Only "named curves" are supported. Each EC implementation supports
* one or several named curves, identified by symbolic identifiers.
* These identifiers are small integers, that correspond to the values
* registered by the
* [IANA](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8).
*
* Since all currently defined elliptic curve identifiers are in the 0..31
* range, it is convenient to encode support of some curves in a 32-bit
* word, such that bit x corresponds to curve of identifier x.
*
* An EC implementation is incarnated by a `br_ec_impl` instance, that
* offers the following fields:
*
* - `supported_curves`
*
* A 32-bit word that documents the identifiers of the curves supported
* by this implementation.
*
* - `generator()`
*
* Callback method that returns a pointer to the conventional generator
* point for that curve.
*
* - `order()`
*
* Callback method that returns a pointer to the subgroup order for
* that curve. That value uses unsigned big-endian encoding.
*
* - `xoff()`
*
* Callback method that returns the offset and length of the X
* coordinate in an encoded point.
*
* - `mul()`
*
* Multiply a curve point with an integer.
*
* - `mulgen()`
*
* Multiply the curve generator with an integer. This may be faster
* than the generic `mul()`.
*
* - `muladd()`
*
* Multiply two curve points by two integers, and return the sum of
* the two products.
*
* All curve points are represented in uncompressed format. The `mul()`
* and `muladd()` methods take care to validate that the provided points
* are really part of the relevant curve subgroup.
*
* For all point multiplication functions, the following holds:
*
* - Functions validate that the provided points are valid members
* of the relevant curve subgroup. An error is reported if that is
* not the case.
*
* - Processing is constant-time, even if the point operands are not
* valid. This holds for both the source and resulting points, and
* the multipliers (integers). Only the byte length of the provided
* multiplier arrays (not their actual value length in bits) may
* leak through timing-based side channels.
*
* - The multipliers (integers) MUST be lower than the subgroup order.
* If this property is not met, then the result is indeterminate,
* but an error value is not necessarily returned.
*
*
* ## ECDSA
*
* ECDSA signatures have two standard formats, called "raw" and "asn1".
* Internally, such a signature is a pair of modular integers `(r,s)`.
* The "raw" format is the concatenation of the unsigned big-endian
* encodings of these two integers, possibly left-padded with zeros so
* that they have the same encoded length. The "asn1" format is the
* DER encoding of an ASN.1 structure that contains the two integer
* values:
*
* ECDSASignature ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
* In general, in all of X.509 and SSL/TLS, the "asn1" format is used.
* BearSSL offers ECDSA implementations for both formats; conversion
* functions between the two formats are also provided. Conversion of a
* "raw" format signature into "asn1" may enlarge a signature by no more
* than 9 bytes for all supported curves; conversely, conversion of an
* "asn1" signature to "raw" may expand the signature but the "raw"
* length will never be more than twice the length of the "asn1" length
* (and usually it will be shorter).
*
* Note that for a given signature, the "raw" format is not fully
* deterministic, in that it does not enforce a minimal common length.
*/
/*
* Standard curve ID. These ID are equal to the assigned numerical
* identifiers assigned to these curves for TLS:
* http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
*/
/** \brief Identifier for named curve sect163k1. */
#define BR_EC_sect163k1 1
/** \brief Identifier for named curve sect163r1. */
#define BR_EC_sect163r1 2
/** \brief Identifier for named curve sect163r2. */
#define BR_EC_sect163r2 3
/** \brief Identifier for named curve sect193r1. */
#define BR_EC_sect193r1 4
/** \brief Identifier for named curve sect193r2. */
#define BR_EC_sect193r2 5
/** \brief Identifier for named curve sect233k1. */
#define BR_EC_sect233k1 6
/** \brief Identifier for named curve sect233r1. */
#define BR_EC_sect233r1 7
/** \brief Identifier for named curve sect239k1. */
#define BR_EC_sect239k1 8
/** \brief Identifier for named curve sect283k1. */
#define BR_EC_sect283k1 9
/** \brief Identifier for named curve sect283r1. */
#define BR_EC_sect283r1 10
/** \brief Identifier for named curve sect409k1. */
#define BR_EC_sect409k1 11
/** \brief Identifier for named curve sect409r1. */
#define BR_EC_sect409r1 12
/** \brief Identifier for named curve sect571k1. */
#define BR_EC_sect571k1 13
/** \brief Identifier for named curve sect571r1. */
#define BR_EC_sect571r1 14
/** \brief Identifier for named curve secp160k1. */
#define BR_EC_secp160k1 15
/** \brief Identifier for named curve secp160r1. */
#define BR_EC_secp160r1 16
/** \brief Identifier for named curve secp160r2. */
#define BR_EC_secp160r2 17
/** \brief Identifier for named curve secp192k1. */
#define BR_EC_secp192k1 18
/** \brief Identifier for named curve secp192r1. */
#define BR_EC_secp192r1 19
/** \brief Identifier for named curve secp224k1. */
#define BR_EC_secp224k1 20
/** \brief Identifier for named curve secp224r1. */
#define BR_EC_secp224r1 21
/** \brief Identifier for named curve secp256k1. */
#define BR_EC_secp256k1 22
/** \brief Identifier for named curve secp256r1. */
#define BR_EC_secp256r1 23
/** \brief Identifier for named curve secp384r1. */
#define BR_EC_secp384r1 24
/** \brief Identifier for named curve secp521r1. */
#define BR_EC_secp521r1 25
/** \brief Identifier for named curve brainpoolP256r1. */
#define BR_EC_brainpoolP256r1 26
/** \brief Identifier for named curve brainpoolP384r1. */
#define BR_EC_brainpoolP384r1 27
/** \brief Identifier for named curve brainpoolP512r1. */
#define BR_EC_brainpoolP512r1 28
/** \brief Identifier for named curve Curve25519. */
#define BR_EC_curve25519 29
/** \brief Identifier for named curve Curve448. */
#define BR_EC_curve448 30
/**
* \brief Structure for an EC public key.
*/
typedef struct {
/** \brief Identifier for the curve used by this key. */
int curve;
/** \brief Public curve point (uncompressed format). */
unsigned char *q;
/** \brief Length of public curve point (in bytes). */
size_t qlen;
} br_ec_public_key;
/**
* \brief Structure for an EC private key.
*
* The private key is an integer modulo the curve subgroup order. The
* encoding below tolerates extra leading zeros. In general, it is
* recommended that the private key has the same length as the curve
* subgroup order.
*/
typedef struct {
/** \brief Identifier for the curve used by this key. */
int curve;
/** \brief Private key (integer, unsigned big-endian encoding). */
unsigned char *x;
/** \brief Private key length (in bytes). */
size_t xlen;
} br_ec_private_key;
/**
* \brief Type for an EC implementation.
*/
typedef struct {
/**
* \brief Supported curves.
*
* This word is a bitfield: bit `x` is set if the curve of ID `x`
* is supported. E.g. an implementation supporting both NIST P-256
* (secp256r1, ID 23) and NIST P-384 (secp384r1, ID 24) will have
* value `0x01800000` in this field.
*/
uint32_t supported_curves;
/**
* \brief Get the conventional generator.
*
* This function returns the conventional generator (encoded
* curve point) for the specified curve. This function MUST NOT
* be called if the curve is not supported.
*
* \param curve curve identifier.
* \param len receiver for the encoded generator length (in bytes).
* \return the encoded generator.
*/
const unsigned char *(*generator)(int curve, size_t *len);
/**
* \brief Get the subgroup order.
*
* This function returns the order of the subgroup generated by
* the conventional generator, for the specified curve. Unsigned
* big-endian encoding is used. This function MUST NOT be called
* if the curve is not supported.
*
* \param curve curve identifier.
* \param len receiver for the encoded order length (in bytes).
* \return the encoded order.
*/
const unsigned char *(*order)(int curve, size_t *len);
/**
* \brief Get the offset and length for the X coordinate.
*
* This function returns the offset and length (in bytes) of
* the X coordinate in an encoded non-zero point.
*
* \param curve curve identifier.
* \param len receiver for the X coordinate length (in bytes).
* \return the offset for the X coordinate (in bytes).
*/
size_t (*xoff)(int curve, size_t *len);
/**
* \brief Multiply a curve point by an integer.
*
* The source point is provided in array `G` (of size `Glen` bytes);
* the multiplication result is written over it. The multiplier
* `x` (of size `xlen` bytes) uses unsigned big-endian encoding.
*
* Rules:
*
* - The specified curve MUST be supported.
*
* - The source point must be a valid point on the relevant curve
* subgroup (and not the "point at infinity" either). If this is
* not the case, then this function returns an error (0).
*
* - The multiplier integer MUST be non-zero and less than the
* curve subgroup order. If this property does not hold, then
* the result is indeterminate and an error code is not
* guaranteed.
*
* Returned value is 1 on success, 0 on error. On error, the
* contents of `G` are indeterminate.
*
* \param G point to multiply.
* \param Glen length of the encoded point (in bytes).
* \param x multiplier (unsigned big-endian).
* \param xlen multiplier length (in bytes).
* \param curve curve identifier.
* \return 1 on success, 0 on error.
*/
uint32_t (*mul)(unsigned char *G, size_t Glen,
const unsigned char *x, size_t xlen, int curve);
/**
* \brief Multiply the generator by an integer.
*
* The multiplier MUST be non-zero and less than the curve
* subgroup order. Results are indeterminate if this property
* does not hold.
*
* \param R output buffer for the point.
* \param x multiplier (unsigned big-endian).
* \param xlen multiplier length (in bytes).
* \param curve curve identifier.
* \return encoded result point length (in bytes).
*/
size_t (*mulgen)(unsigned char *R,
const unsigned char *x, size_t xlen, int curve);
/**
* \brief Multiply two points by two integers and add the
* results.
*
* The point `x*A + y*B` is computed and written back in the `A`
* array.
*
* Rules:
*
* - The specified curve MUST be supported.
*
* - The source points (`A` and `B`) must be valid points on
* the relevant curve subgroup (and not the "point at
* infinity" either). If this is not the case, then this
* function returns an error (0).
*
* - If the `B` pointer is `NULL`, then the conventional
* subgroup generator is used. With some implementations,
* this may be faster than providing a pointer to the
* generator.
*
* - The multiplier integers (`x` and `y`) MUST be non-zero
* and less than the curve subgroup order. If either integer
* is zero, then an error is reported, but if one of them is
* not lower than the subgroup order, then the result is
* indeterminate and an error code is not guaranteed.
*
* - If the final result is the point at infinity, then an
* error is returned.
*
* Returned value is 1 on success, 0 on error. On error, the
* contents of `A` are indeterminate.
*
* \param A first point to multiply.
* \param B second point to multiply (`NULL` for the generator).
* \param len common length of the encoded points (in bytes).
* \param x multiplier for `A` (unsigned big-endian).
* \param xlen length of multiplier for `A` (in bytes).
* \param y multiplier for `A` (unsigned big-endian).
* \param ylen length of multiplier for `A` (in bytes).
* \param curve curve identifier.
* \return 1 on success, 0 on error.
*/
uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len,
const unsigned char *x, size_t xlen,
const unsigned char *y, size_t ylen, int curve);
} br_ec_impl;
/**
* \brief EC implementation "i31".
*
* This implementation internally uses generic code for modular integers,
* with a representation as sequences of 31-bit words. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i31;
/**
* \brief EC implementation "i15".
*
* This implementation internally uses generic code for modular integers,
* with a representation as sequences of 15-bit words. It supports secp256r1,
* secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521).
*/
extern const br_ec_impl br_ec_prime_i15;
/**
* \brief EC implementation "m15" for P-256.
*
* This implementation uses specialised code for curve secp256r1 (also
* known as NIST P-256), with optional Karatsuba decomposition, and fast
* modular reduction thanks to the field modulus special format. Only
* 32-bit multiplications are used (with 32-bit results, not 64-bit).
*/
extern const br_ec_impl br_ec_p256_m15;
/**
* \brief EC implementation "m31" for P-256.
*
* This implementation uses specialised code for curve secp256r1 (also
* known as NIST P-256), relying on multiplications of 31-bit values
* (MUL31).
*/
extern const br_ec_impl br_ec_p256_m31;
/**
* \brief EC implementation "m62" (specialised code) for P-256.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_p256_m62_get()` to dynamically obtain a pointer
* to that implementation.
*/
extern const br_ec_impl br_ec_p256_m62;
/**
* \brief Get the "m62" implementation of P-256, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_p256_m62_get(void);
/**
* \brief EC implementation "m64" (specialised code) for P-256.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_p256_m64_get()` to dynamically obtain a pointer
* to that implementation.
*/
extern const br_ec_impl br_ec_p256_m64;
/**
* \brief Get the "m64" implementation of P-256, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_p256_m64_get(void);
/**
* \brief EC implementation "i15" (generic code) for Curve25519.
*
* This implementation uses the generic code for modular integers (with
* 15-bit words) to support Curve25519. Due to the specificities of the
* curve definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_i15;
/**
* \brief EC implementation "i31" (generic code) for Curve25519.
*
* This implementation uses the generic code for modular integers (with
* 31-bit words) to support Curve25519. Due to the specificities of the
* curve definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_i31;
/**
* \brief EC implementation "m15" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 15 bits. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m15;
/**
* \brief EC implementation "m31" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 31 bits. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m31;
/**
* \brief EC implementation "m62" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 62 bits, with a 124-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_c25519_m62_get()` to dynamically obtain a pointer
* to that implementation. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m62;
/**
* \brief Get the "m62" implementation of Curve25519, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_c25519_m62_get(void);
/**
* \brief EC implementation "m64" (specialised code) for Curve25519.
*
* This implementation uses custom code relying on multiplication of
* integers up to 64 bits, with a 128-bit result. This implementation is
* defined only on platforms that offer the 64x64->128 multiplication
* support; use `br_ec_c25519_m64_get()` to dynamically obtain a pointer
* to that implementation. Due to the specificities of the curve
* definition, the following applies:
*
* - `muladd()` is not implemented (the function returns 0 systematically).
* - `order()` returns 2^255-1, since the point multiplication algorithm
* accepts any 32-bit integer as input (it clears the top bit and low
* three bits systematically).
*/
extern const br_ec_impl br_ec_c25519_m64;
/**
* \brief Get the "m64" implementation of Curve25519, if available.
*
* \return the implementation, or 0.
*/
const br_ec_impl *br_ec_c25519_m64_get(void);
/**
* \brief Aggregate EC implementation "m15".
*
* This implementation is a wrapper for:
*
* - `br_ec_c25519_m15` for Curve25519
* - `br_ec_p256_m15` for NIST P-256
* - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512)
*/
extern const br_ec_impl br_ec_all_m15;
/**
* \brief Aggregate EC implementation "m31".
*
* This implementation is a wrapper for:
*
* - `br_ec_c25519_m31` for Curve25519
* - `br_ec_p256_m31` for NIST P-256
* - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512)
*/
extern const br_ec_impl br_ec_all_m31;
/**
* \brief Get the "default" EC implementation for the current system.
*
* This returns a pointer to the preferred implementation on the
* current system.
*
* \return the default EC implementation.
*/
const br_ec_impl *br_ec_get_default(void);
/**
* \brief Convert a signature from "raw" to "asn1".
*
* Conversion is done "in place" and the new length is returned.
* Conversion may enlarge the signature, but by no more than 9 bytes at
* most. On error, 0 is returned (error conditions include an odd raw
* signature length, or an oversized integer).
*
* \param sig signature to convert.
* \param sig_len signature length (in bytes).
* \return the new signature length, or 0 on error.
*/
size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len);
/**
* \brief Convert a signature from "asn1" to "raw".
*
* Conversion is done "in place" and the new length is returned.
* Conversion may enlarge the signature, but the new signature length
* will be less than twice the source length at most. On error, 0 is
* returned (error conditions include an invalid ASN.1 structure or an
* oversized integer).
*
* \param sig signature to convert.
* \param sig_len signature length (in bytes).
* \return the new signature length, or 0 on error.
*/
size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len);
/**
* \brief Type for an ECDSA signer function.
*
* A pointer to the EC implementation is provided. The hash value is
* assumed to have the length inferred from the designated hash function
* class.
*
* Signature is written in the buffer pointed to by `sig`, and the length
* (in bytes) is returned. On error, nothing is written in the buffer,
* and 0 is returned. This function returns 0 if the specified curve is
* not supported by the provided EC implementation.
*
* The signature format is either "raw" or "asn1", depending on the
* implementation; maximum length is predictable from the implemented
* curve:
*
* | curve | raw | asn1 |
* | :--------- | --: | ---: |
* | NIST P-256 | 64 | 72 |
* | NIST P-384 | 96 | 104 |
* | NIST P-521 | 132 | 139 |
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief Type for an ECDSA signature verification function.
*
* A pointer to the EC implementation is provided. The hashed value,
* computed over the purportedly signed data, is also provided with
* its length.
*
* The signature format is either "raw" or "asn1", depending on the
* implementation.
*
* Returned value is 1 on success (valid signature), 0 on error. This
* function returns 0 if the specified curve is not supported by the
* provided EC implementation.
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature generator, "i31" implementation, "asn1" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature generator, "i31" implementation, "raw" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature verifier, "i31" implementation, "asn1" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature verifier, "i31" implementation, "raw" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature generator, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature generator, "i15" implementation, "raw" format.
*
* \see br_ecdsa_sign()
*
* \param impl EC implementation to use.
* \param hf hash function used to process the data.
* \param hash_value signed data (hashed).
* \param sk EC private key.
* \param sig destination buffer.
* \return the signature length (in bytes), or 0 on error.
*/
size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl,
const br_hash_class *hf, const void *hash_value,
const br_ec_private_key *sk, void *sig);
/**
* \brief ECDSA signature verifier, "i15" implementation, "asn1" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief ECDSA signature verifier, "i15" implementation, "raw" format.
*
* \see br_ecdsa_vrfy()
*
* \param impl EC implementation to use.
* \param hash signed data (hashed).
* \param hash_len hash value length (in bytes).
* \param pk EC public key.
* \param sig signature.
* \param sig_len signature length (in bytes).
* \return 1 on success, 0 on error.
*/
uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl,
const void *hash, size_t hash_len,
const br_ec_public_key *pk, const void *sig, size_t sig_len);
/**
* \brief Get "default" ECDSA implementation (signer, asn1 format).
*
* This returns the preferred implementation of ECDSA signature generation
* ("asn1" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void);
/**
* \brief Get "default" ECDSA implementation (signer, raw format).
*
* This returns the preferred implementation of ECDSA signature generation
* ("raw" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_sign br_ecdsa_sign_raw_get_default(void);
/**
* \brief Get "default" ECDSA implementation (verifier, asn1 format).
*
* This returns the preferred implementation of ECDSA signature verification
* ("asn1" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void);
/**
* \brief Get "default" ECDSA implementation (verifier, raw format).
*
* This returns the preferred implementation of ECDSA signature verification
* ("raw" output format) on the current system.
*
* \return the default implementation.
*/
br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void);
/**
* \brief Maximum size for EC private key element buffer.
*
* This is the largest number of bytes that `br_ec_keygen()` may need or
* ever return.
*/
#define BR_EC_KBUF_PRIV_MAX_SIZE 72
/**
* \brief Maximum size for EC public key element buffer.
*
* This is the largest number of bytes that `br_ec_compute_public()` may
* need or ever return.
*/
#define BR_EC_KBUF_PUB_MAX_SIZE 145
/**
* \brief Generate a new EC private key.
*
* If the specified `curve` is not supported by the elliptic curve
* implementation (`impl`), then this function returns zero.
*
* The `sk` structure fields are set to the new private key data. In
* particular, `sk.x` is made to point to the provided key buffer (`kbuf`),
* in which the actual private key data is written. That buffer is assumed
* to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum
* size for all supported curves.
*
* The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then
* the private key is not actually generated, and `sk` may also be `NULL`;
* the minimum length for `kbuf` is still computed and returned.
*
* If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is
* still generated and stored in `kbuf`.
*
* \param rng_ctx source PRNG context (already initialized).
* \param impl the elliptic curve implementation.
* \param sk the private key structure to fill, or `NULL`.
* \param kbuf the key element buffer, or `NULL`.
* \param curve the curve identifier.
* \return the key data length (in bytes), or zero.
*/
size_t br_ec_keygen(const br_prng_class **rng_ctx,
const br_ec_impl *impl, br_ec_private_key *sk,
void *kbuf, int curve);
/**
* \brief Compute EC public key from EC private key.
*
* This function uses the provided elliptic curve implementation (`impl`)
* to compute the public key corresponding to the private key held in `sk`.
* The public key point is written into `kbuf`, which is then linked from
* the `*pk` structure. The size of the public key point, i.e. the number
* of bytes used in `kbuf`, is returned.
*
* If `kbuf` is `NULL`, then the public key point is NOT computed, and
* the public key structure `*pk` is unmodified (`pk` may be `NULL` in
* that case). The size of the public key point is still returned.
*
* If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key
* point is computed and stored in `kbuf`, and its size is returned.
*
* If the curve used by the private key is not supported by the curve
* implementation, then this function returns zero.
*
* The private key MUST be valid. An off-range private key value is not
* necessarily detected, and leads to unpredictable results.
*
* \param impl the elliptic curve implementation.
* \param pk the public key structure to fill (or `NULL`).
* \param kbuf the public key point buffer (or `NULL`).
* \param sk the source private key.
* \return the public key point length (in bytes), or zero.
*/
size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk,
void *kbuf, const br_ec_private_key *sk);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+241
View File
@@ -0,0 +1,241 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_HMAC_H__
#define BR_BEARSSL_HMAC_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_hmac.h
*
* # HMAC
*
* HMAC is initialized with a key and an underlying hash function; it
* then fills a "key context". That context contains the processed
* key.
*
* With the key context, a HMAC context can be initialized to process
* the input bytes and obtain the MAC output. The key context is not
* modified during that process, and can be reused.
*
* IMPORTANT: HMAC shall be used only with functions that have the
* following properties:
*
* - hash output size does not exceed 64 bytes;
* - hash internal state size does not exceed 64 bytes;
* - internal block length is a power of 2 between 16 and 256 bytes.
*/
/**
* \brief HMAC key context.
*
* The HMAC key context is initialised with a hash function implementation
* and a secret key. Contents are opaque (callers should not access them
* directly). The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
const br_hash_class *dig_vtable;
unsigned char ksi[64], kso[64];
#endif
} br_hmac_key_context;
/**
* \brief HMAC key context initialisation.
*
* Initialise the key context with the provided key, using the hash function
* identified by `digest_vtable`. This supports arbitrary key lengths.
*
* \param kc HMAC key context to initialise.
* \param digest_vtable pointer to the hash function implementation vtable.
* \param key pointer to the HMAC secret key.
* \param key_len HMAC secret key length (in bytes).
*/
void br_hmac_key_init(br_hmac_key_context *kc,
const br_hash_class *digest_vtable, const void *key, size_t key_len);
/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC key context.
*
* \param kc HMAC key context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_key_get_digest(
const br_hmac_key_context *kc)
{
return kc->dig_vtable;
}
/**
* \brief HMAC computation context.
*
* The HMAC computation context maintains the state for a single HMAC
* computation. It is modified as input bytes are injected. The context
* is caller-allocated and has no release function since it does not
* dynamically allocate external resources. Its contents are opaque.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
br_hash_compat_context dig;
unsigned char kso[64];
size_t out_len;
#endif
} br_hmac_context;
/**
* \brief HMAC computation initialisation.
*
* Initialise a HMAC context with a key context. The key context is
* unmodified. Relevant data from the key context is immediately copied;
* the key context can thus be independently reused, modified or released
* without impacting this HMAC computation.
*
* An explicit output length can be specified; the actual output length
* will be the minimum of that value and the natural HMAC output length.
* If `out_len` is 0, then the natural HMAC output length is selected. The
* "natural output length" is the output length of the underlying hash
* function.
*
* \param ctx HMAC context to initialise.
* \param kc HMAC key context (already initialised with the key).
* \param out_len HMAC output length (0 to select "natural length").
*/
void br_hmac_init(br_hmac_context *ctx,
const br_hmac_key_context *kc, size_t out_len);
/**
* \brief Get the HMAC output size.
*
* The HMAC output size is the number of bytes that will actually be
* produced with `br_hmac_out()` with the provided context. This function
* MUST NOT be called on a non-initialised HMAC computation context.
* The returned value is the minimum of the HMAC natural length (output
* size of the underlying hash function) and the `out_len` parameter which
* was used with the last `br_hmac_init()` call on that context (if the
* initialisation `out_len` parameter was 0, then this function will
* return the HMAC natural length).
*
* \param ctx the (already initialised) HMAC computation context.
* \return the HMAC actual output size.
*/
static inline size_t
br_hmac_size(br_hmac_context *ctx)
{
return ctx->out_len;
}
/*
* \brief Get the underlying hash function.
*
* This function returns a pointer to the implementation vtable of the
* hash function used for this HMAC context.
*
* \param hc HMAC context.
* \return the hash function implementation.
*/
static inline const br_hash_class *br_hmac_get_digest(
const br_hmac_context *hc)
{
return hc->dig.vtable;
}
/**
* \brief Inject some bytes in HMAC.
*
* The provided `len` bytes are injected as extra input in the HMAC
* computation incarnated by the `ctx` HMAC context. It is acceptable
* that `len` is zero, in which case `data` is ignored (and may be
* `NULL`) and this function does nothing.
*/
void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len);
/**
* \brief Compute the HMAC output.
*
* The destination buffer MUST be large enough to accommodate the result;
* its length is at most the "natural length" of HMAC (i.e. the output
* length of the underlying hash function). The context is NOT modified;
* further bytes may be processed. Thus, "partial HMAC" values can be
* efficiently obtained.
*
* Returned value is the output length (in bytes).
*
* \param ctx HMAC computation context.
* \param out destination buffer for the HMAC output.
* \return the produced value length (in bytes).
*/
size_t br_hmac_out(const br_hmac_context *ctx, void *out);
/**
* \brief Constant-time HMAC computation.
*
* This function compute the HMAC output in constant time. Some extra
* input bytes are processed, then the output is computed. The extra
* input consists in the `len` bytes pointed to by `data`. The `len`
* parameter must lie between `min_len` and `max_len` (inclusive);
* `max_len` bytes are actually read from `data`. Computing time (and
* memory access pattern) will not depend upon the data byte contents or
* the value of `len`.
*
* The output is written in the `out` buffer, that MUST be large enough
* to receive it.
*
* The difference `max_len - min_len` MUST be less than 2<sup>30</sup>
* (i.e. about one gigabyte).
*
* This function computes the output properly only if the underlying
* hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256,
* SHA-384 or SHA-512).
*
* The provided context is NOT modified.
*
* \param ctx the (already initialised) HMAC computation context.
* \param data the extra input bytes.
* \param len the extra input length (in bytes).
* \param min_len minimum extra input length (in bytes).
* \param max_len maximum extra input length (in bytes).
* \param out destination buffer for the HMAC output.
* \return the produced value length (in bytes).
*/
size_t br_hmac_outCT(const br_hmac_context *ctx,
const void *data, size_t len, size_t min_len, size_t max_len,
void *out);
#ifdef __cplusplus
}
#endif
#endif
+284
View File
@@ -0,0 +1,284 @@
/*
* Copyright (c) 2018 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_KDF_H__
#define BR_BEARSSL_KDF_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_hash.h"
#include "bearssl_hmac.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_kdf.h
*
* # Key Derivation Functions
*
* KDF are functions that takes a variable length input, and provide a
* variable length output, meant to be used to derive subkeys from a
* master key.
*
* ## HKDF
*
* HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869).
* It is based on HMAC, itself using an underlying hash function. Any
* hash function can be used, as long as it is compatible with the rules
* for the HMAC implementation (i.e. output size is 64 bytes or less, hash
* internal state size is 64 bytes or less, and the internal block length is
* a power of 2 between 16 and 256 bytes). HKDF has two phases:
*
* - HKDF-Extract: the input data in ingested, along with a "salt" value.
*
* - HKDF-Expand: the output is produced, from the result of processing
* the input and salt, and using an extra non-secret parameter called
* "info".
*
* The "salt" and "info" strings are non-secret and can be empty. Their role
* is normally to bind the input and output, respectively, to conventional
* identifiers that qualifu them within the used protocol or application.
*
* The implementation defined in this file uses the following functions:
*
* - `br_hkdf_init()`: initialize an HKDF context, with a hash function,
* and the salt. This starts the HKDF-Extract process.
*
* - `br_hkdf_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_hkdf_flip()`: end the HKDF-Extract process, and start the
* HKDF-Expand process.
*
* - `br_hkdf_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
* For correct HKDF processing, the same "info" string must be
* provided for each call.
*
* Note that the HKDF total output size (the number of bytes that
* HKDF-Expand is willing to produce) is limited: if the hash output size
* is _n_ bytes, then the maximum output size is _255*n_.
*
* ## SHAKE
*
* SHAKE is defined in
* [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final)
* under two versions: SHAKE128 and SHAKE256, offering an alleged
* "security level" of 128 and 256 bits, respectively (SHAKE128 is
* about 20 to 25% faster than SHAKE256). SHAKE internally relies on
* the Keccak family of sponge functions, not on any externally provided
* hash function. Contrary to HKDF, SHAKE does not have a concept of
* either a "salt" or an "info" string. The API consists in four
* functions:
*
* - `br_shake_init()`: initialize a SHAKE context for a given
* security level.
*
* - `br_shake_inject()`: inject more input bytes. This function may be
* called repeatedly if the input data is provided by chunks.
*
* - `br_shake_flip()`: end the data injection process, and start the
* data production process.
*
* - `br_shake_produce()`: get the next bytes of output. This function
* may be called several times to obtain the full output by chunks.
*/
/**
* \brief HKDF context.
*
* The HKDF context is initialized with a hash function implementation
* and a salt value. Contents are opaque (callers should not access them
* directly). The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
union {
br_hmac_context hmac_ctx;
br_hmac_key_context prk_ctx;
} u;
unsigned char buf[64];
size_t ptr;
size_t dig_len;
unsigned chunk_num;
#endif
} br_hkdf_context;
/**
* \brief HKDF context initialization.
*
* The underlying hash function and salt value are provided. Arbitrary
* salt lengths can be used.
*
* HKDF makes a difference between a salt of length zero, and an
* absent salt (the latter being equivalent to a salt consisting of
* bytes of value zero, of the same length as the hash function output).
* If `salt_len` is zero, then this function assumes that the salt is
* present but of length zero. To specify an _absent_ salt, use
* `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored).
*
* \param hc HKDF context to initialise.
* \param digest_vtable pointer to the hash function implementation vtable.
* \param salt HKDF-Extract salt.
* \param salt_len HKDF-Extract salt length (in bytes).
*/
void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable,
const void *salt, size_t salt_len);
/**
* \brief The special "absent salt" value for HKDF.
*/
#define BR_HKDF_NO_SALT (&br_hkdf_no_salt)
#ifndef BR_DOXYGEN_IGNORE
extern const unsigned char br_hkdf_no_salt;
#endif
/**
* \brief HKDF input injection (HKDF-Extract).
*
* This function injects some more input bytes ("key material") into
* HKDF. This function may be called several times, after `br_hkdf_init()`
* but before `br_hkdf_flip()`.
*
* \param hc HKDF context.
* \param ikm extra input bytes.
* \param ikm_len number of extra input bytes.
*/
void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len);
/**
* \brief HKDF switch to the HKDF-Expand phase.
*
* This call terminates the HKDF-Extract process (input injection), and
* starts the HKDF-Expand process (output production).
*
* \param hc HKDF context.
*/
void br_hkdf_flip(br_hkdf_context *hc);
/**
* \brief HKDF output production (HKDF-Expand).
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_hkdf_flip()`.
*
* Returned value is the number of actually produced bytes. The total
* output length is limited to 255 times the output length of the
* underlying hash function.
*
* \param hc HKDF context.
* \param info application specific information string.
* \param info_len application specific information string length (in bytes).
* \param out destination buffer for the HKDF output.
* \param out_len the length of the requested output (in bytes).
* \return the produced output length (in bytes).
*/
size_t br_hkdf_produce(br_hkdf_context *hc,
const void *info, size_t info_len, void *out, size_t out_len);
/**
* \brief SHAKE context.
*
* The HKDF context is initialized with a "security level". The internal
* notion is called "capacity"; the capacity is twice the security level
* (for instance, SHAKE128 has capacity 256).
*
* The caller is responsible for allocating the context where
* appropriate. Context initialisation and usage incurs no dynamic
* allocation, so there is no release function.
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
unsigned char dbuf[200];
size_t dptr;
size_t rate;
uint64_t A[25];
#endif
} br_shake_context;
/**
* \brief SHAKE context initialization.
*
* The context is initialized for the provided "security level".
* Internally, this sets the "capacity" to twice the security level;
* thus, for SHAKE128, the `security_level` parameter should be 128,
* which corresponds to a 256-bit capacity.
*
* Allowed security levels are all multiples of 32, from 32 to 768,
* inclusive. Larger security levels imply lower performance; levels
* beyond 256 bits don't make much sense. Standard levels are 128
* and 256 bits (for SHAKE128 and SHAKE256, respectively).
*
* \param sc SHAKE context to initialise.
* \param security_level security level (in bits).
*/
void br_shake_init(br_shake_context *sc, int security_level);
/**
* \brief SHAKE input injection.
*
* This function injects some more input bytes ("key material") into
* SHAKE. This function may be called several times, after `br_shake_init()`
* but before `br_shake_flip()`.
*
* \param sc SHAKE context.
* \param data extra input bytes.
* \param len number of extra input bytes.
*/
void br_shake_inject(br_shake_context *sc, const void *data, size_t len);
/**
* \brief SHAKE switch to production phase.
*
* This call terminates the input injection process, and starts the
* output production process.
*
* \param sc SHAKE context.
*/
void br_shake_flip(br_shake_context *hc);
/**
* \brief SHAKE output production.
*
* Produce more output bytes from the current state. This function may be
* called several times, but only after `br_shake_flip()`.
*
* There is no practical limit to the number of bytes that may be produced.
*
* \param sc SHAKE context.
* \param out destination buffer for the SHAKE output.
* \param len the length of the requested output (in bytes).
*/
void br_shake_produce(br_shake_context *sc, void *out, size_t len);
#ifdef __cplusplus
}
#endif
#endif
+294
View File
@@ -0,0 +1,294 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_PEM_H__
#define BR_BEARSSL_PEM_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_pem.h
*
* # PEM Support
*
* PEM is a traditional encoding layer use to store binary objects (in
* particular X.509 certificates, and private keys) in text files. While
* the acronym comes from an old, defunct standard ("Privacy Enhanced
* Mail"), the format has been reused, with some variations, by many
* systems, and is a _de facto_ standard, even though it is not, actually,
* specified in all clarity anywhere.
*
* ## Format Details
*
* BearSSL contains a generic, streamed PEM decoder, which handles the
* following format:
*
* - The input source (a sequence of bytes) is assumed to be the
* encoding of a text file in an ASCII-compatible charset. This
* includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each
* line ends on a newline character (U+000A LINE FEED). The
* U+000D CARRIAGE RETURN characters are ignored, so the code
* accepts both Windows-style and Unix-style line endings.
*
* - Each object begins with a banner that occurs at the start of
* a line; the first banner characters are "`-----BEGIN `" (five
* dashes, the word "BEGIN", and a space). The banner matching is
* not case-sensitive.
*
* - The _object name_ consists in the characters that follow the
* banner start sequence, up to the end of the line, but without
* trailing dashes (in "normal" PEM, there are five trailing
* dashes, but this implementation is not picky about these dashes).
* The BearSSL decoder normalises the name characters to uppercase
* (for ASCII letters only) and accepts names up to 127 characters.
*
* - The object ends with a banner that again occurs at the start of
* a line, and starts with "`-----END `" (again case-insensitive).
*
* - Between that start and end banner, only Base64 data shall occur.
* Base64 converts each sequence of three bytes into four
* characters; the four characters are ASCII letters, digits, "`+`"
* or "`-`" signs, and one or two "`=`" signs may occur in the last
* quartet. Whitespace is ignored (whitespace is any ASCII character
* of code 32 or less, so control characters are whitespace) and
* lines may have arbitrary length; the only restriction is that the
* four characters of a quartet must appear on the same line (no
* line break inside a quartet).
*
* - A single file may contain more than one PEM object. Bytes that
* occur between objects are ignored.
*
*
* ## PEM Decoder API
*
* The PEM decoder offers a state-machine API. The caller allocates a
* decoder context, then injects source bytes. Source bytes are pushed
* with `br_pem_decoder_push()`. The decoder stops accepting bytes when
* it reaches an "event", which is either the start of an object, the
* end of an object, or a decoding error within an object.
*
* The `br_pem_decoder_event()` function is used to obtain the current
* event; it also clears it, thus allowing the decoder to accept more
* bytes. When a object start event is raised, the decoder context
* offers the found object name (normalised to ASCII uppercase).
*
* When an object is reached, the caller must set an appropriate callback
* function, which will receive (by chunks) the decoded object data.
*
* Since the decoder context makes no dynamic allocation, it requires
* no explicit deallocation.
*/
/**
* \brief PEM decoder context.
*
* Contents are opaque (they should not be accessed directly).
*/
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
/* CPU for the T0 virtual machine. */
struct {
uint32_t *dp;
uint32_t *rp;
const unsigned char *ip;
} cpu;
uint32_t dp_stack[32];
uint32_t rp_stack[32];
int err;
const unsigned char *hbuf;
size_t hlen;
void (*dest)(void *dest_ctx, const void *src, size_t len);
void *dest_ctx;
unsigned char event;
char name[128];
unsigned char buf[255];
size_t ptr;
#endif
} br_pem_decoder_context;
/**
* \brief Initialise a PEM decoder structure.
*
* \param ctx decoder context to initialise.
*/
void br_pem_decoder_init(br_pem_decoder_context *ctx);
/**
* \brief Push some bytes into the decoder.
*
* Returned value is the number of bytes actually consumed; this may be
* less than the number of provided bytes if an event is raised. When an
* event is raised, it must be read (with `br_pem_decoder_event()`);
* until the event is read, this function will return 0.
*
* \param ctx decoder context.
* \param data new data bytes.
* \param len number of new data bytes.
* \return the number of bytes actually received (may be less than `len`).
*/
size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
const void *data, size_t len);
/**
* \brief Set the receiver for decoded data.
*
* When an object is entered, the provided function (with opaque context
* pointer) will be called repeatedly with successive chunks of decoded
* data for that object. If `dest` is set to 0, then decoded data is
* simply ignored. The receiver can be set at any time, but, in practice,
* it should be called immediately after receiving a "start of object"
* event.
*
* \param ctx decoder context.
* \param dest callback for receiving decoded data.
* \param dest_ctx opaque context pointer for the `dest` callback.
*/
static inline void
br_pem_decoder_setdest(br_pem_decoder_context *ctx,
void (*dest)(void *dest_ctx, const void *src, size_t len),
void *dest_ctx)
{
ctx->dest = dest;
ctx->dest_ctx = dest_ctx;
}
/**
* \brief Get the last event.
*
* If an event was raised, then this function returns the event value, and
* also clears it, thereby allowing the decoder to proceed. If no event
* was raised since the last call to `br_pem_decoder_event()`, then this
* function returns 0.
*
* \param ctx decoder context.
* \return the raised event, or 0.
*/
int br_pem_decoder_event(br_pem_decoder_context *ctx);
/**
* \brief Event: start of object.
*
* This event is raised when the start of a new object has been detected.
* The object name (normalised to uppercase) can be accessed with
* `br_pem_decoder_name()`.
*/
#define BR_PEM_BEGIN_OBJ 1
/**
* \brief Event: end of object.
*
* This event is raised when the end of the current object is reached
* (normally, i.e. with no decoding error).
*/
#define BR_PEM_END_OBJ 2
/**
* \brief Event: decoding error.
*
* This event is raised when decoding fails within an object.
* This formally closes the current object and brings the decoder back
* to the "out of any object" state. The offending line in the source
* is consumed.
*/
#define BR_PEM_ERROR 3
/**
* \brief Get the name of the encountered object.
*
* The encountered object name is defined only when the "start of object"
* event is raised. That name is normalised to uppercase (for ASCII letters
* only) and does not include trailing dashes.
*
* \param ctx decoder context.
* \return the current object name.
*/
static inline const char *
br_pem_decoder_name(br_pem_decoder_context *ctx)
{
return ctx->name;
}
/**
* \brief Encode an object in PEM.
*
* This function encodes the provided binary object (`data`, of length `len`
* bytes) into PEM. The `banner` text will be included in the header and
* footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header).
*
* The length (in characters) of the PEM output is returned; that length
* does NOT include the terminating zero, that this function nevertheless
* adds. If using the returned value for allocation purposes, the allocated
* buffer size MUST be at least one byte larger than the returned size.
*
* If `dest` is `NULL`, then the encoding does not happen; however, the
* length of the encoded object is still computed and returned.
*
* The `data` pointer may be `NULL` only if `len` is zero (when encoding
* an object of length zero, which is not very useful), or when `dest`
* is `NULL` (in that case, source data bytes are ignored).
*
* Some `flags` can be specified to alter the encoding behaviour:
*
* - If `BR_PEM_LINE64` is set, then line-breaking will occur after
* every 64 characters of output, instead of the default of 76.
*
* - If `BR_PEM_CRLF` is set, then end-of-line sequence will use
* CR+LF instead of a single LF.
*
* The `data` and `dest` buffers may overlap, in which case the source
* binary data is destroyed in the process. Note that the PEM-encoded output
* is always larger than the source binary.
*
* \param dest the destination buffer (or `NULL`).
* \param data the source buffer (can be `NULL` in some cases).
* \param len the source length (in bytes).
* \param banner the PEM banner expression.
* \param flags the behavioural flags.
* \return the PEM object length (in characters), EXCLUDING the final zero.
*/
size_t br_pem_encode(void *dest, const void *data, size_t len,
const char *banner, unsigned flags);
/**
* \brief PEM encoding flag: split lines at 64 characters.
*/
#define BR_PEM_LINE64 0x0001
/**
* \brief PEM encoding flag: use CR+LF line endings.
*/
#define BR_PEM_CRLF 0x0002
#ifdef __cplusplus
}
#endif
#endif
+150
View File
@@ -0,0 +1,150 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_PRF_H__
#define BR_BEARSSL_PRF_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_prf.h
*
* # The TLS PRF
*
* The "PRF" is the pseudorandom function used internally during the
* SSL/TLS handshake, notably to expand negotiated shared secrets into
* the symmetric encryption keys that will be used to process the
* application data.
*
* TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This
* is implemented by the `br_tls10_prf()` function.
*
* TLS 1.2 redefines the PRF, using an explicit hash function. The
* `br_tls12_sha256_prf()` and `br_tls12_sha384_prf()` functions apply that
* PRF with, respectively, SHA-256 and SHA-384. Most standard cipher suites
* rely on the SHA-256 based PRF, but some use SHA-384.
*
* The PRF always uses as input three parameters: a "secret" (some
* bytes), a "label" (ASCII string), and a "seed" (again some bytes). An
* arbitrary output length can be produced. The "seed" is provided as an
* arbitrary number of binary chunks, that gets internally concatenated.
*/
/**
* \brief Type for a seed chunk.
*
* Each chunk may have an arbitrary length, and may be empty (no byte at
* all). If the chunk length is zero, then the pointer to the chunk data
* may be `NULL`.
*/
typedef struct {
/**
* \brief Pointer to the chunk data.
*/
const void *data;
/**
* \brief Chunk length (in bytes).
*/
size_t len;
} br_tls_prf_seed_chunk;
/**
* \brief PRF implementation for TLS 1.0 and 1.1.
*
* This PRF is the one specified by TLS 1.0 and 1.1. It internally uses
* MD5 and SHA-1.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls10_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* \brief PRF implementation for TLS 1.2, with SHA-256.
*
* This PRF is the one specified by TLS 1.2, when the underlying hash
* function is SHA-256.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls12_sha256_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* \brief PRF implementation for TLS 1.2, with SHA-384.
*
* This PRF is the one specified by TLS 1.2, when the underlying hash
* function is SHA-384.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
void br_tls12_sha384_prf(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
/**
* brief A convenient type name for a PRF implementation.
*
* \param dst destination buffer.
* \param len output length (in bytes).
* \param secret secret value (key) for this computation.
* \param secret_len length of "secret" (in bytes).
* \param label PRF label (zero-terminated ASCII string).
* \param seed_num number of seed chunks.
* \param seed seed chnks for this computation (usually non-secret).
*/
typedef void (*br_tls_prf_impl)(void *dst, size_t len,
const void *secret, size_t secret_len, const char *label,
size_t seed_num, const br_tls_prf_seed_chunk *seed);
#ifdef __cplusplus
}
#endif
#endif
+397
View File
@@ -0,0 +1,397 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BR_BEARSSL_RAND_H__
#define BR_BEARSSL_RAND_H__
#include <stddef.h>
#include <stdint.h>
#include "bearssl_block.h"
#include "bearssl_hash.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \file bearssl_rand.h
*
* # Pseudo-Random Generators
*
* A PRNG is a state-based engine that outputs pseudo-random bytes on
* demand. It is initialized with an initial seed, and additional seed
* bytes can be added afterwards. Bytes produced depend on the seeds and
* also on the exact sequence of calls (including sizes requested for
* each call).
*
*
* ## Procedural and OOP API
*
* For the PRNG of name "`xxx`", two API are provided. The _procedural_
* API defined a context structure `br_xxx_context` and three functions:
*
* - `br_xxx_init()`
*
* Initialise the context with an initial seed.
*
* - `br_xxx_generate()`
*
* Produce some pseudo-random bytes.
*
* - `br_xxx_update()`
*
* Inject some additional seed.
*
* The initialisation function sets the first context field (`vtable`)
* to a pointer to the vtable that supports the OOP API. The OOP API
* provides access to the same functions through function pointers,
* named `init()`, `generate()` and `update()`.
*
* Note that the context initialisation method may accept additional
* parameters, provided as a 'const void *' pointer at API level. These
* additional parameters depend on the implemented PRNG.
*
*
* ## HMAC_DRBG
*
* HMAC_DRBG is defined in [NIST SP 800-90A Revision
* 1](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf).
* It uses HMAC repeatedly, over some configurable underlying hash
* function. In BearSSL, it is implemented under the "`hmac_drbg`" name.
* The "extra parameters" pointer for context initialisation should be
* set to a pointer to the vtable for the underlying hash function (e.g.
* pointer to `br_sha256_vtable` to use HMAC_DRBG with SHA-256).
*
* According to the NIST standard, each request shall produce up to
* 2<sup>19</sup> bits (i.e. 64 kB of data); moreover, the context shall
* be reseeded at least once every 2<sup>48</sup> requests. This
* implementation does not maintain the reseed counter (the threshold is
* too high to be reached in practice) and does not object to producing
* more than 64 kB in a single request; thus, the code cannot fail,
* which corresponds to the fact that the API has no room for error
* codes. However, this implies that requesting more than 64 kB in one
* `generate()` request, or making more than 2<sup>48</sup> requests
* without reseeding, is formally out of NIST specification. There is
* no currently known security penalty for exceeding the NIST limits,
* and, in any case, HMAC_DRBG usage in implementing SSL/TLS always
* stays much below these thresholds.
*
*
* ## AESCTR_DRBG
*
* AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is
* meant to be used only in situations where you are desperate for
* speed, and have an hardware-optimized AES/CTR implementation. Whether
* this will yield perceptible improvements depends on what you use the
* pseudorandom bytes for, and how many you want; for instance, RSA key
* pair generation uses a substantial amount of randomness, and using
* AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key
* generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz).
*
* Internally, it uses CTR mode with successive counter values, starting
* at zero (counter value expressed over 128 bits, big-endian convention).
* The counter is not allowed to reach 32768; thus, every 32768*16 bytes
* at most, the `update()` function is run (on an empty seed, if none is
* provided). The `update()` function computes the new AES-128 key by
* applying a custom hash function to the concatenation of a state-dependent
* word (encryption of an all-one block with the current key) and the new
* seed. The custom hash function uses Hirose's construction over AES-256;
* see the comments in `aesctr_drbg.c` for details.
*
* This DRBG does not follow an existing standard, and thus should be
* considered as inadequate for production use until it has been properly
* analysed.
*/
/**
* \brief Class type for PRNG implementations.
*
* A `br_prng_class` instance references the methods implementing a PRNG.
* Constant instances of this structure are defined for each implemented
* PRNG. Such instances are also called "vtables".
*/
typedef struct br_prng_class_ br_prng_class;
struct br_prng_class_ {
/**
* \brief Size (in bytes) of the context structure appropriate for
* running this PRNG.
*/
size_t context_size;
/**
* \brief Initialisation method.
*
* The context to initialise is provided as a pointer to its
* first field (the vtable pointer); this function sets that
* first field to a pointer to the vtable.
*
* The extra parameters depend on the implementation; each
* implementation defines what kind of extra parameters it
* expects (if any).
*
* Requirements on the initial seed depend on the implemented
* PRNG.
*
* \param ctx PRNG context to initialise.
* \param params extra parameters for the PRNG.
* \param seed initial seed.
* \param seed_len initial seed length (in bytes).
*/
void (*init)(const br_prng_class **ctx, const void *params,
const void *seed, size_t seed_len);
/**
* \brief Random bytes generation.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly.
*
* \param ctx PRNG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void (*generate)(const br_prng_class **ctx, void *out, size_t len);
/**
* \brief Inject additional seed bytes.
*
* The provided seed bytes are added into the PRNG internal
* entropy pool.
*
* \param ctx PRNG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void (*update)(const br_prng_class **ctx,
const void *seed, size_t seed_len);
};
/**
* \brief Context for HMAC_DRBG.
*
* The context contents are opaque, except the first field, which
* supports OOP.
*/
typedef struct {
/**
* \brief Pointer to the vtable.
*
* This field is set with the initialisation method/function.
*/
const br_prng_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
unsigned char K[64];
unsigned char V[64];
const br_hash_class *digest_class;
#endif
} br_hmac_drbg_context;
/**
* \brief Statically allocated, constant vtable for HMAC_DRBG.
*/
extern const br_prng_class br_hmac_drbg_vtable;
/**
* \brief HMAC_DRBG initialisation.
*
* The context to initialise is provided as a pointer to its first field
* (the vtable pointer); this function sets that first field to a
* pointer to the vtable.
*
* The `seed` value is what is called, in NIST terminology, the
* concatenation of the "seed", "nonce" and "personalization string", in
* that order.
*
* The `digest_class` parameter defines the underlying hash function.
* Formally, the NIST standard specifies that the hash function shall
* be only SHA-1 or one of the SHA-2 functions. This implementation also
* works with any other implemented hash function (such as MD5), but
* this is non-standard and therefore not recommended.
*
* \param ctx HMAC_DRBG context to initialise.
* \param digest_class vtable for the underlying hash function.
* \param seed initial seed.
* \param seed_len initial seed length (in bytes).
*/
void br_hmac_drbg_init(br_hmac_drbg_context *ctx,
const br_hash_class *digest_class, const void *seed, size_t seed_len);
/**
* \brief Random bytes generation with HMAC_DRBG.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly. Formally, requesting
* more than 65536 bytes in one request falls out of specification
* limits (but it won't fail).
*
* \param ctx HMAC_DRBG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len);
/**
* \brief Inject additional seed bytes in HMAC_DRBG.
*
* The provided seed bytes are added into the HMAC_DRBG internal
* entropy pool. The process does not _replace_ existing entropy,
* thus pushing non-random bytes (i.e. bytes which are known to the
* attackers) does not degrade the overall quality of generated bytes.
*
* \param ctx HMAC_DRBG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void br_hmac_drbg_update(br_hmac_drbg_context *ctx,
const void *seed, size_t seed_len);
/**
* \brief Get the hash function implementation used by a given instance of
* HMAC_DRBG.
*
* This calls MUST NOT be performed on a context which was not
* previously initialised.
*
* \param ctx HMAC_DRBG context.
* \return the hash function vtable.
*/
static inline const br_hash_class *
br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx)
{
return ctx->digest_class;
}
/**
* \brief Type for a provider of entropy seeds.
*
* A "seeder" is a function that is able to obtain random values from
* some source and inject them as entropy seed in a PRNG. A seeder
* shall guarantee that the total entropy of the injected seed is large
* enough to seed a PRNG for purposes of cryptographic key generation
* (i.e. at least 128 bits).
*
* A seeder may report a failure to obtain adequate entropy. Seeders
* shall endeavour to fix themselves transient errors by trying again;
* thus, callers may consider reported errors as permanent.
*
* \param ctx PRNG context to seed.
* \return 1 on success, 0 on error.
*/
typedef int (*br_prng_seeder)(const br_prng_class **ctx);
/**
* \brief Get a seeder backed by the operating system or hardware.
*
* Get a seeder that feeds on RNG facilities provided by the current
* operating system or hardware. If no such facility is known, then 0
* is returned.
*
* If `name` is not `NULL`, then `*name` is set to a symbolic string
* that identifies the seeder implementation. If no seeder is returned
* and `name` is not `NULL`, then `*name` is set to a pointer to the
* constant string `"none"`.
*
* \param name receiver for seeder name, or `NULL`.
* \return the system seeder, if available, or 0.
*/
br_prng_seeder br_prng_seeder_system(const char **name);
/**
* \brief Context for AESCTR_DRBG.
*
* The context contents are opaque, except the first field, which
* supports OOP.
*/
typedef struct {
/**
* \brief Pointer to the vtable.
*
* This field is set with the initialisation method/function.
*/
const br_prng_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
br_aes_gen_ctr_keys sk;
uint32_t cc;
#endif
} br_aesctr_drbg_context;
/**
* \brief Statically allocated, constant vtable for AESCTR_DRBG.
*/
extern const br_prng_class br_aesctr_drbg_vtable;
/**
* \brief AESCTR_DRBG initialisation.
*
* The context to initialise is provided as a pointer to its first field
* (the vtable pointer); this function sets that first field to a
* pointer to the vtable.
*
* The internal AES key is first set to the all-zero key; then, the
* `br_aesctr_drbg_update()` function is called with the provided `seed`.
* The call is performed even if the seed length (`seed_len`) is zero.
*
* The `aesctr` parameter defines the underlying AES/CTR implementation.
*
* \param ctx AESCTR_DRBG context to initialise.
* \param aesctr vtable for the AES/CTR implementation.
* \param seed initial seed (can be `NULL` if `seed_len` is zero).
* \param seed_len initial seed length (in bytes).
*/
void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx,
const br_block_ctr_class *aesctr, const void *seed, size_t seed_len);
/**
* \brief Random bytes generation with AESCTR_DRBG.
*
* This method produces `len` pseudorandom bytes, in the `out`
* buffer. The context is updated accordingly.
*
* \param ctx AESCTR_DRBG context.
* \param out output buffer.
* \param len number of pseudorandom bytes to produce.
*/
void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx,
void *out, size_t len);
/**
* \brief Inject additional seed bytes in AESCTR_DRBG.
*
* The provided seed bytes are added into the AESCTR_DRBG internal
* entropy pool. The process does not _replace_ existing entropy,
* thus pushing non-random bytes (i.e. bytes which are known to the
* attackers) does not degrade the overall quality of generated bytes.
*
* \param ctx AESCTR_DRBG context.
* \param seed additional seed.
* \param seed_len additional seed length (in bytes).
*/
void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx,
const void *seed, size_t seed_len);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+486
View File
@@ -0,0 +1,486 @@
// <bit> -*- C++ -*-
// Copyright (C) 2018-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bit
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_BIT
#define _GLIBCXX_BIT 1
#pragma GCC system_header
#if __cplusplus >= 201402L
#include <concepts> // for std::integral
#include <type_traits>
#if _GLIBCXX_HOSTED || __has_include(<ext/numeric_traits.h>)
# include <ext/numeric_traits.h>
#else
# include <limits>
/// @cond undocumented
namespace __gnu_cxx
{
template<typename _Tp>
struct __int_traits
{
static constexpr int __digits = std::numeric_limits<_Tp>::digits;
static constexpr _Tp __max = std::numeric_limits<_Tp>::max();
};
}
/// @endcond
#endif
#define __glibcxx_want_bit_cast
#define __glibcxx_want_byteswap
#define __glibcxx_want_bitops
#define __glibcxx_want_int_pow2
#define __glibcxx_want_endian
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup bit_manip Bit manipulation
* @ingroup numerics
*
* Utilities for examining and manipulating individual bits.
*
* @{
*/
#ifdef __cpp_lib_bit_cast // C++ >= 20
/// Create a value of type `To` from the bits of `from`.
/**
* @tparam _To A trivially-copyable type.
* @param __from A trivially-copyable object of the same size as `_To`.
* @return An object of type `_To`.
* @since C++20
*/
template<typename _To, typename _From>
[[nodiscard]]
constexpr _To
bit_cast(const _From& __from) noexcept
#ifdef __cpp_concepts
requires (sizeof(_To) == sizeof(_From))
&& is_trivially_copyable_v<_To> && is_trivially_copyable_v<_From>
#endif
{
return __builtin_bit_cast(_To, __from);
}
#endif // __cpp_lib_bit_cast
#ifdef __cpp_lib_byteswap // C++ >= 23
/// Reverse order of bytes in the object representation of `value`.
/**
* @tparam _Tp An integral type.
* @param __value An object of integer type.
* @return An object of the same type, with the bytes reversed.
* @since C++23
*/
template<integral _Tp>
[[nodiscard]]
constexpr _Tp
byteswap(_Tp __value) noexcept
{
if constexpr (sizeof(_Tp) == 1)
return __value;
#if __cpp_if_consteval >= 202106L && __CHAR_BIT__ == 8
if !consteval
{
if constexpr (sizeof(_Tp) == 2)
return __builtin_bswap16(__value);
if constexpr (sizeof(_Tp) == 4)
return __builtin_bswap32(__value);
if constexpr (sizeof(_Tp) == 8)
return __builtin_bswap64(__value);
if constexpr (sizeof(_Tp) == 16)
#if __has_builtin(__builtin_bswap128)
return __builtin_bswap128(__value);
#else
return (__builtin_bswap64(__value >> 64)
| (static_cast<_Tp>(__builtin_bswap64(__value)) << 64));
#endif
}
#endif
// Fallback implementation that handles even __int24 etc.
using _Up = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
size_t __diff = __CHAR_BIT__ * (sizeof(_Tp) - 1);
_Up __mask1 = static_cast<unsigned char>(~0);
_Up __mask2 = __mask1 << __diff;
_Up __val = __value;
for (size_t __i = 0; __i < sizeof(_Tp) / 2; ++__i)
{
_Up __byte1 = __val & __mask1;
_Up __byte2 = __val & __mask2;
__val = (__val ^ __byte1 ^ __byte2
^ (__byte1 << __diff) ^ (__byte2 >> __diff));
__mask1 <<= __CHAR_BIT__;
__mask2 >>= __CHAR_BIT__;
__diff -= 2 * __CHAR_BIT__;
}
return __val;
}
#endif // __cpp_lib_byteswap
/// @cond undocumented
template<typename _Tp>
constexpr _Tp
__rotl(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
{
// Variant for power of two _Nd which the compiler can
// easily pattern match.
constexpr unsigned __uNd = _Nd;
const unsigned __r = __s;
return (__x << (__r % __uNd)) | (__x >> ((-__r) % __uNd));
}
const int __r = __s % _Nd;
if (__r == 0)
return __x;
else if (__r > 0)
return (__x << __r) | (__x >> ((_Nd - __r) % _Nd));
else
return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r)
}
template<typename _Tp>
constexpr _Tp
__rotr(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
{
// Variant for power of two _Nd which the compiler can
// easily pattern match.
constexpr unsigned __uNd = _Nd;
const unsigned __r = __s;
return (__x >> (__r % __uNd)) | (__x << ((-__r) % __uNd));
}
const int __r = __s % _Nd;
if (__r == 0)
return __x;
else if (__r > 0)
return (__x >> __r) | (__x << ((_Nd - __r) % _Nd));
else
return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r)
}
template<typename _Tp>
constexpr int
__countl_zero(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0)
return _Nd;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
{
constexpr int __diff = _Nd_u - _Nd;
return __builtin_clz(__x) - __diff;
}
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
{
constexpr int __diff = _Nd_ul - _Nd;
return __builtin_clzl(__x) - __diff;
}
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
{
constexpr int __diff = _Nd_ull - _Nd;
return __builtin_clzll(__x) - __diff;
}
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
unsigned long long __high = __x >> _Nd_ull;
if (__high != 0)
{
constexpr int __diff = (2 * _Nd_ull) - _Nd;
return __builtin_clzll(__high) - __diff;
}
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
return (_Nd - _Nd_ull) + __builtin_clzll(__low);
}
}
template<typename _Tp>
constexpr int
__countl_one(_Tp __x) noexcept
{
return std::__countl_zero<_Tp>((_Tp)~__x);
}
template<typename _Tp>
constexpr int
__countr_zero(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0)
return _Nd;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
return __builtin_ctz(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
return __builtin_ctzl(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
return __builtin_ctzll(__x);
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
if (__low != 0)
return __builtin_ctzll(__low);
unsigned long long __high = __x >> _Nd_ull;
return __builtin_ctzll(__high) + _Nd_ull;
}
}
template<typename _Tp>
constexpr int
__countr_one(_Tp __x) noexcept
{
return std::__countr_zero((_Tp)~__x);
}
template<typename _Tp>
constexpr int
__popcount(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
return __builtin_popcount(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
return __builtin_popcountl(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
return __builtin_popcountll(__x);
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
unsigned long long __high = __x >> _Nd_ull;
return __builtin_popcountll(__low) + __builtin_popcountll(__high);
}
}
template<typename _Tp>
constexpr bool
__has_single_bit(_Tp __x) noexcept
{ return std::__popcount(__x) == 1; }
template<typename _Tp>
constexpr _Tp
__bit_ceil(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0 || __x == 1)
return 1;
auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
// If the shift exponent equals _Nd then the correct result is not
// representable as a value of _Tp, and so the result is undefined.
// Want that undefined behaviour to be detected in constant expressions,
// by UBSan, and by debug assertions.
if (!std::__is_constant_evaluated())
{
__glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
}
using __promoted_type = decltype(__x << 1);
if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
{
// If __x undergoes integral promotion then shifting by _Nd is
// not undefined. In order to make the shift undefined, so that
// it is diagnosed in constant expressions and by UBsan, we also
// need to "promote" the shift exponent to be too large for the
// promoted type.
const int __extra_exp = sizeof(__promoted_type) / sizeof(_Tp) / 2;
__shift_exponent |= (__shift_exponent & _Nd) << __extra_exp;
}
return (_Tp)1u << __shift_exponent;
}
template<typename _Tp>
constexpr _Tp
__bit_floor(_Tp __x) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
if (__x == 0)
return 0;
return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1)));
}
template<typename _Tp>
constexpr int
__bit_width(_Tp __x) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
return _Nd - std::__countl_zero(__x);
}
/// @endcond
#ifdef __cpp_lib_bitops // C++ >= 20
/// @cond undocumented
template<typename _Tp>
concept __unsigned_integer = __is_unsigned_integer<_Tp>::value;
/// @endcond
// [bit.rot], rotating
/// Rotate `x` to the left by `s` bits.
template<__unsigned_integer _Tp>
[[nodiscard]] constexpr _Tp
rotl(_Tp __x, int __s) noexcept
{ return std::__rotl(__x, __s); }
/// Rotate `x` to the right by `s` bits.
template<__unsigned_integer _Tp>
[[nodiscard]] constexpr _Tp
rotr(_Tp __x, int __s) noexcept
{ return std::__rotr(__x, __s); }
// [bit.count], counting
/// The number of contiguous zero bits, starting from the highest bit.
template<__unsigned_integer _Tp>
constexpr int
countl_zero(_Tp __x) noexcept
{ return std::__countl_zero(__x); }
/// The number of contiguous one bits, starting from the highest bit.
template<__unsigned_integer _Tp>
constexpr int
countl_one(_Tp __x) noexcept
{ return std::__countl_one(__x); }
/// The number of contiguous zero bits, starting from the lowest bit.
template<__unsigned_integer _Tp>
constexpr int
countr_zero(_Tp __x) noexcept
{ return std::__countr_zero(__x); }
/// The number of contiguous one bits, starting from the lowest bit.
template<__unsigned_integer _Tp>
constexpr int
countr_one(_Tp __x) noexcept
{ return std::__countr_one(__x); }
/// The number of bits set in `x`.
template<__unsigned_integer _Tp>
constexpr int
popcount(_Tp __x) noexcept
{ return std::__popcount(__x); }
#endif // __cpp_lib_bitops
#ifdef __cpp_lib_int_pow2 // C++ >= 20
// [bit.pow.two], integral powers of 2
/// True if `x` is a power of two, false otherwise.
template<__unsigned_integer _Tp>
constexpr bool
has_single_bit(_Tp __x) noexcept
{ return std::__has_single_bit(__x); }
/// The smallest power-of-two not less than `x`.
template<__unsigned_integer _Tp>
constexpr _Tp
bit_ceil(_Tp __x) noexcept
{ return std::__bit_ceil(__x); }
/// The largest power-of-two not greater than `x`.
template<__unsigned_integer _Tp>
constexpr _Tp
bit_floor(_Tp __x) noexcept
{ return std::__bit_floor(__x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3656. Inconsistent bit operations returning a count
/// The smallest integer greater than the base-2 logarithm of `x`.
template<__unsigned_integer _Tp>
constexpr int
bit_width(_Tp __x) noexcept
{ return std::__bit_width(__x); }
#endif // defined (__cpp_lib_int_pow2)
#ifdef __cpp_lib_endian // C++ >= 20
/// Byte order constants
/**
* The platform endianness can be checked by comparing `std::endian::native`
* to one of `std::endian::big` or `std::endian::little`.
*
* @since C++20
*/
enum class endian
{
little = __ORDER_LITTLE_ENDIAN__,
big = __ORDER_BIG_ENDIAN__,
native = __BYTE_ORDER__
};
#endif // __cpp_lib_endian
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++14
#endif // _GLIBCXX_BIT
@@ -0,0 +1,970 @@
// <algorithm> Forward declarations -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/algorithmfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
all_of (C++11)
any_of (C++11)
binary_search
clamp (C++17)
copy
copy_backward
copy_if (C++11)
copy_n (C++11)
count
count_if
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
find_if_not (C++11)
for_each
generate
generate_n
includes
inplace_merge
is_heap (C++11)
is_heap_until (C++11)
is_partitioned (C++11)
is_sorted (C++11)
is_sorted_until (C++11)
iter_swap
lexicographical_compare
lower_bound
make_heap
max
max_element
merge
min
min_element
minmax (C++11)
minmax_element (C++11)
mismatch
next_permutation
none_of (C++11)
nth_element
partial_sort
partial_sort_copy
partition
partition_copy (C++11)
partition_point (C++11)
pop_heap
prev_permutation
push_heap
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
shuffle (C++11)
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
unique
unique_copy
upper_bound
*/
/**
* @defgroup algorithms Algorithms
*
* Components for performing algorithmic operations. Includes
* non-modifying sequence, modifying (mutating) sequence, sorting,
* searching, merge, partition, heap, set, minima, maxima, and
* permutation operations.
*/
/**
* @defgroup mutating_algorithms Mutating
* @ingroup algorithms
*/
/**
* @defgroup non_mutating_algorithms Non-Mutating
* @ingroup algorithms
*/
/**
* @defgroup sorting_algorithms Sorting
* @ingroup algorithms
*/
/**
* @defgroup set_algorithms Set Operations
* @ingroup sorting_algorithms
*
* These algorithms are common set operations performed on sequences
* that are already sorted. The number of comparisons will be
* linear.
*/
/**
* @defgroup binary_search_algorithms Binary Search
* @ingroup sorting_algorithms
*
* These algorithms are variations of a classic binary search, and
* all assume that the sequence being searched is already sorted.
*
* The number of comparisons will be logarithmic (and as few as
* possible). The number of steps through the sequence will be
* logarithmic for random-access iterators (e.g., pointers), and
* linear otherwise.
*
* The LWG has passed Defect Report 270, which notes: <em>The
* proposed resolution reinterprets binary search. Instead of
* thinking about searching for a value in a sorted range, we view
* that as an important special case of a more general algorithm:
* searching for the partition point in a partitioned range. We
* also add a guarantee that the old wording did not: we ensure that
* the upper bound is no earlier than the lower bound, that the pair
* returned by equal_range is a valid range, and that the first part
* of that pair is the lower bound.</em>
*
* The actual effect of the first sentence is that a comparison
* functor passed by the user doesn't necessarily need to induce a
* strict weak ordering relation. Rather, it partitions the range.
*/
// adjacent_find
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
any_of(_IIter, _IIter, _Predicate);
#endif
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
#if __cplusplus > 201402L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
#endif
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
_GLIBCXX20_CONSTEXPR
_BIter2
copy_backward(_BIter1, _BIter1, _BIter2);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy_n(_IIter, _Size, _OIter);
#endif
// count
// count_if
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
fill_n(_OIter, _Size, const _Tp&);
// find
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
// find_first_of
// find_if
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
// for_each
// generate
// generate_n
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _BIter>
void
inplace_merge(_BIter, _BIter, _BIter);
template<typename _BIter, typename _Compare>
void
inplace_merge(_BIter, _BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&, _Compare);
// max_element
// merge
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&, _Compare);
// min_element
#if __cplusplus >= 201103L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>, _Compare);
#endif
// mismatch
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
none_of(_IIter, _IIter, _Predicate);
#endif
// nth_element
// partial_sort
template<typename _IIter, typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
// partition
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
_GLIBCXX20_CONSTEXPR
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
reverse_copy(_BIter, _BIter, _OIter);
_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
rotate(_FIter, _FIter, _FIter);
_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
template<typename _FIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
// search
// search_n
// set_difference
// set_intersection
// set_symmetric_difference
// set_union
#if __cplusplus >= 201103L
template<typename _RAIter, typename _UGenerator>
void
shuffle(_RAIter, _RAIter, _UGenerator&&);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter, _Compare);
#if _GLIBCXX_HOSTED
template<typename _BIter, typename _Predicate>
_BIter
stable_partition(_BIter, _BIter, _Predicate);
#endif
#if __cplusplus < 201103L
// For C++11 swap() is declared in <type_traits>.
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp& __a, _Tp& __b);
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
_GLIBCXX20_CONSTEXPR
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
_GLIBCXX20_CONSTEXPR
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
_GLIBCXX20_CONSTEXPR
_OIter
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_BIter
partition(_BIter, _BIter, _Predicate);
#if _GLIBCXX_HOSTED
template<typename _RAIter>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename _Generator>
_GLIBCXX14_DEPRECATED_SUGGEST("std::shuffle")
void
random_shuffle(_RAIter, _RAIter,
#if __cplusplus >= 201103L
_Generator&&);
#else
_Generator&);
#endif
#endif // HOSTED
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
void
stable_sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
_GLIBCXX_END_NAMESPACE_ALGO
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithmfwd.h>
#endif
#endif
+109
View File
@@ -0,0 +1,109 @@
// align implementation -*- C++ -*-
// Copyright (C) 2014-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/align.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_ALIGN_H
#define _GLIBCXX_ALIGN_H 1
#include <bit> // std::has_single_bit
#include <stdint.h> // uintptr_t
#include <debug/assertions.h> // _GLIBCXX_DEBUG_ASSERT
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Fit aligned storage in buffer.
*
* This function tries to fit @a __size bytes of storage with alignment
* @a __align into the buffer @a __ptr of size @a __space bytes. If such
* a buffer fits then @a __ptr is changed to point to the first byte of the
* aligned storage and @a __space is reduced by the bytes used for alignment.
*
* C++11 20.6.5 [ptr.align]
*
* @param __align A fundamental or extended alignment value.
* @param __size Size of the aligned storage required.
* @param __ptr Pointer to a buffer of @a __space bytes.
* @param __space Size of the buffer pointed to by @a __ptr.
* @return the updated pointer if the aligned storage fits, otherwise nullptr.
*
* @ingroup memory
*/
inline void*
align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
{
if (__space < __size)
return nullptr;
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
const auto __aligned = (__intptr - 1u + __align) & -__align;
const auto __diff = __aligned - __intptr;
if (__diff > (__space - __size))
return nullptr;
else
{
__space -= __diff;
return __ptr = reinterpret_cast<void*>(__aligned);
}
}
#ifdef __glibcxx_assume_aligned // C++ >= 20
/** @brief Inform the compiler that a pointer is aligned.
*
* @tparam _Align An alignment value (i.e. a power of two)
* @tparam _Tp An object type
* @param __ptr A pointer that is aligned to _Align
*
* C++20 20.10.6 [ptr.align]
*
* @ingroup memory
*/
template<size_t _Align, class _Tp>
[[nodiscard,__gnu__::__always_inline__]]
constexpr _Tp*
assume_aligned(_Tp* __ptr) noexcept
{
static_assert(std::has_single_bit(_Align));
if (std::is_constant_evaluated())
return __ptr;
else
{
// This function is expected to be used in hot code, where
// __glibcxx_assert would add unwanted overhead.
_GLIBCXX_DEBUG_ASSERT((uintptr_t)__ptr % _Align == 0);
return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
}
}
#endif // __glibcxx_assume_aligned
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GLIBCXX_ALIGN_H */
@@ -0,0 +1,951 @@
// Allocator traits -*- C++ -*-
// Copyright (C) 2011-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/alloc_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOC_TRAITS_H
#define _ALLOC_TRAITS_H 1
#include <bits/stl_construct.h>
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
# include <bits/ptr_traits.h>
# include <ext/numeric_traits.h>
# if _GLIBCXX_HOSTED
# include <bits/allocator.h>
# endif
# if __cpp_exceptions
# include <bits/stl_iterator.h> // __make_move_if_noexcept_iterator
# endif
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
/// @cond undocumented
struct __allocator_traits_base
{
template<typename _Tp, typename _Up, typename = void>
struct __rebind : __replace_first_arg<_Tp, _Up>
{
static_assert(is_same<
typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
_Tp>::value,
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
};
template<typename _Tp, typename _Up>
struct __rebind<_Tp, _Up,
__void_t<typename _Tp::template rebind<_Up>::other>>
{
using type = typename _Tp::template rebind<_Up>::other;
static_assert(is_same<
typename _Tp::template rebind<typename _Tp::value_type>::other,
_Tp>::value,
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
};
protected:
template<typename _Tp>
using __pointer = typename _Tp::pointer;
template<typename _Tp>
using __c_pointer = typename _Tp::const_pointer;
template<typename _Tp>
using __v_pointer = typename _Tp::void_pointer;
template<typename _Tp>
using __cv_pointer = typename _Tp::const_void_pointer;
template<typename _Tp>
using __pocca = typename _Tp::propagate_on_container_copy_assignment;
template<typename _Tp>
using __pocma = typename _Tp::propagate_on_container_move_assignment;
template<typename _Tp>
using __pocs = typename _Tp::propagate_on_container_swap;
template<typename _Tp>
using __equal = __type_identity<typename _Tp::is_always_equal>;
};
template<typename _Alloc, typename _Up>
using __alloc_rebind
= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
/// @endcond
/**
* @brief Uniform interface to all allocator types.
* @headerfile memory
* @ingroup allocators
* @since C++11
*/
template<typename _Alloc>
struct allocator_traits : __allocator_traits_base
{
/// The allocator type
typedef _Alloc allocator_type;
/// The allocated type
typedef typename _Alloc::value_type value_type;
/**
* @brief The allocator's pointer type.
*
* @c Alloc::pointer if that type exists, otherwise @c value_type*
*/
using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
private:
// Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
template<template<typename> class _Func, typename _Tp, typename = void>
struct _Ptr
{
using type = typename pointer_traits<pointer>::template rebind<_Tp>;
};
template<template<typename> class _Func, typename _Tp>
struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
{
using type = _Func<_Alloc>;
};
// Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
template<typename _A2, typename _PtrT, typename = void>
struct _Diff
{ using type = typename pointer_traits<_PtrT>::difference_type; };
template<typename _A2, typename _PtrT>
struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
{ using type = typename _A2::difference_type; };
// Select _A2::size_type or make_unsigned<_DiffT>::type
template<typename _A2, typename _DiffT, typename = void>
struct _Size : make_unsigned<_DiffT> { };
template<typename _A2, typename _DiffT>
struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
{ using type = typename _A2::size_type; };
public:
/**
* @brief The allocator's const pointer type.
*
* @c Alloc::const_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
*/
using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
/**
* @brief The allocator's void pointer type.
*
* @c Alloc::void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<void> </tt>
*/
using void_pointer = typename _Ptr<__v_pointer, void>::type;
/**
* @brief The allocator's const void pointer type.
*
* @c Alloc::const_void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
*/
using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
/**
* @brief The allocator's difference type
*
* @c Alloc::difference_type if that type exists, otherwise
* <tt> pointer_traits<pointer>::difference_type </tt>
*/
using difference_type = typename _Diff<_Alloc, pointer>::type;
/**
* @brief The allocator's size type
*
* @c Alloc::size_type if that type exists, otherwise
* <tt> make_unsigned<difference_type>::type </tt>
*/
using size_type = typename _Size<_Alloc, difference_type>::type;
/**
* @brief How the allocator is propagated on copy assignment
*
* @c Alloc::propagate_on_container_copy_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_copy_assignment
= __detected_or_t<false_type, __pocca, _Alloc>;
/**
* @brief How the allocator is propagated on move assignment
*
* @c Alloc::propagate_on_container_move_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_move_assignment
= __detected_or_t<false_type, __pocma, _Alloc>;
/**
* @brief How the allocator is propagated on swap
*
* @c Alloc::propagate_on_container_swap if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_swap
= __detected_or_t<false_type, __pocs, _Alloc>;
/**
* @brief Whether all instances of the allocator type compare equal.
*
* @c Alloc::is_always_equal if that type exists,
* otherwise @c is_empty<Alloc>::type
*/
using is_always_equal
= typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
template<typename _Tp>
using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
template<typename _Tp>
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
private:
template<typename _Alloc2>
static constexpr auto
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
-> decltype(__a.allocate(__n, __hint))
{ return __a.allocate(__n, __hint); }
template<typename _Alloc2>
static constexpr pointer
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
{ return __a.allocate(__n); }
template<typename _Tp, typename... _Args>
struct __construct_helper
{
template<typename _Alloc2,
typename = decltype(std::declval<_Alloc2*>()->construct(
std::declval<_Tp*>(), std::declval<_Args>()...))>
static true_type __test(int);
template<typename>
static false_type __test(...);
using type = decltype(__test<_Alloc>(0));
};
template<typename _Tp, typename... _Args>
using __has_construct
= typename __construct_helper<_Tp, _Args...>::type;
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
{ __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR
_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>>
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Tp, _Args...>::value)
{
#if __cplusplus <= 201703L
::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR auto
_S_destroy(_Alloc2& __a, _Tp* __p, int)
noexcept(noexcept(__a.destroy(__p)))
-> decltype(__a.destroy(__p))
{ __a.destroy(__p); }
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR void
_S_destroy(_Alloc2&, _Tp* __p, ...)
noexcept(std::is_nothrow_destructible<_Tp>::value)
{ std::_Destroy(__p); }
template<typename _Alloc2>
static constexpr auto
_S_max_size(_Alloc2& __a, int)
-> decltype(__a.max_size())
{ return __a.max_size(); }
template<typename _Alloc2>
static constexpr size_type
_S_max_size(_Alloc2&, ...)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2466. allocator_traits::max_size() default behavior is incorrect
return __gnu_cxx::__numeric_traits<size_type>::__max
/ sizeof(value_type);
}
template<typename _Alloc2>
static constexpr auto
_S_select(_Alloc2& __a, int)
-> decltype(__a.select_on_container_copy_construction())
{ return __a.select_on_container_copy_construction(); }
template<typename _Alloc2>
static constexpr _Alloc2
_S_select(_Alloc2& __a, ...)
{ return __a; }
public:
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt> if that expression is
* well-formed, otherwise returns @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
{ return _S_allocate(__a, __n, __hint, 0); }
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
static _GLIBCXX20_CONSTEXPR void
deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Tp`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for Tp
* @param __args Constructor arguments.
*
* Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
* if that expression is well-formed, otherwise uses placement-new
* to construct an object of type @a _Tp at location @a __p from the
* arguments @a __args...
*/
template<typename _Tp, typename... _Args>
static _GLIBCXX20_CONSTEXPR auto
construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(_S_construct(__a, __p,
std::forward<_Args>(__args)...)))
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type @a _Tp
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p) if that expression is well-formed,
* otherwise calls @c __p->~_Tp()
*/
template<typename _Tp>
static _GLIBCXX20_CONSTEXPR void
destroy(_Alloc& __a, _Tp* __p)
noexcept(noexcept(_S_destroy(__a, __p, 0)))
{ _S_destroy(__a, __p, 0); }
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size() or @c numeric_limits<size_type>::max()
*
* Returns @c __a.max_size() if that expression is well-formed,
* otherwise returns @c numeric_limits<size_type>::max()
*/
static _GLIBCXX20_CONSTEXPR size_type
max_size(const _Alloc& __a) noexcept
{ return _S_max_size(__a, 0); }
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs.select_on_container_copy_construction() or @a __rhs
*
* Returns @c __rhs.select_on_container_copy_construction() if that
* expression is well-formed, otherwise returns @a __rhs
*/
static _GLIBCXX20_CONSTEXPR _Alloc
select_on_container_copy_construction(const _Alloc& __rhs)
{ return _S_select(__rhs, 0); }
};
#if _GLIBCXX_HOSTED
/// Partial specialization for std::allocator.
template<typename _Tp>
struct allocator_traits<allocator<_Tp>>
{
/// The allocator type
using allocator_type = allocator<_Tp>;
/// The allocated type
using value_type = _Tp;
/// The allocator's pointer type.
using pointer = _Tp*;
/// The allocator's const pointer type.
using const_pointer = const _Tp*;
/// The allocator's void pointer type.
using void_pointer = void*;
/// The allocator's const void pointer type.
using const_void_pointer = const void*;
/// The allocator's difference type
using difference_type = std::ptrdiff_t;
/// The allocator's size type
using size_type = std::size_t;
/// How the allocator is propagated on copy assignment
using propagate_on_container_copy_assignment = false_type;
/// How the allocator is propagated on move assignment
using propagate_on_container_move_assignment = true_type;
/// How the allocator is propagated on swap
using propagate_on_container_swap = false_type;
/// Whether all instances of the allocator type compare equal.
using is_always_equal = true_type;
template<typename _Up>
using rebind_alloc = allocator<_Up>;
template<typename _Up>
using rebind_traits = allocator_traits<allocator<_Up>>;
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
[[__nodiscard__,__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt>
*/
[[__nodiscard__,__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n,
[[maybe_unused]] const_void_pointer __hint)
{
#if __cplusplus <= 201703L
return __a.allocate(__n, __hint);
#else
return __a.allocate(__n);
#endif
}
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
deallocate(allocator_type& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for
* an object of type `_Up`.
* @param __args Constructor arguments.
*
* Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
* in C++11, C++14 and C++17. Changed in C++20 to call
* `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
*/
template<typename _Up, typename... _Args>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
construct(allocator_type& __a __attribute__((__unused__)), _Up* __p,
_Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{
#if __cplusplus <= 201703L
__a.construct(__p, std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
/**
* @brief Destroy an object of type @a _Up
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p).
*/
template<typename _Up>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p)
noexcept(is_nothrow_destructible<_Up>::value)
{
#if __cplusplus <= 201703L
__a.destroy(__p);
#else
std::destroy_at(__p);
#endif
}
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size()
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR size_type
max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
{
#if __cplusplus <= 201703L
return __a.max_size();
#else
return size_t(-1) / sizeof(value_type);
#endif
}
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR allocator_type
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
/// Explicit specialization for std::allocator<void>.
template<>
struct allocator_traits<allocator<void>>
{
/// The allocator type
using allocator_type = allocator<void>;
/// The allocated type
using value_type = void;
/// The allocator's pointer type.
using pointer = void*;
/// The allocator's const pointer type.
using const_pointer = const void*;
/// The allocator's void pointer type.
using void_pointer = void*;
/// The allocator's const void pointer type.
using const_void_pointer = const void*;
/// The allocator's difference type
using difference_type = std::ptrdiff_t;
/// The allocator's size type
using size_type = std::size_t;
/// How the allocator is propagated on copy assignment
using propagate_on_container_copy_assignment = false_type;
/// How the allocator is propagated on move assignment
using propagate_on_container_move_assignment = true_type;
/// How the allocator is propagated on swap
using propagate_on_container_swap = false_type;
/// Whether all instances of the allocator type compare equal.
using is_always_equal = true_type;
template<typename _Up>
using rebind_alloc = allocator<_Up>;
template<typename _Up>
using rebind_traits = allocator_traits<allocator<_Up>>;
/// allocate is ill-formed for allocator<void>
static void*
allocate(allocator_type&, size_type, const void* = nullptr) = delete;
/// deallocate is ill-formed for allocator<void>
static void
deallocate(allocator_type&, void*, size_type) = delete;
/**
* @brief Construct an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for
* an object of type `_Up`.
* @param __args Constructor arguments.
*
* Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
* in C++11, C++14 and C++17. Changed in C++20 to call
* `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
*/
template<typename _Up, typename... _Args>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
construct(allocator_type&, _Up* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{ std::_Construct(__p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Invokes the destructor for `*__p`.
*/
template<typename _Up>
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR void
destroy(allocator_type&, _Up* __p)
noexcept(is_nothrow_destructible<_Up>::value)
{ std::_Destroy(__p); }
/// max_size is ill-formed for allocator<void>
static size_type
max_size(const allocator_type&) = delete;
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return `__rhs`
*/
[[__gnu__::__always_inline__]]
static _GLIBCXX20_CONSTEXPR allocator_type
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
#endif
/// @cond undocumented
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
{ __one = __two; }
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void
__do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_copy(_Alloc& __one, const _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocca =
typename __traits::propagate_on_container_copy_assignment::type;
#if __cplusplus >= 201703L
if constexpr (__pocca::value)
__one = __two;
#else
__do_alloc_on_copy(__one, __two, __pocca());
#endif
}
template<typename _Alloc>
[[__gnu__::__always_inline__]]
constexpr _Alloc
__alloc_on_copy(const _Alloc& __a)
{
typedef allocator_traits<_Alloc> __traits;
return __traits::select_on_container_copy_construction(__a);
}
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
{ __one = std::move(__two); }
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_move(_Alloc& __one, _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocma
= typename __traits::propagate_on_container_move_assignment::type;
#if __cplusplus >= 201703L
if constexpr (__pocma::value)
__one = std::move(__two);
#else
__do_alloc_on_move(__one, __two, __pocma());
#endif
}
#if __cplusplus < 201703L
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
{
using std::swap;
swap(__one, __two);
}
template<typename _Alloc>
[[__gnu__::__always_inline__]]
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
[[__gnu__::__always_inline__]]
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_swap(_Alloc& __one, _Alloc& __two)
{
using __traits = allocator_traits<_Alloc>;
using __pocs = typename __traits::propagate_on_container_swap::type;
#if __cplusplus >= 201703L
if constexpr (__pocs::value)
{
using std::swap;
swap(__one, __two);
}
#else
__do_alloc_on_swap(__one, __two, __pocs());
#endif
}
template<typename _Alloc, typename _Tp,
typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
typename = void>
struct __is_alloc_insertable_impl
: false_type
{ };
template<typename _Alloc, typename _Tp, typename _ValueT>
struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
__void_t<decltype(allocator_traits<_Alloc>::construct(
std::declval<_Alloc&>(), std::declval<_ValueT*>(),
std::declval<_Tp>()))>>
: true_type
{ };
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_copy_insertable
: __is_alloc_insertable_impl<_Alloc,
typename _Alloc::value_type const&>::type
{ };
#if _GLIBCXX_HOSTED
// std::allocator<_Tp> just requires CopyConstructible
template<typename _Tp>
struct __is_copy_insertable<allocator<_Tp>>
: is_copy_constructible<_Tp>
{ };
#endif
// true if _Alloc::value_type is MoveInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_move_insertable
: __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
{ };
#if _GLIBCXX_HOSTED
// std::allocator<_Tp> just requires MoveConstructible
template<typename _Tp>
struct __is_move_insertable<allocator<_Tp>>
: is_move_constructible<_Tp>
{ };
#endif
// Trait to detect Allocator-like types.
template<typename _Alloc, typename = void>
struct __is_allocator : false_type { };
template<typename _Alloc>
struct __is_allocator<_Alloc,
__void_t<typename _Alloc::value_type,
decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
: true_type { };
template<typename _Alloc>
using _RequireAllocator
= typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
template<typename _Alloc>
using _RequireNotAllocator
= typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
#if __cpp_concepts >= 201907L
template<typename _Alloc>
concept __allocator_like = requires (_Alloc& __a) {
typename _Alloc::value_type;
__a.deallocate(__a.allocate(1u), 1u);
};
#endif
/// @endcond
#endif // C++11
/// @cond undocumented
// To implement Option 3 of DR 431.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_swap
{ static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
template<typename _Alloc>
struct __alloc_swap<_Alloc, false>
{
static void
_S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
{
// Precondition: swappable allocators.
if (__one != __two)
swap(__one, __two);
}
};
#if __cplusplus >= 201103L
template<typename _Tp, bool
= __or_<is_copy_constructible<typename _Tp::value_type>,
is_nothrow_move_constructible<typename _Tp::value_type>>::value>
struct __shrink_to_fit_aux
{ static bool _S_do_it(_Tp&) noexcept { return false; } };
template<typename _Tp>
struct __shrink_to_fit_aux<_Tp, true>
{
_GLIBCXX20_CONSTEXPR
static bool
_S_do_it(_Tp& __c) noexcept
{
#if __cpp_exceptions
try
{
_Tp(__make_move_if_noexcept_iterator(__c.begin()),
__make_move_if_noexcept_iterator(__c.end()),
__c.get_allocator()).swap(__c);
return true;
}
catch(...)
{ return false; }
#else
return false;
#endif
}
};
#endif
/**
* Destroy a range of objects using the supplied allocator. For
* non-default allocators we do not optimize away invocation of
* destroy() even if _Tp has a trivial destructor.
*/
template<typename _ForwardIterator, typename _Allocator>
_GLIBCXX20_CONSTEXPR
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator& __alloc)
{
for (; __first != __last; ++__first)
#if __cplusplus < 201103L
__alloc.destroy(std::__addressof(*__first));
#else
allocator_traits<_Allocator>::destroy(__alloc,
std::__addressof(*__first));
#endif
}
#if _GLIBCXX_HOSTED
template<typename _ForwardIterator, typename _Tp>
__attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>&)
{
std::_Destroy(__first, __last);
}
#endif
/// @endcond
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _ALLOC_TRAITS_H
+295
View File
@@ -0,0 +1,295 @@
// Allocators -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOCATOR_H
#define _ALLOCATOR_H 1
#include <bits/c++allocator.h> // Define the base class to std::allocator.
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
#include <type_traits>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup allocators
* @{
*/
// Since C++20 the primary template should be used for allocator<void>,
// but then it would have a non-trivial default ctor and dtor for C++20,
// but trivial for C++98-17, which would be an ABI incompatibility between
// different standard dialects. So C++20 still uses the allocator<void>
// explicit specialization, with the historical ABI properties, but with
// the same members that are present in the primary template.
/** std::allocator<void> specialization.
*
* @headerfile memory
*/
template<>
class allocator<void>
{
public:
typedef void value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20, allocator_traits does the right thing.
typedef void* pointer;
typedef const void* const_pointer;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
using propagate_on_container_move_assignment = true_type;
using is_always_equal
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
= true_type;
#if __cplusplus >= 202002L
// As noted above, these members are present for C++20 to provide the
// same API as the primary template, but still trivial as in pre-C++20.
allocator() = default;
~allocator() = default;
template<typename _Up>
__attribute__((__always_inline__))
constexpr
allocator(const allocator<_Up>&) noexcept { }
// No allocate member because it's ill-formed by LWG 3307.
// No deallocate member because it would be undefined to call it
// with any pointer which wasn't obtained from allocate.
#endif // C++20
#endif // C++11
};
/**
* @brief The @a standard allocator, as per C++03 [20.4.1].
*
* See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator
* for further details.
*
* @tparam _Tp Type of allocated object.
*
* @headerfile memory
*/
template<typename _Tp>
class allocator : public __allocator_base<_Tp>
{
public:
typedef _Tp value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20.
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
using propagate_on_container_move_assignment = true_type;
using is_always_equal
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
= true_type;
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3035. std::allocator's constructors should be constexpr
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator() _GLIBCXX_NOTHROW { }
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator(const allocator& __a) _GLIBCXX_NOTHROW
: __allocator_base<_Tp>(__a) { }
#if __cplusplus >= 201103L
// Avoid implicit deprecation.
allocator& operator=(const allocator&) = default;
#endif
template<typename _Tp1>
__attribute__((__always_inline__))
_GLIBCXX20_CONSTEXPR
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
__attribute__((__always_inline__))
#if __cpp_constexpr_dynamic_alloc
constexpr
#endif
~allocator() _GLIBCXX_NOTHROW { }
#if __cplusplus > 201703L
[[nodiscard,__gnu__::__always_inline__]]
constexpr _Tp*
allocate(size_t __n)
{
if (std::__is_constant_evaluated())
{
if (__builtin_mul_overflow(__n, sizeof(_Tp), &__n))
std::__throw_bad_array_new_length();
return static_cast<_Tp*>(::operator new(__n));
}
return __allocator_base<_Tp>::allocate(__n, 0);
}
[[__gnu__::__always_inline__]]
constexpr void
deallocate(_Tp* __p, size_t __n)
{
if (std::__is_constant_evaluated())
{
::operator delete(__p);
return;
}
__allocator_base<_Tp>::deallocate(__p, __n);
}
#endif // C++20
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
bool
operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return false; }
#endif
// Inherit everything else.
};
/** Equality comparison for std::allocator objects
*
* @return true, for all std::allocator objects.
* @relates std::allocator
*/
template<typename _T1, typename _T2>
__attribute__((__always_inline__))
inline _GLIBCXX20_CONSTEXPR bool
operator==(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
template<typename _T1, typename _T2>
__attribute__((__always_inline__))
inline _GLIBCXX20_CONSTEXPR bool
operator!=(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return false; }
#endif
/// @cond undocumented
// Invalid allocator<cv T> partial specializations.
// allocator_traits::rebind_alloc can be used to form a valid allocator type.
template<typename _Tp>
class allocator<const _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<volatile _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<const volatile _Tp>
{
public:
typedef _Tp value_type;
allocator() { }
template<typename _Up> allocator(const allocator<_Up>&) { }
};
/// @endcond
/// @} group allocator
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class allocator<char>;
extern template class allocator<wchar_t>;
#endif
// Undefine.
#undef __allocator_base
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
// -*- C++ -*- header.
// Copyright (C) 2008-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_lockfree_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
#ifndef _GLIBCXX_ATOMIC_LOCK_FREE_H
#define _GLIBCXX_ATOMIC_LOCK_FREE_H 1
#pragma GCC system_header
/**
* @addtogroup atomics
* @{
*/
/**
* Lock-free property.
*
* 0 indicates that the types are never lock-free.
* 1 indicates that the types are sometimes lock-free.
* 2 indicates that the types are always lock-free.
*/
#if __cplusplus >= 201103L
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#ifdef _GLIBCXX_USE_CHAR8_T
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#endif
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif
/// @} group atomics
#endif
@@ -0,0 +1,40 @@
// Low-level type for atomic operations -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file atomic_word.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_ATOMIC_WORD_H
#define _GLIBCXX_ATOMIC_WORD_H 1
typedef int _Atomic_word;
// This is a memory order acquire fence.
#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
// This is a memory order release fence.
#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
#endif
+148
View File
@@ -0,0 +1,148 @@
// Wrapper of C-language FILE struct -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 27.8 File-based streams
//
/** @file bits/basic_file.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _GLIBCXX_BASIC_FILE_STDIO_H
#define _GLIBCXX_BASIC_FILE_STDIO_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/c++io.h> // for __c_lock and __c_file
#include <bits/move.h> // for swap
#include <ios>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Generic declaration.
template<typename _CharT>
class __basic_file;
// Specialization.
template<>
class __basic_file<char>
{
// Underlying data source/sink.
__c_file* _M_cfile;
// True iff we opened _M_cfile, and thus must close it ourselves.
bool _M_cfile_created;
public:
__basic_file(__c_lock* __lock = 0) throw ();
#if __cplusplus >= 201103L
__basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept
: _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created)
{
__rv._M_cfile = nullptr;
__rv._M_cfile_created = false;
}
__basic_file& operator=(const __basic_file&) = delete;
__basic_file& operator=(__basic_file&&) = delete;
void
swap(__basic_file& __f) noexcept
{
std::swap(_M_cfile, __f._M_cfile);
std::swap(_M_cfile_created, __f._M_cfile_created);
}
#endif
__basic_file*
open(const char* __name, ios_base::openmode __mode, int __prot = 0664);
#if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
__basic_file*
open(const wchar_t* __name, ios_base::openmode __mode);
#endif
__basic_file*
sys_open(__c_file* __file, ios_base::openmode);
__basic_file*
sys_open(int __fd, ios_base::openmode __mode) throw ();
__basic_file*
close();
_GLIBCXX_PURE bool
is_open() const throw ();
_GLIBCXX_PURE int
fd() throw ();
_GLIBCXX_PURE __c_file*
file() throw ();
~__basic_file();
streamsize
xsputn(const char* __s, streamsize __n);
streamsize
xsputn_2(const char* __s1, streamsize __n1,
const char* __s2, streamsize __n2);
streamsize
xsgetn(char* __s, streamsize __n);
streamoff
seekoff(streamoff __off, ios_base::seekdir __way) throw ();
int
sync();
streamsize
showmanyc();
#if __cplusplus >= 201103L
#ifdef _GLIBCXX_USE_STDIO_PURE
using native_handle_type = __c_file*; // FILE*
#elif _GLIBCXX_USE__GET_OSFHANDLE
using native_handle_type = void*; // HANDLE
#else
using native_handle_type = int; // POSIX file descriptor
#endif
native_handle_type
native_handle() const noexcept;
#endif
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
@@ -0,0 +1,883 @@
// -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
/** @file bits/boost_concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
// GCC Note: based on version 1.12.0 of the Boost library.
#ifndef _BOOST_CONCEPT_CHECK_H
#define _BOOST_CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for traits and tags
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
struct _Bit_iterator;
struct _Bit_const_iterator;
_GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_END_NAMESPACE_VERSION
}
namespace __gnu_debug
{
template<typename _Iterator, typename _Sequence, typename _Category>
class _Safe_iterator;
}
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#define _IsUnused __attribute__ ((__unused__))
// When the C-C code is in use, we would like this function to do as little
// as possible at runtime, use as few resources as possible, and hopefully
// be elided out of existence... hmmm.
template <class _Concept>
_GLIBCXX14_CONSTEXPR inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
// No definition: if this is referenced, there's a problem with
// the instantiating type not being one of the required integer types.
// Unfortunately, this results in a link-time error, not a compile-time error.
void __error_type_must_be_an_integer_type();
void __error_type_must_be_an_unsigned_integer_type();
void __error_type_must_be_a_signed_integer_type();
// ??? Should the "concept_checking*" structs begin with more than _ ?
#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
template <_func##_type_var##_concept _Tp1> \
struct _concept_checking##_type_var##_concept { }; \
typedef _concept_checking##_type_var##_concept< \
&_ns::_concept <_type_var>::__constraints> \
_concept_checking_typedef##_type_var##_concept
#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
template <_func##_type_var1##_type_var2##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_concept< \
&_ns::_concept <_type_var1,_type_var2>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_concept
#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
template <class _Tp1, class _Tp2>
struct _Aux_require_same { };
template <class _Tp>
struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
template <class _Tp1, class _Tp2>
struct _SameTypeConcept
{
void __constraints() {
typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
}
};
template <class _Tp>
struct _IntegerConcept {
void __constraints() {
__error_type_must_be_an_integer_type();
}
};
template <> struct _IntegerConcept<short> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
template <> struct _IntegerConcept<int> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
template <> struct _IntegerConcept<long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
template <> struct _IntegerConcept<long long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long long>
{ void __constraints() {} };
template <class _Tp>
struct _SignedIntegerConcept {
void __constraints() {
__error_type_must_be_a_signed_integer_type();
}
};
template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
template <class _Tp>
struct _UnsignedIntegerConcept {
void __constraints() {
__error_type_must_be_an_unsigned_integer_type();
}
};
template <> struct _UnsignedIntegerConcept<unsigned short>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned int>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long long>
{ void __constraints() {} };
//===========================================================================
// Basic Concepts
template <class _Tp>
struct _DefaultConstructibleConcept
{
void __constraints() {
_Tp __a _IsUnused; // require default constructor
}
};
template <class _Tp>
struct _AssignableConcept
{
void __constraints() {
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
__a = __b; // const required for argument to assignment
}
_Tp __a;
// possibly should be "Tp* a;" and then dereference "a" in constraint
// functions? present way would require a default ctor, i think...
};
template <class _Tp>
struct _CopyConstructibleConcept
{
void __constraints() {
_Tp __a(__b); // require copy constructor
_Tp* __ptr _IsUnused = &__a; // require address of operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __a) {
_Tp __c _IsUnused(__a); // require const copy constructor
const _Tp* __ptr _IsUnused = &__a; // require const address of operator
}
_Tp __b;
};
// The SGI STL version of Assignable requires copy constructor and operator=
template <class _Tp>
struct _SGIAssignableConcept
{
void __constraints() {
_Tp __b _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__a = __b; // const required for argument to assignment
}
_Tp __a;
};
template <class _From, class _To>
struct _ConvertibleConcept
{
void __constraints() {
_To __y _IsUnused = __x;
}
_From __x;
};
// The C++ standard requirements for many concepts talk about return
// types that must be "convertible to bool". The problem with this
// requirement is that it leaves the door open for evil proxies that
// define things like operator|| with strange return types. Two
// possible solutions are:
// 1) require the return type to be exactly bool
// 2) stay with convertible to bool, and also
// specify stuff about all the logical operators.
// For now we just test for convertible to bool.
template <class _Tp>
void __aux_require_boolean_expr(const _Tp& __t) {
bool __x _IsUnused = __t;
}
// FIXME
template <class _Tp>
struct _EqualityComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a == __b);
}
_Tp __a, __b;
};
template <class _Tp>
struct _LessThanComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
}
_Tp __a, __b;
};
// This is equivalent to SGI STL's LessThanComparable.
template <class _Tp>
struct _ComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
__aux_require_boolean_expr(__a > __b);
__aux_require_boolean_expr(__a <= __b);
__aux_require_boolean_expr(__a >= __b);
}
_Tp __a, __b;
};
#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
template <class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
bool __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
template <class _Ret, class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
_Ret __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
// Function Object Concepts
template <class _Func, class _Return>
struct _GeneratorConcept
{
void __constraints() {
const _Return& __r _IsUnused = __f();// require operator() member function
}
_Func __f;
};
template <class _Func>
struct _GeneratorConcept<_Func,void>
{
void __constraints() {
__f(); // require operator() member function
}
_Func __f;
};
template <class _Func, class _Return, class _Arg>
struct _UnaryFunctionConcept
{
void __constraints() {
__r = __f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
_Return __r;
};
template <class _Func, class _Arg>
struct _UnaryFunctionConcept<_Func, void, _Arg> {
void __constraints() {
__f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _Return, class _First, class _Second>
struct _BinaryFunctionConcept
{
void __constraints() {
__r = __f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
_Return __r;
};
template <class _Func, class _First, class _Second>
struct _BinaryFunctionConcept<_Func, void, _First, _Second>
{
void __constraints() {
__f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
};
template <class _Func, class _Arg>
struct _UnaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__arg)); // require op() returning bool
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _First, class _Second>
struct _BinaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
}
_Func __f;
_First __a;
_Second __b;
};
// use this when functor is used inside a container class like std::set
template <class _Func, class _First, class _Second>
struct _Const_BinaryPredicateConcept {
void __constraints() {
__const_constraints(__f);
}
void __const_constraints(const _Func& __fun) {
__function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
// operator() must be a const member function
__aux_require_boolean_expr(__fun(__a, __b));
}
_Func __f;
_First __a;
_Second __b;
};
//===========================================================================
// Iterator Concepts
template <class _Tp>
struct _TrivialIteratorConcept
{
void __constraints() {
// __function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _AssignableConcept<_Tp> >();
__function_requires< _EqualityComparableConcept<_Tp> >();
// typedef typename std::iterator_traits<_Tp>::value_type _V;
(void)*__i; // require dereference operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_TrivialIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
*__i = *__j; // require dereference and assignment
}
_Tp __i, __j;
};
template <class _Tp>
struct _InputIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
// require iterator_traits typedef's
typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
// __function_requires< _SignedIntegerConcept<_Diff> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::pointer _Pt;
typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::input_iterator_tag> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
}
_Tp __i;
};
template <class _Tp, class _ValueT>
struct _OutputIteratorConcept
{
void __constraints() {
__function_requires< _AssignableConcept<_Tp> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
*__i++ = __val(); // require postincrement and assignment
}
_Tp __i;
// Use a function pointer here so no definition of the function needed.
// Just need something that returns a _ValueT (which might be a reference).
_ValueT (*__val)();
};
template<typename _Tp>
struct _Is_vector_bool_iterator
{ static const bool __value = false; };
#ifdef _GLIBCXX_DEBUG
namespace __cont = ::std::_GLIBCXX_STD_C;
#else
namespace __cont = ::std;
#endif
// Trait to identify vector<bool>::iterator
template <>
struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
{ static const bool __value = true; };
// And for vector<bool>::const_iterator.
template <>
struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
{ static const bool __value = true; };
// And for __gnu_debug::vector<bool> iterators too.
template <typename _It, typename _Seq, typename _Tag>
struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
: _Is_vector_bool_iterator<_It> { };
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _ForwardIteratorReferenceConcept
{
void __constraints() {
#if __cplusplus >= 201103L
typedef typename std::iterator_traits<_Tp>::reference _Ref;
static_assert(std::is_reference<_Ref>::value,
"reference type of a forward iterator must be a real reference");
#endif
}
};
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
struct _Mutable_ForwardIteratorReferenceConcept
{
void __constraints() {
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::value_type _Val;
__function_requires< _SameTypeConcept<_Ref, _Val&> >();
}
};
// vector<bool> iterators are not real forward iterators, but we ignore that.
template <class _Tp>
struct _ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
// vector<bool> iterators are not real forward iterators, but we ignore that.
template <class _Tp>
struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
{
void __constraints() { }
};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
template <class _Tp>
struct _ForwardIteratorConcept
{
void __constraints() {
__function_requires< _InputIteratorConcept<_Tp> >();
__function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::forward_iterator_tag> >();
__function_requires< _ForwardIteratorReferenceConcept<_Tp> >();
_Tp& __j = ++__i;
const _Tp& __k = __i++;
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r = *__k;
_Ref __r2 = *__i++;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_ForwardIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::value_type _Val;
__function_requires< _Mutable_ForwardIteratorReferenceConcept<_Tp> >();
}
_Tp __i;
};
template <class _Tp>
struct _BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::bidirectional_iterator_tag> >();
_Tp& __j = --__i; // require predecrement operator
const _Tp& __k = __i--; // require postdecrement operator
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r = *__j--;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
}
_Tp __i;
};
template <class _Tp>
struct _RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _ComparableConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Tp& __j = __i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
_Tp& __k = __i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with
// difference type
__n = __i - __j; // require difference operator
_Ref __r = __i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
typename std::iterator_traits<_Tp>::difference_type __n;
};
template <class _Tp>
struct _Mutable_RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _RandomAccessIteratorConcept<_Tp> >();
__function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
}
_Tp __i;
typename std::iterator_traits<_Tp>::difference_type __n;
};
#pragma GCC diagnostic pop
//===========================================================================
// Container Concepts
template <class _Container>
struct _ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::difference_type _Difference_type;
typedef typename _Container::size_type _Size_type;
typedef typename _Container::const_reference _Const_reference;
typedef typename _Container::const_pointer _Const_pointer;
typedef typename _Container::const_iterator _Const_iterator;
void __constraints() {
__function_requires< _InputIteratorConcept<_Const_iterator> >();
__function_requires< _AssignableConcept<_Container> >();
const _Container __c;
__i = __c.begin();
__i = __c.end();
__n = __c.size();
__n = __c.max_size();
__b = __c.empty();
}
bool __b;
_Const_iterator __i;
_Size_type __n;
};
template <class _Container>
struct _Mutable_ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::reference _Reference;
typedef typename _Container::iterator _Iterator;
typedef typename _Container::pointer _Pointer;
void __constraints() {
__function_requires< _ContainerConcept<_Container> >();
__function_requires< _AssignableConcept<_Value_type> >();
__function_requires< _InputIteratorConcept<_Iterator> >();
__i = __c.begin();
__i = __c.end();
__c.swap(__c2);
}
_Iterator __i;
_Container __c, __c2;
};
template <class _ForwardContainer>
struct _ForwardContainerConcept
{
void __constraints() {
__function_requires< _ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::const_iterator _Const_iterator;
__function_requires< _ForwardIteratorConcept<_Const_iterator> >();
}
};
template <class _ForwardContainer>
struct _Mutable_ForwardContainerConcept
{
void __constraints() {
__function_requires< _ForwardContainerConcept<_ForwardContainer> >();
__function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::iterator _Iterator;
__function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
}
};
template <class _ReversibleContainer>
struct _ReversibleContainerConcept
{
typedef typename _ReversibleContainer::const_iterator _Const_iterator;
typedef typename _ReversibleContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
__function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
__function_requires<
_BidirectionalIteratorConcept<_Const_reverse_iterator> >();
const _ReversibleContainer __c;
_Const_reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
};
template <class _ReversibleContainer>
struct _Mutable_ReversibleContainerConcept
{
typedef typename _ReversibleContainer::iterator _Iterator;
typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
__function_requires<
_Mutable_ForwardContainerConcept<_ReversibleContainer> >();
__function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
_Reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
_ReversibleContainer __c;
};
template <class _RandomAccessContainer>
struct _RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::const_reference _Const_reference;
typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
typedef typename _RandomAccessContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires<
_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
__function_requires<
_RandomAccessIteratorConcept<_Const_reverse_iterator> >();
const _RandomAccessContainer __c;
_Const_reference __r _IsUnused = __c[__n];
}
_Size_type __n;
};
template <class _RandomAccessContainer>
struct _Mutable_RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::reference _Reference;
typedef typename _RandomAccessContainer::iterator _Iterator;
typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<
_RandomAccessContainerConcept<_RandomAccessContainer> >();
__function_requires<
_Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
_Reference __r _IsUnused = __c[__i];
}
_Size_type __i;
_RandomAccessContainer __c;
};
// A Sequence is inherently mutable
template <class _Sequence>
struct _SequenceConcept
{
typedef typename _Sequence::reference _Reference;
typedef typename _Sequence::const_reference _Const_reference;
void __constraints() {
// Matt Austern's book puts DefaultConstructible here, the C++
// standard places it in Container
// function_requires< DefaultConstructible<Sequence> >();
__function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
__function_requires< _DefaultConstructibleConcept<_Sequence> >();
_Sequence
__c _IsUnused(__n, __t),
__c2 _IsUnused(__first, __last);
__c.insert(__p, __t);
__c.insert(__p, __n, __t);
__c.insert(__p, __first, __last);
__c.erase(__p);
__c.erase(__p, __q);
_Reference __r _IsUnused = __c.front();
__const_constraints(__c);
}
void __const_constraints(const _Sequence& __c) {
_Const_reference __r _IsUnused = __c.front();
}
typename _Sequence::value_type __t;
typename _Sequence::size_type __n;
typename _Sequence::value_type *__first, *__last;
typename _Sequence::iterator __p, __q;
};
template <class _FrontInsertionSequence>
struct _FrontInsertionSequenceConcept
{
void __constraints() {
__function_requires< _SequenceConcept<_FrontInsertionSequence> >();
__c.push_front(__t);
__c.pop_front();
}
_FrontInsertionSequence __c;
typename _FrontInsertionSequence::value_type __t;
};
template <class _BackInsertionSequence>
struct _BackInsertionSequenceConcept
{
typedef typename _BackInsertionSequence::reference _Reference;
typedef typename _BackInsertionSequence::const_reference _Const_reference;
void __constraints() {
__function_requires< _SequenceConcept<_BackInsertionSequence> >();
__c.push_back(__t);
__c.pop_back();
_Reference __r _IsUnused = __c.back();
}
void __const_constraints(const _BackInsertionSequence& __c) {
_Const_reference __r _IsUnused = __c.back();
};
_BackInsertionSequence __c;
typename _BackInsertionSequence::value_type __t;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#pragma GCC diagnostic pop
#undef _IsUnused
#endif // _GLIBCXX_BOOST_CONCEPT_CHECK
@@ -0,0 +1,37 @@
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support \
for the ISO C++ 2011 standard. This support must be enabled \
with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif
@@ -0,0 +1,64 @@
// Base to std::allocator -*- C++ -*-
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_CXX_ALLOCATOR_H
#define _GLIBCXX_CXX_ALLOCATOR_H 1
#include <bits/new_allocator.h>
#if __cplusplus >= 201103L
namespace std
{
/**
* @brief An alias to the base class for std::allocator.
*
* Used to set the std::allocator base class to std::__new_allocator.
*
* @ingroup allocators
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
using __allocator_base = __new_allocator<_Tp>;
}
#else
// Define __new_allocator as the base class to std::allocator.
# define __allocator_base __new_allocator
#endif
#ifndef _GLIBCXX_SANITIZE_STD_ALLOCATOR
# if defined(__SANITIZE_ADDRESS__)
# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1
# elif defined __has_feature
# if __has_feature(address_sanitizer)
# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1
# endif
# endif
#endif
#endif
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
// Underlying io library details -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++io.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
// c_io_stdio.h - Defines for using "C" stdio.h
#ifndef _GLIBCXX_CXX_IO_H
#define _GLIBCXX_CXX_IO_H 1
#include <cstdio>
#include <bits/gthr.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef __GTHREAD_LEGACY_MUTEX_T
// The layout of __gthread_mutex_t changed in GCC 13, but libstdc++ doesn't
// actually use the basic_filebuf::_M_lock member, so define it consistently
// with the old __gthread_mutex_t to avoid an unnecessary layout change:
typedef __GTHREAD_LEGACY_MUTEX_T __c_lock;
#else
typedef __gthread_mutex_t __c_lock;
#endif
// for basic_file.h
typedef FILE __c_file;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
+92
View File
@@ -0,0 +1,92 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++locale.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#ifndef _GLIBCXX_CXX_LOCALE_H
#define _GLIBCXX_CXX_LOCALE_H 1
#pragma GCC system_header
#include <clocale>
#define _GLIBCXX_NUM_CATEGORIES 0
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef int* __c_locale;
// Convert numeric value of type double and long double to string and
// return length of string. If vsnprintf is available use it, otherwise
// fall back to the unsafe vsprintf which, in general, can be dangerous
// and should be avoided.
inline int
__convert_from_v(const __c_locale&, char* __out,
const int __size __attribute__((__unused__)),
const char* __fmt, ...)
{
char* __old = std::setlocale(LC_NUMERIC, 0);
char* __sav = 0;
if (__builtin_strcmp(__old, "C"))
{
const size_t __len = __builtin_strlen(__old) + 1;
__sav = new char[__len];
__builtin_memcpy(__sav, __old, __len);
std::setlocale(LC_NUMERIC, "C");
}
__builtin_va_list __args;
__builtin_va_start(__args, __fmt);
#if _GLIBCXX_USE_C99_STDIO && !_GLIBCXX_HAVE_BROKEN_VSNPRINTF
const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
#else
const int __ret = __builtin_vsprintf(__out, __fmt, __args);
#endif
__builtin_va_end(__args);
if (__sav)
{
std::setlocale(LC_NUMERIC, __sav);
delete [] __sav;
}
return __ret;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,81 @@
// Concept-checking control -*- C++ -*-
// Copyright (C) 2001-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _CONCEPT_CHECK_H
#define _CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
// All places in libstdc++-v3 where these are used, or /might/ be used, or
// don't need to be used, or perhaps /should/ be used, are commented with
// "concept requirements" (and maybe some more text). So grep like crazy
// if you're looking for additional places to use these.
// Concept-checking code is off by default unless users turn it on via
// configure options or editing c++config.h.
// It is not supported for freestanding implementations.
#if !defined(_GLIBCXX_CONCEPT_CHECKS)
#define __glibcxx_function_requires(...)
#define __glibcxx_class_requires(_a,_b)
#define __glibcxx_class_requires2(_a,_b,_c)
#define __glibcxx_class_requires3(_a,_b,_c,_d)
#define __glibcxx_class_requires4(_a,_b,_c,_d,_e)
#else // the checks are on
#include <bits/boost_concept_check.h>
// Note that the obvious and elegant approach of
//
//#define glibcxx_function_requires(C) debug::function_requires< debug::C >()
//
// won't work due to concept templates with more than one parameter, e.g.,
// BinaryPredicateConcept. The preprocessor tries to split things up on
// the commas in the template argument list. We can't use an inner pair of
// parenthesis to hide the commas, because "debug::(Temp<Foo,Bar>)" isn't
// a valid instantiation pattern. Thus, we steal a feature from C99.
#define __glibcxx_function_requires(...) \
__gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
#define __glibcxx_class_requires(_a,_C) \
_GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C);
#define __glibcxx_class_requires2(_a,_b,_C) \
_GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C);
#define __glibcxx_class_requires3(_a,_b,_c,_C) \
_GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C);
#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \
_GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C);
#endif // enable/disable
#endif // _GLIBCXX_CONCEPT_CHECK
@@ -0,0 +1,614 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpp_type_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/type_traits}
*/
// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
#ifndef _CPP_TYPE_TRAITS_H
#define _CPP_TYPE_TRAITS_H 1
#pragma GCC system_header
#include <bits/c++config.h>
//
// This file provides some compile-time information about various types.
// These representations were designed, on purpose, to be constant-expressions
// and not types as found in <bits/type_traits.h>. In particular, they
// can be used in control structures and the optimizer hopefully will do
// the obvious thing.
//
// Why integral expressions, and not functions nor types?
// Firstly, these compile-time entities are used as template-arguments
// so function return values won't work: We need compile-time entities.
// We're left with types and constant integral expressions.
// Secondly, from the point of view of ease of use, type-based compile-time
// information is -not- *that* convenient. One has to write lots of
// overloaded functions and to hope that the compiler will select the right
// one. As a net effect, the overall structure isn't very clear at first
// glance.
// Thirdly, partial ordering and overload resolution (of function templates)
// is highly costly in terms of compiler-resource. It is a Good Thing to
// keep these resource consumption as least as possible.
//
// See valarray_array.h for a case use.
//
// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
//
// Update 2005: types are also provided and <bits/type_traits.h> has been
// removed.
//
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __true_type { };
struct __false_type { };
template<bool>
struct __truth_type
{ typedef __false_type __type; };
template<>
struct __truth_type<true>
{ typedef __true_type __type; };
// N.B. The conversions to bool are needed due to the issue
// explained in c++/19404.
template<class _Sp, class _Tp>
struct __traitor
{
enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
typedef typename __truth_type<__value>::__type __type;
};
// Compare for equality of types.
template<typename, typename>
struct __are_same
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __are_same<_Tp, _Tp>
{
enum { __value = 1 };
typedef __true_type __type;
};
// Holds if the template-argument is a void type.
template<typename _Tp>
struct __is_void
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_void<void>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Integer types
//
template<typename _Tp>
struct __is_integer
{
enum { __value = 0 };
typedef __false_type __type;
};
// Thirteen specializations (yes there are eleven standard integer
// types; <em>long long</em> and <em>unsigned long long</em> are
// supported as extensions). Up to four target-specific __int<N>
// types are supported as well.
template<>
struct __is_integer<bool>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
# ifdef __WCHAR_TYPE__
template<>
struct __is_integer<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
# endif
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_integer<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#if __cplusplus >= 201103L
template<>
struct __is_integer<char16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char32_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<>
struct __is_integer<short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
#define __INT_N(TYPE) \
__extension__ \
template<> \
struct __is_integer<TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
}; \
__extension__ \
template<> \
struct __is_integer<unsigned TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
};
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__INT_N(__GLIBCXX_TYPE_INT_N_1)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__INT_N(__GLIBCXX_TYPE_INT_N_2)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__INT_N(__GLIBCXX_TYPE_INT_N_3)
#endif
#undef __INT_N
//
// Floating point types
//
template<typename _Tp>
struct __is_floating
{
enum { __value = 0 };
typedef __false_type __type;
};
// three specializations (float, double and 'long double')
template<>
struct __is_floating<float>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<double>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<long double>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef __STDCPP_FLOAT16_T__
template<>
struct __is_floating<_Float16>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT32_T__
template<>
struct __is_floating<_Float32>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT64_T__
template<>
struct __is_floating<_Float64>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_FLOAT128_T__
template<>
struct __is_floating<_Float128>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#ifdef __STDCPP_BFLOAT16_T__
template<>
struct __is_floating<__gnu_cxx::__bfloat16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
//
// Pointer types
//
template<typename _Tp>
struct __is_pointer
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __is_pointer<_Tp*>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// An arithmetic type is an integer type or a floating point type
//
template<typename _Tp>
struct __is_arithmetic
: public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
{ };
//
// A scalar type is an arithmetic type or a pointer type
//
template<typename _Tp>
struct __is_scalar
: public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
//
// For use in std::copy and std::find overloads for streambuf iterators.
//
template<typename _Tp>
struct __is_char
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_char<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef __WCHAR_TYPE__
template<>
struct __is_char<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename _Tp>
struct __is_byte
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_byte<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#if __cplusplus >= 201703L
enum class byte : unsigned char;
template<>
struct __is_byte<byte>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif // C++17
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_byte<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename> struct iterator_traits;
// A type that is safe for use with memcpy, memmove, memcmp etc.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable
{
enum { __value = __is_trivially_copyable(_Tp) };
};
// Cannot use memcpy/memmove/memcmp on volatile types even if they are
// trivially copyable, so ensure __memcpyable<volatile int*, volatile int*>
// and similar will be false.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable<volatile _Tp>
{
enum { __value = 0 };
};
// Whether two iterator types can be used with memcpy/memmove.
template<typename _OutputIter, typename _InputIter>
struct __memcpyable
{
enum { __value = 0 };
};
template<typename _Tp>
struct __memcpyable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcpyable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether two iterator types can be used with memcmp.
// This trait only says it's well-formed to use memcmp, not that it
// gives the right answer for a given algorithm. So for example, std::equal
// needs to add additional checks that the types are integers or pointers,
// because other trivially copyable types can overload operator==.
template<typename _Iter1, typename _Iter2>
struct __memcmpable
{
enum { __value = 0 };
};
// OK to use memcmp with pointers to trivially copyable types.
template<typename _Tp>
struct __memcmpable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<const _Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether memcmp can be used to determine ordering for a type
// e.g. in std::lexicographical_compare or three-way comparisons.
// True for unsigned integer-like types where comparing each byte in turn
// as an unsigned char yields the right result. This is true for all
// unsigned integers on big endian targets, but only unsigned narrow
// character types (and std::byte) on little endian targets.
template<typename _Tp, bool _TreatAsBytes =
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
__is_integer<_Tp>::__value
#else
__is_byte<_Tp>::__value
#endif
>
struct __is_memcmp_ordered
{
static const bool __value = _Tp(-1) > _Tp(1); // is unsigned
};
template<typename _Tp>
struct __is_memcmp_ordered<_Tp, false>
{
static const bool __value = false;
};
// Whether two types can be compared using memcmp.
template<typename _Tp, typename _Up, bool = sizeof(_Tp) == sizeof(_Up)>
struct __is_memcmp_ordered_with
{
static const bool __value = __is_memcmp_ordered<_Tp>::__value
&& __is_memcmp_ordered<_Up>::__value;
};
template<typename _Tp, typename _Up>
struct __is_memcmp_ordered_with<_Tp, _Up, false>
{
static const bool __value = false;
};
#if __cplusplus >= 201703L
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
// std::byte is not an integer, but it can be compared using memcmp.
template<>
struct __is_memcmp_ordered<std::byte, false>
{ static constexpr bool __value = true; };
#endif
// std::byte can only be compared to itself, not to other types.
template<>
struct __is_memcmp_ordered_with<std::byte, std::byte, true>
{ static constexpr bool __value = true; };
template<typename _Tp, bool _SameSize>
struct __is_memcmp_ordered_with<_Tp, std::byte, _SameSize>
{ static constexpr bool __value = false; };
template<typename _Up, bool _SameSize>
struct __is_memcmp_ordered_with<std::byte, _Up, _SameSize>
{ static constexpr bool __value = false; };
#endif
//
// Move iterator type
//
template<typename _Tp>
struct __is_move_iterator
{
enum { __value = 0 };
typedef __false_type __type;
};
// Fallback implementation of the function in bits/stl_iterator.h used to
// remove the move_iterator wrapper.
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
inline _Iterator
__miter_base(_Iterator __it)
{ return __it; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
} // extern "C++"
#endif //_CPP_TYPE_TRAITS_H
@@ -0,0 +1,33 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2005-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpu_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _GLIBCXX_CPU_DEFINES
#define _GLIBCXX_CPU_DEFINES 1
#endif
@@ -0,0 +1,59 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 22.1 Locales
//
// Default information, may not be appropriate for specific host.
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @brief Base class for ctype.
struct ctype_base
{
// Non-standard typedefs.
typedef const int* __to_type;
// NB: Offsets into ctype<char>::_M_table force a particular size
// on the mask type. Because of this, we don't use an enum.
typedef unsigned int mask;
static const mask upper = 1 << 0;
static const mask lower = 1 << 1;
static const mask alpha = 1 << 2;
static const mask digit = 1 << 3;
static const mask xdigit = 1 << 4;
static const mask space = 1 << 5;
static const mask print = 1 << 6;
static const mask graph = (1 << 2) | (1 << 3) | (1 << 9); // alnum|punct
static const mask cntrl = 1 << 8;
static const mask punct = 1 << 9;
static const mask alnum = (1 << 2) | (1 << 3); // alpha|digit
static const mask blank = 1 << 10;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -0,0 +1,173 @@
// Locale support -*- C++ -*-
// Copyright (C) 2000-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ctype_inline.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*)
// functions go in ctype.cc
// The following definitions are portable, but insanely slow. If one
// cares at all about performance, then specialized ctype
// functionality should be added for the native os in question: see
// the config/os/bits/ctype_*.h files.
// Constructing a synthetic "C" table should be seriously considered...
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
ctype<char>::
is(mask __m, char __c) const
{
if (_M_table)
return _M_table[static_cast<unsigned char>(__c)] & __m;
else
{
bool __ret = false;
const size_t __bitmasksize = 15;
size_t __bitcur = 0; // Lowest bitmask in ctype_base == 0
for (; __bitcur <= __bitmasksize; ++__bitcur)
{
const mask __bit = static_cast<mask>(1 << __bitcur);
if (__m & __bit)
{
bool __testis;
switch (__bit)
{
case space:
__testis = isspace(__c);
break;
case print:
__testis = isprint(__c);
break;
case cntrl:
__testis = iscntrl(__c);
break;
case upper:
__testis = isupper(__c);
break;
case lower:
__testis = islower(__c);
break;
case alpha:
__testis = isalpha(__c);
break;
case digit:
__testis = isdigit(__c);
break;
case punct:
__testis = ispunct(__c);
break;
case xdigit:
__testis = isxdigit(__c);
break;
case alnum:
__testis = isalnum(__c);
break;
case graph:
__testis = isgraph(__c);
break;
#ifdef _GLIBCXX_USE_C99_CTYPE_TR1
case blank:
__testis = isblank(__c);
break;
#endif
default:
__testis = false;
break;
}
__ret |= __testis;
}
}
return __ret;
}
}
const char*
ctype<char>::
is(const char* __low, const char* __high, mask* __vec) const
{
if (_M_table)
while (__low < __high)
*__vec++ = _M_table[static_cast<unsigned char>(*__low++)];
else
{
// Highest bitmask in ctype_base == 11.
const size_t __bitmasksize = 15;
for (;__low < __high; ++__vec, ++__low)
{
mask __m = 0;
// Lowest bitmask in ctype_base == 0
size_t __i = 0;
for (;__i <= __bitmasksize; ++__i)
{
const mask __bit = static_cast<mask>(1 << __i);
if (this->is(__bit, *__low))
__m |= __bit;
}
*__vec = __m;
}
}
return __high;
}
const char*
ctype<char>::
scan_is(mask __m, const char* __low, const char* __high) const
{
if (_M_table)
while (__low < __high
&& !(_M_table[static_cast<unsigned char>(*__low)] & __m))
++__low;
else
while (__low < __high && !this->is(__m, *__low))
++__low;
return __low;
}
const char*
ctype<char>::
scan_not(mask __m, const char* __low, const char* __high) const
{
if (_M_table)
while (__low < __high
&& (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0)
++__low;
else
while (__low < __high && this->is(__m, *__low) != 0)
++__low;
return __low;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -0,0 +1,60 @@
// cxxabi.h subset for cancellation -*- C++ -*-
// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_forced.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_FORCED_H
#define _CXXABI_FORCED_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#ifdef __cplusplus
namespace __cxxabiv1
{
/**
* @brief Thrown as part of forced unwinding.
* @ingroup exceptions
*
* A magic placeholder class that can be caught by reference to
* recognize forced unwinding.
*/
class __forced_unwind
{
virtual ~__forced_unwind() throw();
// Prevent catch by value.
virtual void __pure_dummy() = 0;
};
}
#endif // __cplusplus
#pragma GCC visibility pop
#endif // __CXXABI_FORCED_H
@@ -0,0 +1,81 @@
// ABI Support -*- C++ -*-
// Copyright (C) 2016-2024 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_init_exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _CXXABI_INIT_EXCEPTION_H
#define _CXXABI_INIT_EXCEPTION_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#include <stddef.h>
#include <bits/c++config.h>
#ifndef _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_HAVE_CDTOR_CALLABI 0
#else
#define _GLIBCXX_HAVE_CDTOR_CALLABI 1
#endif
#ifdef __cplusplus
namespace std
{
class type_info;
}
namespace __cxxabiv1
{
struct __cxa_refcounted_exception;
extern "C"
{
// Allocate memory for the primary exception plus the thrown object.
void*
__cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
void
__cxa_free_exception(void*) _GLIBCXX_NOTHROW;
// Initialize exception (this is a GNU extension)
__cxa_refcounted_exception*
__cxa_init_primary_exception(void *__object, std::type_info *__tinfo,
void (_GLIBCXX_CDTOR_CALLABI *__dest) (void *))
_GLIBCXX_NOTHROW;
}
} // namespace __cxxabiv1
#endif
#pragma GCC visibility pop
#endif // _CXXABI_INIT_EXCEPTION_H
@@ -0,0 +1,59 @@
// Control various target specific ABI tweaks. Generic version.
// Copyright (C) 2004-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_tweaks.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_TWEAKS_H
#define _CXXABI_TWEAKS_H 1
#ifdef __cplusplus
namespace __cxxabiv1
{
extern "C"
{
#endif
// The generic ABI uses the first byte of a 64-bit guard variable.
#define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0)
#define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1
#define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1)
#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (2, 1)
__extension__ typedef int __guard __attribute__((mode (__DI__)));
// __cxa_vec_ctor has void return type.
typedef void __cxa_vec_ctor_return_type;
#define _GLIBCXX_CXA_VEC_CTOR_RETURN(x) return
// Constructors and destructors do not return a value.
typedef void __cxa_cdtor_return_type;
#ifdef __cplusplus
}
} // namespace __cxxabiv1
#endif
#endif
@@ -0,0 +1,72 @@
// Tag type for yielding ranges rather than values in <generator> -*- C++ -*-
// Copyright (C) 2023-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef _GLIBCXX_BITS_ELEMENTS_OF
#define _GLIBCXX_BITS_ELEMENTS_OF
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/version.h>
// C++ >= 23 && __glibcxx_coroutine
#if defined(__glibcxx_ranges) && defined(__glibcxx_generator)
#include <bits/ranges_base.h>
#include <bits/memoryfwd.h>
#if _GLIBCXX_HOSTED
# include <bits/allocator.h> // likely desirable if hosted.
#endif // HOSTED
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
/**
* @ingroup ranges
* @since C++23
* @{
*/
template<range _Range, typename _Alloc = allocator<byte>>
struct elements_of
{
[[no_unique_address]] _Range range;
[[no_unique_address]] _Alloc allocator = _Alloc();
};
template<typename _Range, typename _Alloc = allocator<byte>>
elements_of(_Range&&, _Alloc = _Alloc())
-> elements_of<_Range&&, _Alloc>;
/// @}
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __glibcxx_generator && __glibcxx_ranges
#endif // _GLIBCXX_BITS_ELEMENTS_OF

Some files were not shown because too many files have changed in this diff Show More