kernel/util/index.html · kernel/util/index.rst 공식 원문 ↗

Zephyr 3.7.0 · Kernel · sys-util

Utilities

Compile-time macro와 작은 runtime helper를 정확한 signature·제약·반환 규칙과 함께 기능군별로 찾아봅니다.

Official pathkernel/util/index.html
Source filekernel/util/index.rst
Source versionZephyr 3.7.0
TranslationFull · reviewed

본문 기준: Zephyr 3.7.0 LTS3 · 이후 유지보수 패치는 별도입니다.

Part 1

요약·해설

공식 Doxygen의 82개 macro와 19개 function, 예제 코드 34개를 원래 순서와 내용 그대로 연결한 한국어 reference입니다.

Macro

82 definitions

Function

19 definitions

Examples

34 exact blocks

Part 2

접을 수 있는 영어 원문 전체

영어 원문 전체 펼치기
원문 SHA-256 98623C34B5673F0774042C6A426924C918E954350B5FC583F6616E87F5DF860B
.. _util_api:

Utilities
#########

This page contains reference documentation for ``<sys/util.h>``, which provides
miscellaneous utility functions and macros.

.. doxygengroup:: sys-util

Part 3

한국어 전문 번역

이 페이지는 가 제공하는 miscellaneous utility function과 macro의 reference입니다. Doxygen group 이름은 sys-util이며 pointer cast, array·type inspection, bitfield, arithmetic, compile-time metaprogramming, encoding·memory helper까지 포함합니다.

sys-util 기능 지도
Pointer · field

cast · mask · compile check

Array · type

bounds · container · token

Arithmetic

align · round · units · wait

Bit · config

mask · Kconfig conditional

Variadic macro

map · list · index · paste

Runtime helper

convert · UTF-8 · XOR

아래 101개 정의는 공식 Doxygen 렌더링 순서를 유지합니다.

Pointer·bitfield·compile-time 기본 매크로

POINTER_TO_UINT(x)

Pointer x를 unsigned integer로 cast합니다.

UINT_TO_POINTER(x)

Unsigned integer x를 void pointer로 cast합니다.

POINTER_TO_INT(x)

Pointer x를 signed integer로 cast합니다.

INT_TO_POINTER(x)

Signed integer x를 void pointer로 cast합니다.

BITS_PER_LONG

long int 한 개의 bit 수입니다.

BITS_PER_LONG_LONG

long long int 한 개의 bit 수입니다.

GENMASK(h, l)

Bit position l에서 h까지 연속해서 1인 bitmask를 만듭니다.

GENMASK64(h, l)

Bit position l에서 h까지 연속해서 1인 64-bit bitmask를 만듭니다.

LSB_GET(value)

value에서 least-significant bit를 추출합니다.

FIELD_GET(mask, value)

mask가 나타내는 field position과 width에 맞춰 value의 bitfield element를 추출합니다.

FIELD_PREP(mask, value)

mask가 나타내는 field position과 width에 value를 배치합니다. 결과는 다른 field와 logical OR로 결합해야 합니다.

ZERO_OR_COMPILE_ERROR(cond)

cond가 true로 평가되면 0이고, 그렇지 않으면 compile error를 발생시킵니다.

Array·type·container 매크로

IS_ARRAY(array)

array가 array type이면 0이고 아니면 compile error입니다. C에서만 제공되며 C++에서는 사용할 수 없습니다.

ARRAY_SIZE(array)

주어진 array의 element 수를 반환합니다. C에서 pointer를 넘기면 compile error입니다. C++에서는 language 제약 때문에 operator[]를 구현한 type도 array로 받아들일 수 있어 결과가 의미 없을 수 있습니다.

IS_ARRAY_ELEMENT(array, ptr)

ptr이 array element인지 확인합니다. PART_OF_ARRAY보다 엄격해 array-element boundary alignment도 검사합니다. C에서 array 자리에 pointer를 넘기면 compile error이며, array에 속하면 1, 아니면 0을 반환합니다.

ARRAY_INDEX(array, ptr)

array 안 element ptr의 index를 반환합니다. CONFIG_ASSERT=y에서는 ptr이 범위 밖이거나 element boundary에 align되지 않으면 runtime assertion이 발생합니다. C에서 array 자리에 pointer를 넘기면 compile error입니다.

PART_OF_ARRAY(array, ptr)

ptr이 array 범위 안에 있는지 검사해 1 또는 0을 반환합니다. C에서는 array가 실제 array가 아니면 compile error를 내어 ptr과 array를 뒤바꾼 실수를 잡지만 C++에는 이 검사가 없습니다.

ARRAY_INDEX_FLOOR(array, ptr)

array 범위 안의 임의 ptr을 바로 아래 element index로 내림합니다. ARRAY_INDEX와 달리 element boundary alignment를 요구하지 않으며 CONFIG_ASSERT=y에서는 범위 밖 ptr에 runtime assertion을 냅니다.

ARRAY_FOR_EACH(array, idx)

idx라는 index variable로 array member를 순회합니다. array는 대상 array, idx는 사용할 index variable 이름입니다.

ARRAY_FOR_EACH_PTR(array, ptr)

ptr을 각 element pointer로 두고 array member를 순회합니다.

SAME_TYPE(a, b)

a와 b의 type이 compatible하면 1, 아니면 0을 반환합니다.

CONTAINER_OF_VALIDATE(ptr, type, field)

CONTAINER_OF parameter를 검증합니다. C mode에만 적용됩니다.

CONTAINER_OF(ptr, type, field)

Structure element ptr에서 그 element를 포함하는 structure의 pointer를 구합니다. ptr은 member pointer, type은 containing type, field는 member name이며 containing structure pointer를 반환합니다.

 struct foo {
    int bar;
 };

 struct foo my_foo;
 int *ptr = &my_foo.bar;

 struct foo *container = CONTAINER_OF(ptr, struct foo, bar);

예제에서 container는 my_foo를 가리킵니다.

SIZEOF_FIELD(type, member)

type structure의 member field 크기를 byte 단위로 반환합니다.

CONCAT(...)

Preprocessor pass에서 입력 token을 하나의 token으로 연결합니다. Number, 다른 macro, macro argument 등을 조합해 identifier를 만들 수 있습니다. 가변 인자는 연결할 token이며 결합된 token을 반환합니다.

Alignment·산술·단위·대기 매크로

IS_ALIGNED(ptr, align)

ptr이 align boundary에 맞춰 정렬됐는지 확인합니다.

ROUND_UP(x, align)

x를 align의 다음 multiple로 올림합니다.

ROUND_DOWN(x, align)

x를 align의 이전 multiple로 내림합니다.

WB_UP(x)

x를 다음 word boundary로 올림합니다.

WB_DN(x)

x를 이전 word boundary로 내림합니다.

DIV_ROUND_UP(n, d)

Numerator n을 denominator d로 나눈 값을 올림해 반환합니다.

DIV_ROUND_UP(1, 2); // 1
DIV_ROUND_UP(3, 2); // 2
DIV_ROUND_CLOSEST(n, d)

n / d를 가장 가까운 integer로 반올림합니다. 음수 denominator도 예제와 같이 처리합니다.

DIV_ROUND_CLOSEST(5, 2); // 3
DIV_ROUND_CLOSEST(5, -2); // -3
DIV_ROUND_CLOSEST(5, 3); // 2
ceiling_fraction(numerator, divider)

numerator / divider fraction에 ceiling을 적용합니다. Deprecated API이므로 DIV_ROUND_UP()을 사용해야 합니다.

MAX(a, b)

a와 b 중 maximum을 반환합니다. Argument가 두 번 평가되므로 side effect에 주의해야 하며 GCC-only single-evaluation variant는 Z_MAX입니다.

MIN(a, b)

a와 b 중 minimum을 반환합니다. Argument가 두 번 평가되므로 side effect에 주의해야 하며 GCC-only single-evaluation variant는 Z_MIN입니다.

CLAMP(val, low, high)

val을 inclusive range [low, high] 안으로 제한합니다. Argument가 여러 번 평가되며 GCC-only single-evaluation variant는 Z_CLAMP입니다.

IN_RANGE(val, min, max)

val이 inclusive range [min, max] 안이면 true, 아니면 false입니다. val은 두 번 평가됩니다.

LOG2(x)

