## registerkinds.api -- derived from ~/src/sml/nj/smlnj-110.58/new/new/src/MLRISC/instructions/cells.sig
#
# Per-architecture description of register sets.
#
# We are interested here in a 'register' as something
# on which an instruction can be data-dependent, so
# we include not only int and float registers but
# also condition-code registers.
#
# For coding convenience we even allow control
# dependencies and words in main memory to be 'registers'.
#
# There is a lot of redundancy between this API and
# Platform Register_Info, presumably because Platform_Register_Info # Platform_Register_Info is from
src/lib/compiler/back/low/main/nextcode/platform-register-info.api# derives from the original SML/NJ codebase dating back to 1990,
# whereas Registerkinds derives from the separate and
# later MLRISC project (== compiler backend lowhalf), which
# has never been fully integrated. XXX SUCKO FIXME
# Compiled by:
#
src/lib/compiler/back/low/lib/lowhalf.lib# This api is 'include'-ed in:
#
#
src/lib/compiler/back/low/intel32/code/registerkinds-intel32.codemade.pkg#
src/lib/compiler/back/low/sparc32/code/registerkinds-sparc32.codemade.pkg# This api is implemented in:
#
#
src/lib/compiler/back/low/code/registerkinds-g.pkgstipulate
package rkj = registerkinds_junk; # registerkinds_junk is from
src/lib/compiler/back/low/code/registerkinds-junk.pkgherein
api Registerkinds {
#
# all_registerkinds: List( rkj::Registerkind ); # List of all the registerkinds. # Commented out because never used -- 2011-06-24 CrT
codetemp_id_if_above: rkj::Universal_Register_Id; # All ids >= this value belong to codetemps, not to hardware registers.
info_for_registerkind # Find info record by looping over registerkind_infos list.
:
rkj::Registerkind
->
rkj::Registerkind_Info;
get_id_range_for_physical_register_kind # Return the range of ids used to name registers in a given hardware register set.
:
rkj::Registerkind
->
{ min_register_id: Int,
max_register_id: Int
};
#
# We define a single int address space into which
# all register ids and codetemps ids are mapped.
#
# To get a sense of it, you can peek at the
# 'min_register_id' and 'max_register_id' values defined in
#
#
src/lib/compiler/back/low/intel32/code/registerkinds-intel32.codemade.pkg #
src/lib/compiler/back/low/pwrpc32/code/registerkinds-pwrpc32.codemade.pkg #
src/lib/compiler/back/low/sparc32/code/registerkinds-sparc32.codemade.pkg #
# In general the hardware registers come first, then
# the global codetemps (of which there are one...),
# and finally the plain dynamically allocated codetemps
# (of which there may be thousands) have the space running
# roughly from 512 -> maxint.
#
# This function returns the 'min_register_id' and 'max_register_id' values
# for the given hardware register set.
get_ith_int_hardware_register: Int -> rkj::Codetemp_Info; # Abbreviation for get_ith_hardware_register_of_kind rkj::INT_REGISTER;
get_ith_float_hardware_register: Int -> rkj::Codetemp_Info; # Abbreviation for get_ith_hardware_register_of_kind rkj::FLOAT_REGISTER;
#
get_ith_hardware_register_of_kind
:
rkj::Registerkind
->
(rkj::Intrakind_Register_Id -> rkj::Codetemp_Info);
#
# Return the i-th physical register of the given kind.
#
# Raises NO_SUCH_PHYSICAL_REGISTER if there are no physical register of the given number.
# Also raises NO_SUCH_PHYSICAL_REGISTER if the given number if outside of the range.
#
# NOTE: This function returns the same register for the
# same argument every time.
# See also the function clone_register below.
get_hardware_registers_of_kind: # This is essentially a convenience function looping over get_ith_hardware_register_of_kind
rkj::Registerkind
->
{ from: rkj::Intrakind_Register_Id,
to: rkj::Intrakind_Register_Id,
step: Int
}
->
List( rkj::Codetemp_Info );
make_codetemp_info_of_kind: rkj::Registerkind -> (X -> rkj::Codetemp_Info); # rkj::Registerkind = INT_REGISTER
| FLOAT_REGISTER | RAM_BYTE | FLAGS_REGISTER | ...
make_int_codetemp_info: X -> rkj::Codetemp_Info; # Abbreviation for make_codetemp_info_of_kind rkj::INT_REGISTER (Oh boy, does THIS one get called a lot!)
make_float_codetemp_info: X -> rkj::Codetemp_Info; # Abbreviation for make_codetemp_info_of_kind rkj::FLOAT_REGISTER
#
# Generate a new codetemp. A codetemp is an intermediate
# result in the code which needs to be either assigned
# a physical register or else some place in ram to live in.
#
# The new codetemp is assigned a unique id distinct from
# all other codetemps of all kinds.
#
# IMPORTANT: if you are using issue_codetemp_of_kind, it is
# important to partially apply it first to get a function,
# then use this function generate new codetemps -- the first
# application is slow because it calls info_for_registerkind
# which loops linearly over the registerkinds_info list.
#
# NB: These three fns completely ignore their
# X arguments, but some packages, e.g.
src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg # depend on being able to hand them garbage.
# This probably bears study and cleaning up. XXX SUCKO FIXME.
make_global_codetemp_info_of_kind: rkj::Registerkind -> (X -> rkj::Codetemp_Info);
#
# This is part of a special hack to support the virtual_framepointer
# on intel32; for details on the hack generally see:
#
#
src/lib/compiler/back/low/omit-framepointer/free-up-framepointer-in-machcode.api #
# Our function here gets called exactly once, in
#
#
src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg get_codetemps_made_count_for_kind: rkj::Registerkind -> (Void -> Int); # Get number of codetemps created of given kind.
get_next_codetemp_id_to_allot: Void -> rkj::Universal_Register_Id; # Returns highest codetemp id alloted (+1) -- 512 more than count of codetemps created. Def is: fun get_next_codetemp_id_to_allot () = *next_codetemp_id_to_allot;
clone_codetemp_info: rkj::Codetemp_Info -> rkj::Codetemp_Info;
#
# Given a codetemp c, create a new codetemp that has the same
# kind as c, and a new notes list initialized
# with the contents of c's notes list.
#
# A new codetemp id is allocated, but the
# codetemps_made_count counter for this kind is NOT incremented!
#
# This is called (only) once each in:
#
#
src/lib/compiler/back/low/regor/register-spilling-g.pkg #
src/lib/compiler/back/low/regor/register-spilling-with-renaming-g.pkg #
# (I don't get the point of this, as yet...)
reset_codetemp_id_allocation_counters: Void -> Void; # Reset all counters.
#################################################
# Imported support for lists of codetemps which
# are segregated by kind -- in practice, floats from ints.
#
# We use these to track which codetemps are
# live, dead, spilled etc:
Codetemplists = rkj::cls::Codetemplists;
empty_codetemplists: Codetemplists;
get_int_codetemp_infos: Codetemplists -> List( rkj::Codetemp_Info );
get_float_codetemp_infos: Codetemplists -> List( rkj::Codetemp_Info );
add_codetemp_info_to_appropriate_kindlist: (rkj::Codetemp_Info, Codetemplists) -> Codetemplists; # Used for both float and int.
drop_codetemp_info_from_codetemplists: (rkj::Codetemp_Info, Codetemplists) -> Codetemplists; # Used for both float and int.
get_codetemp_infos_for_kind: rkj::Registerkind -> Codetemplists -> List( rkj::Codetemp_Info );
get_always_zero_register: rkj::Registerkind -> Null_Or( rkj::Codetemp_Info );
#
# Return a register that is always zero on the architecture,
# if one exists. IMPORTANT: each call returns the same register.
# See also clone_register above.
stackptr_r: rkj::Codetemp_Info; # Stack pointer register
asm_tmp_r: rkj::Codetemp_Info; # Assembly temporary
fasm_tmp: rkj::Codetemp_Info; # Floating point temporary
};
end;
## Changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.