PreviousUpNext

15.4.314  src/lib/compiler/back/low/main/sparc32/backend-lowhalf-sparc32.pkg

# backend-lowhalf-sparc32.pkg
# Sparc-specific backend

# Compiled by:
#     src/lib/compiler/mythryl-compiler-support-for-sparc32.lib

stipulate
    package irc =  iterated_register_coalescing;                                        # iterated_register_coalescing                  is from   src/lib/compiler/back/low/regor/iterated-register-coalescing.pkg
    package cig =  codetemp_interference_graph;                                         # codetemp_interference_graph                   is from   src/lib/compiler/back/low/regor/codetemp-interference-graph.pkg
    package sma =  supported_architectures;                                             # supported_architectures                       is from   src/lib/compiler/front/basics/main/supported-architectures.pkg

    package treecode_sparc32
        = 
        treecode_form_g (                                                               # treecode_form_g                               is from   src/lib/compiler/back/low/treecode/treecode-form-g.pkg
            #
            package lac =  late_constant;                                               # late_constant                                 is from   src/lib/compiler/back/low/main/nextcode/late-constant.pkg
            package rgn =  nextcode_ramregions;                                         # nextcode_ramregions                           is from   src/lib/compiler/back/low/main/nextcode/nextcode-ramregions.pkg
            package trx =  treecode_extension_sparc32;                                  # treecode_extension_sparc32                    is from   src/lib/compiler/back/low/main/sparc32/treecode-extension-sparc32.pkg
        );


    package treecode_eval_sparc32
        =
        treecode_eval_g (                                                               # treecode_eval_g                               is from   src/lib/compiler/back/low/treecode/treecode-eval-g.pkg
            #
            package tcf =  treecode_sparc32;
            #
            fun eq _ _ =  FALSE;
            #
            eq_rext = eq;
            eq_fext = eq;
            eq_ccext = eq;
            eq_sext = eq;
        );


    package treecode_hash_sparc32
        = 
        treecode_hash_g (                                                               # treecode_hash_g                               is from   src/lib/compiler/back/low/treecode/treecode-hash-g.pkg
            #
            package tcf =  treecode_sparc32;
            #
            fun h _ _ = 0u0;
            #
            hash_sext  = h;
            hash_rext  = h;
            hash_fext  = h;
            hash_ccext = h;
        );


    package gas_pseudo_ops_sparc32
        =
        gas_pseudo_ops_sparc32_g (                                                      # gas_pseudo_ops_sparc32_g                      is from   src/lib/compiler/back/low/sparc32/mcg/gas-pseudo-ops-sparc32-g.pkg
            #
            package tcf =  treecode_sparc32;
            package tce =  treecode_eval_sparc32;
        );


    package client_pseudo_ops_sparc32
          = client_pseudo_ops_mythryl_g (                                               # client_pseudo_ops_mythryl_g                   is from   src/lib/compiler/back/low/main/nextcode/client-pseudo-ops-mythryl-g.pkg
                #
                package bpo =  gas_pseudo_ops_sparc32;                                  # "bpo" == "base_pseudo_ops".
            );


    package pseudo_ops_sparc32
        =
        pseudo_op_g (                                                                   # pseudo_op_g                                   is from   src/lib/compiler/back/low/mcg/pseudo-op-g.pkg
            #
            package cpo =  client_pseudo_ops_sparc32;
        );


    package code_buffer_sparc32
          = codebuffer_g (                                                              # codebuffer_g                                  is from   src/lib/compiler/back/low/code/codebuffer-g.pkg# 
                #
                pseudo_ops_sparc32
            );

    package treecode_buffer_sparc32
          = treecode_codebuffer_g (                                                             # treecode_codebuffer_g                         is from   src/lib/compiler/back/low/treecode/treecode-codebuffer-g.pkg
                #
                package tcf =  treecode_sparc32;
                package cst =  code_buffer_sparc32;
            );

    # Specialized sparc instruction set 
    #
    package machcode_sparc32
          = machcode_sparc32_g (                                                                # machcode_sparc32_g                            is from   src/lib/compiler/back/low/sparc32/code/machcode-sparc32-g.codemade.pkg
                #
                treecode_sparc32
            );


    package pseudo_instructions_sparc32
          = pseudo_instructions_sparc32_g (                                             # pseudo_instructions_sparc32_g                 is from   src/lib/compiler/back/low/main/sparc32/pseudo-instructions-sparc32-g.pkg
                #
                machcode_sparc32
            );


    package machcode_universals_sparc32
          = machcode_universals_sparc32_g (                                             # machcode_universals_sparc32_g                 is from   src/lib/compiler/back/low/sparc32/code/machcode-universals-sparc32-g.pkg
                #
                package mcf =  machcode_sparc32;
                package tce =  treecode_eval_sparc32;
                package tch =  treecode_hash_sparc32;
            );


    package compile_register_moves_sparc32
          = compile_register_moves_sparc32_g (                                          # compile_register_moves_sparc32_g              is from   src/lib/compiler/back/low/sparc32/code/compile-register-moves-sparc32-g.pkg
                #
                machcode_sparc32
            );


    package translate_machcode_to_asmcode_sparc32
          = translate_machcode_to_asmcode_sparc32_g (                                   # translate_machcode_to_asmcode_sparc32_g       is from   src/lib/compiler/back/low/sparc32/emit/translate-machcode-to-asmcode-sparc32-g.codemade.pkg
                #
                package mcf =  machcode_sparc32;
                package crm =  compile_register_moves_sparc32;
                package cst =  code_buffer_sparc32;
                package tce =  treecode_eval_sparc32;
                #
                v9 = FALSE;
            );

    package execode_emitter_sparc32
        = 
        translate_machcode_to_execode_sparc32_g (                                       # translate_machcode_to_execode_sparc32_g       is from   src/lib/compiler/back/low/sparc32/emit/translate-machcode-to-execode-sparc32-g.codemade.pkg
            #
            package mcf =  machcode_sparc32;
            package cst =  code_buffer_sparc32;
            package tce =  treecode_eval_sparc32;
            package csb =  code_segment_buffer;                                         # code_segment_buffer                           is from   src/lib/compiler/execution/code-segments/code-segment-buffer.pkg
            #
            package asm_emitter         = translate_machcode_to_asmcode_sparc32;
        );

    # Flowgraph data package specialized to Sparc instructions 
    #
    package machcode_controlflow_graph_sparc32
          = machcode_controlflow_graph_g (                                              # machcode_controlflow_graph_g                  is from   src/lib/compiler/back/low/mcg/machcode-controlflow-graph-g.pkg
                #
                package mcf =  machcode_sparc32;
#               package pop =  pseudo_ops_sparc32;
                package meg =  digraph_by_adjacency_list;                               # digraph_by_adjacency_list                     is from   src/lib/graph/digraph-by-adjacency-list.pkg
                package mu  =  machcode_universals_sparc32;
                package ae  =  translate_machcode_to_asmcode_sparc32;
            );

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

        package   platform_register_info_sparc32
        : (weak)  Platform_Register_Info                                                # Platform_Register_Info                        is from   src/lib/compiler/back/low/main/nextcode/platform-register-info.api
        {
            # Export to client packages:
            #                                                                           # "tcf" == "treecode_form".
            package tcf =  treecode_sparc32;
            package rgk =  registerkinds_sparc32;                                       # registerkinds_sparc32                 is from   src/lib/compiler/back/low/sparc32/code/registerkinds-sparc32.codemade.pkg


            gp = rgk::get_ith_int_hardware_register;
            fp = rgk::get_ith_float_hardware_register;

            fun reg  r =  tcf::CODETEMP_INFO (32, gp r); 
            fun freg f =  tcf::CODETEMP_INFO_FLOAT (64, fp f);

            return_ptr          = gp 15;        

            stipulate
                stdarg0                     = reg 24;  #  %i0
                stdfate0                    = reg 25;  #  %i1
                stdclos0                    = reg 26;  #  %i2
                stdlink0                    = reg  1;  #  %g1
                #
                base_pointer0               = reg 27;  #  %i3
                heap_allocation_limit0      = reg  4;  #  %g4                           # heap_allocation_pointer may not advance beyond this point.
                current_thread_ptr0         = reg 29;  #  %i5
                heap_changelog_pointer0     = reg  5;  #  %g5                           # Every (pointer) update to the heap gets logged to this cons-cell list, to help the heapcleaner.
                exception_handler_register0 = reg  7;  #  %g7
                heapcleaner_link0           = tcf::CODETEMP_INFO (32, return_ptr); 
                framepointer0               = reg 30;                                   # Holds current C stackframe, which holds pointers to runtime resources like the heapcleaner ("garbage collector"), which is written in C.

            herein

                virtual_framepointer    = registerkinds_sparc32::make_int_codetemp_info ();
                    #
                    # This appears to violate the statement in                                          XXX BUGGO FIXME
                    #     http://www.smlnj.org//compiler-notes/omit-vfp.ps
                    # that "the virtual frame pointer cannot be allocated using [rgk::make_int_codetemp_info ()]..."
                    #      "the virtual frame pointer must   be allocated using [rgk::make_global_codetemp()]..."
                    #
                    # Note that    src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg
                    # -- which is presumably much better tested -- does in fact use rgk::make_global_codetemp().
                    #
                    # If there is an actual architectural difference at work, it needs to be commented.

                vfptr                   = tcf::CODETEMP_INFO (32, virtual_framepointer);

                fun stdarg _            = stdarg0;
                fun stdfate _           = stdfate0;
                fun stdclos _           = stdclos0;

                fun stdlink _                   = stdlink0;
                fun base_pointer _                      = base_pointer0;
                fun heap_allocation_limit _     = heap_allocation_limit0;       # heap_allocation_pointer may not advance beyond this point.

                fun current_thread_ptr _        = current_thread_ptr0;

                heap_is_exhausted__test
                    =
                    THE (tcf::CC (tcf::GTU, rgk::psr));  /* %psr */             # A platform-specific test for  (heap_allocation_pointer > heap_allocation_limit)  ;
                                                                                # this will be used in   src/lib/compiler/back/low/main/nextcode/emit-treecode-heapcleaner-calls-g.pkg
                                                                                # In this version we are only checking status bits set by a comparison done separately
                                                                                # by code generated in   src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg

                heap_allocation_pointer = reg (6);  #  %g6                      # We allot ram just by advancing this pointer.  We use this very heavily -- every 10 instructions or so.
                                                                                # Note that no 'stackptr' is defined.

                fun heap_changelog_pointer      _ =  heap_changelog_pointer0;   # Every (pointer) update to the heap gets logged to this cons-cell list.
                                                                                # (The heapcleaner scans this list to detect intergenerational pointers.)

                fun exception_handler_register  _ =  exception_handler_register0;

                fun heapcleaner_link            _ =  heapcleaner_link0;

                fun framepointer                        _ = framepointer0;                              # Holds current C stackframe, which holds pointers to runtime resources like the heapcleaner ("garbage collector"), which is written in C.

                # Warning %o2 is used as the asm_tmp
                #
                miscregs =
                    map reg
                        [2, 3,                          #  %g2-%g3 
                         8, 9,                          #  %o0-%o1 
                         16, 17, 18, 19, 20, 21, 22, 23,  #  %l0-%l7 
                         28, 31,                                #  %i4, %i6, %i7 
                         11, 12, 13];                   #  %o3-%o5 
                calleesave = rw_vector::from_list miscregs;

                #  Note: We need at least one register for shuffling purposes. 
                #
                fun fromto (n, m, inc)
                    =
                    if (n>m)   [];
                    else       n ! fromto (n+inc, m, inc);
                    fi;

                floatregs   =  map freg (fromto (0, 31, 2));
                savedfpregs =  [];

                stipulate
                    fun un_reg (tcf::CODETEMP_INFO (_, r)) =>  r;
                        un_reg _                 =>  raise exception DIE "sparc-nextcode-registers: unREG";
                    end;

                    package cos =  rkj::cos;                                            # "cos" == "colorset".

                    --- =  cos::difference_of_colorsets;

                    infix my  --- ;
                herein

                    all_regs = map gp (fromto (0, 31, 1));

                    available_int_registers
                        =
                        map un_reg  ( [stdlink0, stdclos0, stdarg0, stdfate0, heapcleaner_link0]
                                      @ miscregs
                                    );

                    global_int_registers
                        =
                        cos::get_codetemps_in_colorset
                            #
                            (   cos::make_colorset  all_regs
                                ---
                                cos::make_colorset  available_int_registers
                            );



                    available_float_registers =   map fp (fromto (0, 30, 2));
                    global_float_registers    =   [];

                    use_signed_heaplimit_check =  FALSE;

                    address_width =  32;

                    ccall_caller_save_r
                        =
                        map  un_reg  [heap_allocation_limit0, heap_changelog_pointer0, exception_handler_register0, heap_allocation_pointer];

                    ccall_caller_save_f = [];
                end;
            end;
        };
    end;
