PreviousUpNext

15.3.90  src/lib/compiler/back/low/code/machcode-universals.api

# machcode-universals.api
#
# This api defines a basic set of operations which we support on
# all abstract machine-codes.  By supporting this API on all architectures
# we can write some machine-code transformations in an architecture-agnostic
# way despite the specific abstract machine codes being highly architecture-specific.
#
# For example we manipulate basicblock-terminal branches and gotos via this interface in
#
#     src/lib/compiler/back/low/mcg/machcode-controlflow-graph-g.pkg     

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


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 api is implemented in:
    #
    #    src/lib/compiler/back/low/intel32/code/machcode-universals-intel32-g.pkg
    #    src/lib/compiler/back/low/pwrpc32/code/machcode-universals-pwrpc32-g.pkg
    #    src/lib/compiler/back/low/sparc32/code/machcode-universals-sparc32-g.pkg
    #
    api Machcode_Universals {
        #
        package mcf:  Machcode_Form;                                            # Machcode_Form                 is from   src/lib/compiler/back/low/code/machcode-form.api
        package rgk:  Registerkinds;                                            # Registerkinds                 is from   src/lib/compiler/back/low/code/registerkinds.api

        sharing mcf::rgk == rgk;                                                # "rgk" == "registerkinds".

        # Classify instructions 
        #
        package k: api {        
            #
            Kind = JUMP                 # Branches, including returns.
                 | NOP                  # No-ops 
                 | PLAIN                # Normal instructions 
                 | COPY                 # Parallel copy 
                 | CALL                 # Call instructions 
                 | CALL_WITH_CUTS       # Call with cut edges 
                 | PHI                  # A phi node.    (For SSA -- static single assignment.) 
                 | SINK                 # A sink node.   (For SSA -- static single assignment.) 
                 | SOURCE               # A source node. (For SSA -- static single assignment.) 
                 ;
        };

        instruction_kind:   mcf::Machine_Op -> k::Kind;

        # Parallel moves:
        #
        move_instruction:  mcf::Machine_Op -> Bool;
        move_tmp_r:        mcf::Machine_Op -> Null_Or( rkj::Codetemp_Info );
        move_dst_src:      mcf::Machine_Op -> (List( rkj::Codetemp_Info ), List( rkj::Codetemp_Info ));

        # No-op:
        #
        nop:       Void -> mcf::Machine_Op;

        # Jump instruction:
        #
        jump:        lbl::Codelabel -> mcf::Machine_Op;

        # load immediate; must be within immed_range 
        #
        immed_range:   { lo: Int, hi: Int };
        load_immed:    { immed: Int, t: rkj::Codetemp_Info } -> mcf::Machine_Op;
        load_operand:  { operand: mcf::Operand, t: rkj::Codetemp_Info } -> mcf::Machine_Op;


        # Targets of a branch instruction 
        # precondition: instruction must be of type k::JUMP.
        #
        Target = LABELLED  lbl::Codelabel | FALLTHROUGH | ESCAPES;
        branch_targets:  mcf::Machine_Op -> List( Target );

        # Set the jump target;
        # error if not a jump instruction.  
        #
        set_jump_target:  (mcf::Machine_Op, lbl::Codelabel) -> mcf::Machine_Op;

        # Set the branch target;
        # error if not a branch instruction, t=TRUE, f=FALSE case 
        #
        set_branch_targets:  { i: mcf::Machine_Op, t: lbl::Codelabel, f: lbl::Codelabel } -> mcf::Machine_Op;

        # Equality and hashing on operands:
        #
        eq_operand:       (mcf::Operand, mcf::Operand) -> Bool;
        hash_operand:     mcf::Operand -> Unt;

        # Given a conditional jump instruction and label, return a conditional
        # jump that has the complimentary condition and that targets the given
        # label.  If the given instruction is not a conditional jump, then
        # the NEGATE_CONDITIONAL exception is raised.
        #
        exception NEGATE_CONDITIONAL;
        negate_conditional:  (mcf::Machine_Op, lbl::Codelabel) -> mcf::Machine_Op;

        # Def/use ("definition/use")
        # for the register allocator:
        #
        def_use
            :
            rkj::Registerkind
            -> 
            mcf::Machine_Op
            ->
            ( List( rkj::Codetemp_Info ),
              List( rkj::Codetemp_Info )
            );

        # Annotations:
        #
        get_notes
            :
            mcf::Machine_Op
            ->
            ( mcf::Machine_Op,
              List( note::Note )
            );

        annotate
            :
            ( mcf::Machine_Op,
              note::Note
            )
            ->
            mcf::Machine_Op;

        replicate                       # Should this be renamed just "clone"?
            :
            mcf::Machine_Op
            ->
            mcf::Machine_Op;
    };
end;

## Changes by Jeff Prothero Copyright (c) 2010-2013,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext