public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Function argument passing
@ 2009-07-13 14:35 Mohamed Shafi
  2009-07-15 18:55 ` Richard Henderson
  0 siblings, 1 reply; 4+ messages in thread
From: Mohamed Shafi @ 2009-07-13 14:35 UTC (permalink / raw)
  To: GCC

Hello all,

I am doing a port for a private target in GCC 4.4.0. It generates code
for both little & big endian.

The ABI for the target is as follows:

1. All arguments passed in stack are passed using their alignment constrains.
Solution: For this to happen no argument promotion should be done.

2. Functions with a variable number of arguments pass the last fixed
argument and all subsequent variable arguments on the stack. Such
arguments of fewer than 4 bytes are located on the stack as if the
argument had been promoted to 32 bits.

Solution:
For TARGET_STRICT_ARGUMENT_NAMING the internals says the following :

This hook controls how the named argument to FUNCTION_ARG is set for
varargs and stdarg functions. If this hook returns true, the named
argument is always true for named arguments, and false for unnamed
arguments. If it returns false, but
TARGET_PRETEND_OUTGOING_VARARGS_NAMED returns true, then all arguments
are treated as named. Otherwise, all named arguments except the last
are treated as named.

So i made both TARGET_STRICT_ARGUMENT_NAMING and
PRETEND_OUTGOING_VARARGS_NAMED to return false. Is this correct?

How to make the varargs argument to be promoted to 32bits when the
normal argument don't require promotion as mentioned in point (1) ?

3. A function returning a structure or union receives in D0 the
address of the returned structure or union. The caller allocates space
for the returned object.
Solution: Used TARGET_FUNCTION_VALUE and returned D0 reg_rtx for
structure and unions.

4. A long long return value is returned in R6 and R7, R6 containing
the most significant  long word and R7 containing the least
significant long word, regardless of the endianess mode.
Solution: Used TARGET_RETURN_IN_MSB to return true when the mode is
little endian

5. If the first argument is a long long , it is passed in R6 and R7,
R6 containing the most significant long word and R7 containing the
least significant long word, regardless of the endianess mode.
For return value, i have done as mentioned in (4) but I am not sure
how to control the argument passing so that R6 contains the msw and R7
contains lsw, regardless of the endianess mode.


Regards,
Shafi

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

* Re: Function argument passing
  2009-07-13 14:35 Function argument passing Mohamed Shafi
@ 2009-07-15 18:55 ` Richard Henderson
  2009-08-24 13:41   ` Mohamed Shafi
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Henderson @ 2009-07-15 18:55 UTC (permalink / raw)
  To: Mohamed Shafi; +Cc: GCC

On 07/13/2009 07:35 AM, Mohamed Shafi wrote:
> So i made both TARGET_STRICT_ARGUMENT_NAMING and
> PRETEND_OUTGOING_VARARGS_NAMED to return false. Is this correct?

Yes.

> How to make the varargs argument to be promoted to 32bits when the
> normal argument don't require promotion as mentioned in point (1) ?

There is no way at present.  You'll have to extend the 
promote_function_args hook to accept a "bool named" parameter.

> 4. A long long return value is returned in R6 and R7, R6 containing
> the most significant  long word and R7 containing the least
> significant long word, regardless of the endianess mode.
> Solution: Used TARGET_RETURN_IN_MSB to return true when the mode is
> little endian

I don't believe this is correct.  RETURN_IN_MSB is supposed to be 
handling the case where the data to be returned is smaller than the 
register in which it is returned -- e.g. a 3 byte structure returned in 
a 32-bit register.  I believe you should be using...

> 5. If the first argument is a long long , it is passed in R6 and R7,
> R6 containing the most significant long word and R7 containing the
> least significant long word, regardless of the endianess mode.
> For return value, i have done as mentioned in (4) but I am not sure
> how to control the argument passing so that R6 contains the msw and R7
> contains lsw, regardless of the endianess mode.

For both return values and arguments, we support a PARALLEL which allows 
the target to indicate where each piece of the value is located.  It's 
also true that the generated rtl is more complicated, so you'd want to 
avoid this solution in big-endian mode, when it isn't needed.

So here you would do

if (WORDS_BIG_ENDIAN)
   return gen_rtx_REG (DImode, 6);
else
   {
     rtx r6, r7, par;

     r7 = gen_rtx_REG (SImode, 7);
     r7 = gen_rtx_EXPR_LIST (SImode, r7, GEN_INT (0));
     r6 = gen_rtx_REG (SImode, 6);
     r6 = gen_rtx_EXPR_LIST (SImode, r6, GEN_INT (4));
     par = gen_rtx_PARALLEL (DImode, gen_rtvec (2, r7, r6)));
     return par;
   }

See the docs for FUNCTION_ARG for details.


r~

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

* Re: Function argument passing
  2009-07-15 18:55 ` Richard Henderson
@ 2009-08-24 13:41   ` Mohamed Shafi
  2009-08-25 20:19     ` Richard Henderson
  0 siblings, 1 reply; 4+ messages in thread
From: Mohamed Shafi @ 2009-08-24 13:41 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC

2009/7/16 Richard Henderson <rth@redhat.com>:
> On 07/13/2009 07:35 AM, Mohamed Shafi wrote:
>>
>> So i made both TARGET_STRICT_ARGUMENT_NAMING and
>> PRETEND_OUTGOING_VARARGS_NAMED to return false. Is this correct?
>
> Yes.
>
>> How to make the varargs argument to be promoted to 32bits when the
>> normal argument don't require promotion as mentioned in point (1) ?
>
> There is no way at present.  You'll have to extend the promote_function_args
> hook to accept a "bool named" parameter.
>
>> 4. A long long return value is returned in R6 and R7, R6 containing
>> the most significant  long word and R7 containing the least
>> significant long word, regardless of the endianess mode.
>> Solution: Used TARGET_RETURN_IN_MSB to return true when the mode is
>> little endian
>
> I don't believe this is correct.  RETURN_IN_MSB is supposed to be handling
> the case where the data to be returned is smaller than the register in which
> it is returned -- e.g. a 3 byte structure returned in a 32-bit register.  I
> believe you should be using...
>
>> 5. If the first argument is a long long , it is passed in R6 and R7,
>> R6 containing the most significant long word and R7 containing the
>> least significant long word, regardless of the endianess mode.
>> For return value, i have done as mentioned in (4) but I am not sure
>> how to control the argument passing so that R6 contains the msw and R7
>> contains lsw, regardless of the endianess mode.
>
> For both return values and arguments, we support a PARALLEL which allows the
> target to indicate where each piece of the value is located.  It's also true
> that the generated rtl is more complicated, so you'd want to avoid this
> solution in big-endian mode, when it isn't needed.
>
> So here you would do
>
> if (WORDS_BIG_ENDIAN)
>  return gen_rtx_REG (DImode, 6);
> else
>  {
>    rtx r6, r7, par;
>
>    r7 = gen_rtx_REG (SImode, 7);
>    r7 = gen_rtx_EXPR_LIST (SImode, r7, GEN_INT (0));
>    r6 = gen_rtx_REG (SImode, 6);
>    r6 = gen_rtx_EXPR_LIST (SImode, r6, GEN_INT (4));
>    par = gen_rtx_PARALLEL (DImode, gen_rtvec (2, r7, r6)));
>    return par;
>  }
>
> See the docs for FUNCTION_ARG for details.
>

    I am getting the following error when i make a function call.

(call_insn 18 17 19 3 1.c:29 (set (parallel:DI [
                (expr_list:REG_UNUSED (reg:SI 7 d7)
                    (const_int 0 [0x0]))
                (expr_list:REG_UNUSED (reg:SI 6 d6)
                    (const_int 4 [0x4]))
            ])
        (call:SI (mem:SI (symbol_ref:SI ("dd1") [flags 0x41]
<function_decl 0xb7bfa980 dd1>) [0 S4 A8])
            (const_int 8 [0x8]))) -1 (nil)
    (expr_list:REG_DEP_TRUE (use (reg:SI 7 d7))
        (expr_list:REG_DEP_TRUE (use (reg:SI 6 d6))
            (nil))))

How do i write a pattern for this?
Another question is in LITTLE ENDIAN mode for the return value will
the compiler know that values are actually stored the other way.. in
big endian format? And generate the code accordingly for the rest of
the program?

Regards,
Shafi

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

* Re: Function argument passing
  2009-08-24 13:41   ` Mohamed Shafi
@ 2009-08-25 20:19     ` Richard Henderson
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2009-08-25 20:19 UTC (permalink / raw)
  To: Mohamed Shafi; +Cc: GCC

On 08/23/2009 10:19 PM, Mohamed Shafi wrote:
>      I am getting the following error when i make a function call.
>
> (call_insn 18 17 19 3 1.c:29 (set (parallel:DI [
>                  (expr_list:REG_UNUSED (reg:SI 7 d7)
>                      (const_int 0 [0x0]))
>                  (expr_list:REG_UNUSED (reg:SI 6 d6)
>                      (const_int 4 [0x4]))
>              ])
>          (call:SI (mem:SI (symbol_ref:SI ("dd1") [flags 0x41]
> <function_decl 0xb7bfa980 dd1>) [0 S4 A8])
>              (const_int 8 [0x8]))) -1 (nil)
>      (expr_list:REG_DEP_TRUE (use (reg:SI 7 d7))
>          (expr_list:REG_DEP_TRUE (use (reg:SI 6 d6))
>              (nil))))
>
> How do i write a pattern for this?

That isn't an error.  Presumably the actual error is that this
pattern isn't recognized.  Your call_value pattern is probably
wrong.  It should look sort of like

> (define_expand "call_value_osf"
>   [(parallel [(set (match_operand 0 "" "")
>                    (call (mem:DI (match_operand 1 "" ""))
>                          (match_operand 2 "" "")))
>               (use (reg:DI 29))
>               (clobber (reg:DI 26))])]

from alpha.  Notice that operand 0 has no predicate and no
constraint.

> Another question is in LITTLE ENDIAN mode for the return value will
> the compiler know that values are actually stored the other way.. in
> big endian format? And generate the code accordingly for the rest of
> the program?

Yes.


r~ 
 
 
 
 
 
 
 

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

end of thread, other threads:[~2009-08-25 15:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-13 14:35 Function argument passing Mohamed Shafi
2009-07-15 18:55 ` Richard Henderson
2009-08-24 13:41   ` Mohamed Shafi
2009-08-25 20:19     ` Richard Henderson

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