2009/10/22 Richard Henderson <r...@redhat.com>: > On 10/21/2009 07:25 AM, Mohamed Shafi wrote: >> >> For accessing a->b GCC generates the following code: >> >> move.l (sp-16), d3 >> lsrr.l #<16, d3 >> move.l (sp-12),d2 >> asll #<16,d2 >> or d3,d2 >> cmpeq.w #<2,d2 >> jf _L2 >> >> Because data registers are 40 bit for 'asll' operation the shift count >> should be 16+8 or there should be sign extension from 32bit to 40 bits >> after the 'or' operation. The target has instruction to sign extend >> from 32bit to 40 bit. >> >> Similarly there are other operation that requires sign/zero extension. >> So is there any way to tell GCC that the data registers are 40bit and >> there by expect it to generate sign/zero extension accordingly ? > > Define a machine mode for your 40-bit type in cpu-modes.def. Depending on > how your 40-bit type is stored in memory, you'll use either > > INT_MODE (RI, 5) // load-store uses exactly 5 bytes > FRACTIONAL_INT_MODE (RI, 40, 8) // load-store uses 8 bytes > Richard thanks for the reply.
Load-store uses 32bits. Sign extension happens automatically. So i have choosen INT_MODE (RI, 5) and copied movsi and renamed it to movri. I have also specified that RImode need only one register. > Where I've arbitrarily chosen "RImode" as a mnemonic for Register Integral > Mode. Now you define arithmetic operations, as needed, on > RImode. You define the "extendsiri" pattern to be that sign-extend from > 32-to-40-bit instruction. You define your comparison patterns on RImode, > and not on SImode, since your comparison instruction works on the entire 40 > bits. I have defined extendsiri and cbranchri4 patterns. When i compile a program like unsigned long xh = 1; int main () { unsigned long yh = 0xffffull; unsigned long z = xh * yh; if (z != yh) abort (); return 0; } I get the following ICE internal compiler error: in immed_double_const, at emit-rtl.c:553 This happens from cse_insn () calls insert() -> gen_lowpart -> gen_lowpart_common -> simplify_gen_subreg -> simplfy_immed_subreg. simplify_immed_subreg is called with the parameters (outermode=RImode, (const_int 65535), innermode=DImode, byte=0) cse_insn is called for the following insn (insn 10 9 11 3 bug7.c:14 (set (reg:RI 67) (const_int 65535 [0xffff])) 4 {movri} (nil)) How can i overcome this? Regards, Shafi > > You'll wind up with a selection of patterns in your machine description that > have a sign-extension pattern built in, depending on the exact behaviour of > your ISA. There are plenty of examples on x86_64, mips64, and Alpha (to > name a few) that have similar properties with SI and DImodes. Examine the > -fdump-rtl-combine-details dump for exemplars of the canonical forms that > the combiner creates when it tries to merge sign-extension instructions into > preceeding patterns. >