2009/10/22 Richard Henderson <[email protected]>:
> 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.
>