User Tools

Site Tools


documentation:amask

Architecture Mask (amask)

The Architecture Mask instruction, AMASK, reports which instruction set extensions the processor implements. Its companion, IMPLVER, reports only the processor generation (0 for the 21064 family, 1 for the 21164 family, 2 for the 21264, 3 for the 21364), and is meant for tuning decisions rather than for choosing instructions. 1) User programs on Linux normally do not execute AMASK themselves, but read the kernel's AT_HWCAP value with getauxval(), as shown below. The table of which processor introduced each extension is under Instruction Set: ISA extensions.

Semantics

AMASK clears the bits of its operand that correspond to extensions the processor implements, and copies through unchanged the bits for reserved and absent extensions. From the Architecture Reference Manual:

Rbv represents a mask of the requested architectural extensions. Bits are cleared that correspond to architectural extensions that are present. Reserved bits and bits that correspond to absent extensions are copied unchanged. In either case, the result is placed in Rc. If the result is zero, all requested features are present.

Software may specify an Rbv of all 1's to determine the complete set of architectural extensions implemented by a processor.

The polarity is inverted relative to the usual convention: a bit that remains set means the extension is absent.

Bit assignments

Bit Extension
0 byte/word extension (BWX): LDBU, LDWU, SEXTB, SEXTW, STB, STW
1 square-root and floating-point convert extension (FIX)
2 count extension (CIX): CTLZ, CTPOP, CTTZ
8 multimedia extension (MVI)
9 precise arithmetic trap reporting in hardware
12 prefetch with modify intent

Per-processor behavior

On the earliest implementations AMASK is a no-op that copies its operand straight through, so every extension correctly reports as absent:

  • On 21064/21064A/21066/21068/21066A (EV4/EV45/LCA/LCA45 chips), AMASK copies Rbv to Rc.
  • On 21164 (EV5), AMASK copies Rbv to Rc.
  • On 21164A (EV56), 21164PC (PCA56), and 21264 (EV6), AMASK correctly indicates support for architecture extensions by copying Rbv to Rc and clearing appropriate bits.

The 21264 hardware reference manuals give the feature mask each processor reports, that is, the bits that AMASK clears, and the value of AT_HWCAP under Linux:

Processor Feature mask Extensions
EV6 (21264), pass 1 0x001 BWX 2)
EV6 (21264), pass 2 0x303 BWX, FIX, MVI, precise traps
EV67 (21264A) 0x307 BWX, FIX, CIX, MVI, precise traps 3)
EV68CB and EV68DC 0x1307 BWX, FIX, CIX, MVI, precise traps, prefetch with modify intent 4)

Example

This program uses GCC's __builtin_alpha_amask intrinsic to determine which architectural extensions are present in the host CPU.

#include <stdio.h>
 
enum CPUFeatures {
    BWX = 1UL << 0,
    FIX = 1UL << 1,
    CIX = 1UL << 2,
    MVI = 1UL << 8,
};
 
int main(void)
{
	/* amask clears the bits of extensions that are implemented, so a
	   bit remaining set means the extension is absent. */
	unsigned long absent = __builtin_alpha_amask(~0UL);
 
	printf("%lX\n", absent);
	if (!(absent & BWX)) puts("BWX supported.");
	if (!(absent & FIX)) puts("FIX supported.");
	if (!(absent & CIX)) puts("CIX supported.");
	if (!(absent & MVI)) puts("MVI supported.");
	return 0;
}

In the kernel

Linux wraps the instruction in arch/alpha/include/asm/special_insns.h:

enum amask_enum {
	AMASK_BWX = (1UL << 0),
	AMASK_FIX = (1UL << 1),
	AMASK_CIX = (1UL << 2),
	AMASK_MAX = (1UL << 8),
	AMASK_PRECISE_TRAP = (1UL << 9),
};
 
#define amask(mask)						\
({ unsigned long __amask, __input = (mask);			\
   __asm__ ("amask %1,%0" : "=r"(__amask) : "rI"(__input));	\
   __amask; })

Kernel code tests it with the architectural polarity, for example if (!amask(AMASK_PRECISE_TRAP)). The sense is inverted once, on the way out to userspace, so that the bits in AT_HWCAP are set for features that are present:

#define ELF_HWCAP  (~amask(-1))

A user program therefore tests the bits of AT_HWCAP directly, without the inversion: 5)

#include <stdio.h>
#include <sys/auxv.h>
 
int main(void)
{
	/* The kernel inverts AMASK's result, so a set bit means present. */
	unsigned long hwcap = getauxval(AT_HWCAP);
 
	if (hwcap & (1UL << 0)) puts("BWX supported.");
	if (hwcap & (1UL << 1)) puts("FIX supported.");
	if (hwcap & (1UL << 2)) puts("CIX supported.");
	if (hwcap & (1UL << 8)) puts("MVI supported.");
	return 0;
}

The kernel also passes a processor class as AT_PLATFORM: ev56 for any 21164-family processor, ev6 for any later processor without CIX, and ev67 for one with it. 6) Both values can be checked without writing a program: LD_SHOW_AUXV=1 makes the dynamic linker print the auxiliary vector, including HWCAP in hexadecimal and PLATFORM, before running the program named. 7)

LD_SHOW_AUXV=1 /bin/true

References

documentation/amask.txt · Last modified: by 127.0.0.1