public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Legitimize address, Please HELP!
@ 2001-12-05  3:36 dimmy
  2001-12-05  7:31 ` Jan Hubicka
  2001-12-05 15:52 ` Richard Henderson
  0 siblings, 2 replies; 9+ messages in thread
From: dimmy @ 2001-12-05  3:36 UTC (permalink / raw)
  To: gcc

Fellows,

Sorry bothering you.

I am writing msp430 support and got a question:
How to get rid of operands like:

(mem/s:HI (plus:HI (mem:HI (plus:HI (reg/f:HI 1 r1)
                        (const_int 18 [0x12])) 0)
                (const_int 2 [0x2])) 3))

The CPU core does support (mem:xx (plus reg:xx const_int)), but not the
operand above.

I define  GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR)
as:
------------------------
#ifdef REG_OK_STRICT
#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
{                                                       \
  if (legitimate_address_p (mode, operand, 1))          \
    goto ADDR;                                          \
}
#  else
#  define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
{                                                       \
  if (legitimate_address_p (mode, operand, 0))          \
    goto ADDR;                                          \
}
#endif
--------------------------
where legitimate_address_p is defined as follows:
--------------------------
int
legitimate_address_p (mode, operand, strict)
enum machine_mode mode;
rtx operand;
int strict;
{
    rtx x = operand;

    /* accept @Rn */
    if (GET_CODE (operand) == REG
            &&(strict ? REG_OK_FOR_BASE_STRICT_P (x)
               : REG_OK_FOR_BASE_NOSTRICT_P (x)))  
        return 1;

    /* accept address */
    if (CONSTANT_ADDRESS_P (operand))
        return 1;

    /* accept X(Rn) */
    if (GET_CODE (operand) == PLUS
            && GET_CODE (XEXP (operand, 0)) == REG
            && REG_OK_FOR_BASE_P (XEXP (operand, 0))
            && CONSTANT_ADDRESS_P (XEXP (operand, 1)))
        return 1;

}
--------------------------

Shall I define something else to prevent invalid address generation or what?

By now I cannot compile only 'unwind-dw2-fde.c' in gcc-3.0/gcc
Everything else seems to be fine!!!

by the way, when I run xgcc, it produces invalid code,
when cc1, it does not want to compile and says:

unwind-dw2-fde.c: In function `search_object':
unwind-dw2-fde.c:930: Unrecognizable insn:
(insn 1212 29 30 (set (reg:HI 14 r14 [49])
        (mem/s:HI (plus:HI (mem:HI (plus:HI (reg/f:HI 1 r1)
                        (const_int 12 [0xc])) 0)
                (const_int 10 [0xa])) 13)) -1 (nil)
    (nil))

Tricks like if (GET_CODE (operand) == PLUS && GET_CODE (XEXP (operand, 
0)) == MEM) return 0; do not help at all.


Thanks in advance,
Dmitry.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05  3:36 Legitimize address, Please HELP! dimmy
@ 2001-12-05  7:31 ` Jan Hubicka
  2001-12-05  8:23   ` dimmy
  2001-12-05 15:52 ` Richard Henderson
  1 sibling, 1 reply; 9+ messages in thread
From: Jan Hubicka @ 2001-12-05  7:31 UTC (permalink / raw)
  To: dimmy; +Cc: gcc

> int
> legitimate_address_p (mode, operand, strict)
> enum machine_mode mode;
> rtx operand;
> int strict;
> {
>    rtx x = operand;
> 
>    /* accept @Rn */
>    if (GET_CODE (operand) == REG
>            &&(strict ? REG_OK_FOR_BASE_STRICT_P (x)
>               : REG_OK_FOR_BASE_NOSTRICT_P (x)))  
>        return 1;
> 
>    /* accept address */
>    if (CONSTANT_ADDRESS_P (operand))
>        return 1;
> 
>    /* accept X(Rn) */
>    if (GET_CODE (operand) == PLUS
>            && GET_CODE (XEXP (operand, 0)) == REG
>            && REG_OK_FOR_BASE_P (XEXP (operand, 0))
>            && CONSTANT_ADDRESS_P (XEXP (operand, 1)))
>        return 1;
> 
Missing return 0;
> }
> --------------------------
> 
> Shall I define something else to prevent invalid address generation or what?

