PreviousUpNext

15.4.442  src/lib/compiler/back/low/treecode/treecode-eval-g.pkg

## treecode-eval-g.pkg
#
# Fns to evaluate and compare treecode expressions.

# Compiled by:
#     src/lib/compiler/back/low/lib/lowhalf.lib




###             "It is a good morning exercise for
###              a research scientist to discard
###              a pet hypothesis every day before
###              breakfast. It keeps him young."
###
###                             -- Konrad Lorenz



stipulate
    package lbl =  codelabel;                                                                           # codelabel                     is from   src/lib/compiler/back/low/code/codelabel.pkg
    package rkj =  registerkinds_junk;                                                                  # registerkinds_junk            is from   src/lib/compiler/back/low/code/registerkinds-junk.pkg
herein

    # This generic gets invoked in
    #
    #     src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg
    #     src/lib/compiler/back/low/main/pwrpc32/backend-lowhalf-pwrpc32.pkg
    #     src/lib/compiler/back/low/main/sparc32/backend-lowhalf-sparc32.pkg
    #
    generic package   treecode_eval_g   (
        #             ===============
        #
        package tcf: Treecode_Form;                                                                     # Treecode_Form                 is from   src/lib/compiler/back/low/treecode/treecode-form.api

        # Equality extensions 
        eq_sext:   tcf::Eq_Fns -> (tcf::Sext,  tcf::Sext)   -> Bool;                                    # "s" is for "statement".
        eq_rext:   tcf::Eq_Fns -> (tcf::Rext,  tcf::Rext)   -> Bool;
        eq_fext:   tcf::Eq_Fns -> (tcf::Fext,  tcf::Fext)   -> Bool;
        eq_ccext:  tcf::Eq_Fns -> (tcf::Ccext, tcf::Ccext)  -> Bool;
    )
    : (weak) Treecode_Eval                                                                              # Treecode_Eval                 is from   src/lib/compiler/back/low/treecode/treecode-eval.api
    {
        # Export to client packages:
        #
        package tcf =  tcf;                                                                             # "tcf" == "treecode_form".
        package lac =  tcf::lac;                                                                        # "lac" == "late_constant".

        stipulate
            package mi =  tcf::mi;                                                                      # "mi"  == "machine_int".
        herein

            eq_label =   lbl::same_codelabel;

            fun eq_labels ([],[]) => TRUE;
                eq_labels (a ! b, c ! d) => eq_label (a, c) and eq_labels (b, d);
                eq_labels _ => FALSE;
            end 

            also
            fun eq_cell ( rkj::CODETEMP_INFO { id=>x, ... },
                          rkj::CODETEMP_INFO { id=>y, ... }
                        )
                =
                x == y

            also
            fun eq_cells ([], [])         =>  TRUE;
                eq_cells (x ! xs, y ! ys) =>  eq_cell (x, y) and eq_cells (xs, ys);
                eq_cells _                =>  FALSE;
            end 

            also
            fun eq_copy ((t1, dst1, src1), (t2, dst2, src2))
                =
                t1==t2                  and
                eq_cells (dst1, dst2)   and
                eq_cells (src1, src2)

            also fun eq_ctrl  (c1, c2) =   eq_cell  (c1, c2)
            also fun eq_ctrls (c1, c2) =   eq_cells (c1, c2)

            # Statements:
            #
            also
            fun equality ()
              =
              { void_expression  =>  same_void_expression,
                int_expression   =>  same_int_expression,
                float_expression =>  same_float_expression,
                flag_expression  =>  same_flag_expression                                               # flag expressions handle zero/parity/overflow/... flag stuff.
              }

            also
            fun same_void_expression (tcf::LOAD_INT_REGISTER (a, b, c), tcf::LOAD_INT_REGISTER (d, e, f))
                     =>
                     a==d   and   eq_cell (b, e)   and   same_int_expression (c, f);

                same_void_expression (tcf::LOAD_INT_REGISTER_FROM_FLAGS_REGISTER (a, b), tcf::LOAD_INT_REGISTER_FROM_FLAGS_REGISTER (c, d))
                     =>
                     eq_cell (a, c) and same_flag_expression (b, d);

                same_void_expression (tcf::LOAD_FLOAT_REGISTER (a, b, c), tcf::LOAD_FLOAT_REGISTER (d, e, f))
                     => 
                     a==d and eq_cell (b, e) and same_float_expression (c, f);

                same_void_expression (tcf::MOVE_INT_REGISTERS x, tcf::MOVE_INT_REGISTERS y) => eq_copy (x, y);
                same_void_expression (tcf::MOVE_FLOAT_REGISTERS x, tcf::MOVE_FLOAT_REGISTERS y) => eq_copy (x, y);
                same_void_expression (tcf::GOTO (a, b), tcf::GOTO (a', b')) => same_int_expression (a, a');
                same_void_expression (tcf::CALL { funct=>a, defs=>b, uses=>c, ... },
                       tcf::CALL { funct=>d, defs=>e, uses=>f, ... } ) =>  
                    same_int_expression (a, d) and same_expressionlists (b, e) and same_expressionlists (c, f);
                same_void_expression (tcf::RET _, tcf::RET _) => TRUE;
                same_void_expression (tcf::STORE_INT (a, b, c, _), tcf::STORE_INT (d, e, f, _)) => 
                    a==d and same_int_expression (b, e) and same_int_expression (c, f);
                same_void_expression (tcf::STORE_FLOAT (a, b, c, _), tcf::STORE_FLOAT (d, e, f, _)) =>
                    a==d and same_int_expression (b, e) and same_float_expression (c, f);
                same_void_expression (tcf::NOTE (s1, _), s2) => same_void_expression (s1, s2);
                same_void_expression (s1, tcf::NOTE (s2, _)) => same_void_expression (s1, s2);
                same_void_expression (tcf::PHI x, tcf::PHI y) => x==y;
                same_void_expression (tcf::SOURCE, tcf::SOURCE) => TRUE;
                same_void_expression (tcf::SINK, tcf::SINK) => TRUE;
                same_void_expression (tcf::IF_GOTO (b, c), tcf::IF_GOTO (b', c')) => 
                   same_flag_expression (b, b') and eq_label (c, c');
                same_void_expression (tcf::IF (b, c, d), tcf::IF (b', c', d')) => 
                   same_flag_expression (b, b') and same_void_expression (c, c') and same_void_expression (d, d');
                same_void_expression (tcf::RTL { attributes=>x, ... }, tcf::RTL { attributes=>y, ... } ) => x==y;
                same_void_expression (tcf::REGION (a, b), tcf::REGION (a', b')) => eq_ctrl (b, b') and same_void_expression (a, a');
                same_void_expression (tcf::EXT a, tcf::EXT a') => eq_sext (equality()) (a, a');
                same_void_expression _ => FALSE;
            end 

            also
            fun same_void_expressions ([],[]) => TRUE;
                same_void_expressions (a ! b, c ! d) => same_void_expression (a, c) and same_void_expressions (b, d);
                same_void_expressions _ => FALSE;
            end 

            also
            fun eq_lowhalf (tcf::FLAG_EXPRESSION a, tcf::FLAG_EXPRESSION b) => same_flag_expression (a, b);
                eq_lowhalf (tcf::INT_EXPRESSION a, tcf::INT_EXPRESSION b) => same_int_expression (a, b);
                eq_lowhalf (tcf::FLOAT_EXPRESSION a, tcf::FLOAT_EXPRESSION b) => same_float_expression (a, b);
                eq_lowhalf _ => FALSE;
            end 

            also
            fun same_expressionlists ([],[]) => TRUE;
                same_expressionlists (a ! b, c ! d) => eq_lowhalf (a, c) and same_expressionlists (b, d);
                same_expressionlists _ => FALSE;
            end 

            also
            fun eq2 ((a, b, c), (d, e, f))
                =
                a==d and same_int_expression (b, e) and same_int_expression (c, f)

            also
            fun eq3 ((m, a, b, c), (n, d, e, f))
                =
                m == n          and
                a == d          and
                same_int_expression (b, e)  and
                same_int_expression (c, f)

            also
            fun same_int_expression (tcf::CODETEMP_INFO (a, b), tcf::CODETEMP_INFO (c, d)) => a==c and eq_cell (b, d);
                same_int_expression (tcf::LITERAL a, tcf::LITERAL b)   =>   a == b;
                same_int_expression (tcf::LABEL a, tcf::LABEL b) => eq_label (a, b);
                same_int_expression (tcf::LABEL_EXPRESSION a, tcf::LABEL_EXPRESSION b) => same_int_expression (a, b);
                same_int_expression (tcf::LATE_CONSTANT a, tcf::LATE_CONSTANT b) => lac::same_late_constant (a, b);
                same_int_expression (tcf::NEG (t, x), tcf::NEG (t', x'))   =>   t == t' and same_int_expression (x, x');
                same_int_expression (tcf::ADD x, tcf::ADD y) => eq2 (x, y);
                same_int_expression (tcf::SUB x, tcf::SUB y) => eq2 (x, y);
                same_int_expression (tcf::MULS x, tcf::MULS y) => eq2 (x, y);
                same_int_expression (tcf::DIVS x, tcf::DIVS y) => eq3 (x, y);
                same_int_expression (tcf::REMS x, tcf::REMS y) => eq3 (x, y);
                same_int_expression (tcf::MULU x, tcf::MULU y) => eq2 (x, y);
                same_int_expression (tcf::DIVU x, tcf::DIVU y) => eq2 (x, y);
                same_int_expression (tcf::REMU x, tcf::REMU y) => eq2 (x, y);
                same_int_expression (tcf::NEG_OR_TRAP (t, x), tcf::NEG_OR_TRAP (t', x'))   =>   t == t' and same_int_expression (x, x');
                same_int_expression (tcf::ADD_OR_TRAP x, tcf::ADD_OR_TRAP y) => eq2 (x, y);
                same_int_expression (tcf::SUB_OR_TRAP x, tcf::SUB_OR_TRAP y) => eq2 (x, y);
                same_int_expression (tcf::MULS_OR_TRAP x, tcf::MULS_OR_TRAP y) => eq2 (x, y);
                same_int_expression (tcf::DIVS_OR_TRAP x, tcf::DIVS_OR_TRAP y) => eq3 (x, y);
                same_int_expression (tcf::BITWISE_AND x, tcf::BITWISE_AND y) => eq2 (x, y);
                same_int_expression (tcf::BITWISE_OR x, tcf::BITWISE_OR y) => eq2 (x, y);
                same_int_expression (tcf::BITWISE_XOR x, tcf::BITWISE_XOR y) => eq2 (x, y);
                same_int_expression (tcf::BITWISE_EQV x, tcf::BITWISE_EQV y) => eq2 (x, y);
                same_int_expression (tcf::BITWISE_NOT (a, b), tcf::BITWISE_NOT (c, d))   =>   a==c and same_int_expression (b, d);
                same_int_expression (tcf::RIGHT_SHIFT x, tcf::RIGHT_SHIFT y) => eq2 (x, y);
                same_int_expression (tcf::RIGHT_SHIFT_U x, tcf::RIGHT_SHIFT_U y) => eq2 (x, y);
                same_int_expression (tcf::LEFT_SHIFT x, tcf::LEFT_SHIFT y) => eq2 (x, y);

                same_int_expression ( tcf::CONDITIONAL_LOAD (a, b, c, d),
                                      tcf::CONDITIONAL_LOAD (e, f, g, h)
                                    )
                                    => 
                                    a==e
                                    and same_flag_expression (b, f)
                                    and same_int_expression  (c, g)
                                    and same_int_expression  (d, h);

                same_int_expression (tcf::SIGN_EXTEND (a, b, c), tcf::SIGN_EXTEND (a', b', c'))
                    => 
                    a==a' and b==b' and same_int_expression (c, c');

                same_int_expression (tcf::ZERO_EXTEND (a, b, c), tcf::ZERO_EXTEND (a', b', c'))
                    => 
                    a==a' and b==b' and same_int_expression (c, c');

                same_int_expression (tcf::FLOAT_TO_INT (a, b, c, d), tcf::FLOAT_TO_INT (e, f, g, h))
                    => 
                    a==e and b==f and c==g and same_float_expression (d, h);

                same_int_expression (tcf::LOAD (a, b, _), tcf::LOAD (c, d, _)) => a==c and same_int_expression (b, d);
                same_int_expression (tcf::LET (a, b), tcf::LET (c, d)) => same_void_expression (a, c) and same_int_expression (b, d);
                same_int_expression (tcf::ARG x, tcf::ARG y) => x == y;
                same_int_expression (tcf::PARAM x, tcf::PARAM y) => x == y;
                same_int_expression (tcf::QQQ, tcf::QQQ) => TRUE;
                same_int_expression (tcf::ATATAT(t1, k1, e1), tcf::ATATAT(t2, k2, e2)) => 
                   t1==t2 and k1==k2 and same_int_expression (e1, e2);
                same_int_expression (tcf::BITSLICE (t1, s1, e1), tcf::BITSLICE (t2, s2, e2)) =>
                   t1==t2 and s1==s2 and same_int_expression (e1, e2);
                same_int_expression (tcf::RNOTE (a, _), b) => same_int_expression (a, b);
                same_int_expression (a, tcf::RNOTE (b, _)) => same_int_expression (a, b);
                same_int_expression (tcf::PRED (a, b), tcf::PRED (a', b')) => eq_ctrl (b, b') and same_int_expression (a, a');
                same_int_expression (tcf::REXT (a, b), tcf::REXT (a', b')) =>   
                     a==a' and eq_rext (equality()) (b, b'); 
                same_int_expression _ => FALSE;
            end 

            also
            fun eq_rexps ([],[]) => TRUE;
                eq_rexps (a ! b, c ! d) => same_int_expression (a, c) and eq_rexps (b, d);
                eq_rexps _ => FALSE;
            end 

            also
            fun eq2' ((a, b, c), (d, e, f))
                =
                a==d and same_float_expression (b, e) and same_float_expression (c, f)

            also
            fun eq1' ((a, b), (d, e))
                =
                a==d and same_float_expression (b, e) 

            also
            fun same_float_expression (tcf::CODETEMP_INFO_FLOAT (t1, x),    tcf::CODETEMP_INFO_FLOAT (t2, y)   ) =>   t1==t2  and  eq_cell (x, y);
                same_float_expression (tcf::FLOAD (a, b, _), tcf::FLOAD (c, d, _)) =>   a==c    and  same_int_expression (b, d);
                #
                same_float_expression (tcf::FADD x, tcf::FADD y) =>  eq2' (x, y); 
                same_float_expression (tcf::FMUL x, tcf::FMUL y) =>  eq2' (x, y);
                same_float_expression (tcf::FSUB x, tcf::FSUB y) =>  eq2' (x, y); 
                same_float_expression (tcf::FDIV x, tcf::FDIV y) =>  eq2' (x, y);
                #
                same_float_expression (tcf::COPY_FLOAT_SIGN x, tcf::COPY_FLOAT_SIGN y) => eq2' (x, y);
                #
                same_float_expression ( tcf::FCONDITIONAL_LOAD (t,  x,  y,  z ),
                                        tcf::FCONDITIONAL_LOAD (t', x', y', z')
                                      )
                                      =>
                                      t==t'
                                      and same_flag_expression  (x, x')
                                      and same_float_expression (y, y')
                                      and same_float_expression (z, z');
                #
                same_float_expression (tcf::FABS  x, tcf::FABS  y) =>  eq1' (x, y);
                same_float_expression (tcf::FNEG  x, tcf::FNEG  y) =>  eq1' (x, y);
                same_float_expression (tcf::FSQRT x, tcf::FSQRT y) =>  eq1' (x, y);
                #
                same_float_expression (tcf::INT_TO_FLOAT   (a, b, c), tcf::INT_TO_FLOAT   (a', b', c')) =>   a==a' and b==b' and same_int_expression   (c, c');
                same_float_expression (tcf::FLOAT_TO_FLOAT (a, b, c), tcf::FLOAT_TO_FLOAT (a', b', c')) =>   a==a' and b==b' and same_float_expression (c, c');
                #
                same_float_expression (tcf::FEXT (a, f), tcf::FEXT (b, g)) => a==b and eq_fext (equality()) (f, g); 
                same_float_expression (tcf::FNOTE (a, _), b) => same_float_expression (a, b);
                same_float_expression (a, tcf::FNOTE (b, _)) => same_float_expression (a, b);
                same_float_expression (tcf::FPRED (a, b), tcf::FPRED (a', b')) => eq_ctrl (b, b') and same_float_expression (a, a');
                #
                same_float_expression _ => FALSE;
            end 

            also
            fun eq_fexps ([],[]) => TRUE;
                eq_fexps (a ! b, c ! d) => same_float_expression (a, c) and eq_fexps (b, d);
                eq_fexps _ => FALSE;
            end 

            also
            fun same_flag_expression (tcf::CC (c1, x), tcf::CC (c2, y)) => c1==c2 and eq_cell (x, y);
                same_flag_expression (tcf::FCC (c1, x), tcf::FCC (c2, y)) => c1==c2 and eq_cell (x, y);
                same_flag_expression (tcf::CMP (x, a, b, c), tcf::CMP (y, d, e, f)) => 
                   a==d and same_int_expression (b, e) and same_int_expression (c, f) and x == y;
                same_flag_expression (tcf::FCMP (x, a, b, c), tcf::FCMP (y, d, e, f)) =>
                   a==d and same_float_expression (b, e) and same_float_expression (c, f) and x == y;
                same_flag_expression (tcf::NOT x, tcf::NOT y) => same_flag_expression (x, y);
                same_flag_expression (tcf::AND x, tcf::AND y) => same_flag_expression2 (x, y);
                same_flag_expression (tcf::OR x,  tcf::OR y) => same_flag_expression2 (x, y);
                same_flag_expression (tcf::XOR x, tcf::XOR y) => same_flag_expression2 (x, y);
                same_flag_expression (tcf::EQV x, tcf::EQV y) => same_flag_expression2 (x, y);
                same_flag_expression (tcf::CCNOTE (a, _), b) => same_flag_expression (a, b);
                same_flag_expression (a, tcf::CCNOTE (b, _)) => same_flag_expression (a, b);
                same_flag_expression (tcf::CCEXT (t, a), tcf::CCEXT (t', b)) => 
                   t==t' and eq_ccext (equality()) (a, b);
                same_flag_expression (tcf::TRUE, tcf::TRUE) => TRUE;
                same_flag_expression (tcf::FALSE, tcf::FALSE) => TRUE;
                same_flag_expression _ => FALSE;
            end 

            also
            fun same_flag_expression2 ((x, y), (x', y'))
                =
                same_flag_expression (x, x') and same_flag_expression (y, y')

            also
            fun same_flag_expressions ([],[]) => TRUE;
                same_flag_expressions (a ! b, c ! d) => same_flag_expression (a, c) and same_flag_expressions (b, d);
                same_flag_expressions _ => FALSE;
            end;

            exception NON_CONSTANT;

            fun make_evaluation_functions { label_to_int, late_constant_to_integer }
                =
                { evaluate_int_expression,
                  evaluate_flag_expression
                }
                where

                    fun drm tcf::d::ROUND_TO_ZERO   => mi::DIV_TO_ZERO;                                 # Special rounding-mode just for divide instructions.
                        drm tcf::d::ROUND_TO_NEGINF => mi::DIV_TO_NEGINF;
                    end;

                    fun evaluate_int_expression (tcf::LITERAL i) => i;
                        evaluate_int_expression (tcf::LATE_CONSTANT c) => late_constant_to_integer c;
                        evaluate_int_expression (tcf::LABEL l) => multiword_int::from_int (label_to_int l);
                        evaluate_int_expression (tcf::LABEL_EXPRESSION e) => evaluate_int_expression e;

                        evaluate_int_expression (tcf::NEG (size, x)) => mi::neg (size, evaluate_int_expression x);
                        evaluate_int_expression (tcf::ADD (size, x, y)) => mi::add (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::SUB (size, x, y)) => mi::sub (size, evaluate_int_expression x, evaluate_int_expression y);

                        evaluate_int_expression (tcf::MULS (size, x, y)) => mi::muls (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::DIVS (m, size, x, y)) => mi::divs (drm m, size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::REMS (m, size, x, y)) => mi::rems (drm m, size, evaluate_int_expression x, evaluate_int_expression y);

                        evaluate_int_expression (tcf::MULU (size, x, y)) => mi::mulu (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::DIVU (size, x, y)) => mi::divu (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::REMU (size, x, y)) => mi::remu (size, evaluate_int_expression x, evaluate_int_expression y);

                        evaluate_int_expression (tcf::NEG_OR_TRAP (size, x)) => mi::negt (size, evaluate_int_expression x);
                        evaluate_int_expression (tcf::ADD_OR_TRAP (size, x, y)) => mi::addt (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::SUB_OR_TRAP (size, x, y)) => mi::subt (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::MULS_OR_TRAP (size, x, y)) => mi::mult (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::DIVS_OR_TRAP (m, size, x, y)) => mi::divt (drm m, size, evaluate_int_expression x, evaluate_int_expression y);

                        evaluate_int_expression (tcf::BITWISE_NOT (size, x)) => mi::bitwise_not (size, evaluate_int_expression x);
                        evaluate_int_expression (tcf::BITWISE_AND (size, x, y)) => mi::bitwise_and (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::BITWISE_OR (size, x, y)) => mi::bitwise_or (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::BITWISE_XOR (size, x, y)) => mi::bitwise_xor (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::BITWISE_EQV (size, x, y)) => mi::eqvb (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::LEFT_SHIFT (size, x, y)) => mi::sll_x (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::RIGHT_SHIFT_U (size, x, y)) => mi::srl_x (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::RIGHT_SHIFT (size, x, y)) => mi::sra_x (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_int_expression (tcf::BITSLICE (size, x, y)) => mi::bitslice (size, x, evaluate_int_expression y);

                        evaluate_int_expression (tcf::CONDITIONAL_LOAD (size, cc, x, y)) =>  if (evaluate_flag_expression cc)  evaluate_int_expression x;
                                                                                             else                              evaluate_int_expression y;
                                                                                             fi;

                        evaluate_int_expression (tcf::SIGN_EXTEND (a, b, x)) => mi::sx (a, b, evaluate_int_expression x);
                        evaluate_int_expression (tcf::ZERO_EXTEND (a, b, x)) => mi::zx (a, b, evaluate_int_expression x);

                        evaluate_int_expression (tcf::RNOTE (e, _)) => evaluate_int_expression e;

                        evaluate_int_expression _ => raise exception NON_CONSTANT;
                    end 

                    also
                    fun evaluate_flag_expression (tcf::TRUE ) => TRUE;
                        evaluate_flag_expression (tcf::FALSE) => FALSE;
                        #
                        evaluate_flag_expression (tcf::CMP (size, tcf::EQ,  x, y)) => mi::eq  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::NE,  x, y)) => mi::ne  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::GT,  x, y)) => mi::gt  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::GE,  x, y)) => mi::ge  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::LT,  x, y)) => mi::lt  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::LE,  x, y)) => mi::le  (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::GTU, x, y)) => mi::gtu (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::LTU, x, y)) => mi::ltu (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::GEU, x, y)) => mi::geu (size, evaluate_int_expression x, evaluate_int_expression y);
                        evaluate_flag_expression (tcf::CMP (size, tcf::LEU, x, y)) => mi::leu (size, evaluate_int_expression x, evaluate_int_expression y);
                        #
                        evaluate_flag_expression (tcf::NOT x) => not (evaluate_flag_expression x);
                        #
                        evaluate_flag_expression (tcf::AND (x, y)) =>  evaluate_flag_expression x and evaluate_flag_expression y;
                        evaluate_flag_expression (tcf::OR  (x, y)) =>  evaluate_flag_expression x or  evaluate_flag_expression y;
                        evaluate_flag_expression (tcf::XOR (x, y)) =>  evaluate_flag_expression x !=  evaluate_flag_expression y;
                        evaluate_flag_expression (tcf::EQV (x, y)) =>  evaluate_flag_expression x ==  evaluate_flag_expression y;
                        #
                        evaluate_flag_expression (tcf::CCNOTE (e, _)) => evaluate_flag_expression e;
                        #
                        evaluate_flag_expression _ => raise exception NON_CONSTANT;
                    end;
                end;

            fun value_of e
                = 
                multiword_int::to_int  (evaluate_int_expression  e)
                where   
                    my  { evaluate_int_expression, ... }
                        =
                        make_evaluation_functions
                          {
                            late_constant_to_integer =>  \\ lateconst =  multiword_int::from_int (lac::late_constant_to_int  lateconst),
                            label_to_int             =>  lbl::get_codelabel_address
                          };
                end;

            my ====   =   same_int_expression;
        end;
    };
end;

## COPYRIGHT (c) 2001 Lucent Technologies, Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext