public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: daniel tian <daniel.xntian@gmail.com>
To: gcc@gcc.gnu.org, uday@cse.iitb.ac.in,
	yxun lan <dennis.yxun@gmail.com>,
	 	iant@google.com
Subject: logical error with 16bit arithmatic operations
Date: Fri, 27 Mar 2009 12:49:00 -0000	[thread overview]
Message-ID: <121fadb80903270212p5ab2c977t86778eed45b94d23@mail.gmail.com> (raw)

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

             reply	other threads:[~2009-03-27  9:12 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-27 12:49 daniel tian [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=121fadb80903270212p5ab2c977t86778eed45b94d23@mail.gmail.com \
    --to=daniel.xntian@gmail.com \
    --cc=dennis.yxun@gmail.com \
    --cc=gcc@gcc.gnu.org \
    --cc=iant@google.com \
    --cc=uday@cse.iitb.ac.in \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).