public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* logical error with 16bit arithmatic operations
@ 2009-03-27 12:49 daniel tian
  2009-03-27 18:21 ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: daniel tian @ 2009-03-27 12:49 UTC (permalink / raw)
  To: gcc, uday, yxun lan, iant

Hello,
      I am porting gcc to a 32bit RISC chip, and  I met a logical
error with 16bit arithmetic operations in generating assemble code.
the error is between two 16bit data movement(unsigned short).
While like A = B,  A, and B are all unsigned short type.  B is a
result of a series of computation, which may have value in high 16bit.
Because A , B are both HImode, so the move insn doesn't take zero
extend operation, so A will have value in high 16bit which will caused
a wrong result in computation. Like the following CRC calculation.

     There is a comment added with "//" in logical error position.


Here is the .sched2 script:
;;   ======================================================
;;   -- basic block 0 from 10 to 92 -- after reload
;;   ======================================================

;;	  0--> 10   R3=R4                              :nothing
;;	  1--> 11   R7=R5                              :nothing
;;	  2--> 89   R0=`x25_crc_table'                 :nothing
;;	  3--> 92   pc=L58                             :nothing
;;	Ready list (final):
;;   total time = 3
;;   new head = 10
;;   new tail = 92

;;   ======================================================
;;   -- basic block 1 from 25 to 53 -- after reload
;;   ======================================================

;;	  0--> 25   R6=[post_modify]                   :rice_load,nothing
;;	  1--> 57   R7=R7-0x1                          :nothing
;;	  2--> 26   R4=R6 0>>0x4                       :nothing
;;	  3--> 27   R4=zxn(R4)                         :nothing
;;	  4--> 28   R4=R5^R4                           :nothing
;;	  5--> 32   R4=zxn(R4)                         :nothing
;;	  6--> 35   R4=R4+R4                           :nothing
;;	  7--> 37   R5=[R4+R0]                         :rice_load,nothing
;;	  8--> 42   R6=zxn(R6)                         :nothing
;;	  9--> 38   R5=R5^R13                          :nothing
;;	 10--> 40   R4=R5 0>>0xc                       :nothing
;;	 11--> 43   R4=R4^R6                           :nothing
;;	 12--> 47   R4=zxn(R4)                         :nothing
;;	 13--> 48   R4=R4&0xf                          :nothing
;;	 14--> 50   R4=R4+R4                           :nothing
;;	 15--> 52   R4=[R4+R0]                         :rice_load,nothing
;;	 16--> 46   R5=R5<<0x4                         :nothing
;;	 17--> 53   R6=R5^R4                           :nothing
;;	Ready list (final):
;;   total time = 17
;;   new head = 25
;;   new tail = 53

;;   ======================================================
;;   -- basic block 2 from 23 to 62 -- after reload
;;   ======================================================

;;	  0--> 87   R2=zxn(R6)                         :nothing


;;	  1--> 23   R5=R6 0>>0xc                       :nothing
             //R5 and R6 are both unsigned short type. But R6 will
have it's value in high 16bit because of series of logical operations
(AND, OR, XOR and so on). Doing it like this way will cause R5 also
being valued in high 16bit. This will cause a wrong value. The correct
one is : R5 = R2 0 >> 0xC. because R2 did zero extend in former insn
from R6. But How I let gcc know it.


;;	  2--> 31   R13=R2<<0x4                        :nothing
;;	  3--> 62   pc={(R7>0x0)?L20:pc}               :nothing
;;	Ready list (final):
;;   total time = 3
;;   new head = 87
;;   new tail = 62

;;   ======================================================
;;   -- basic block 3 from 100 to 100 -- after reload
;;   ======================================================

;;	  0--> 100  return                             :nothing
;;	Ready list (final):
;;   total time = 0
;;   new head = 100
;;   new tail = 100



PS, I compile the c code with -Os command. Here is C code:

static  const unsigned short  x25_crc_table[16] =
{
  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
  0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
};

/*
** FUNCTION:    crc_X25
**
** DESCRIPTION: This function generates a crc on from the data given
**              using the X 25 CRC lookup table.
**
**
** PARAMETERS:  Data to check:
**              Array of data:                  UTINY *
**              Length of data in array:        LONG
**              CRC initial value:              USHORT
**
** RETURNS:     USHORT, The CRC calculated.
**
*/
unsigned short crc_X25(unsigned char *data, long length, unsigned short crc_reg)
{
  unsigned short temp;


  /* Use 4 bits out of the data/polynomial at a time */
  while (length > 0)
  {               /* step through the data */
    temp = crc_reg;

    temp >>= 12u;
    temp ^= (*data) >> 4u;  /* xor data (MS 4 bits) with the MS 4 bits */
    temp &= 0xf;            /* of the CRC reg to be used as index in array */
    temp = crc_reg = (unsigned short )((crc_reg << 4u) ^ x25_crc_table[temp]);

    /* Now do second half of byte */
    temp >>= 12u;
    temp ^= *data;      /* xor data with the 4 MS bits of the CRC reg */
    temp &= 0xf;        /* to be used as index in array */
    crc_reg = (unsigned short )((crc_reg << 4u) ^ x25_crc_table[temp]);
		crc_reg = crc_reg & 0xFFFF;
    data++;         /* move on through data array */
    length--;
  }
  return (crc_reg);
}

from the C language,  It occurred in statement:  temp = crc_reg;
R5 register stands for 'temp'.
R6 register is "crc_reg"


Any, any suggestion is appreciated.
Thank you very much.

                        Tianxiaonan

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-03-31  6:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-27 12:49 logical error with 16bit arithmatic operations daniel tian
2009-03-27 18:21 ` Ian Lance Taylor
2009-03-31  6:55   ` daniel tian
2009-03-31  9:02     ` Ian Lance Taylor
2009-03-31 11:51       ` daniel tian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).