herein

    package backend_lowhalf_sparc32
        = 
        backend_lowhalf_g (                                                             # backend_lowhalf_g                             is from   src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg
            #
            package mp  =  machine_properties_sparc32;                                  # machine_properties_sparc32                    is from   src/lib/compiler/back/low/main/sparc32/machine-properties-sparc32.pkg
            abi_variant =  NULL;
            #
            package t   =  treecode_sparc32;
            #
            package cpo =  client_pseudo_ops_sparc32;
            package pop =  pseudo_ops_sparc32;
            #
            package trx =  treecode_extension_sparc32;                                  # treecode_extension_sparc32                    is from   src/lib/compiler/back/low/main/sparc32/treecode-extension-sparc32.pkg
            package pri =  platform_register_info_sparc32;
            package mu  =  machcode_universals_sparc32;
            #
            package ae  =  translate_machcode_to_asmcode_sparc32;
            package crm =  compile_register_moves_sparc32;
            #
            package cal                                                                 # "cal" == "ccalls" (native C calls).
                =
                ccalls_sparc32_g (                                                      # ccalls_sparc32_g                              is from   src/lib/compiler/back/low/sparc32/ccalls/ccalls-sparc32-g.pkg
                    #
                    package tcf =  treecode_sparc32;
                    #
                    fun ix x = x;
                );

            package fuf {                                                               # "fuf" == "free_up_framepointer".
                #
                package mcg = machcode_controlflow_graph_sparc32;
                package mcf = machcode_sparc32;
                #
                virtual_framepointer =   pri::virtual_framepointer;

                # No rewriting necessary, backend
                # uses %fp instead of %sp                                               # Is that comment reversed? -- 2011-06-15 CrT
                # 
                fun replace_framepointer_uses_with_stackpointer_in_machcode_controlflow_graph _ = ();
            };

            package t2m                                                                 # "t2m" == "translate_treecode_to_machcode".
                =
                translate_treecode_to_machcode_sparc32_g (                              # translate_treecode_to_machcode_sparc32_g      is from   src/lib/compiler/back/low/sparc32/treecode/translate-treecode-to-machcode-sparc32-g.pkg
                    #
                    package mcf = machcode_sparc32;
                    package psi = pseudo_instructions_sparc32;

                    package txc
                        =
                        treecode_extension_compiler_sparc32_g (                         # treecode_extension_compiler_sparc32_g         is from   src/lib/compiler/back/low/main/sparc32/treecode-extension-compiler-sparc32-g.pkg
                            #
                            package mcf =  machcode_sparc32;
                            package tcf =  treecode_sparc32;
                            package tcs =  treecode_buffer_sparc32;
                            package mcg =  machcode_controlflow_graph_sparc32;
                        );

                    v9 = FALSE;
                    mulu_cost = REF 5;
                    mult_cost = REF 3;
                    divu_cost = REF 5;
                    divt_cost = REF 5;
                    registerwindow = REF FALSE;
                    use_br = REF FALSE;
                );

            package jumps_sparc32
                =
                jump_size_ranges_sparc32_g (                                            # jump_size_ranges_sparc32_g            is from   src/lib/compiler/back/low/sparc32/jmp/jump-size-ranges-sparc32-g.pkg
                    #
                    package mcf =  machcode_sparc32;
                    package tce =  treecode_eval_sparc32;
                    package crm =  compile_register_moves_sparc32;
                );

            package sja                                                                 # "sja" == "squash_jumps_and...".
            = # squash_jumps_and_make_machinecode_bytevector_sparc32_g  is from   src/lib/compiler/back/low/jmp/squash-jumps-and-write-code-to-code-segment-buffer-sparc32-g.pkg
                squash_jumps_and_make_machinecode_bytevector_sparc32_g (
                    #
                    package mcg =  machcode_controlflow_graph_sparc32;
                    package jmp =  jumps_sparc32;
                    package xe  =  execode_emitter_sparc32;
                    package mu  =  mu;                                                  # "mu"  == "machcode_universals".
                    package ae  =  translate_machcode_to_asmcode_sparc32;
                    #
                    package dsp
                        =
                        delay_slots_sparc32_g (                                         # delay_slots_sparc32_g                         is from   src/lib/compiler/back/low/sparc32/jmp/delay-slots-sparc32-g.pkg
                            #
                            package mcf = machcode_sparc32;                             # "mcf" == "machcode_form" (abstract machine code).
                            package mu  = mu;                                           # "mu"  == "machcode_universals".
                        );
                 );

            package ra                                                                  # "ra"  == "register_allocator".
                = 
                regor_risc_g (                                                          # regor_risc_g                                  is from   src/lib/compiler/back/low/regor/regor-risc-g.pkg
                    #
                    package mcf =  machcode_sparc32;
                    package mcg =  machcode_controlflow_graph_sparc32;
                    package mu  =  mu;                                                  # "mu"  == "machcode_universals".
                    #   
                    package rmi                                                         # "rmi" == "rewrite_machine_instructions".
                        =
                        instructions_rewrite_sparc32_g (                                # instructions_rewrite_sparc32_g                is from   src/lib/compiler/back/low/sparc32/regor/instructions-rewrite-sparc32-g.pkg
                            machcode_sparc32
                        );

                    package asi                                                         # "asi" == "architecture-specific spill instructions".
                        =
                        spill_instructions_sparc32_g (                                  # spill_instructions_sparc32_g                  is from   src/lib/compiler/back/low/sparc32/regor/spill-instructions-sparc32-g.pkg
                            #
                            machcode_sparc32
                        );

                    package ae  =   translate_machcode_to_asmcode_sparc32;              # "ae"  == "asmcode_emitter".

                    package rsp = register_spilling_per_chaitin_heuristic;              # register_spilling_per_chaitin_heuristic       is from   src/lib/compiler/back/low/regor/register-spilling-per-chaitin-heuristic.pkg
                                                                                        # "rsp" == "register_spilling_per_xxx_heuristic".

                    package spl                                                         # "spl" == "spill".
                        =
                        register_spilling_g (                                           # register_spilling_g                           is from   src/lib/compiler/back/low/regor/register-spilling-g.pkg
                            #
                            package mu =  mu;                                           # "mu"  == "machcode_universals".
                            package ae =  translate_machcode_to_asmcode_sparc32;        # "ae"  == "asmcode_emitter".
                        );

                    package spill_table                                                 # Not an actual generic parameter.
                        =
                        spill_table_g (                                                 # spill_table_g                                 is from   src/lib/compiler/back/low/main/main/spill-table-g.pkg
                            machine_properties_sparc32                                  # machine_properties_sparc32                    is from   src/lib/compiler/back/low/main/sparc32/machine-properties-sparc32.pkg
                        );

                    fp = machcode_sparc32::rgk::framepointer_r;

                    spill = nextcode_ramregions::spill;

                    Spill_Operand_Kind
                        =
                        SPILL_LOC | CONST_VAL;

                    Spill_Info = Void;

                    fun before_ra _
                        =
                        spill_table::spill_init();

                    machine_architecture                                                # PWRPC32/SPARC32/INTEL32.
                        =
                        machine_properties_sparc32::machine_architecture;

                    package i = machcode_sparc32;

                    fun pure (i::BASE_OP (i::LOAD  _)) =>  TRUE;
                        pure (i::BASE_OP (i::FLOAD _)) =>  TRUE;
                        pure (i::BASE_OP (i::SETHI _)) =>  TRUE;
                        pure (i::BASE_OP (i::SHIFT _)) =>  TRUE;
                        pure (i::BASE_OP (i::FPOP1 _)) =>  TRUE;
                        pure (i::BASE_OP (i::FPOP2 _)) =>  TRUE;
                        #
                        pure (i::NOTE { op, ... } ) =>  pure  op;
                        #
                        pure _ => FALSE;
                    end;

                    # Make copy:
                    #
                    package rap {                                                                       # "rap" == "register allocation parameter".
                        #
                        locally_allocated_hardware_registers =  platform_register_info_sparc32::available_int_registers;
                        globally_allocated_hardware_registers =  platform_register_info_sparc32::global_int_registers;

                        fun make_disp loc
                            =
                            t::LITERAL (t::mi::from_int (32, spill_table::get_reg_loc loc));

                        fun spill_loc { info, an, register, id }
                            = 
                            {   kind => SPILL_LOC,

                                operand => i::DISPLACE {
                                            base => fp,
                                            disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT id),
                                            ramregion  => spill
                                        }

                            };

                        mode = irc::no_optimization;
                    };

                    package fap {                                                                       # "fap" == "floating point register allocation parameter".
                        #
                        locally_allocated_hardware_registers =  platform_register_info_sparc32::available_float_registers;
                        globally_allocated_hardware_registers =  platform_register_info_sparc32::global_float_registers;

                        fun make_disp loc
                            =
                            t::LITERAL (t::mi::from_int (32, spill_table::get_freg_loc loc));

                        fun spill_loc (s, an, loc)
                            = 
                            i::DISPLACE {
                                base => fp,
                                disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT loc),
                                ramregion  => spill
                            };

                        mode = irc::no_optimization;
                    };
                );
      );
end;

## COPYRIGHT (c) 1998 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext