## 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.pkgherein
# 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.