It is normal for invalid addresses to be generated and rejected
during the compilation.
If you want to do some special tricks, you may define LEGITIMIZE
macros, but in your case, it the default behaviour is most probably
OK.  I guess only problem is the missing return :)

Honza

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05  7:31 ` Jan Hubicka
@ 2001-12-05  8:23   ` dimmy
  2001-12-05  9:16     ` Jan Hubicka
  0 siblings, 1 reply; 9+ messages in thread
From: dimmy @ 2001-12-05  8:23 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc

Jan,
return is not missing.
Even some improvements to legitimate_address_p
such as:
-------------------
int
legitimate_address_p (mode, operand, strict)
enum machine_mode mode;
rtx operand;
int strict;
{
    rtx xfoob, x = operand;


  if (GET_CODE (operand) == PLUS
        && ((GET_CODE (XEXP (operand, 0)) == MEM )
            ||GET_CODE (XEXP (operand, 1)) == MEM )
       )
    {  
        fprintf(stderr,"interesting address mode\n");     
        goto fail;
    }

    xfoob = XEXP (operand, 0);
   
    if (GET_CODE (operand) == MEM  
        &&  GET_CODE (xfoob) == PLUS
        &&  GET_CODE (XEXP (xfoob, 0)) == MEM)
    {
        fprintf(stderr,"Super interesting address mode\n");
        goto fail;
    }
    

    if (GET_CODE (operand) == PLUS
                 && GET_CODE (XEXP (operand, 0)) == PLUS)
    return 0;
                   
    /* accept @Rn */
    if (GET_CODE (operand) == REG
            &&(strict ? REG_OK_FOR_BASE_STRICT_P (x)
               : REG_OK_FOR_BASE_NOSTRICT_P (x)))
        goto granded;

    /* accept address */
    if (CONSTANT_ADDRESS_P (operand))
        goto granded;

    /* accept X(Rn) */
    if (GET_CODE (operand) == PLUS
            && GET_CODE (XEXP (operand, 0)) == REG 
            && REG_OK_FOR_BASE_P (XEXP (operand, 0))
            && CONSTANT_ADDRESS_P (XEXP (operand, 1))
        )
        goto granded;

fail:
    return 0;
granded:
    fprintf(stderr,"legitimate_address_p --- Ok\n");
    return 1;
}

do not help.

I thought that it might be cause I defined
frame_pointer_regnum  equial to stack pointer.
Now I assigned frame_pointer_regnum to another register and still got
the same error.

This happens only when frame pointer required.

here is the part of RTL dump:

(jump_insn/i 451 450 452 (set (pc)
        (if_then_else (ne (cc0)
                (const_int 0 [0x0]))
            (label_ref 380)
            (pc))) 127 {bne} (nil)
    (expr_list:REG_BR_PROB (const_int 6001 [0x1771])
        (nil)))  
*****************/
        jne      .L402  ;        .L402
/*****************
(insn/i 457 946 458 (set (mem/s:HI (plus:HI (reg/v:HI 6 r6 [136])
                (const_int 2 [0x2])) 0)
        (plus:HI (mem/s:HI (plus:HI (reg/v:HI 6 r6 [136])
                    (const_int 2 [0x2])) 0)
            (mem/s:HI (plus:HI (mem:HI (plus:HI (reg/f:HI 4 r4)
                            (const_int 22 [0x16])) 0)
                    (const_int 2 [0x2])) 0))) 37 {*addhi3_3} (nil)
    (expr_list:REG_DEAD (reg/v:HI 6 r6 [136])
        (nil)))  
*****************/
        add     2(22(r4)), 2(r6)            ;       ----- INVALID!!
;; will be output as:      add     2(r675750800), 2(r6)

.L401:
/*****************
(insn/i 461 460 462 (set (reg:HI 15 r15) 
        (mem/s:HI (plus:HI (reg/f:HI 4 r4)
                (const_int 2 [0x2])) 0)) 26 {*movhi3} (nil)
    (nil))
*****************/
        mov     2(r4), r15



So, thank you anyway.
Dmitry



Jan Hubicka wrote:

>>int
>>legitimate_address_p (mode, operand, strict)
>>enum machine_mode mode;
>>rtx operand;
>>int strict;
>>{
>>   rtx x = operand;
>>
>>   /* accept @Rn */
>>   if (GET_CODE (operand) == REG
>>           &&(strict ? REG_OK_FOR_BASE_STRICT_P (x)
>>              : REG_OK_FOR_BASE_NOSTRICT_P (x)))  
>>       return 1;
>>
>>   /* accept address */
>>   if (CONSTANT_ADDRESS_P (operand))
>>       return 1;
>>
>>   /* accept X(Rn) */
>>   if (GET_CODE (operand) == PLUS
>>           && GET_CODE (XEXP (operand, 0)) == REG
>>           && REG_OK_FOR_BASE_P (XEXP (operand, 0))
>>           && CONSTANT_ADDRESS_P (XEXP (operand, 1)))
>>       return 1;
>>
>Missing return 0;
>
>>}
>>--------------------------
>>
>>Shall I define something else to prevent invalid address generation or what?
>>
>
>It is normal for invalid addresses to be generated and rejected
>during the compilation.
>If you want to do some special tricks, you may define LEGITIMIZE
>macros, but in your case, it the default behaviour is most probably
>OK.  I guess only problem is the missing return :)
>
>Honza
>
>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05  8:23   ` dimmy
@ 2001-12-05  9:16     ` Jan Hubicka
       [not found]       ` <3C0E6806.3060706@mail.ru>
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Hubicka @ 2001-12-05  9:16 UTC (permalink / raw)
  To: dimmy; +Cc: Jan Hubicka, gcc

> Jan,
> return is not missing.
> Even some improvements to legitimate_address_p
> such as:
> -------------------
> int
> legitimate_address_p (mode, operand, strict)
> enum machine_mode mode;
> rtx operand;
> int strict;
> {
>    rtx xfoob, x = operand;
> 
> 
>  if (GET_CODE (operand) == PLUS
>        && ((GET_CODE (XEXP (operand, 0)) == MEM )
>            ||GET_CODE (XEXP (operand, 1)) == MEM )
>       )
>    {  
>        fprintf(stderr,"interesting address mode\n");     
>        goto fail;
>    }
> 
>    xfoob = XEXP (operand, 0);
>   
>    if (GET_CODE (operand) == MEM  
>        &&  GET_CODE (xfoob) == PLUS
>        &&  GET_CODE (XEXP (xfoob, 0)) == MEM)
>    {
>        fprintf(stderr,"Super interesting address mode\n");
>        goto fail;
>    }
>    
> 
>    if (GET_CODE (operand) == PLUS
>                 && GET_CODE (XEXP (operand, 0)) == PLUS)
>    return 0;
>                   
>    /* accept @Rn */
>    if (GET_CODE (operand) == REG
>            &&(strict ? REG_OK_FOR_BASE_STRICT_P (x)
>               : REG_OK_FOR_BASE_NOSTRICT_P (x)))
>        goto granded;
> 
>    /* accept address */
>    if (CONSTANT_ADDRESS_P (operand))
>        goto granded;
> 
>    /* accept X(Rn) */
>    if (GET_CODE (operand) == PLUS
>            && GET_CODE (XEXP (operand, 0)) == REG 
>            && REG_OK_FOR_BASE_P (XEXP (operand, 0))
>            && CONSTANT_ADDRESS_P (XEXP (operand, 1))
>        )
>        goto granded;
> 
> fail:
>    return 0;
> granded:
>    fprintf(stderr,"legitimate_address_p --- Ok\n");
>    return 1;
> }
> 
> do not help.
> 
> I thought that it might be cause I defined
> frame_pointer_regnum  equial to stack pointer.
> Now I assigned frame_pointer_regnum to another register and still got
> the same error.
> 
> This happens only when frame pointer required.
> 
> here is the part of RTL dump:
> 
> (jump_insn/i 451 450 452 (set (pc)
>        (if_then_else (ne (cc0)
>                (const_int 0 [0x0]))
>            (label_ref 380)
>            (pc))) 127 {bne} (nil)
>    (expr_list:REG_BR_PROB (const_int 6001 [0x1771])
>        (nil)))  
> *****************/
>        jne      .L402  ;        .L402
> /*****************
> (insn/i 457 946 458 (set (mem/s:HI (plus:HI (reg/v:HI 6 r6 [136])
>                (const_int 2 [0x2])) 0)
>        (plus:HI (mem/s:HI (plus:HI (reg/v:HI 6 r6 [136])
>                    (const_int 2 [0x2])) 0)
>            (mem/s:HI (plus:HI (mem:HI (plus:HI (reg/f:HI 4 r4)
>                            (const_int 22 [0x16])) 0)
>                    (const_int 2 [0x2])) 0))) 37 {*addhi3_3} (nil)
>    (expr_list:REG_DEAD (reg/v:HI 6 r6 [136])
>        (nil)))  
> *****************/
>        add     2(22(r4)), 2(r6)            ;       ----- INVALID!!
> ;; will be output as:      add     2(r675750800), 2(r6)

