Actually, what I've done is probably something in between what you were suggesting and what I was initially doing. If we consider the multiplication, I've modified the define_expand for example to:
(define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "") (mult:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" "")))] "" " { emit_function_call_2args (DImode, DImode, DImode, \"my_version_of_mull\", operands[0], operands[1], operands[2]); DONE; }") and my emit function is: void emit_function_call_2args ( enum machine_mode return_mode, enum machine_mode arg1_mode, enum machine_mode arg2_mode, const char *fname, rtx op0, rtx op1, rtx op2) { tree id; rtx insn; /* Move arguments */ emit_move_insn (gen_rtx_REG (arg1_mode, GP_ARG_FIRST), op1); emit_move_insn (gen_rtx_REG (arg2_mode, GP_ARG_FIRST + 1), op2); /* Get name */ id = get_identifier (fname); /* Generate call value */ insn = gen_call_value ( gen_rtx_REG (return_mode, 6), gen_rtx_MEM (DImode, gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id))), GEN_INT (64), NULL ); /* Annotate the call to say we are using both argument registers */ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (arg1_mode, GP_ARG_FIRST)); use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (arg1_mode, GP_ARG_FIRST + 1)); /* Emit call */ emit_call_insn (insn); /* Set back return to op0 */ emit_move_insn (op0, gen_rtx_REG (return_mode, GP_RETURN)); } First off: does this seem correct? Second, I have a bit of a worry in the case where, if we consider this C code : bar (a * b, c * d); it is possible that the compiler would have normally generated this : mult output1, a, b mult output2, c, d call bar Which would be problematic for my expand system since this would expand into: mov output1, a mov output2, b call internal_mult mov output1, return_reg mov output1, c #Rewriting on output1... mov output2, d call internal_mult mov output2, return_reg call bar However, I am unsure this is possible in the expand stage, would the expand stage automatically have this instead: mult tmp1, a, b mult tmp2, c, d mov output1, tmp1 mov output2, tmp2 call bar in which case, I know I can do what I am currently doing. Thanks again for your help and I apologize for these basic questions... Jc On Tue, Sep 1, 2009 at 2:30 PM, Jean Christophe Beyler<jean.christophe.bey...@gmail.com> wrote: > I have looked at how other targest use the > init_builtins/expand_builtins. Of course, I don't understand > everything there but it seems indeed to be more for generating a > series of instructions instead of a function call. I haven't seen > anything resembling what I want to do. > > I had also first thought of going directly in the define_expand and > expanding to the function call I would want. The problem I have is > that it is unclear to me how to handle (set-up) the arguments of the > builtin_function I am trying to define. > > To go from no function call to : > > - Potentially spill output registers > - Potentially spill scratch registers > > - Setup output registers with the operands > - Perform function call > - Copy return to output operand > > - Potentially restore scratch registers > - Potentially restore output registers > > Seems a bit difficult to do at the define_expand level and might not > generate good code. I guess I could potentially perform a pass in the > tree representation to do what I am looking for but I am not sure that > that is the best solution either. > > For the moment, I will continue looking at what you suggest and also > see if my solution works. I see that, for example, the compiler will > not always generate the call I need to change. Therefore, it does seem > that I need another solution than the one I propose. > > I'm more and more considering a pass in the middle-end to get what I > need. Do you think this is better? > > Thanks for your input, > Jc > > On Tue, Sep 1, 2009 at 12:34 PM, Ian Lance Taylor<i...@google.com> wrote: >> Jean Christophe Beyler <jean.christophe.bey...@gmail.com> writes: >> >>> I have been also been looking into how to generate a function call for >>> certain operations. I've looked at various other targets for a similar >>> problem/solution but have not seen anything. On my target >>> architecture, we have certain optimized versions of the multiplication >>> for example. >>> >>> I wanted to replace certain mutliplications with a function call. The >>> solution I found was to do perform a FAIL on the define_expand of the >>> multiplication for these cases. This forces the compiler to generate a >>> function call to __multdi3. >>> >>> I then go in the define_expand of the function call and check the >>> symbol_ref to see what function is called. I can then modify the call >>> at that point. >>> >>> My question is: is this a good approach or is there another solution >>> that you would use? >> >> I think that what you describe will work. I would probably generate a >> call to a builtin function in the define_expand. Look for the way >> targets use init_builtins and expand_builtin. Normally expand_builtin >> expands to some target-specific RTL, but it can expand to a function >> call too. >> >> Ian >> >