Positive unsigned integral x의 log2를 계산합니다. 1 이상이면 log2(x), 1 미만이면 -1입니다. Constant expression 지원을 위해 argument를 여러 번 확장하므로 side effect가 없어야 합니다.

LOG2CEIL(x)

Unsigned integral x에 ceil(log2(x))를 적용합니다. 1 미만이면 0입니다. Argument를 여러 번 확장하므로 side effect가 없어야 합니다.

NHPOT(x)

x 이상인 다음 power of two, 즉 2^ceil(log2(x))를 계산합니다. 결과가 64-bit를 saturate하면 0입니다. Argument에 side effect가 없어야 합니다.

KB(x)

x kibibyte에 해당하는 byte 수입니다.

MB(x)

x mebibyte에 해당하는 byte 수입니다.

GB(x)

x gibibyte에 해당하는 byte 수입니다.

KHZ(x)

x kHz에 해당하는 Hz 수입니다.

MHZ(x)

x MHz에 해당하는 Hz 수입니다.

WAIT_FOR(expr, timeout, delay_stmt)

expr이 true가 될 때까지 timeout microsecond 동안 spin하고 iteration 사이에 optional delay_stmt를 실행합니다. Hardware read/write/initialize/reset 같은 asynchronous request 대기에 흔히 씁니다. delay_stmt에는 NULL, k_yield(), k_msleep(1), k_busy_wait(1) 등을 줄 수 있으며 timeout이면 boolean false를 반환합니다.

Bit·configuration 조건 매크로

BIT(n)

Bit position n만 set된 unsigned integer를 만듭니다. Assembly language에서는 signed입니다.

BIT64(_n)

Bit position _n만 set된 64-bit unsigned integer를 만듭니다.

WRITE_BIT(var, bit, set)

Boolean set 값에 따라 variable var의 bit 번호 bit를 clear하거나 set합니다. set이 0이면 clear하고 그 외에는 set하며 var를 side effect로 변경합니다.

BIT_MASK(n)

Bit 0부터 n-1까지 set된 mask를 만들며 n이 0이면 0입니다.

BIT64_MASK(n)

Bit 0부터 n-1까지 set된 64-bit mask를 만들며 n이 0이면 0입니다.

IS_POWER_OF_TWO(x)

x가 power of two인지 검사합니다.

IS_SHIFTED_BIT_MASK(m, s)

m에서 s를 lowest bit로 하여 bit가 끊기지 않고 연속해서 set됐는지 검사합니다. Bit width에 의존하지 않습니다.

IS_BIT_MASK(m)

m의 bit가 LSB부터 끊기지 않고 연속해서 set됐는지 검사합니다.

IS_ENABLED(config_macro)

config_macro가 literal 1로 정의되면 1, 정의되지 않았거나 그 외이면 0입니다. Linux config_enabled() 기법처럼 Kconfig macro를 preprocessor 전용 조건이 아닌 C compiler가 볼 수 있는 expression으로 바꿉니다. CONFIG_FOO가 없어도 compiler가 branch 안 code의 error와 warning을 검사할 수 있습니다. #if 안에서는 plain #if defined()보다 이점이 없으므로 권장하지 않습니다.

if (IS_ENABLED(CONFIG_FOO)) {
        do_something_with_foo
}
COND_CODE_1(_flag, _if_1_code, _else_code)

_flag가 integer literal 1로 확장되면 _if_1_code, 아니면 _else_code를 그 자리에서 확장합니다. Comma가 argument separator로 처리되지 않도록 두 code expression을 괄호로 감싸야 하며 확장 때 괄호는 제거됩니다. _flag는 macro expansion 결과여도 되지만 arithmetic 결과가 1인 expression은 안 되고 literal 1이어야 합니다.

COND_CODE_1(CONFIG_FLAG, (uint32_t x;), (there_is_no_flag();))
uint32_t x;

동일한 preprocessor 분기는 다음처럼 별도 macro를 정의하는 방식으로도 쓸 수 있지만 COND_CODE_1은 사용 위치에서 바로 해결돼 더 간결합니다.

#if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1)
#define MAYBE_DECLARE(x) uint32_t x
#else
#define MAYBE_DECLARE(x) there_is_no_flag()
#endif

