PreviousUpNext

15.4.346  src/lib/compiler/back/low/pwrpc32/mcg/pseudo-ops-pwrpc32-osx-g.pkg

## pseudo-ops-pwrpc32-osx-g.pkg

# Compiled by:
#     src/lib/compiler/back/low/pwrpc32/backend-pwrpc32.lib

# PWRPC32/Darwin (aka MacOS X) pseudo operations.


stipulate
    package lbl =  codelabel;                                           # codelabel                     is from   src/lib/compiler/back/low/code/codelabel.pkg
    package lem =  lowhalf_error_message;                               # lowhalf_error_message         is from   src/lib/compiler/back/low/control/lowhalf-error-message.pkg
    package pbt =  pseudo_op_basis_type;                                # pseudo_op_basis_type          is from   src/lib/compiler/back/low/mcg/pseudo-op-basis-type.pkg
    package ptf =  sfprintf;                                            # sfprintf                      is from   src/lib/src/sfprintf.pkg
herein

    generic package   pseudo_ops_pwrpc32_osx_g   (                      # Nowhere invoked.
        #             ========================
        #
        package tcf:   Treecode_Form;                                   # Treecode_Form                 is from   src/lib/compiler/back/low/treecode/treecode-form.api

        package tce: Treecode_Eval                                      # Treecode_Eval                 is from   src/lib/compiler/back/low/treecode/treecode-eval.api
                     where
                         tcf == tcf;                                    # "tcf" == "treecode_form".
    )
    : (weak)  Base_Pseudo_Ops                                           # Base_Pseudo_Ops               is from   src/lib/compiler/back/low/mcg/base-pseudo-ops.api
    {
        # Export to client packages:
        #
        package tcf =  tcf;

        stipulate
            package lac =  tcf::lac;                                    # "lac" == "late_constant".

            package ndn                                                 # "ndn" == "endian".
                =
                big_endian_pseudo_op_g (                                # big_endian_pseudo_op_g        is from   src/lib/compiler/back/low/mcg/big-endian-pseudo-op-g.pkg
                    #
                    package tcf = tcf;                                  # "tcf" == "treecode_form".
                    package tce = tce;                                  # "tce" == "treecode_eval".
                    #
                    icache_alignment  =  16;                            # Cache line size.
                    max_alignment     =  THE 7;                         # Maximum alignment for internal labels 
                    #
                    nop = { size=>4, en=>0ux60000000: one_word_unt::Unt };  #  FIX . ori 0, 0, 0 
                );

        /* EXPAND
            package gap                                                 # "gap" == "gnu_assembler_pseudo_ops".
                = 
                gnu_assembler_pseudo_op_g (                             # gnu_assembler_pseudo_op_g     is from   src/lib/compiler/back/low/mcg/gnu-assembler-pseudo-op-g.pkg
                    #
                    package tcf = tcf;                                  # "tcf" == "treecode_form".
                    #   
                    label_format = { gPrefix="", aPrefix="L"}
             )
        */
        herein

            Pseudo_Op(X)
                =
                pbt::Pseudo_Op( tcf::Label_Expression, X ); 


            fun error msg
                =
                lem::error ("pseudo_ops_pwrpc32_osx_g.", msg);


            current_pseudo_op_size_in_bytes =  ndn::current_pseudo_op_size_in_bytes;
            put_pseudo_op                  =  ndn::put_pseudo_op;

            label_to_string
                =
                lbl::codelabel_format_for_asm
                  {
                    global_symbol_prefix   =>  "",
                    anonymous_label_prefix =>  "L"
                  };

            fun pr_integer i
                =
                if  (multiword_int::sign i < 0)   "-" + multiword_int::to_string (multiword_int::neg i); 
                else                          multiword_int::to_string i;
                fi;

            fun pr_int i
                =
                if   (i < 0)   "-" + int::to_string(-i);
                else                 int::to_string  i;
                fi;

            # operator precedences:
            # Note: these differ from C's precedences
            #     2 MULT, DIV, LSHIFT, RSHIFT
            #     1 AND, OR
            #     0 PLUS, MINUS


            fun parens (str, prec, op_prec)
                = 
                if (prec > op_prec)   "(" + str + ")";
                else                        str;
                fi;

            fun label_expression_to_string le
                =
                to_string (le, 0)

            also
            fun to_string (tcf::LABEL lab, _) => label_to_string lab; 
                to_string (tcf::LABEL_EXPRESSION le, p) => to_string (le, p);

                to_string (tcf::LATE_CONSTANT lateconst, _)
                    => 
                    pr_int (lac::late_constant_to_int  lateconst)
                    except
                        _ =  lac::late_constant_to_string  lateconst;

                to_string (tcf::LITERAL i, _)
                    =>
                    pr_integer i;

                to_string (tcf::MULS(_, lambda_expression1, lambda_expression2), _)
                    =>
                    to_string (lambda_expression1, 2) + "*" + to_string (lambda_expression2, 2);

                to_string (tcf::DIVS (tcf::d::ROUND_TO_ZERO, _, lambda_expression1, lambda_expression2), _)                     # d:: is a special rounding mode just for divide instructions.
                    =>
                    to_string (lambda_expression1, 2) + "/" + to_string (lambda_expression2, 2);

                to_string (tcf::LEFT_SHIFT(_, lambda_expression, count), prec) => to_string (lambda_expression, 2) + "<<" + to_string (count, 2);
                to_string (tcf::RIGHT_SHIFT_U(_, lambda_expression, count), prec) => to_string (lambda_expression, 2) + ">>" + to_string (count, 2);

                to_string (tcf::BITWISE_AND(_, lambda_expression, mask), prec)
                    => 
                    parens (to_string (lambda_expression, 1) + "&" + to_string (mask, 1), prec, 1);

                to_string (tcf::BITWISE_OR(_, lambda_expression, mask), prec)
                    => 
                    parens (to_string (lambda_expression, 1) + "|" + to_string (mask, 1), prec, 1);

                to_string (tcf::ADD(_, lambda_expression1, lambda_expression2), prec)
                    => 
                    parens (to_string (lambda_expression1, 0) + "+" + to_string (lambda_expression2, 0), prec, 0);

                to_string (tcf::SUB(_, lambda_expression1, lambda_expression2), prec)
                    => 
                    parens (to_string (lambda_expression1, 0) + "-" + to_string (lambda_expression2, 0), prec, 0);

                to_string _ => error "to_string";
            end;

            fun decls (fmt, labs)
                =
                string::cat 
                    (map (\\ lab =  (ptf::sprintf' fmt [ptf::STRING (label_expression_to_string (tcf::LABEL lab))]))
                         labs);

            fun pseudo_op_to_string (pbt::ALIGN_SIZE n)   => ptf::sprintf' "\t.align\t%d" [ptf::INT n];
                pseudo_op_to_string (pbt::ALIGN_ENTRY)    => "\t.align\t4";     #  16 byte boundary 
                pseudo_op_to_string (pbt::ALIGN_LABEL)    => "\t.align\t2";

                pseudo_op_to_string (pbt::DATA_LABEL lab) => label_to_string lab + ":";
                pseudo_op_to_string (pbt::DATA_READ_ONLY) => "\t.const_data";
                pseudo_op_to_string (pbt::DATA)           => "\t.data";
                pseudo_op_to_string (pbt::BSS)         => "\t.section\t__DATA, __BSS";
                pseudo_op_to_string (pbt::TEXT)           => "\t.text";
                pseudo_op_to_string (pbt::SECTION at)     => "\t.section\t" + quickstring__premicrothread::to_string at;
                pseudo_op_to_string (pbt::REORDER)        => "";
                pseudo_op_to_string (pbt::NOREORDER)      => "";

                pseudo_op_to_string (pbt::ASCII  s) =>  ptf::sprintf'  "\t.ascii\t\"%s\""  [ptf::STRING (string::to_cstring s)];
                pseudo_op_to_string (pbt::ASCIIZ s) =>  ptf::sprintf'  "\t.asciz\t\"%s\""  [ptf::STRING (string::to_cstring s)];

                pseudo_op_to_string (pbt::INT { size, i } )     => {

                   fun join []                      =>  [];
                       join [lambda_expression]     =>  [label_expression_to_string lambda_expression];
                       join (lambda_expression ! r) =>  label_expression_to_string lambda_expression ! ", " ! join r;
                   end;

                   pop = (case size
                             8 => "\t.byte\t";
                            16 => "\t.short\t";
                            32 => "\t.long\t";
                            64 => error "INT2";
                            _ => error ("pop: INT size = " + int::to_string size); esac
                         );             # end case

                     string::cat (pop ! join i);
                   };

                pseudo_op_to_string (pbt::SPACE size)
                    =>
                    ptf::sprintf' "\t.space\t%d" [ptf::INT size];

                pseudo_op_to_string (pbt::FLOAT { size, f } )
                    =>
                    {
                        fun join [] => [];
                            join [f] => [f];
                            join (f ! r) => f ! ", " ! join r;
                        end;

                        pop =  case size
                                  32 => "\t.single ";
                                 64 => "\t.double ";
                                 _ => error ("pop: FLOAT size = " + int::to_string size);
                               esac;

                        string::cat (pop ! join f);
                    };

                pseudo_op_to_string (pbt::IMPORT labs) =>  decls("\t.extern\t%s", labs);
                pseudo_op_to_string (pbt::EXPORT labs) =>  decls("\t.globl\t%s", labs);
                pseudo_op_to_string (pbt::COMMENT txt) =>  ptf::sprintf'  "; %s"  [ptf::STRING txt];
                pseudo_op_to_string (pbt::EXT _)       =>  error "EXT";
            end;

            fun define_private_label  label
                =
                label_to_string label   +    ":";
        end;
    };
end;

## COPYRIGHT (c) 2002 Bell labs, Lucent Technologies.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext