PreviousUpNext

15.4.472  src/lib/compiler/back/top/highcode/highcode-baseops.pkg

## highcode-baseops.pkg
#
# See overview comments in:
#
#     src/lib/compiler/back/top/highcode/highcode-baseops.api

# Compiled by:
#     src/lib/compiler/core.sublib





###                  "The mathematics are distinguished
###                   by a particular privilege,
###                   that is, in the course of ages,
###                   they may always advance and
###                   can never recede."
###
###                              -- Edward Gibbon,
###                                 Decline and Fall of the Roman Empire


stipulate
    package cty =  ctypes;                                                      # ctypes                is from   src/lib/compiler/back/low/ccalls/ctypes.pkg
herein

    package   highcode_baseops
    : (weak)  Highcode_Baseops                                                  # Highcode_Baseops      is from   src/lib/compiler/back/top/highcode/highcode-baseops.api
    {
        # Number_Kind_And_Size gives kind of number (int/unt/float)
        # plus size-in-bits:
        #
        Number_Kind_And_Size 
          #
          = INT   Int                                                   # Fixed-length   signed-integer type.
          | UNT   Int                                                   # Fixed-length unsigned-integer type.
          | FLOAT Int                                                   # Fixed-length floating-point   type.   
          ;

        Math_Op
          #
          = ADD | SUBTRACT | MULTIPLY | DIVIDE | NEGATE                 # Int or Float.  For int, this does Round-to-zero division -- this is the native instruction on Intel32.
          | ABS | FSQRT | FSIN | FCOS | FTAN                            # Float only.
          | LSHIFT | RSHIFT | RSHIFTL                                   # Int only.
          | BITWISE_AND | BITWISE_OR | BITWISE_XOR | BITWISE_NOT        # Int only.
          | REM                                                         # Int only.               This does round-to-zero remainder -- this is the native instruction on Intel32.
          | DIV                                                         # Int only.               This does round-to-negative-infinity division  -- this will be much slower on Intel32, has to be faked.
          | MOD                                                         # Int only.               This does round-to-negative-infinity remainder -- this will be much slower on Intel32, has to be faked.
          ;

        Comparison_Op = GT | GE | LT | LE | LEU | LTU | GEU | GTU | EQL | NEQ;


        # Various base operations.  Those that are designated "inline" by a
        # _MACRO suffic on their name are expanded into lambda code in terms of other operators
        # in  src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
        # as is the "checkbounds=>TRUE" version of GET_VECSLOT_NUMERIC_CONTENTS or SET_VECSLOT_TO_NUMERIC_VALUE.
        #
        Baseop
          #
          = ARITH  { op: Math_Op, overflow: Bool, kind_and_size: Number_Kind_And_Size }
          | LSHIFT_MACRO  Number_Kind_And_Size
          | RSHIFT_MACRO  Number_Kind_And_Size
          | RSHIFTL_MACRO  Number_Kind_And_Size                         # "RSHIFTL" may be "right-shift logical", where "logical" means "without extending sign".
          | COMPARE  { op: Comparison_Op, kind_and_size: Number_Kind_And_Size }
          #
          | SHRINK_UNT  (Int, Int)
          | SHRINK_INT  (Int, Int)
          | CHOP        (Int, Int)
          | STRETCH     (Int, Int)
          | COPY        (Int, Int)
          #
          | SHRINK_INTEGER      Int
          | CHOP_INTEGER        Int
          | STRETCH_TO_INTEGER  Int
          | COPY_TO_INTEGER     Int
          #
          | ROUND         { floor: Bool, from: Number_Kind_And_Size, to: Number_Kind_And_Size }
          | CONVERT_FLOAT {              from: Number_Kind_And_Size, to: Number_Kind_And_Size }
          #
          | GET_VECSLOT_NUMERIC_CONTENTS  { kind_and_size: Number_Kind_And_Size, checkbounds: Bool, immutable: Bool }   # Stays same  after the bounds-check gets expanded out in src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
          | SET_VECSLOT_TO_NUMERIC_VALUE  { kind_and_size: Number_Kind_And_Size, checkbounds: Bool }                            # Stays same  after the bounds-check gets expanded out in src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
          #
          | MAKE_NONEMPTY_RW_VECTOR_MACRO               # Inline typeagnostic rw_vector creation.
          #
          | RW_VECTOR_GET                               # Typeagnostic rw_vector fetch.
          | RO_VECTOR_GET                               # Typeagnostic    vector fetch.
          | RW_VECTOR_SET                               # Store to vector. Winds up as unsafe::rw_vector::set.                  Updates the heap changelog.
          #
          | RW_VECTOR_GET_WITH_BOUNDSCHECK              # Typeagnostic rw_vector fetch.                                 # Gets replaced by RW_VECTOR_GET after the bounds-check gets expanded in src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
          | RO_VECTOR_GET_WITH_BOUNDSCHECK              # Typeagnostic    vector fetch.                                 # Gets replaced by RW_VECTOR_GET after the bounds-check gets expanded in src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
          | RW_VECTOR_SET_WITH_BOUNDSCHECK              # Store to vector, inlined.                                             Gets replaced by RW_VECTOR_SET after bounds-check is expanded out in src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
          #
          | RW_MATRIX_GET_MACRO                         # Fetch from typeagnostic rw_matrix.
          | RO_MATRIX_GET_MACRO                         # Fetch from typeagnostic    matrix.
          | RW_MATRIX_SET_MACRO                         #       rw_matrix update (maybe boxed).
          #
          | RW_MATRIX_GET_WITH_BOUNDSCHECK_MACRO        # Fetch from typeagnostic rw_matrix.
          | RO_MATRIX_GET_WITH_BOUNDSCHECK_MACRO        # Fetch from typeagnostic    matrix.
          | RW_MATRIX_SET_WITH_BOUNDSCHECK_MACRO        #       rw_matrix update (maybe boxed)
          #
          | POINTER_EQL
          | POINTER_NEQ                                 # Pointer equality.
          #
          | POLY_EQL
          | POLY_NEQ                                    # Typeagnostic equality.
          #
          | IS_BOXED                                    # ((i & 1) == 0)        TRUE  for pointers, FALSE for tagged ints -- see fun   'boxed' in   src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg
          | IS_UNBOXED                                  # ((i & 1) != 1)        FALSE for pointers, TRUE  for tagged ints -- see fun 'unboxed' in   src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg
          #
          | VECTOR_LENGTH_IN_SLOTS                      # Vector, string, rw_vector, ... length 
          | HEAPCHUNK_LENGTH_IN_WORDS                   # Length of arbitrary heap chunk, excluding tagword itself.
          #
          | CAST                                        # If this is introduced at all, it must(?) be in   src/lib/compiler/back/top/forms/drop-types-from-anormcode-junk.pkg
          | WCAST                                       # This might have been weak sealing of packages at one point; I can find no evidence that it ever gets introduced by the current compiler.
          #
          | MARK_EXCEPTION_WITH_STRING                  # Mark an exception value with a string.
          # 
          | GET_RUNTIME_ASM_PACKAGE_RECORD              # Get the pointer to the run-vector.    (This may be dead code -- I can't find where it gets implemented. -- 2011-08-24 CrT)
          # 
          | GET_EXCEPTION_HANDLER_REGISTER              # Get exception-handler from dedicated register.
          | SET_EXCEPTION_HANDLER_REGISTER              # Set exception-handler dedicated register. (On x86 this "register" is a ram location.)
          # 
          | GET_CURRENT_MICROTHREAD_REGISTER            # Get dedicated 'current thread' register -- see current_thread_ptr in src/lib/compiler/back/top/highcode/highcode-baseops.pkg
          | SET_CURRENT_MICROTHREAD_REGISTER            # Set dedicated 'current thread' register. (On x86 this "register" is a ram location.)
          # 
          | PSEUDOREG_GET | PSEUDOREG_SET               # Get/set pseudo registers.
          | SETMARK | DISPOSE                           # Capture/dispose frames.
          # 
          | CALLCC                                      # Fate ("continuaton") operations.
          | CALL_WITH_CURRENT_CONTROL_FATE
          | THROW
          | MAKE_ISOLATED_FATE                          # "Isolating a function." Something involving setting the exception handler -- see   src/lib/compiler/back/top/nextcode/translate-anormcode-to-nextcode-g.pkg
          # 
          | MAKE_REFCELL                                # Allocate a REF cell.
          | GET_REFCELL_CONTENTS                        # Implements the *ref op.
          | SET_REFCELL                                 # Implements the ':=' op.                                               Updates the heap changelog.
          | SET_REFCELL_TO_TAGGED_INT_VALUE             # Implements the ':=' op for Ref(Tagged_Int) refcells.         Does NOT update  the heap changelog.
          # 
          | SET_VECSLOT_TO_BOXED_VALUE                  # Store in vector a String or Float64 value.                            Updates the heap changelog.
          | SET_VECSLOT_TO_TAGGED_INT_VALUE             # Store in vector an Tagged_Int value.                         Does NOT update  the heap changelog.
          #
          | GET_BATAG_FROM_TAGWORD                      # Extract (b-tag << 2 | a-tag) from given tagword.
                                                        # Used in rep()         in   src/lib/std/src/unsafe/unsafe-chunk.pkg
                                                        # Used in poly_equal()  in   src/lib/core/init/core.pkg
          #
          | MAKE_WEAK_POINTER_OR_SUSPENSION                             # Make a weak pointer or suspension.
          | SET_STATE_OF_WEAK_POINTER_OR_SUSPENSION                     # Set the state of a special chunk.
          | GET_STATE_OF_WEAK_POINTER_OR_SUSPENSION                     # Get the state of a special chunk.
          | USELVAR | DEFLVAR
          | MIN_MACRO  Number_Kind_And_Size                             # Inline min.
          | MAX_MACRO  Number_Kind_And_Size                             # Inline max.
          | ABS_MACRO  Number_Kind_And_Size                             # Inline abs.
          | NOT_MACRO                                                   # Inline bool not operator.
          | COMPOSE_MACRO                                               # Inline compose ('o')  operator.
          | THEN_MACRO                                                  # Inline "then" operator.
          | IGNORE_MACRO                                                # Inline "ignore" function.
          | ALLOCATE_RW_VECTOR_MACRO                                    # Inline typeagnostic rw_vector allocation.
          | ALLOCATE_RO_VECTOR_MACRO                                    # Inline typeagnostic vector allocation.
          | ALLOCATE_NUMERIC_RW_VECTOR_MACRO  Number_Kind_And_Size      # Inline typelocked rw_vector allocation.
          | ALLOCATE_NUMERIC_RO_VECTOR_MACRO  Number_Kind_And_Size      # Inline typelocked vector allocation.

          | MAKE_EXCEPTION_TAG                                          # Make a new exception tag.
          | WRAP                                                        # Box a value by wrapping it.
          | UNWRAP                                                      # Unbox a value by unwrapping it.

          #  Primops to support new
          # rw_vector representations: 
          #
          | MAKE_ZERO_LENGTH_VECTOR                                     # Allocate zero-length rw_vector header.
          | GET_VECTOR_DATACHUNK                                        # Get data pointer from arr/vec header.
          | RECORD_GET                                                  # Fetch-from-record operation.
          | RAW64_GET                                                   # Fetch-from-raw64  operation.

          #  Primops to support new experimental
          #     C "foreign-function interface" (FFI). 
          #
          | GET_FROM_NONHEAP_RAM   Number_Kind_And_Size         # Load from arbitrary memory location.
          | SET_NONHEAP_RAM     Number_Kind_And_Size            # Store to arbitrary memory location.

          | RAW_CCALL   Null_Or   { c_prototype:                 cty::Cfun_Type,
                                    ml_argument_representations: List( Ccall_Type ),
                                    ml_result_representation:    Null_Or( Ccall_Type ),
                                    is_reentrant:                Bool
                                  }
                #
                # RAW_CCALL makes a call to a C-function.
                # The baseop carries C function prototype information and specifies
                # which of its (ML-) arguments are floating point. C prototype
                # information is for use by the backend, ML information is for
                # use by the nextcode converter.



          | RAW_ALLOCATE_C_RECORD  { fblock: Bool }
                #
                # This allocates uninitialized storage on the heap.
                # The record is meant to hold short-lived C chunks, i.e., they
                # are not ML pointers.  The representation is 
                # the same as RECORD with tag four_byte_aligned_nonpointer_data_btag or tag_fblock.

          | IDENTITY_MACRO                      #  typeagnostic identity 

          | CVT64                               # convert between external and
                                                # internal representation of
                                                # simulated 64-bit scalars

        also
        Ccall_Type = CCI32 | CCI64 | CCR64 | CCML;

        # Default integer arithmetic and comparison operators:
        #
        iadd = ARITH { op=> ADD,      overflow=>TRUE, kind_and_size=>INT 31 };
        isub = ARITH { op=> SUBTRACT, overflow=>TRUE, kind_and_size=>INT 31 };
        imul = ARITH { op=> MULTIPLY, overflow=>TRUE, kind_and_size=>INT 31 };
        idiv = ARITH { op=> DIVIDE,   overflow=>TRUE, kind_and_size=>INT 31 };
        ineg = ARITH { op=> NEGATE,   overflow=>TRUE, kind_and_size=>INT 31 };

        ieql = COMPARE { op=>EQL, kind_and_size=>INT 31 };
        ineq = COMPARE { op=>NEQ, kind_and_size=>INT 31 };
        igt  = COMPARE { op=> GT, kind_and_size=>INT 31 };
        ilt  = COMPARE { op=> LT, kind_and_size=>INT 31 };
        ige  = COMPARE { op=> GE, kind_and_size=>INT 31 };
        ile  = COMPARE { op=> LE, kind_and_size=>INT 31 };

        # * default floating-point equality operator 
        feqld = COMPARE { op=>EQL, kind_and_size=>FLOAT 64 };

        ##########################################################################
        #               OTHER PRIMOP-RELATED UTILITY FUNCTIONS
        ##########################################################################

        fun kind_and_size_to_string (INT 31)      => "";                                                # Possible 64-BIT_ISSUE
            kind_and_size_to_string (INT bits)    => int::to_string bits;
            kind_and_size_to_string (UNT 32)      => "u";                                       # Possible 64-BIT_ISSUE
            kind_and_size_to_string (UNT bits)    => "u" + int::to_string bits;
            kind_and_size_to_string (FLOAT 64)    => "f";
            kind_and_size_to_string (FLOAT  bits) => "f" + int::to_string bits;
        end;


        cvt_param =   int::to_string;

        fun cvt_params (from, to)
            =
            cat [cvt_param from, "_", cvt_param to];


        fun baseop_to_string (ARITH { op, overflow, kind_and_size } )
                =>
                cat [    case op    
                                ADD             => "+";
                                SUBTRACT        => "-";
                                MULTIPLY        => "*";
                                DIVIDE          => "/";
                                NEGATE          => "-_";
                                FSQRT           => "fsqrt";
                                FSIN            => "fsin";
                                FCOS            => "fcos";
                                FTAN            => "ftan";
                                LSHIFT          => "lshift";
                                RSHIFT          => "rshift";
                                RSHIFTL         => "rshift_l";
                                BITWISE_AND     => "bitwise_and";
                                BITWISE_OR      => "bitwise_or";
                                BITWISE_XOR     => "bitwise_xor";
                                BITWISE_NOT     => "bitwise_not";
                                ABS             => "abs";
                                REM             => "rem";
                                DIV             => "div";
                                MOD             => "mod";
                            esac,

                            (overflow ?? "" :: "n"),

                            kind_and_size_to_string kind_and_size
                      ];

            baseop_to_string (LSHIFT_MACRO kind_and_size ) =>  "inllshift"  + kind_and_size_to_string kind_and_size;
            baseop_to_string (RSHIFT_MACRO kind_and_size ) =>  "inlrshift"  + kind_and_size_to_string kind_and_size;
            baseop_to_string (RSHIFTL_MACRO kind_and_size) =>  "inlrshiftl" + kind_and_size_to_string kind_and_size;

            baseop_to_string (COMPARE { op, kind_and_size } )
                =>
                (    case op   
                       GT  => ">";
                       LT  => "<";
                       GE  => ">=";
                       LE  => "<=";
                       GEU => ">=U";
                       GTU => ">U";
                       LEU => "<=U";
                       LTU => "<U";
                       EQL => "=";
                       NEQ => "!=";
                   esac
                   +
                   kind_and_size_to_string kind_and_size
                );

            baseop_to_string (SHRINK_INT arg  ) => "test_"  + cvt_params arg;
            baseop_to_string (SHRINK_UNT arg ) => "test_"  + cvt_params arg;
            baseop_to_string (STRETCH arg) => "extend" + cvt_params arg;
            baseop_to_string (CHOP arg ) => "trunc"  + cvt_params arg;
            baseop_to_string (COPY arg  ) => "copy"   + cvt_params arg;

            baseop_to_string (SHRINK_INTEGER i) => "test_inf_" + cvt_param i;
            baseop_to_string (CHOP_INTEGER i) => "trunc_inf_" + cvt_param i;
            baseop_to_string (STRETCH_TO_INTEGER i) => cat ["extend_", cvt_param i, "_inf"];
            baseop_to_string (COPY_TO_INTEGER i) =>  cat ["copy_", cvt_param i, "_inf"];

            baseop_to_string (ROUND { floor=>TRUE, from=>FLOAT 64, to=>INT 31 } ) => "floor";
            baseop_to_string (ROUND { floor=>FALSE, from=>FLOAT 64, to=>INT 31 } ) => "round";

            baseop_to_string (ROUND { floor, from, to } )
                =>
                (   (floor ?? "floor" :: "round")
                    +
                    kind_and_size_to_string from
                    +
                    "_"
                    +
                    kind_and_size_to_string to
                );

            baseop_to_string (CONVERT_FLOAT { from=>INT 31, to=>FLOAT 64 } ) => "convert_float";
            baseop_to_string (CONVERT_FLOAT { from, to } ) =>   ("convert_float" + kind_and_size_to_string from + "_" + kind_and_size_to_string to);

            baseop_to_string (GET_VECSLOT_NUMERIC_CONTENTS { kind_and_size, checkbounds, immutable } )
                => 
                ("get_vecslot_numeric_contents" + kind_and_size_to_string kind_and_size
                + (checkbounds ?? "<with-boundscheck>" :: "")
                + (immutable   ?? "<immutable>"        :: "")
                );

            baseop_to_string (SET_VECSLOT_TO_NUMERIC_VALUE { kind_and_size, checkbounds } ) =>     ("numupdate" + kind_and_size_to_string kind_and_size + (if checkbounds "<checkbounds>"; else "";fi));

            baseop_to_string GET_REFCELL_CONTENTS => "*_";
            baseop_to_string SET_REFCELL => ":=";
            baseop_to_string SET_REFCELL_TO_TAGGED_INT_VALUE => "(to Ref(Tagged_Int)):=";
            baseop_to_string IS_BOXED => "is_boxed";
            baseop_to_string IS_UNBOXED => "is_unboxed";
            baseop_to_string CAST => "cast";
            baseop_to_string WCAST => "wcast";
            baseop_to_string POINTER_EQL => "pointer_eql";
            baseop_to_string POINTER_NEQ => "pointer_neq";  
            baseop_to_string POLY_EQL => "polyeql";
            baseop_to_string POLY_NEQ => "polyneq";  
            baseop_to_string GET_EXCEPTION_HANDLER_REGISTER => "get_exception_handler_register";
            baseop_to_string MAKE_REFCELL => "makeref";
            baseop_to_string SET_EXCEPTION_HANDLER_REGISTER => "set_exception_handler_register";
            baseop_to_string VECTOR_LENGTH_IN_SLOTS => "vector_length_in_slots";
            baseop_to_string HEAPCHUNK_LENGTH_IN_WORDS => "heapchunk_length_in_words";
            baseop_to_string CALLCC => "callcc";
            baseop_to_string CALL_WITH_CURRENT_CONTROL_FATE => "call_with_current_control_fate";
            baseop_to_string MAKE_ISOLATED_FATE => "make_isolated_fate";
            baseop_to_string THROW => "throw";
            baseop_to_string RW_VECTOR_GET => "get_rw_vecslot_contents";
            baseop_to_string SET_VECSLOT_TO_TAGGED_INT_VALUE => "set_vecslot_to_tagged_int";
            baseop_to_string SET_VECSLOT_TO_BOXED_VALUE => "set_vecslot_to_boxedvalue";
            baseop_to_string RW_VECTOR_SET => "set_vecslot";
            baseop_to_string RW_VECTOR_GET_WITH_BOUNDSCHECK => "get_rw_vecslot_contents_after_bounds_check";
            baseop_to_string RO_VECTOR_GET_WITH_BOUNDSCHECK => "get_ro_vecslot_contents_after_bounds_check";
            baseop_to_string RW_VECTOR_SET_WITH_BOUNDSCHECK => "set_vecslot_after_bounds_check";
            baseop_to_string MAKE_NONEMPTY_RW_VECTOR_MACRO => "inlmkarray";
            baseop_to_string RO_VECTOR_GET => "get_ro_vecslot_contents";
            baseop_to_string GET_RUNTIME_ASM_PACKAGE_RECORD => "getrunvec";
            baseop_to_string GET_CURRENT_MICROTHREAD_REGISTER => "get_current_microthread_register";
            baseop_to_string SET_CURRENT_MICROTHREAD_REGISTER => "set_current_microthread_register";
            baseop_to_string PSEUDOREG_GET => "getpseudo";
            baseop_to_string PSEUDOREG_SET => "setpseudo";
            baseop_to_string SETMARK => "setmark";
            baseop_to_string DISPOSE => "dispose";
            baseop_to_string GET_BATAG_FROM_TAGWORD => "get_batag_from_tagword";
            baseop_to_string MAKE_WEAK_POINTER_OR_SUSPENSION => "make_weak_pointer_or_suspension";
            baseop_to_string SET_STATE_OF_WEAK_POINTER_OR_SUSPENSION => "set_state_of_weak_pointer_or_suspension";
            baseop_to_string GET_STATE_OF_WEAK_POINTER_OR_SUSPENSION => "get_state_of_weak_pointer_or_suspension";
            baseop_to_string USELVAR => "uselvar";
            baseop_to_string DEFLVAR => "deflvar";
            baseop_to_string (MIN_MACRO nk) => cat ["inlmin(", kind_and_size_to_string nk, ")"];
            baseop_to_string (MAX_MACRO nk) => cat ["inlmax(", kind_and_size_to_string nk, ")"];
            baseop_to_string (ABS_MACRO nk) => cat ["inlabs(", kind_and_size_to_string nk, ")"];
            baseop_to_string NOT_MACRO => "inlnot";
            baseop_to_string COMPOSE_MACRO => "inlcompose";
            baseop_to_string THEN_MACRO => "inlthen";
            baseop_to_string IGNORE_MACRO => "inlignore";
            baseop_to_string (ALLOCATE_RW_VECTOR_MACRO) => "inl_array";
            baseop_to_string (ALLOCATE_RO_VECTOR_MACRO) => "inl_vector";
            baseop_to_string (ALLOCATE_NUMERIC_RW_VECTOR_MACRO kind_and_size) =>           cat ["inl_monoarray(", kind_and_size_to_string kind_and_size, ")"];
            baseop_to_string (ALLOCATE_NUMERIC_RO_VECTOR_MACRO kind_and_size) =>           cat ["inl_monovector(", kind_and_size_to_string kind_and_size, ")"];
            baseop_to_string (MARK_EXCEPTION_WITH_STRING) => "markexn";

            baseop_to_string RO_MATRIX_GET_MACRO => "ro_matrix_get";
            baseop_to_string RW_MATRIX_GET_MACRO => "rw_matrix_get";
            baseop_to_string RW_MATRIX_SET_MACRO => "rw_matrix_set";

            baseop_to_string RO_MATRIX_GET_WITH_BOUNDSCHECK_MACRO => "ro_matrix_get_with_boundscheck";
            baseop_to_string RW_MATRIX_GET_WITH_BOUNDSCHECK_MACRO => "rw_matrix_get_with_boundscheck";
            baseop_to_string RW_MATRIX_SET_WITH_BOUNDSCHECK_MACRO => "rw_matrix_set_with_boundscheck";

            baseop_to_string MAKE_EXCEPTION_TAG => "mketag";
            baseop_to_string WRAP   => "wrap";
            baseop_to_string UNWRAP => "unwrap";

            # Primops to support new rw_vector representations:
            #
            baseop_to_string MAKE_ZERO_LENGTH_VECTOR    =>  "make_zero_length_vector";
            baseop_to_string GET_VECTOR_DATACHUNK       =>  "getseqdata";
            baseop_to_string RECORD_GET =>  "get_recslot_contents";
            baseop_to_string RAW64_GET  =>  "get_raw64slot_contents";

            # Primops to support new experimental
            # C "foreign-function interface" (FFI):
            #
            baseop_to_string (GET_FROM_NONHEAP_RAM nk)            => cat ["raw_load(", kind_and_size_to_string nk, ")"];
            baseop_to_string (SET_NONHEAP_RAM   nk)           => cat ["raw_store(", kind_and_size_to_string nk, ")"];
            baseop_to_string (RAW_CCALL _)            => "raw_ccall";
            baseop_to_string (RAW_ALLOCATE_C_RECORD { fblock } ) => cat ["raw_", if fblock  "fblock"; else "iblock";fi, "_record"];

            baseop_to_string IDENTITY_MACRO => "inlidentity";
            baseop_to_string CVT64       => "cvt64";
        end;


        # TRUE means "May not be dead-code eliminated":
        #
        fun might_have_side_effects  (ARITH { overflow, ... }) =>   overflow;
            #
            might_have_side_effects  (RSHIFT_MACRO _)           => FALSE;
            might_have_side_effects  (RSHIFTL_MACRO _)          => FALSE;
            #
            might_have_side_effects  (COMPARE _)                => FALSE;
            #
            might_have_side_effects  (STRETCH _)                => FALSE;
            might_have_side_effects  (CHOP  _)                  => FALSE;
            might_have_side_effects  (COPY   _)                 => FALSE;
            #
            might_have_side_effects   POINTER_EQL               => FALSE;
            might_have_side_effects   POINTER_NEQ               => FALSE;
            #
            might_have_side_effects   POLY_EQL                  => FALSE;
            might_have_side_effects   POLY_NEQ                  => FALSE;
            #
            might_have_side_effects   IS_BOXED                  => FALSE;
            might_have_side_effects   IS_UNBOXED                => FALSE;
            #
            might_have_side_effects   VECTOR_LENGTH_IN_SLOTS    => FALSE;
            might_have_side_effects   HEAPCHUNK_LENGTH_IN_WORDS => FALSE;
            #
            might_have_side_effects   CAST                      => FALSE;
            might_have_side_effects   WCAST                     => FALSE;
            #
            might_have_side_effects  (MIN_MACRO _)              => FALSE;
            might_have_side_effects  (MAX_MACRO _)              => FALSE;
            might_have_side_effects   NOT_MACRO                 => FALSE;
            might_have_side_effects   COMPOSE_MACRO             => FALSE;
            might_have_side_effects   IGNORE_MACRO              => FALSE;
            #
            might_have_side_effects   WRAP                      => FALSE;
            might_have_side_effects   UNWRAP                    => FALSE;
            #
            might_have_side_effects   IDENTITY_MACRO            => FALSE;
            might_have_side_effects   CVT64                     => FALSE;
            #
            might_have_side_effects    _                        => TRUE;
        end;
            #
            # should return more than just a boolean:
            # { Store, Fate }-{ read, write }           XXX BUGGO FIXME


        fun might_raise_exception  (ROUND _)                                    =>  TRUE;                       # Currently nowhere used.
            might_raise_exception   MAKE_NONEMPTY_RW_VECTOR_MACRO               =>  TRUE;
            #   
            might_raise_exception   RW_VECTOR_GET_WITH_BOUNDSCHECK              =>  TRUE;
            might_raise_exception   RO_VECTOR_GET_WITH_BOUNDSCHECK              =>  TRUE;
            might_raise_exception   RW_VECTOR_SET_WITH_BOUNDSCHECK              =>  TRUE;
            #   
            might_raise_exception   RW_MATRIX_GET_WITH_BOUNDSCHECK_MACRO        =>  TRUE;
            might_raise_exception   RO_MATRIX_GET_WITH_BOUNDSCHECK_MACRO        =>  TRUE;
            might_raise_exception   RW_MATRIX_SET_WITH_BOUNDSCHECK_MACRO        =>  TRUE;
            #
            might_raise_exception  (ARITH { overflow, ... }) => overflow;
            #
            might_raise_exception  (GET_VECSLOT_NUMERIC_CONTENTS { checkbounds, ... }) =>  checkbounds;
            might_raise_exception  (SET_VECSLOT_TO_NUMERIC_VALUE { checkbounds, ... }) =>  checkbounds;
            #
            might_raise_exception   _ => FALSE;
        end;

    };                                                                                  #  package highcode_baseops 
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext