arch/hexagon/include/asm/bitops.h

Source file repositories/reference/linux-study-clean/arch/hexagon/include/asm/bitops.h

File Facts

System
Linux kernel
Corpus path
arch/hexagon/include/asm/bitops.h
Extension
.h
Size
6715 bytes
Lines
305
Domain
Architecture Layer
Bucket
arch/hexagon
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef _ASM_BITOPS_H
#define _ASM_BITOPS_H

#include <linux/compiler.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/barrier.h>

#ifdef __KERNEL__

/*
 * The offset calculations for these are based on BITS_PER_LONG == 32
 * (i.e. I get to shift by #5-2 (32 bits per long, 4 bytes per access),
 * mask by 0x0000001F)
 *
 * Typically, R10 is clobbered for address, R11 bit nr, and R12 is temp
 */

/**
 * test_and_clear_bit - clear a bit and return its old value
 * @nr:  bit number to clear
 * @addr:  pointer to memory
 */
static inline int test_and_clear_bit(int nr, volatile void *addr)
{
	int oldval;

	__asm__ __volatile__ (
	"	{R10 = %1; R11 = asr(%2,#5); }\n"
	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
	"1:	R12 = memw_locked(R10);\n"
	"	{ P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n"
	"	memw_locked(R10,P1) = R12;\n"
	"	{if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n"
	: "=&r" (oldval)
	: "r" (addr), "r" (nr)
	: "r10", "r11", "r12", "p0", "p1", "memory"
	);

	return oldval;
}

/**
 * test_and_set_bit - set a bit and return its old value
 * @nr:  bit number to set
 * @addr:  pointer to memory
 */
static inline int test_and_set_bit(int nr, volatile void *addr)
{
	int oldval;

	__asm__ __volatile__ (
	"	{R10 = %1; R11 = asr(%2,#5); }\n"
	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
	"1:	R12 = memw_locked(R10);\n"
	"	{ P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n"
	"	memw_locked(R10,P1) = R12;\n"
	"	{if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n"
	: "=&r" (oldval)
	: "r" (addr), "r" (nr)
	: "r10", "r11", "r12", "p0", "p1", "memory"
	);


	return oldval;

}

/**
 * test_and_change_bit - toggle a bit and return its old value
 * @nr:  bit number to set
 * @addr:  pointer to memory
 */
static inline int test_and_change_bit(int nr, volatile void *addr)
{
	int oldval;

	__asm__ __volatile__ (
	"	{R10 = %1; R11 = asr(%2,#5); }\n"
	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n"
	"1:	R12 = memw_locked(R10);\n"
	"	{ P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n"
	"	memw_locked(R10,P1) = R12;\n"
	"	{if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n"
	: "=&r" (oldval)
	: "r" (addr), "r" (nr)
	: "r10", "r11", "r12", "p0", "p1", "memory"
	);

	return oldval;

Annotation

Implementation Notes