roy rosen <roy.1ro...@gmail.com> writes:

> 2011/3/24 Ian Lance Taylor <i...@google.com>:
>> roy rosen <roy.1ro...@gmail.com> writes:
>>
>>>> You build a RECORD_TYPE holding the fields you want to return.  You
>>>> define the appropriate builtin functions to return that record type.
>>>
>>> How is that done? using define_insn? How do I tell it to return a struct?
>>> Is there an example I can look at?
>>
>> A RECORD_TYPE is what gcc generates when you define a struct in your
>> source code.  For an example of a backend building a struct, see, e.g.,
>> ix86_build_builtin_va_list_abi.
>>
>> When you define your builtin functions in TARGET_INIT_BUILTINS you
>> specify the argument types and the return type, typically by building a
>> FUNCTION_TYPE and passing it to add_builtin_function.  To define a
>> builtin which returns a struct, just arrange for the return type of the
>> FUNCTION_TYPE that you pass to add_builtin_function be the RECORD_TYPE
>> that you built.
>
> I understood this part.
> What I don't understand is:
> In addition to adding the builtin function, in the md file I have a
> define_insn for each built in, for example:
>
> (define_insn "A_ssodssxx2w"
>       [(set (match_operand:SI 0 "register_operand" "=d ")
>       (unspec:SI [(match_operand:SI 1 "register_operand" "d ")
>       (match_operand:SI 2 "register_operand" "d ")]
>       UNSPEC_A_SSODSSXX2W))]
>       ""
>       "ssodssxx.2w %2,%1,%0 %!"
> )
>
> How do I create something equivalent which would have an rtl set
> expression to the structure.

At the RTL level the structure doesn't matter.  Your instruction
presumably sets some registers.  A register is just a register, it
doesn't have a type.

In TARGET_EXPAND_BUILTIN you need to pick up the two registers and
assemble them into a PARALLEL.  You're going to build REGs to pass to
the insn pattern.  Then do something along the lines of:

  ret0 = gen_rtx_EXPR_LIST (VOIDmode, reg0, const0_rtx);
  ret1 = gen_rtx_EXPR_LIST (VOIDmode, reg1, const1_rtx);
  ret = gen_rtx_PARALLEL (??mode, gen_rtvec (2, reg0, reg1));
  tree nt = build_qualified_type (struct_type, TYPE_QUAL_CONST);
  target = assign_temp (nt, 0, 0, 1);
  emit_group_store (target, ret, struct_type, ??);

Ian

Reply via email to