MAYBE_DECLARE(x);
COND_CODE_0(_flag, _if_0_code, _else_code)

COND_CODE_1과 같지만 _flag가 integer literal 0인지 검사합니다. 0이면 괄호 안 _if_0_code, 아니면 _else_code를 확장합니다.

IF_ENABLED(_flag, _code)

_flag가 정의돼 literal 1이면 괄호 안 _code를 넣고, 아니면 아무것도 넣지 않습니다. #if defined(CONFIG_FLAG) 분기의 compact alternative입니다.

IF_ENABLED(CONFIG_FLAG, (uint32_t foo;))
uint32_t foo;
#if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1)
uint32_t foo;
#endif
IF_DISABLED(_flag, _code)

_flag가 정의되지 않았거나 1이 아니면 괄호 안 _code를 넣고, 1이면 아무것도 넣지 않습니다. IF_ENABLED의 반대입니다.

IF_DISABLED(CONFIG_FLAG, (uint32_t foo;))
uint32_t foo;
IS_EMPTY(...)

Macro replacement expression이 비어 있는지 검사하며 __VA_ARGS__의 empty argument 처리에 COND_CODE_1·COND_CODE_0과 함께 사용할 수 있습니다. Defined macro만 지원하므로 경우에 따라 #ifdef가 추가로 필요합니다. 문서 예제에서 EMPTY, NON_EMPTY, UNDEFINED는 각각 true, false, true를 반환하고 조건부 code가 포함됩니다.

 #define EMPTY
 #define NON_EMPTY  1
 #undef  UNDEFINED
 IS_EMPTY(EMPTY)
 IS_EMPTY(NON_EMPTY)
 IS_EMPTY(UNDEFINED)
 #if defined(EMPTY) && IS_EMPTY(EMPTY) == true
 some_conditional_code
 #endif
IS_EQ(a, b)

C preprocessor 단계에서 a == b처럼 평가하고 short-circuit합니다. Integer literal 0~4095에만 동작합니다.

LIST_DROP_EMPTY(...)

__VA_ARGS__ 같은 preprocessor-generated list에서 empty element를 제거합니다. FOR_EACH가 empty element까지 처리하지 않게 만들 때 사용합니다.

 #define LIST ,a,b,,d,

LIST를 EMPTY 표기로 펼치면 다음과 같습니다.

 EMPTY, a, b, EMPTY, d

LIST_DROP_EMPTY을 적용하면 empty item이 사라집니다.

 LIST_DROP_EMPTY(LIST)
 a, b, d
EMPTY

아무것도 확장하지 않는 macro입니다. Empty result가 필요할 때 의도를 드러내고 checkpatch warning을 피하는 데 사용합니다.

 #define LIST_ITEM(n) , item##n

앞에 EMPTY를 명시하면 같은 expansion을 유지하면서 의도를 표현합니다.

 #define LIST_ITEM(n) EMPTY, item##n
IDENTITY(V)

Argument V를 그대로 확장합니다. FOR_EACH에서 list element transformation이 필요 없을 때 유용합니다.

Variadic list·mapping 매크로

GET_ARG_N(N, ...)

1부터 세는 index N에 해당하는 variadic argument를 반환합니다.

GET_ARGS_LESS_N(N, ...)

가변 argument list의 앞 N개를 버리고 나머지 list를 반환합니다.

UTIL_OR(a, b)

C preprocessor 단계에서 a || b처럼 평가하고 short-circuit합니다. Binary ||와 달리 a는 literal 0 또는 1로 확장돼야 하지만 b는 어떤 값도 가능합니다. a가 1일 때 b를 확장하면 build error가 나는 경우를 피할 수 있습니다.

UTIL_AND(a, b)

C preprocessor 단계에서 a && b처럼 평가하고 short-circuit합니다. a는 literal 0 또는 1이어야 하지만 b는 어떤 값도 가능하며, a가 0일 때 b expansion이 build error를 내는 경우를 피할 수 있습니다.

UTIL_INC(x)

Integer literal x가 0~4095이면 x+1인 literal로 확장합니다. UTIL_DEC의 반대입니다.

UTIL_DEC(x)

Integer literal x가 0~4095이면 x-1인 literal로 확장합니다. UTIL_INC의 반대입니다.

