This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to support 40bit GP register


2009/10/22 Richard Henderson <rth@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.
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]