I’m woking on TARGET_PROMOTE_FUNCTION_MODE for csky, and now there’s some
confusion.

 

For csky, the “POMOTE_MODE” is:

qi/hi -> si

the code is 

#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \

  if (GET_MODE_CLASS (MODE) == MODE_INT   \

      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \

    (MODE) = SImode;

 

And the TARGET_PROMOTE_FUNCTION_MODE is
default_promote_function_mode_always_promote.

 

I expected it can work as “POMOTE_MODE” just as the description at “gcc
internal”. But it calls promote_mode() and treat “libcalls” specially.:

machine_mode

promote_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode,

        int *punsignedp ATTRIBUTE_UNUSED)

{

#ifdef PROMOTE_MODE

  enum tree_code code;

  int unsignedp;

  scalar_mode smode;

#endif

 

  /* For libcalls this is invoked without TYPE from the backends

     TARGET_PROMOTE_FUNCTION_MODE hooks.  Don't do anything in that

     case.  */

  if (type == NULL_TREE)

    return mode;

……

 

Why don’t promote the mode here? And when I compile runtime library, the
“char” and “short” args are promoted WITHOUT special treatment!

 

So, I modified the code to make sure the TARGET_PROMOTE_FUNCTION_MODE work
as POMOTE_MODE:

#undef  TARGET_PROMOTE_FUNCTION_MODE

#define TARGET_PROMOTE_FUNCTION_MODE \

  csky_promote_function_mode

 

……

 

static machine_mode

csky_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,

                           machine_mode mode,

                           int *punsignedp ATTRIBUTE_UNUSED,

                           const_tree fntype ATTRIBUTE_UNUSED,

                           int for_return ATTRIBUTE_UNUSED)

{

  if (GET_MODE_CLASS (mode) == MODE_INT

      && GET_MODE_SIZE (mode) < UNITS_PER_WORD)

    return SImode;

 

  return mode;

}

 

But this code could lead to another mistake when I use some builtin
functions.

 

The __sync_val_compare_and_swap_1() coded at
“libgcc/config/csky/linux-atomic.c” use type “unsigned char” as its
argrument.

And this is consistent with the definition at gcc/builtins.def.

But when the code run at emit_library_call_value_1, all of the args are
treated as “signed”.

 

Part of source code of emit_library_call_value_1 ↓. The “unsigned_p” was
inited to 0, and was used at prmote_funciton_mode without reassignment.

  for (unsigned int i = 0; count < nargs; i++, count++)

    {

      rtx val = args[i].first;

      function_arg_info arg (args[i].second, /*named=*/true);

      int unsigned_p = 0;

……

 

      arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,

                    NULL_TREE, 0);

      argvec[count].mode = arg.mode;

      argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val,

                       unsigned_p);

      argvec[count].reg = targetm.calls.function_arg (args_so_far, arg);

 

……

 

What’s reason for this act? 

Reply via email to