UTIL_X2(y)

Integer literal y가 0~4095이면 2y인 literal로 확장합니다.

LISTIFY(LEN, F, sep, ...)

Length LEN만큼 F(i, ...)를 반복 호출해 sep로 구분한 code sequence를 만듭니다. LEN은 4095 미만 integer literal이고 sep는 comma도 받을 수 있게 괄호로 감싸야 합니다. Undefined argument로 호출하면 undefined behavior입니다.

#define FOO(i, _) MY_PWM ## i
{ LISTIFY(PWM_COUNT, FOO, (,)) }

예제는 PWM_COUNT가 2일 때 { MY_PWM0 , MY_PWM1 }로 확장됩니다.

FOR_EACH(F, sep, ...)

가변 argument 각각에 F(element)를 호출하고 호출 사이에 괄호로 감싼 sep를 넣습니다.

#define F(x) int a##x
FOR_EACH(F, (;), 4, 5, 6);

확장 결과는 다음과 같습니다.

int a4;
int a5;
int a6;
FOR_EACH_NONEMPTY_TERM(F, term, ...)

FOR_EACH와 비슷하지만 separator 대신 각 F 호출 뒤 terminator를 붙이고 empty element는 버립니다. Empty argument list이면 아무것도 확장하지 않아, 비어 있을 수 있는 __VA_ARGS__ 결과를 더 큰 initializer에 넣기 편합니다.

FOR_EACH(F, (sep), a, b) // F(a) sep F(b)
                         //               ^^^ no sep here!
FOR_EACH_NONEMPTY_TERM(F, (term), a, b) // F(a) term F(b) term
                                        //                ^^^^
FOR_EACH_NONEMPTY_TERM(F, (term), a, EMPTY, b) // F(a) term F(b) term

여러 optional list를 initializer에 이어 붙이는 예시는 다음과 같습니다.

#define SQUARE(x) ((x)*(x))

int my_array[] = {
        FOR_EACH_NONEMPTY_TERM(SQUARE, (,), FOO(...))
        FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAR(...))
        FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAZ(...))
};
FOR_EACH_IDX(F, sep, ...)

각 argument에 F(index, element)를 호출하고 sep로 구분합니다. Index는 0부터 시작합니다.

#define F(idx, x) int a##idx = x
FOR_EACH_IDX(F, (;), 4, 5, 6);

확장 결과는 다음과 같습니다.

int a0 = 4;
int a1 = 5;
int a2 = 6;
FOR_EACH_FIXED_ARG(F, sep, fixed_arg, ...)

각 variable element에 같은 fixed_arg를 더해 F(element, fixed_arg)를 호출하고 sep로 구분합니다.

static void func(int val, void *dev);
FOR_EACH_FIXED_ARG(func, (;), dev, 4, 5, 6);

확장 결과는 다음과 같습니다.

func(4, dev);
func(5, dev);
func(6, dev);
FOR_EACH_IDX_FIXED_ARG(F, sep, fixed_arg, ...)

FOR_EACH_IDX와 FOR_EACH_FIXED_ARG를 결합해 각 element마다 F(index, element, fixed_arg)를 호출합니다.

#define F(idx, x, fixed_arg) int fixed_arg##idx = x
FOR_EACH_IDX_FIXED_ARG(F, (;), a, 4, 5, 6);

확장 결과는 다음과 같습니다.

int a0 = 4;
int a1 = 5;
int a2 = 6;
REVERSE_ARGS(...)

가변 argument list의 순서를 뒤집습니다.

NUM_VA_ARGS_LESS_1(...)

Variadic argument 수에서 1을 뺀 값을 반환하며 최대 64개 argument를 지원합니다.

NUM_VA_ARGS(...)

Variadic argument 수를 반환하며 최대 63개 argument를 지원합니다.

MACRO_MAP_CAT(...)

첫 argument인 one-argument macro를 나머지 각 argument에 적용하고 결과를 하나의 token으로 paste합니다. FOR_EACH와 달리 separator 없이 단일 token을 만듭니다.

#define FOO(x) item_##x##_

MACRO_MAP_CAT(FOO, a, b, c)의 결과는 다음 token입니다.

item_a_item_b_item_c_
MACRO_MAP_CAT_N(N, ...)

