PreviousUpNext

15.3.95  src/lib/compiler/back/low/code/registerkinds.api

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

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

    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.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext