From 779939b2553d7aff642f2ca81021b53a967935c9 Mon Sep 17 00:00:00 2001 From: Ralf Corsepius Date: Tue, 15 Feb 2005 17:43:25 +0000 Subject: (_CPU_Bitfield_Find_first_bit, _CPU_Priority_Mask, _CPU_Priority_bits_index): New. --- cpukit/score/cpu/powerpc/rtems/score/cpu.h | 88 ++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'cpukit/score') diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h index 90563f09d6..6f1ac9b02f 100644 --- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h +++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h @@ -275,6 +275,94 @@ void _CPU_Context_Initialize( /* end of Context handler macros */ #endif /* ASM */ +#ifndef ASM +/* Bitfield handler macros */ + +/* + * This routine sets _output to the bit number of the first bit + * set in _value. _value is of CPU dependent type Priority_Bit_map_control. + * This type may be either 16 or 32 bits wide although only the 16 + * least significant bits will be used. + * + * There are a number of variables in using a "find first bit" type + * instruction. + * + * (1) What happens when run on a value of zero? + * (2) Bits may be numbered from MSB to LSB or vice-versa. + * (3) The numbering may be zero or one based. + * (4) The "find first bit" instruction may search from MSB or LSB. + * + * RTEMS guarantees that (1) will never happen so it is not a concern. + * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and + * _CPU_Priority_Bits_index(). These three form a set of routines + * which must logically operate together. Bits in the _value are + * set and cleared based on masks built by _CPU_Priority_mask(). + * The basic major and minor values calculated by _Priority_Major() + * and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index() + * to properly range between the values returned by the "find first bit" + * instruction. This makes it possible for _Priority_Get_highest() to + * calculate the major and directly index into the minor table. + * This mapping is necessary to ensure that 0 (a high priority major/minor) + * is the first bit found. + * + * This entire "find first bit" and mapping process depends heavily + * on the manner in which a priority is broken into a major and minor + * components with the major being the 4 MSB of a priority and minor + * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest + * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next + * to the lowest priority. + * + * If your CPU does not have a "find first bit" instruction, then + * there are ways to make do without it. Here are a handful of ways + * to implement this in software: + * + * - a series of 16 bit test instructions + * - a "binary search using if's" + * - _number = 0 + * if _value > 0x00ff + * _value >>=8 + * _number = 8; + * + * if _value > 0x0000f + * _value >=8 + * _number += 4 + * + * _number += bit_set_table[ _value ] + * + * where bit_set_table[ 16 ] has values which indicate the first + * bit set + */ + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { \ + asm volatile ("cntlzw %0, %1" : "=r" ((_output)), "=r" ((_value)) : \ + "1" ((_value))); \ + } + +/* end of Bitfield handler macros */ + +/* + * This routine builds the mask which corresponds to the bit fields + * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion + * for that routine. + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 0x80000000 >> (_bit_number) ) + +/* + * This routine translates the bit numbers returned by + * _CPU_Bitfield_Find_first_bit() into something suitable for use as + * a major or minor component of a priority. See the discussion + * for that routine. + */ + +#define _CPU_Priority_bits_index( _priority ) \ + (_priority) + +/* end of Priority handler macros */ +#endif /* ASM */ + /* functions */ #ifndef ASM -- cgit v1.2.3