lib/crc/x86/crc-pclmul-template.S

Source file repositories/reference/linux-study-clean/lib/crc/x86/crc-pclmul-template.S

File Facts

System
Linux kernel
Corpus path
lib/crc/x86/crc-pclmul-template.S
Extension
.S
Size
21549 bytes
Lines
576
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: lib
Status
atlas-only

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

//
// Template to generate [V]PCLMULQDQ-based CRC functions for x86
//
// Copyright 2025 Google LLC
//
// Author: Eric Biggers <ebiggers@google.com>

#include <linux/linkage.h>
#include <linux/objtool.h>

// Offsets within the generated constants table
.set OFFSETOF_BSWAP_MASK,			-5*16	// msb-first CRCs only
.set OFFSETOF_FOLD_ACROSS_2048_BITS_CONSTS,	-4*16	// must precede next
.set OFFSETOF_FOLD_ACROSS_1024_BITS_CONSTS,	-3*16	// must precede next
.set OFFSETOF_FOLD_ACROSS_512_BITS_CONSTS,	-2*16	// must precede next
.set OFFSETOF_FOLD_ACROSS_256_BITS_CONSTS,	-1*16	// must precede next
.set OFFSETOF_FOLD_ACROSS_128_BITS_CONSTS,	0*16	// must be 0
.set OFFSETOF_SHUF_TABLE,			1*16
.set OFFSETOF_BARRETT_REDUCTION_CONSTS,		4*16

// Emit a VEX (or EVEX) coded instruction if allowed, or emulate it using the
// corresponding non-VEX instruction plus any needed moves.  The supported
// instruction formats are:
//
//     - Two-arg [src, dst], where the non-VEX format is the same.
//     - Three-arg [src1, src2, dst] where the non-VEX format is
//	 [src1, src2_and_dst].  If src2 != dst, then src1 must != dst too.
//
// \insn gives the instruction without a "v" prefix and including any immediate
// argument if needed to make the instruction follow one of the above formats.
// If \unaligned_mem_tmp is given, then the emitted non-VEX code moves \arg1 to
// it first; this is needed when \arg1 is an unaligned mem operand.
.macro	_cond_vex	insn:req, arg1:req, arg2:req, arg3, unaligned_mem_tmp
.if AVX_LEVEL == 0
  // VEX not allowed.  Emulate it.
  .ifnb \arg3 // Three-arg [src1, src2, dst]
    .ifc "\arg2", "\arg3" // src2 == dst?
      .ifnb \unaligned_mem_tmp
	movdqu		\arg1, \unaligned_mem_tmp
	\insn		\unaligned_mem_tmp, \arg3
      .else
	\insn		\arg1, \arg3
      .endif
    .else // src2 != dst
      .ifc "\arg1", "\arg3"
	.error "Can't have src1 == dst when src2 != dst"
      .endif
      .ifnb \unaligned_mem_tmp
	movdqu		\arg1, \unaligned_mem_tmp
	movdqa		\arg2, \arg3
	\insn		\unaligned_mem_tmp, \arg3
      .else
	movdqa		\arg2, \arg3
	\insn		\arg1, \arg3
      .endif
    .endif
  .else // Two-arg [src, dst]
    .ifnb \unaligned_mem_tmp
	movdqu		\arg1, \unaligned_mem_tmp
	\insn		\unaligned_mem_tmp, \arg2
    .else
	\insn		\arg1, \arg2
    .endif
  .endif
.else
  // VEX is allowed.  Emit the desired instruction directly.
  .ifnb \arg3
	v\insn		\arg1, \arg2, \arg3
  .else
	v\insn		\arg1, \arg2

Annotation

Implementation Notes