PreviousUpNext

15.4.324  src/lib/compiler/back/low/mcg/gnu-assembler-pseudo-op-g.pkg

## gnu-assembler-pseudo-ops-g.pkg

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



# Implements the string related functions to emit pseudo-ops
# in the standard GAS syntax.


stipulate
    package lbl =  codelabel;                                                                           # codelabel                     is from   src/lib/compiler/back/low/code/codelabel.pkg
    package pbt =  pseudo_op_basis_type;                                                                # pseudo_op_basis_type          is from   src/lib/compiler/back/low/mcg/pseudo-op-basis-type.pkg
herein

    api Gnu_Assembler_Pseudo_Ops {
        #
        package tcf:                    Treecode_Form;                                                  # Treecode_Form                 is from   src/lib/compiler/back/low/treecode/treecode-form.api
        #
        label_expression_to_string:     tcf::Label_Expression -> String;
        to_string:                      pbt::Pseudo_Op( tcf::Label_Expression, X ) -> String;
        define_private_label:           lbl::Codelabel -> String;
    };
end;

# We get invoked from:
#
#     src/lib/compiler/back/low/pwrpc32/mcg/gas-pseudo-ops-pwrpc32-g.pkg
#     src/lib/compiler/back/low/sparc32/mcg/gas-pseudo-ops-sparc32-g.pkg
#     src/lib/compiler/back/low/intel32/mcg/gas-pseudo-ops-intel32-g.pkg

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

    # This generic is invoked from:
    #
    #     src/lib/compiler/back/low/intel32/mcg/gas-pseudo-ops-intel32-g.pkg
    #     src/lib/compiler/back/low/pwrpc32/mcg/gas-pseudo-ops-pwrpc32-g.pkg
    #     src/lib/compiler/back/low/pwrpc32/mcg/pseudo-ops-pwrpc32-osx-g.pkg
    #     src/lib/compiler/back/low/sparc32/mcg/gas-pseudo-ops-sparc32-g.pkg
    #
    generic package   gnu_assembler_pseudo_op_g   (
        #             =========================
        #
        package tcf:    Treecode_Form;                                                                  # Treecode_Form                 is from   src/lib/compiler/back/low/treecode/treecode-form.api
        #
        label_format:           { global_symbol_prefix:    String,
                                  anonymous_label_prefix:  String
                                };
    )
    : (weak) Gnu_Assembler_Pseudo_Ops                                                                   # Gnu_Assembler_Pseudo_Ops      is from   src/lib/compiler/back/low/mcg/gnu-assembler-pseudo-op-g.pkg
    {
        # Export to client packages:
        #
        package tcf =  tcf;                                                                             # "tcf" == "treecode_form".

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

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

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

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

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


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

            fun label_expression_to_string le
                =
                to_string (le, 0)

            also
            fun to_string (tcf::LABEL lab, _) =>  lbl::codelabel_format_for_asm  label_format  lab; 
                to_string (tcf::LABEL_EXPRESSION le, p) =>  to_string (le, p);
                #
                to_string (tcf::NEG(_, tcf::LATE_CONSTANT c), _)
                    =>
                    print_int(-(lac::late_constant_to_int c))
                    except _ = "-" + lac::late_constant_to_string c;

                to_string (tcf::NEG(_, tcf::LITERAL i), _) => print_integer(-i);
                to_string (tcf::NEG(_, lambda_expression), prec) => parens (to_string (lambda_expression, 3), prec, 3);


                to_string (tcf::LATE_CONSTANT c, _)
                    => 
                    print_int (lac::late_constant_to_int c)
                    except
                        _ = lac::late_constant_to_string c;


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


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


                to_string (tcf::DIVS (tcf::d::ROUND_TO_ZERO, _, lambda_expression1, lambda_expression2), prec)
                    =>
                    parens (to_string (lambda_expression1, 2) + "/" + to_string (lambda_expression2, 2), prec, 2);


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


                to_string (tcf::RIGHT_SHIFT_U(_, lambda_expression, count), prec)
                    =>
                    parens (to_string (lambda_expression, 2) + ">>" + to_string (count, 2), prec, 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 define_private_label lab
                =
                label_expression_to_string (tcf::LABEL lab) + ":";

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

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

                to_string (pbt::DATA_LABEL lab) =>  lbl::codelabel_format_for_asm label_format lab + ":";
                to_string (pbt::DATA_READ_ONLY) =>  "\t.section\t.rodata";
                to_string (pbt::DATA)       =>  "\t.data";
                to_string (pbt::BSS)        =>  "\t.section\t.bss";
                to_string (pbt::TEXT)       =>  "\t.text";
                to_string (pbt::SECTION at)     =>  "\t.section\t" + quickstring__premicrothread::to_string at;

                to_string (pbt::REORDER)        =>  "";
                to_string (pbt::NOREORDER)      =>  "";

                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.int\t";
                                  64 =>  error "INT2";
                                   n =>  error ("unexpected INT size: " + int::to_string n);
                             esac;


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

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

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

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

                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 ";
                                 128 => "\t.extended ";
                                 n   => error ("unexpected FLOAT size: " + int::to_string n);
                              esac;


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

                to_string (pbt::IMPORT labs) =>  decls("\t.extern\t%s", labs);
                to_string (pbt::EXPORT labs) =>  decls("\t.global\t%s", labs);
                to_string (pbt::COMMENT txt) =>  ptf::sprintf' "/* %s */" [ptf::STRING txt];


                to_string (pbt::EXT _) => error "EXT";
            end;
        end;
    };
end;

## COPYRIGHT (c) 2001 Lucent Technologies, 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