## jump-size-ranges-intel32-g.pkg --- information to resolve jumps for runtime code generation.
#
# See background comments in
#
#
src/lib/compiler/back/low/jmp/jump-size-ranges.api# Compiled by:
#
src/lib/compiler/back/low/intel32/backend-intel32.lib# We get invoked from:
#
#
src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkgstipulate
package lem = lowhalf_error_message; # lowhalf_error_message is from
src/lib/compiler/back/low/control/lowhalf-error-message.pkgherein
generic package jump_size_ranges_intel32_g (
# ==========================
#
package mcf: Machcode_Intel32; # Machcode_Intel32 is from
src/lib/compiler/back/low/intel32/code/machcode-intel32.codemade.api package tce: Treecode_Eval # Treecode_Eval is from
src/lib/compiler/back/low/treecode/treecode-eval.api where
tcf == mcf::tcf; # "tcf" == "treecode_form".
package xe: Execode_Emitter # Execode_Emitter is from
src/lib/compiler/back/low/emit/execode-emitter.api where
mcf == mcf; # "mcf" == "machcode_form" (abstract machine code).
)
: (weak) Jump_Size_Ranges # Jump_Size_Ranges is from
src/lib/compiler/back/low/jmp/jump-size-ranges.api {
# Export to client packages:
#
package mcf = mcf; # "mcf" == "machcode_form" (abstract machine code).
package rgk = mcf::rgk; # "rgk" == "registerkinds".
stipulate
package lac = mcf::lac; # "lac" == "late_constant".
herein
fun error msg
=
lem::error("jump_size_ranges_intel32_g", msg);
esp = 4; # XXX SUCKO FIXME We shouldn't need this here -- we already define this three(!) times in src/lib/compiler/back/low/intel32/intel32.architecture-description
ebp = 5; # " "
branch_delayed_arch = FALSE;
fun imm8 i
=
-128 <= i and i < 128;
fun is_sdi (mcf::NOTE { op, ... } ) => is_sdi op;
is_sdi (mcf::LIVE _) => TRUE;
is_sdi (mcf::DEAD _) => TRUE;
is_sdi (mcf::COPY _) => FALSE;
is_sdi (mcf::BASE_OP base_op)
=>
case base_op
#
mcf::JMP (operand, _ ) => do_operand operand;
mcf::JCC { operand, ... } => do_operand operand;
#
mcf::BINARY { src, dst, ... } => do_operand src or do_operand dst;
mcf::MOVE { src, dst, ... } => do_operand src or do_operand dst;
mcf::LEA { address, ... } => do_operand address;
#
( mcf::CMPL arg
| mcf::CMPW arg | mcf::CMPB arg
| mcf::TESTL arg | mcf::TESTW arg | mcf::TESTB arg) => cmptest arg;
#
mcf::MULTDIV { src, ... } => do_operand src;
mcf::MUL3 { src1, ... } => do_operand src1;
#
mcf::UNARY { operand, ... } => do_operand operand;
mcf::SET { operand, ... } => do_operand operand;
#
mcf::CMOV { src, dst, ... } => do_operand src;
#
mcf::PUSHL operand => do_operand operand;
mcf::PUSHW operand => do_operand operand;
mcf::PUSHB operand => do_operand operand;
mcf::POP operand => do_operand operand;
mcf::FSTPT operand => do_operand operand;
mcf::FSTPL operand => do_operand operand;
mcf::FSTPS operand => do_operand operand;
mcf::FSTL operand => do_operand operand;
mcf::FSTS operand => do_operand operand;
mcf::FLDT operand => do_operand operand;
mcf::FLDL operand => do_operand operand;
mcf::FLDS operand => do_operand operand;
mcf::FILD operand => do_operand operand;
mcf::FILDL operand => do_operand operand;
mcf::FILDLL operand => do_operand operand;
#
mcf::FBINARY { src, dst, ... } => do_operand src or do_operand dst;
mcf::FIBINARY { src, ... } => do_operand src;
_ => FALSE;
esac
where
fun do_operand (mcf::IMMED_LABEL _) => TRUE;
do_operand (mcf::LABEL_EA _) => TRUE;
do_operand (mcf::DISPLACE { disp, ... } ) => do_operand disp;
do_operand (mcf::INDEXED { disp, ... } ) => do_operand disp;
do_operand _ => FALSE;
end;
fun cmptest { lsrc, rsrc }
=
do_operand lsrc or do_operand rsrc;
end;
end;
fun min_size_of (mcf::NOTE { op, ... } ) => min_size_of op;
#
min_size_of (mcf::LIVE _) => 0;
min_size_of (mcf::DEAD _) => 0;
min_size_of (mcf::BASE_OP i)
=>
case i
mcf::JMP _ => 2;
mcf::JCC _ => 2;
mcf::LEA _ => 2;
_ => 1;
esac;
min_size_of _ => error "min_size_of";
end;
fun max_size_of _ = 12;
# Value of span-dependent operand
#
fun do_operand (mcf::IMMED_LABEL label_expression) => tce::value_of label_expression;
do_operand (mcf::LABEL_EA label_expression) => tce::value_of label_expression;
#
do_operand _ => error "do_operand";
end;
encode = xe::op_to_bytevector;
fun sdi_size (mcf::NOTE { op, ... }, labmap, loc)
=>
sdi_size (op, labmap, loc);
sdi_size (mcf::LIVE _, _, _) => 0;
sdi_size (mcf::DEAD _, _, _) => 0;
sdi_size (mcf::BASE_OP instruction, labmap, loc)
=>
{
fun branch (operand, short, long)
=
{ offset = do_operand operand - loc;
if (imm8 (offset - 2)) short;
else long;
fi;
};
case instruction
mcf::JMP (operand, _) => branch (operand, 2, 5);
mcf::JCC { operand, ... } => branch (operand, 2, 6);
_ => vector_of_one_byte_unts::length (encode (mcf::BASE_OP instruction));
esac;
}; # fun sdi_size
sdi_size _ => error "sdi_size";
end;
# Instantiate given instruction to given size at given location:
#
fun instantiate_span_dependent_op { sdi => mcf::NOTE { op, ... }, size_in_bytes, at }
=>
instantiate_span_dependent_op { sdi => op, size_in_bytes, at };
instantiate_span_dependent_op { sdi => mcf::LIVE _, ... } => [];
instantiate_span_dependent_op { sdi => mcf::DEAD _, ... } => [];
instantiate_span_dependent_op { sdi => mcf::BASE_OP base_op, size_in_bytes, at }
=>
case base_op
#
mcf::JMP (operand, labs)
=>
[mcf::jmp (mcf::RELATIVE (do_operand operand - at), labs)];
mcf::JCC { cond, operand }
=>
[mcf::jcc { cond, operand=>mcf::RELATIVE (do_operand operand - at) } ];
operand => [mcf::BASE_OP operand];
esac;
instantiate_span_dependent_op _ => error "instantiate_span_dependent_op";
end;
end;
};
end;
## COPYRIGHT (c) 1997 Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.