<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>
Given:<br><br><br>MODULE RTTest; IMPORT RT0;<br><br>PROCEDURE F1 (b: RT0.Binder) = BEGIN<br>EVAL b(0);<br>END F1;<br><br>BEGIN END RTTest.<br><br><br>This tends to fail on Aligned_procedures := FALSE architectures.<br>I see this testing SPARC64_SOLARIS with gcc 4.7 backend,<br>when the procedure isn't 8-aligned -- alignment fault.<br><br><br>IL is reasonable:<br><br>...<br>(89)         start_call_indirect type:addr<br>(90)           load_integer type:int_64 0<br>(91)           pop_param type:int_64<br>(92)           load var:0x5 offset:0 src_t:addr dst_t:addr m3name:noname <br>(93)           loophole type1:addr type2:int_64<br>(94)           load_integer type:int_64 7<br>(95)           and type:int_64<br>(96)           if_true type:int_64 label:1 frequency:0X32(50)<br>(97)           load var:0x5 offset:0 src_t:addr dst_t:addr m3name:noname <br>(98)           load_nil<br>...<br><br><br>but the assembly is inefficient and incorrect:<br><br><br>RTTest__F1:<br>.LLFB0:<br>    save    %sp, -208, %sp<br>.LLCFI0:<br>    stx    %i0, [%fp+2175]<br>    ldx    [%fp+2175], %g1<br>    stx    %g1, [%fp+2039]<br>    ldx    [%fp+2039], %g1<br>    and    %g1, 7, %g1 <= correct<br>    and    %g1, 1, %g1  <= incorrect<br>    and    %g1, 0xff, %g1  <=  pointless, inefficient<br>    cmp    %g1, 0<br><br><br>current parse.c:<br><br><br>M3CG_HANDLER (IF_TRUE)<br>{<br>  tree cond = m3_cast (boolean_type_node, EXPR_REF (-1));<br>  EXPR_POP ();<br><br>  add_stmt (build3 (COND_EXPR, t_void, cond,<br>                    build1 (GOTO_EXPR, t_void, label),<br>                    NULL_TREE));<br>}<br><br><br>static tree<br>m3_cast (tree type, tree op0)<br>{<br>  return m3_build1 (NOP_EXPR, type, op0);<br>}<br><br><br>Thoughts?<br><br><br>I'm thinking, something like:<br><br><br>PROCEDURE If_closure (proc: Val;  true, false: Label;  freq: Frequency) =<br>  VAR skip := Next_label ();  nope := skip;<br>  BEGIN<br>    IF (false # No_label) THEN  nope := false; END;<br>    IF NOT Target.Aligned_procedures THEN<br>      Push (proc);<br>      Force ();<br>      cg.loophole (Type.Addr, Target.Integer.cg_type);<br>      Push_int (TargetMap.CG_Align_bytes[Target.Integer.cg_type] - 1);<br>      cg.and (Target.Integer.cg_type);<br>      <br>      == insert comparisong to 0 here ==<br><br>      cg.if_true (Target.Integer.cg_type, nope, Always - freq);<br>      SPop (1, "If_closure-unaligned");<br>    END;<br>    <br><br>and possibly if_true should assert that top of stack is boolean already.<br><br><br>I'll check that this isn't something I broke in 4.7 -- maybe boolean changed.<br><br><br>I was thinking this had something to do with tagged types, but no -- there is nothing<br>related to them in the IL. I guess function pointers can't be tagged?<br><br><br> - Jay                                        </div></body>
</html>