The __cregister Keyword

The compiler extends the C/C++ language by adding the __cregister keyword to allow high level language access to control registers.

When you use the __cregister keyword on an object, the compiler compares the name of the object to a list of standard control registers (see Table 7-4). If the name matches, the compiler generates the code to reference the control register. If the name does not match, the compiler issues an error.

Table 7-4 Control Registers for C64x+, C6740, and C6600

Register Description
AMR Addressing mode register
CSR Control status register
DNUM DSP core number register
ECR Exception clear register
EFR Exception flag register
GFPGFR Galois field multiply control register
GPLYA GMPY A-side polynomial register
GPLYB GMPY B-side polynomial register
ICR Interrupt clear register
IER Interrupt enable register
IERR Internal exception report register
IFR Interrupt flag register. (IFR is read only.)
ILC Inner loop count register
IRP Interrupt return pointer register
ISR Interrupt set register
ISTP Interrupt service table pointer register
ITSR Interrupt task state register
NRP Nonmaskable interrupt return pointer register
NTSR NMI/exception task state register
PCE1 Program counter, E1 phase
REP Restricted entry point address register
RILC Reload inner loop count register
SSR Saturation status register
TSCH Time-stamp counter (high 32) register
TSCL Time-stamp counter (low 32) register
TSR Task state register

The additional control registers listed in Table 7-5 are used for floating-point operations on C6740 and C6600 devices:

Table 7-5 Additional Control Registers for C6740 and C6600

Register Description
FADCR Floating-point adder configuration register
FAUCR Floating-point auxiliary configuration register
FMCR Floating-point multiplier configuration register

The __cregister keyword can be used only in file scope. The __cregister keyword is not allowed on any declaration within the boundaries of a function. It can only be used on objects of type integer or pointer. The __cregister keyword is not allowed on objects of any floating-point type or on any structure or union objects.

The __cregister keyword does not imply that the object is volatile. If the control register being referenced is volatile (that is, can be modified by some external control), then the object must be declared with the volatile keyword also.

To use the control registers in Table 7-4, you must declare each register as follows. The c6x.h include file defines all the control registers through this syntax:

extern __cregister volatile unsigned intregister;

Once you have declared the register, you can use the register name directly. See the TMS320C64x/C64x+ DSP CPU and Instruction Set Reference Guide (SPRU732), the TMS320C66x DSP CPU and Instruction Set Reference Guide (SPRUGH7), or the TMS320C674x DSP CPU and Instruction Set Reference Guide (SPRUFE8) for detailed information on the control registers.

See Example 1 for an example that declares and uses control registers.