avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] int32_t Support


From: User Tomdean
Subject: [avr-gcc-list] int32_t Support
Date: Wed, 13 Sep 2006 21:48:58 -0700 (PDT)

I need to use int32_t and do left and right shifts on them.  I
sometimes see strange values.  In trying to isolate this, I see
wrapping at 16 bits.

Is support for int32_t implemented?

In stdint.h, I see, after #ifdef DOXYGEN
  typedef unsigned long int uint32_t;
  typedef signed long int int32_t;
and, after the #else,
  typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__)));
  typedef int int32_t __attribute__ ((__mode__ (__SI__)));

It seems an int32_t is really 16 bits.

>From a dump of the code below, idx seems to be 32 bits.  However, the
calls to __divmodsi4 seem to make this an int16_t.  Is this true?

The output decreases to one at 0x0000ffff and wraps to zero at
0x00010000.

Or, am I seeing something funny, again?  Missing something?

tomdean

#include <stdio.h>
#include <avr/io.h>
#include <stdlib.h>         /* abs */

/*
 * prototypes
 */
uint8_t bin_to_hex(uint8_t);
char *bin_to_decimal(int32_t, char *);
void serial_send(unsigned char);
void serial_print(const char *);

/* Send the character on the serial line.  */
void serial_send(unsigned char c) {
  /* wait for tx buffer empty */
  while (!(UCSRA & (1 << UDRE)));
  /* send the char */
  UDR = c;
  return;
}

/* Send the buffer on the serial line.  */
void serial_print(const char *msg) {
  while (*msg != 0)
    serial_send (*msg++);
  return;
}

/*
 * bin_to_decimal - the avr-libc version uses 16 bits MAX
 *
 * This should be an assembly shift/test bcd routine and split into
 * a call for each type
 */
char *bin_to_decimal(int32_t value, char *p) {
  unsigned char c;
  uint8_t sign = 0; /* assume positive */
  if (value<0) sign = 1;
  value=abs(value);
  if (value == 0) {
         *--p = '0';
  } else do {
    c = value % 10;
    value = value / 10;
    *--p = c + '0';
  } while (value != 0);
  if (sign) *--p='-';
  return p;
}

/*
 * bin_to_hex
 */
uint8_t bin_to_hex(uint8_t c) {
  c &= 0x0f;
  if (c > 9) c+= 7;
  return c + '0';
}

/*
 * main()
 *
 * int32_t = (uint8_t<<8)+uint8_t
 */
int main() {
  int32_t idx;
  char buf[10];
  /* serial port */
  UBRRH = 0;   /* high order bits */
  /* enable tx and rx */
  UCSRB = (1 << RXEN) | (1 << TXEN);
  UCSRC = (1 << URSEL) | (1 << USBS) | (1 << UCSZ1) | (1 << UCSZ0);
  UBRRL = 12;  /* 38400 at 8.000 mHz */

  idx=65530;
  while (1) {
        serial_send(bin_to_hex(idx>>28));
        serial_send(bin_to_hex(idx>>24));
        serial_send(bin_to_hex(idx>>20));
        serial_send(bin_to_hex(idx>>16));
        serial_send(bin_to_hex(idx>>12));
        serial_send(bin_to_hex(idx>>8));
        serial_send(bin_to_hex(idx>>4));
        serial_send(bin_to_hex(idx));
        serial_send(' ');
        buf[9]='\0';
        serial_print(bin_to_decimal(idx, &buf[9]));
        serial_send('\n');
        if (idx == 65600) break;
        ++idx;
  }
 return 0;
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]