MACRO_MAP_CAT과 같지만 mapping할 argument 수 N을 고정합니다. N보다 많은 argument는 무시하고 각 expansion 결과를 한 token으로 붙입니다.

Runtime utility 함수

static inline bool is_power_of_two(unsigned int x)

Unsigned x가 power of two이면 true, 아니면 false를 반환합니다.

ALWAYS_INLINE static bool is_null_no_warn(void *p)

Pointer p가 NULL이면 true입니다. Macro argument가 절대 NULL일 수 없는 context에서 직접 NULL check가 compiler warning을 만들 수 있으므로 이 inline function으로 검사합니다. CONFIG_COMPILER_SAVE_TEMPS=y 또는 -ftrack-macro-expansion=0에서도 warning을 피하면서 compiler는 후속 optimization에서 check를 제거할 수 있습니다.

static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift)

Signed 64-bit value를 shift bit만큼 arithmetic right shift하며 새로 열린 bit position은 sign bit로 채웁니다.

static inline void bytecpy(void *dst, const void *src, size_t size)

src에서 dst로 size byte를 반드시 byte-by-byte 방식으로 copy합니다.

static inline void byteswp(void *a, void *b, size_t size)

Memory region a와 b 사이 size byte를 반드시 byte-by-byte 방식으로 swap합니다.

int char2hex(char c, uint8_t *x)

문자 c 하나를 hexadecimal nibble로 변환해 x에 저장합니다. 성공하면 0, 실패하면 negative error code입니다.

int hex2char(uint8_t x, char *c)

Hexadecimal nibble x 하나를 문자로 변환해 c에 저장합니다. 성공하면 0, 실패하면 negative error code입니다.

size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen)

buflen byte binary array를 string representation으로 바꿔 size hexlen의 hex storage에 저장합니다. 변환 string 길이를 반환하고 error이면 0입니다.

size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen)

길이 hexlen의 hexadecimal string을 binary array로 바꿔 size buflen의 buf에 저장합니다. Binary array 길이를 반환하고 error이면 0입니다.

static inline uint8_t bcd2bin(uint8_t bcd)

BCD 8421 값을 binary representation으로 변환합니다.

static inline uint8_t bin2bcd(uint8_t bin)

Binary value를 BCD 8421 representation으로 변환합니다.

uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value)

uint8_t value를 ASCII decimal string으로 바꿔 size buflen의 buf에 저장합니다. 공간이 충분하면 NULL terminator를 붙입니다. Terminator를 제외한 변환 길이를 반환하고 error이면 0입니다.

static inline int32_t sign_extend(uint32_t value, uint8_t index)

8·16·32-bit value에서 0-based index(0~31)를 sign bit로 사용해 int32_t로 sign extension합니다.

static inline int64_t sign_extend_64(uint64_t value, uint8_t index)

64-bit value에서 0-based index(0~63)를 sign bit로 사용해 int64_t로 sign extension합니다.

char *utf8_trunc(char *utf8_str)

이미 다른 방식으로 NULL terminator가 삽입돼 잘린 UTF-8 string이 올바른 1~4 byte UTF-8 character boundary에서 끝나도록 다시 truncate하고 원래 utf8_str pointer를 반환합니다.

char *utf8_lcpy(char *dst, const char *src, size_t n)

UTF-8 src를 dst로 copy합니다. n이 0보다 크면 dst는 항상 NULL-terminated이고 올바른 UTF-8 boundary에서 잘립니다. 최대 n-1 character를 copy하며 n=0이면 아무 작업도 하지 않고 terminator도 쓰지 않습니다. dst를 반환합니다.

static inline void mem_xor_n(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, size_t len)

길이 len byte인 src1과 src2를 byte-wise XOR해 길이 len byte의 dst에 저장합니다.

static inline void mem_xor_32(uint8_t dst[4], const uint8_t src1[4], const uint8_t src2[4])

32-bit src1과 src2를 XOR해 32-bit dst에 저장합니다.

static inline void mem_xor_128(uint8_t dst[16], const uint8_t src1[16], const uint8_t src2[16])

128-bit src1과 src2를 XOR해 128-bit dst에 저장합니다.

Source

출처

영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.