HI to SI mode miss conversion on MIPS.
Hiroyuki Machida
machida@sm.sony.co.jp
Thu Feb 10 04:04:00 GMT 2000
Hi,
I found the problem about HI to SI mode conversion on MIPS.
REPEATED BY
gcc -O2 -g -df -dc hisi.c -o hisi
./hisi
VERSION
gcc version 2.95.2 19991024 (release) for MIPS
gcc version 2.96 20000124 (experimental) for MIPS
The attached test program shows that gcc produces the incorrect
object for swapping lower and upper byte. This test code derived
from linux kernel linux/drivers/net/slhc.c.
The test swaps 0x0000235f twice, expceted results is 0x0000235f. But
you will get 0x005f235f on MIPSEB box. (This problem is occured even
if on MIPSEL box)
I tracked down in rough. In my observation, required "zero_extend"
or somthing was vanished on the "combination-phase".
Followings are interested portions of the test programe and
corresponding RTL codes. The problem is occured at the line 65 of
the C source code.
In the hisi.c.08.flow, RTLs look good. But #78, #86 and #99 in the
hisi.c.09.combine produce incorrect result.
In my concern, The RTL corresspoindig to #95 in the hisi.c.08.flow,
(set (reg:SI 111) (zero_extend:SI (reg:HI 111)))
must be put at the next of
#86 (set (subreg:SI (reg:HI 111) 0) (ior:SI (reg:SI 114) (reg:SI 117)))
in the hisi.c.09.combine.
The attached patch is a workaround for this problem. Does anyone
have better solution or real fix ?
=== Portion of C codes in hisi.c.
line 16:
__inline__ __const__ __u16 uswb16(__u16 x)
{
return ((__u16)(
(((__u16)( x ) & (__u16)0x00ffU) << 8)
| (((__u16)( x ) & (__u16)0xff00U) >> 8) ) ) ;
}
:
:
unsigned long result = 0 ;
:
:
line 65:
result += swb16(swapped);
=== Portion of RTLs in hisi.08.flow. (produced by -df )
Note: Commtents begin with ";;".
"Rxxx" denotes register xxx in comments.
"#xx" denotes the insn number xx.
;; R108 <- (__u16) swapped
#67 (set (reg:HI 109) (mem/v/f:HI (symbol_ref:SI ("swapped")) 1))
#69 (set (reg:SI 108) (zero_extend:SI (reg:HI 109)))
;; R114 <- ( R108 & 0xff) << 8
#76 (set (reg:SI 112) (and:SI (reg:SI 108) (const_int 255 [0xff])))
#78 (set (reg:SI 114) (ashift:SI (reg:SI 112) (const_int 8 [0x8])))
;; R117 <- ((__u16)(R108 & 0xff00)) >> 8
#79 (set (reg:SI 115) (and:SI (reg:SI 108) (const_int 65280 [0xff00])))
#80 (set (reg:SI 116) (zero_extend:SI (subreg:HI (reg:SI 115) 0)))
#81 (set (reg:SI 117) (lshiftrt:SI (reg:SI 116) (const_int 8 [0x8])))
;; R121 <- (__u16) (R114 | R117)
#84 (set (reg:SI 120) (ior:SI (reg:SI 114) (reg:SI 117)))
#85 (set (reg:SI 121) (zero_extend:SI (subreg:HI (reg:SI 120) 0)))
;; R122 <- (__u16)R121
#86 (set (subreg:SI (reg:HI 111) 0) (reg:SI 121)) ;; paradoixcal subreg
#95 (set (reg:SI 122) (zero_extend:SI (reg:HI 111)))
;; result <- R122+R107
#99 (set (reg:SI 124) (plus:SI (reg:SI 107) (reg:SI 122)))
#101 (set (mem/f:SI (symbol_ref:SI ("result")) 3) (reg:SI 124))
=== Portion of RTLs in hisi.09.combine. (produced buy -dc)
;; R108 <- (__u16) swapped
#67 (set (reg:HI 109) (mem/v/f:HI (symbol_ref:SI ("swapped")) 1))
#69 (set (reg:SI 108) (zero_extend:SI (reg:HI 109)))
;; R114 <- R108 << 8 ;; upper part of R114 is not cleard.
#76 NOTE_INSN_DELETED
#78 (set (reg:SI 114) (ashift:SI (reg:SI 108) (const_int 8 [0x8])))
;; R117 <- R108 >> 8
#79 NOTE_INSN_DELETED
#80 NOTE_INSN_DELETED
#81 (set (reg:SI 117) (lshiftrt:SI (reg:SI 108) (const_int 8 [0x8])))
#84 NOTE_INSN_DELETED
#85 NOTE_INSN_DELETED
;; R111 <- R117 | R114
#86 (set (subreg:SI (reg:HI 111) 0) (ior:SI (reg:SI 114) (reg:SI 117)))
;; R122 <- R103 | R106
#95 (set (reg:SI 122) (ior:SI (reg:SI 103) (reg:SI 106)))
;; result <- R122 + R111
#99 (set (reg:SI 124) (plus:SI (reg:SI 122) (subreg:SI (reg:HI 111) 0)))
#101 (set (mem/f:SI (symbol_ref:SI ("result")) 3) (reg:SI 124))
===
---
Hiroyuki Machida
Creative Station SCE Inc./Sony Corp.
More information about the Gcc-bugs
mailing list