Do you know how the instruction got created?  What appears to be wrong
is not legitimate_address_p (in case it really refuse the address in question),
but the origin of insn.
Most of addresses are legitimized - gcc replaces the subexpressions by 
registers until the resulting address is valid, but this apparently not.
This may be due to bug in compiler, but more probably due to wrong
expander or something who accepts the operand, expect it to be register
but it really is memory (the inner one).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
       [not found]       ` <3C0E6806.3060706@mail.ru>
@ 2001-12-05  9:52         ` Jan Hubicka
  2001-12-05 11:14           ` dimmy
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Hubicka @ 2001-12-05  9:52 UTC (permalink / raw)
  To: dimmy; +Cc: Jan Hubicka, gcc

> Jan, thanks for reply.
> I really do not know much about the process of the creation of 
> instructions - only that written in gcc info.
> 
> I will appreciate if you can tell me what's wrong with the expander like:
I don't see the bug directly in expanders you quoted, but few problems:
1) match_operand calls the predicate, so memory_operand call in movhi1
   condition is redundant.  Similary in movhi2, where you call
   nonimmediate_operand that is supperset of register_operand already
   tested.
2) the zero_shifted/indexed_location test probably should be hid
   in new operand writen in your md file used in patterns instead of
   general_operand to make thinks cleaner.
   Basically the condition should mention only tests that depdends
   on multiple
3) "m" is wrong constraint for general_operand. Eighter you need
   to use memory_operand, or allow some registers and constants
   in the constraint.
   The constraints and predicates should be in "harmony" one should
   not be considerably stronger/weaker than the other otherwise you
   are asking for problems in reload pass.
   In case the second pattern is expected to load address as integer
   value (i386 lea equivalent), it should use
   (match_operand "address_operand" "a"), not memory and should come last
   to avoid matches in dumb cases.
   
4) For speed you should probably move more probable movhi3 first.
5) All three patterns can be single pattern with multiple alternative
   output template.  This will result in faster compiler and better
   produced code if you do so.  Some late passes, as reload, do not
   take a look if different pattern match, only test if given pattern
   and usually also alternative, allow the suggested optimization.
6) Similary you can collapse multiple alternatives to single:
   "=m,r,r,m,r,m,m,r
     m,r,P,P,m,r,i,i"
   can be:
   "=m   ,r"
     mrPi,mrPi"
   Also it is good to prohibit mem->mem move in the conditional + add
   expander to split it into two instructions early like i386.md does.
   Otherwise the need for register in this case is discovered late in
   the register allocation progress often resulting in dumb spill.

In case you do have flags register (as cc attribute suggest), please
consider not using cc0, as it looks you do use.  We are tying to zap
that.  Look at i386.md/sparc.md about how new backends are usually
done.

Concerning your problem.  The problematic piece of code is not
contained in the mov expander, instead it is, most probably, some
other code generating the add/mov directly and getting thinks wrong.

one of ways to get it is to add test for current_insn_uid in emit-rtl.c
and break program in debugger when offending instruction is emit. Then
you will be probably able to figure out where it incarned.

See the gcc readings page.  I believe there are some links to other porting
docs, than the gcc manual itself.  it is good idea to read them (even when I
never did :), because it can save you some headaches later.

Hope this helps,
Honza
> 
> ========================
> (define_expand "movhi"
>  [(set (match_operand:HI 0 "nonimmediate_operand" "")
>        (match_operand:HI 1 "general_operand" ""))]
>  ""
>  "")
> 
> 
> (define_insn "*movhi1"
>  [(set (match_operand:HI 0 "memory_operand"      "=m")
>        (match_operand:HI 1 "general_operand"           "m"))]
>  "( memory_operand(operands[0], VOIDmode)
>        && !register_operand(operands[0], VOIDmode)
>        && zero_shifted(operands[1])       
>        && indexed_location(operands[1]))" 
> "mov\\t@%E1, %0"
>  [(set_attr "length" "3")
>   (set_attr "cc" "none")])
> 
> 
> (define_insn "*movhi2"
>  [(set (match_operand:HI 0 "register_operand" "=r")
>        (match_operand:HI 1 "general_operand"      "m"))]
>  "(nonimmediate_operand(operands[0], VOIDmode)
>                && zero_shifted(operands[1])  
>                && indexed_location(operands[1]) )"
>       "mov\\t@%E1, %A0"
>  [(set_attr "length" "2")
>   (set_attr "cc" "none")])
> 
> (define_insn "*movhi3"
>  [(set (match_operand:HI 0 "nonimmediate_operand"      "=m,r,r,m,r,m,m,r")
>        (match_operand:HI 1 "general_operand"           " 
> m,r,P,P,m,r,i,i"))]
>  "(nonimmediate_operand(operands[0], HImode)
>        && !zero_shifted(operands[1])
>        && !indexed_location(operands[1]) )"
>  "mov\\t%1, %0 "
>  [(set_attr "length" "1,3,1,2,2,2,3,2")
>   (set_attr "cc" "none")])
> ==============================

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05  9:52         ` Jan Hubicka
@ 2001-12-05 11:14           ` dimmy
  2001-12-05 11:23             ` Jan Hubicka
  0 siblings, 1 reply; 9+ messages in thread
From: dimmy @ 2001-12-05 11:14 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc

Jan,
thanks

But still some thingsa are not clear:

>2) the zero_shifted/indexed_location test probably should be hid
>   in new operand writen in your md file used in patterns instead of
>   general_operand to make thinks cleaner.
>   Basically the condition should mention only tests that depdends
>   on multiple
>3) "m" is wrong constraint for general_operand. Eighter you need
>   to use memory_operand, or allow some registers and constants
>   in the constraint.
>
If any type of addressing mode is allowed for instruction, I do not know 
how to combine
memory_operand, register and immediate. I can probably write my own 
predicate. Correct?

>   The constraints and predicates should be in "harmony" one should
>   not be considerably stronger/weaker than the other otherwise you
>   are asking for problems in reload pass.
>   In case the second pattern is expected to load address as integer
>   value (i386 lea equivalent), it should use
>   (match_operand "address_operand" "a"), not memory and should come last
>   to avoid matches in dumb cases.
>   
>4) For speed you should probably move more probable movhi3 first.
>5) All three patterns can be single pattern with multiple alternative
>   output template.  This will result in faster compiler and better
>   produced code if you do so.  Some late passes, as reload, do not
>   take a look if different pattern match, only test if given pattern
>   and usually also alternative, allow the suggested optimization.
>6) Similary you can collapse multiple alternatives to single:
>   "=m,r,r,m,r,m,m,r
>     m,r,P,P,m,r,i,i"
>   can be:
>   "=m   ,r"
>     mrPi,mrPi"
>
The instruction length depends on addressing mode.
So, mem->mem has length 3, mem->reg - 2, reg->reg -1, etc.
O course, I can collapse constraints into:
"=mr"
"mrPi"
and then dig an addressing mode. (What type of predicate should I use 
then? general? memory? ...)

 So, will be correct the following:

(define_insn "*movhi3"
 [(set 	(match_operand:HI 0 "nonimmediate_operand"      "=mr")
	(match_operand:HI 1 "general_operand"           "mrPi"))]

""
"* return msp_emit_movhi3(insn, operand, NULL);"
 [(set_attr "length" "3")
   (set_attr "cc" "none")])

and inside msp_emit_movhi3() issue assembler instructions and set up the 
insn lenght as third parameter?
I actually do that for SI and DI modes, but I thought that coding in .md 
is a bit cheaper.



>
>   Also it is good to prohibit mem->mem move in the conditional + add
>   expander to split it into two instructions early like i386.md does.
>   Otherwise the need for register in this case is discovered late in
>   the register allocation progress often resulting in dumb spill.
>
Only in conditional code? Do you mean if I have to compare 2 mem 
locations like
a==b first I have to move one of them to register?
It seems to me that it's cheaper to do
    cmp &a, &b    ;    compare values at addresses a and b
than
    mov &a, r4
    mov &b, r5
    cmp r4, r5

Am I wrong?

>
>In case you do have flags register (as cc attribute suggest), please
>consider not using cc0, as it looks you do use.  We are tying to zap
>that.  Look at i386.md/sparc.md about how new backends are usually
>done.
>
could not get it. What do you mean?


>
>Concerning your problem.  The problematic piece of code is not
>contained in the mov expander, instead it is, most probably, some
>other code generating the add/mov directly and getting thinks wrong.
>
The cpu core contains only 27 instructions and all instructions looks 
the same - for example
'mov' has the same addressing modes as 'add', 'tst', etc... I dump rtl 
phases I could not find where
this instruction being generated.

>
>one of ways to get it is to add test for current_insn_uid in emit-rtl.c
>and break program in debugger when offending instruction is emit. Then
>you will be probably able to figure out where it incarned.
>
nothing much there...

>
>See the gcc readings page.  I believe there are some links to other porting
>docs, than the gcc manual itself.  it is good idea to read them (even when I
>never did :), because it can save you some headaches later.
>
nothing much there eather :)

Thanks
Dmitry.

>
>Hope this helps,
>Honza
>
>>========================
>>(define_expand "movhi"
>> [(set (match_operand:HI 0 "nonimmediate_operand" "")
>>       (match_operand:HI 1 "general_operand" ""))]
>> ""
>> "")
>>
>>
>>(define_insn "*movhi1"
>> [(set (match_operand:HI 0 "memory_operand"      "=m")
>>       (match_operand:HI 1 "general_operand"           "m"))]
>> "( memory_operand(operands[0], VOIDmode)
>>       && !register_operand(operands[0], VOIDmode)
>>       && zero_shifted(operands[1])       
>>       && indexed_location(operands[1]))" 
>>"mov\\t@%E1, %0"
>> [(set_attr "length" "3")
>>  (set_attr "cc" "none")])
>>
>>
>>(define_insn "*movhi2"
>> [(set (match_operand:HI 0 "register_operand" "=r")
>>       (match_operand:HI 1 "general_operand"      "m"))]
>> "(nonimmediate_operand(operands[0], VOIDmode)
>>               && zero_shifted(operands[1])  
>>               && indexed_location(operands[1]) )"
>>      "mov\\t@%E1, %A0"
>> [(set_attr "length" "2")
>>  (set_attr "cc" "none")])
>>
>>(define_insn "*movhi3"
>> [(set (match_operand:HI 0 "nonimmediate_operand"      "=m,r,r,m,r,m,m,r")
>>       (match_operand:HI 1 "general_operand"           " 
>>m,r,P,P,m,r,i,i"))]
>> "(nonimmediate_operand(operands[0], HImode)
>>       && !zero_shifted(operands[1])
>>       && !indexed_location(operands[1]) )"
>> "mov\\t%1, %0 "
>> [(set_attr "length" "1,3,1,2,2,2,3,2")
>>  (set_attr "cc" "none")])
>>==============================
>>
>
>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05 11:14           ` dimmy
@ 2001-12-05 11:23             ` Jan Hubicka
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Hubicka @ 2001-12-05 11:23 UTC (permalink / raw)
  To: dimmy; +Cc: Jan Hubicka, gcc

> Jan,
> thanks
> 
> But still some thingsa are not clear:
> 
> >2) the zero_shifted/indexed_location test probably should be hid
> >  in new operand writen in your md file used in patterns instead of
> >  general_operand to make thinks cleaner.
> >  Basically the condition should mention only tests that depdends
> >  on multiple
> >3) "m" is wrong constraint for general_operand. Eighter you need
> >  to use memory_operand, or allow some registers and constants
> >  in the constraint.
> >
> If any type of addressing mode is allowed for instruction, I do not know 
> how to combine
> memory_operand, register and immediate. I can probably write my own 
> predicate. Correct?

memory+register+immediate is general_operand, but yes, if nothing apply,
just write your own operand.

In case your architecture limits constants in all cases (it appears to),
there are macros (LEGITIMATE_CONSTNAT?) or something like that to do
the trick w/o need to write new predicates for everything.
> 
> >  The constraints and predicates should be in "harmony" one should
> >  not be considerably stronger/weaker than the other otherwise you
> >  are asking for problems in reload pass.
> >  In case the second pattern is expected to load address as integer
> >  value (i386 lea equivalent), it should use
> >  (match_operand "address_operand" "a"), not memory and should come last
> >  to avoid matches in dumb cases.
> >  
> >4) For speed you should probably move more probable movhi3 first.
> >5) All three patterns can be single pattern with multiple alternative
> >  output template.  This will result in faster compiler and better
> >  produced code if you do so.  Some late passes, as reload, do not
> >  take a look if different pattern match, only test if given pattern
> >  and usually also alternative, allow the suggested optimization.
> >6) Similary you can collapse multiple alternatives to single:
> >  "=m,r,r,m,r,m,m,r
> >    m,r,P,P,m,r,i,i"
> >  can be:
> >  "=m   ,r"
> >    mrPi,mrPi"
> >
> The instruction length depends on addressing mode.
> So, mem->mem has length 3, mem->reg - 2, reg->reg -1, etc.
> O course, I can collapse constraints into:
> "=mr"
> "mrPi"
> and then dig an addressing mode. (What type of predicate should I use 

Hmm, then I guess you may try to keep the alternatives and see what
happends.  I've missed the length attribute.

> then? general? memory? ...)
> 
> So, will be correct the following:
> 
> (define_insn "*movhi3"
> [(set 	(match_operand:HI 0 "nonimmediate_operand"      "=mr")
> 	(match_operand:HI 1 "general_operand"           "mrPi"))]
> 
> ""
> "* return msp_emit_movhi3(insn, operand, NULL);"
> [(set_attr "length" "3")
>   (set_attr "cc" "none")])

This looks correct.
> 
> and inside msp_emit_movhi3() issue assembler instructions and set up the 
> insn lenght as third parameter?
If you will still use the alternative you can use template with line per
alternative starting by '@'.
> I actually do that for SI and DI modes, but I thought that coding in .md 
> is a bit cheaper.
> 
> 
> 
> >
> >  Also it is good to prohibit mem->mem move in the conditional + add
> >  expander to split it into two instructions early like i386.md does.
> >  Otherwise the need for register in this case is discovered late in
> >  the register allocation progress often resulting in dumb spill.
> >
> Only in conditional code? Do you mean if I have to compare 2 mem 
> locations like
> a==b first I have to move one of them to register?
> It seems to me that it's cheaper to do
>    cmp &a, &b    ;    compare values at addresses a and b
> than
>    mov &a, r4
>    mov &b, r5
>    cmp r4, r5
> 
> Am I wrong?
No, I meant conditional of the pattern (the condition),
but I see your architecture supports mem->mem moves, so the comment is wrong
anyway.
> >
> >Concerning your problem.  The problematic piece of code is not
> >contained in the mov expander, instead it is, most probably, some
> >other code generating the add/mov directly and getting thinks wrong.
> >
> The cpu core contains only 27 instructions and all instructions looks 
> the same - for example
> 'mov' has the same addressing modes as 'add', 'tst', etc... I dump rtl 
> phases I could not find where
> this instruction being generated.

All I can advise you is to use debugger and figure out how the instruction
(and invalid operand) is constructed.  Until then without the sources for
port you are working on it is really dificult to tell something.

Honza

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
  2001-12-05  3:36 Legitimize address, Please HELP! dimmy
  2001-12-05  7:31 ` Jan Hubicka
@ 2001-12-05 15:52 ` Richard Henderson
  1 sibling, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2001-12-05 15:52 UTC (permalink / raw)
  To: dimmy; +Cc: gcc

On Wed, Dec 05, 2001 at 03:33:37PM +0300, dimmy wrote:
>     if (GET_CODE (operand) == PLUS
>             && GET_CODE (XEXP (operand, 0)) == REG
>             && REG_OK_FOR_BASE_P (XEXP (operand, 0))

Should depend on strict here.


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Legitimize address, Please HELP!
@ 2001-12-06  5:03 dimmy the wild
  0 siblings, 0 replies; 9+ messages in thread
From: dimmy the wild @ 2001-12-06  5:03 UTC (permalink / raw)
  To: rth; +Cc: gcc


Richard,
thanks...
I set it up as:
    /* accept X(Rn) :  (Rn + X) points to the operand address*/
    if (GET_CODE (operand) == PLUS
            && GET_CODE (XEXP (operand, 0)) == REG
            && CONSTANT_ADDRESS_P (XEXP (operand, 1))
            &&(strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (operand, 0))
                      : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (operand, 0)))
        )
        goto granded;

Did not help eather.

Also, I found, that if fails to compile the following:

static /* inline */  fde *
binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
{
#ifdef WILL_CRASH_IF_NOT_DEFINED
        char tt[20];
#endif
        struct fde_vector *vec = ob->u.sort; /* THIS LEADS TO INCORRECT CODE */
        size_t lo, hi;

#ifdef WILL_CRASH_IF_NOT_DEFINED
/* this is not a part of unwind-dw2-fde.c 
   but these two dummie calls helping gcc to produce correct code!!!
*/
        set(vec->array,&lo,&hi,tt);
        reset(vec,tt, lo,hi);
#endif

        for (lo = 0, hi = vec->count; lo < hi; )
        {
                size_t i = (lo + hi) / 2;
                fde *f = vec->array[i];
                _Unwind_Ptr pc_begin, pc_range;
                const char *p;
                int encoding;

                encoding = get_fde_encoding (f);
                p = read_encoded_value_with_base (encoding,
                                                  base_from_object (encoding,
ob),
                                                  f->pc_begin, &pc_begin);
                read_encoded_value_with_base (encoding & 0x0F, 0, p, &pc_range);

                if ((_Unwind_Ptr)pc < pc_begin)
                        hi = i;
                else if ((_Unwind_Ptr)pc >= pc_begin + pc_range )
                        lo = i + 1;
                else
                        return f;
        }

        return 0;
}

which is a part of unwind-dw2-fde.c
But, guring gcc build xgcc does not complain about wrong operand (assembler
does), but if I run
cc1 it says:


unwind-dw2-fde.c: In function `search_object':
unwind-dw2-fde.c:930: Unrecognizable insn:
(insn 1212 29 30 (set (reg:HI 14 r14 [49])
        (mem/s:HI (plus:HI (mem:HI (plus:HI (reg/f:HI 1 r1)
                        (const_int 12 [0xc])) 0)
                (const_int 10 [0xa])) 13)) -1 (nil)

One more thing:
The function above is inlined in unwind-dw2-fde.c
Any sort of optimization results as wrong operand, 
Absemse of optimization results Unrecognizable insn.

The example above can be compiled without optimization fine.
With -Ox it produces wrong code but does not complain about 
wron addressing mode.


Does anybody have any idea why?
If you want I can send you complete sources of the gcc port.
Thanks in advance,
Dmitry.



On Wed, 5 Dec 2001 15:51:13 -0800
Richard Henderson <rth@redhat.com> wrote:

> On Wed, Dec 05, 2001 at 03:33:37PM +0300, dimmy wrote:
> >     if (GET_CODE (operand) == PLUS
> >             && GET_CODE (XEXP (operand, 0)) == REG
> >             && REG_OK_FOR_BASE_P (XEXP (operand, 0))
> 
> Should depend on strict here.
> 
> 
> r~
> 


*********************************************************************
   ("`-''-/").___..--''"`-._     (\       Dimmy the Wild      UA1ACZ
    `6_ 6  )   `-.  (     ).`-.__.`)      Enterprise Information Sys 
    (_Y_.)'  ._   )  `._ `. ``-..-'       Nevsky prospekt,   20 / 44
  _..`--'_..-_/  /--'_.' ,'               Saint Petersburg,   Russia
 (il),-''  (li),'  ((!.-'                 +7 (812) 314-8860, 5585314
*********************************************************************

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2001-12-06 12:51 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-05  3:36 Legitimize address, Please HELP! dimmy
2001-12-05  7:31 ` Jan Hubicka
2001-12-05  8:23   ` dimmy
2001-12-05  9:16     ` Jan Hubicka
     [not found]       ` <3C0E6806.3060706@mail.ru>
2001-12-05  9:52         ` Jan Hubicka
2001-12-05 11:14           ` dimmy
2001-12-05 11:23             ` Jan Hubicka
2001-12-05 15:52 ` Richard Henderson
2001-12-06  5:03 dimmy the wild

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).