This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6xSimulator.c _sat() error

Hi

I'm using the C6xSimulator.c file to compile mex files for the C6472. I think I've discovered an error with the _sat() intrinsic when passing a negative value less then 

Below are 2 screens showing the decimal and hex result when I pass 0xffff fff0 0000 0004 to the _sat() routine. The returned result in y32 is 0x0000 0004 when it should be 0x8000 0000. It looks like the if statement for the minimum is incorrect.

Would this be the correct code? (replace a40.x2.lo == 0 with  !(a40.x2.lo & MIN_INT32)  



  if(a40.x2.hi > 0 || ((a40.x2.hi == 0) && (a40.x2.lo & MIN_INT32)))
    y32 = MAX_INT32;
  //else if ((a40.x2.hi < 0) && (a40.x2.lo == 0))
  else if ((a40.x2.hi < 0) && !(a40.x2.lo & MIN_INT32))
    y32 = MIN_INT32;
  else
    y32 = a40.x2.lo;

Cheers2u

Eddie

typedef struct _INT40X2
{
  int32 lo;
  int8  hi;
  int8  unused0;
  int8  unused1;
  int8  unused2;
} int40x2;

union reg40
{
int40 x1;
int40x2 x2;

uint40 x1u;
int40x2u x2u;
};

Hex version of same numbers below

  • Thank you for notifying us of this problem.  I can reproduce the same incorrect result.

    There are no current plans for a release of the host intrinsics package.  That being the case, this is the fix implemented in the _sat routine.  You'll see this is more than a fix.  The routine is entirely re-implemented.  

    int32 _sat(int40 a)
    {
      int32 y32;
      int64_ll a_ll = a;
    
      /* Since a 40-bit value is modeled with a 64-bit type, it is impossible   */
      /* to be certain about what is in the upper 24-bits.  Make sure the upper */
      /* 24-bits are copies of the sign bit.                                    */ 
      int64_ll sign_bits_mask = ~((int64_ll)0) << 40;
      int64_ll sign_bit = a_ll & ((int64_ll)1 << 39);
      a_ll &= ~sign_bits_mask;
      if (sign_bit)
        a_ll |= sign_bits_mask;
    
      if (a_ll > MAX_INT32)
         y32 = MAX_INT32;
      else if (a_ll < MIN_INT32)
         y32 = MIN_INT32;
      else
         y32 = a_ll;
    
      return(y32);
    } /* end of _sat() function */
    

    Thanks and regards,

    -George