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