12.11 DSP Control Register

The DSP-enhanced core includes a DSP control register that has six fields: CCOND (condition code bits), OUFLAG (overflow/underflow bits), EFI (extract fail indicator bit), C (carry bit), SCOUNT (size count bits) and POS (position bits). The compiler treats the SCOUNT and POS fields as global variables, such that instructions that modify SCOUNT or POS are never optimized away. These instructions include WRDSP, EXTPDP, EXTPDPV, and MTHLIP. A function call that jumps to a function containing WRDSP, EXTPDP, EXTPDPV, or MTHLIP is also never deleted by the compiler.

For correctness, you must assume that a function call clobbers all fields of the DSP control register. That is, do not depend on the values in CCOND, OUFLAG, EFI or C across a function-call boundary. Re-initialize the values of CCOND, OUFLAG, EFI or C before using them. Note that because SCOUNT and POS fields are treated as global variables, the values of SCOUNT and POS are always valid across function-call boundaries and can be used without re-initialization.

The following example shows possibly incorrect code. The first built-in function "__builtin_mips_addsc" sets the carry bit (C) in the DSP control register, and the second built-in function "__builtin_mips_addwc" reads the carry bit (C) from the DSP control register. However, a function call "func" inserted between "__builtin_mips_addsc" and "__builtin_mips_addwc" may change the carry bit to affect the correct result of "__builtin_mips_addwc".

  Incorrect Ex:
  int test (int a, int b, int c, int d)
  {
    __builtin_mips_addsc (a, b);
    func();   // may clobber the carry bit
    return __builtin_mips_addwc (c, d);
  } 

The previous example may be corrected by moving "func" before the first built-in function or after the second built-in function as follows. p

  Corrected Ex:
  int test (int a, int b, int c, int d)
  {
    func();    // may affect the carry bit
    __builtin_mips_addsc (a, b);
    return __builtin_mips_addwc (c, d);
  }
  /* -------------------------------------------------------- */
  int test (int a, int b, int c, int d)
  {
    int i;
    __builtin_mips_addsc (a, b);
    i = __builtin_mips_addwc (c, d);
    func();    // may affect the carry bit
    return i;
  }