PreviousUpNext

15.4.258  src/lib/compiler/back/low/intel32/emit/translate-machcode-to-asmcode-intel32-g.codemade.pkg

## translate-machcode-to-asmcode-intel32-g.codemade.pkg
#
# This file generated at   2015-12-06:08:43:06   by
#
#     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-asmcode-xxx-g-package.pkg
#
# from the architecture description file
#
#     src/lib/compiler/back/low/intel32/intel32.architecture-description
#
# Edits to this file will be LOST on next system rebuild.

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


# We are invoked by:
#
#     src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg
#
stipulate
    package lem =  lowhalf_error_message;                                               # lowhalf_error_message         is from   src/lib/compiler/back/low/control/lowhalf-error-message.pkg
    package pp  =  standard_prettyprinter;                                              # standard_prettyprinter                is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package rkj =  registerkinds_junk;                                          # registerkinds_junk            is from   src/lib/compiler/back/low/code/registerkinds-junk.pkg
herein

    generic package translate_machcode_to_asmcode_intel32_g (
        #
        package cst: Codebuffer;                                                        # Codebuffer                    is from   src/lib/compiler/back/low/code/codebuffer.api
        
        package mcf: Machcode_Intel32                                                   # Machcode_Intel32              is from   src/lib/compiler/back/low/intel32/code/machcode-intel32.codemade.api
                     where
                         tcf == cst::pop::tcf;                          # "tcf" == "treecode_form".
        
        package crm: Compile_Register_Moves_Intel32                                     # Compile_Register_Moves_Intel32        is from   src/lib/compiler/back/low/intel32/code/compile-register-moves-intel32.api
                     where
                         mcf == mcf;
        
        package tce: Treecode_Eval                                                      # Treecode_Eval                 is from   src/lib/compiler/back/low/treecode/treecode-eval.api
                     where
                         tcf == mcf::tcf;                                       # "tcf" == "treecode_form".
        

###line 782.9 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        package ramregs : Machcode_Address_Of_Ramreg_Intel32 where mcf == mcf;

###line 784.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        ramreg_base: Null_Or( rkj::Codetemp_Info );

    )
    : (weak) Machcode_Codebuffer_Pp
    {
                                                                                # Machcode_Codebuffer_Pp                is from   src/lib/compiler/back/low/emit/machcode-codebuffer-pp.api
        
        # Export to client packages:
        #
        package cst =  cst;                                                     # "cst"  == "codestream".
        package mcf =  mcf;                                                     # "mcf" == "machcode_form" (abstract machine code).
        
        stipulate
            package rgk =  mcf::rgk;            # "rgk" == "registerkinds".
            package tcf =  mcf::tcf;            # "tcf" == "treecode_form".
            package pop =  cst::pop;                                            # "pop" == "pseudo_op".
            package lac =  mcf::lac;                                            # "lac" == "late_constant".
        herein
        
        include package   asm_flags;                                                    # asm_flags             is from   src/lib/compiler/back/low/emit/asm-flags.pkg
        
        fun error msg
            =
            lem::error ("translate_machcode_to_asmcode_intel32_g", msg);
        
        fun make_codebuffer (pp: pp::Pp) format_annotations
            =
            {   # stream = *asm_stream::asm_out_stream;                         # asm_stream            is from   src/lib/compiler/back/low/emit/asm-stream.pkg
        
                fun emit' s
                    =
                    pp.lit s;
        
                newline = REF TRUE;
                tabs    = REF 0;
        
                fun tabbing 0 => ();
                    tabbing n => { emit' "\t"; tabbing (n - 1); } ;
                end;
        
                fun emit s
                    =
                    {   tabbing *tabs;
                        tabs := 0;
                        newline := FALSE;
                        emit' s;
                    };
        
                fun nl     ()
                    =
                    {   tabs := 0;
                        if (not *newline)
                            #
                            newline := TRUE;
                            emit' "\n";
                        fi;
                    };
        
                fun comma  () =  emit ", ";
                fun tab    () =  tabs := 1;
                fun indent () =  tabs := 2;
        
                fun ms n
                    =
                    {   s = int::to_string n;
        
                        if (n < 0)   "-" + string::substring (s, 1, size s - 1);
                        else         s;
                        fi;
                    };
        
                fun put_label lab           = emit (pop::cpo::bpo::label_expression_to_string (tcf::LABEL lab));
                fun put_label_expression le = emit (pop::cpo::bpo::label_expression_to_string (tcf::LABEL_EXPRESSION le));
        
                fun put_const lateconst
                    =
                    emit (lac::late_constant_to_string  lateconst);
        
                fun put_int i
                    =
                    emit (ms i);
        
                fun paren f
                    =
                    {   emit "(";
                        f ();
                        emit ")";
                    };
        
                fun put_private_label  label
                    =
                    emit (pop::cpo::bpo::define_private_label label  +  "\n");
        
                fun put_public_label  label
                    =
                    put_private_label  label;
        
                fun put_comment  msg
                    =
                    {   tab ();
                        emit ("/* " + msg + " */");
                        nl ();
                    };
        
                fun put_bblock_note a
                    =
                    put_comment (note::to_string a);
        
                fun get_notes () =  error "get_notes";
                fun do_nothing _ =  ();
                fun fail _       =  raise exception DIE "asmcode-emitter";
        
                fun put_ramregion  ramregion
                    =
                    put_comment (mcf::rgn::ramregion_to_string  ramregion);
        
                put_ramregion
                    =
                    if *show_region    put_ramregion;
                    else               do_nothing;
                    fi;
        
                fun put_pseudo_op  pseudo_op
                    =
                    {   emit (pop::pseudo_op_to_string  pseudo_op);
                        emit "\n";
                    };
        
                fun init  size
                    =
                    {   put_comment ("Code Size = " + ms size);
                        nl ();
                    };
        
                put_register_info = asm_formatting_utilities::reginfo
                                         (emit, format_annotations);
        
                fun put_register r
                    =
                    {   emit (rkj::register_to_string r);
                        put_register_info r;
                    };
        
                fun put_registerset (title, registerset)
                    =
                    {   nl ();
                        put_comment  (title  +  rkj::cls::codetemplists_to_string  registerset);
                    };
        
                put_registerset
                    =
                    if *show_registerset   put_registerset;
                    else                   do_nothing;
                    fi;
        
                fun put_defs  registerset =  put_registerset ("defs: ", registerset);
                fun put_uses  registerset =  put_registerset ("uses: ", registerset);
        
                put_cuts_to
                    =
                    *show_cuts_to   ??   asm_formatting_utilities::put_cuts_to  emit
                                    ::   do_nothing;
        
                fun emitter instruction
                    =
                    {
                        # NB: The following incorrect-indentation problem is nontrivial to fix
                        #     so I'm just living with it for the moment.  -- 2011-05-14 CrT

        fun asm_cond (mcf::EQ) => "e";
            asm_cond (mcf::NE) => "ne";
            asm_cond (mcf::LT) => "l";
            asm_cond (mcf::LE) => "le";
            asm_cond (mcf::GT) => "g";
            asm_cond (mcf::GE) => "ge";
            asm_cond (mcf::BB) => "b";
            asm_cond (mcf::BE) => "be";
            asm_cond (mcf::AA) => "a";
            asm_cond (mcf::AE) => "ae";
            asm_cond (mcf::CC) => "c";
            asm_cond (mcf::NC) => "nc";
            asm_cond (mcf::PP) => "p";
            asm_cond (mcf::NP) => "np";
            asm_cond (mcf::OO) => "o";
            asm_cond (mcf::NO) => "no";
        end

        also
        fun put_cond x 
            =
            emit (asm_cond x)

        also
        fun asm_binary_op (mcf::ADDL) => "addl";
            asm_binary_op (mcf::SUBL) => "subl";
            asm_binary_op (mcf::ANDL) => "andl";
            asm_binary_op (mcf::ORL) => "orl";
            asm_binary_op (mcf::XORL) => "xorl";
            asm_binary_op (mcf::SHLL) => "shll";
            asm_binary_op (mcf::SARL) => "sarl";
            asm_binary_op (mcf::SHRL) => "shrl";
            asm_binary_op (mcf::MULL) => "mull";
            asm_binary_op (mcf::IMULL) => "imull";
            asm_binary_op (mcf::ADCL) => "adcl";
            asm_binary_op (mcf::SBBL) => "sbbl";
            asm_binary_op (mcf::ADDW) => "addw";
            asm_binary_op (mcf::SUBW) => "subw";
            asm_binary_op (mcf::ANDW) => "andw";
            asm_binary_op (mcf::ORW) => "orw";
            asm_binary_op (mcf::XORW) => "xorw";
            asm_binary_op (mcf::SHLW) => "shlw";
            asm_binary_op (mcf::SARW) => "sarw";
            asm_binary_op (mcf::SHRW) => "shrw";
            asm_binary_op (mcf::MULW) => "mulw";
            asm_binary_op (mcf::IMULW) => "imulw";
            asm_binary_op (mcf::ADDB) => "addb";
            asm_binary_op (mcf::SUBB) => "subb";
            asm_binary_op (mcf::ANDB) => "andb";
            asm_binary_op (mcf::ORB) => "orb";
            asm_binary_op (mcf::XORB) => "xorb";
            asm_binary_op (mcf::SHLB) => "shlb";
            asm_binary_op (mcf::SARB) => "sarb";
            asm_binary_op (mcf::SHRB) => "shrb";
            asm_binary_op (mcf::MULB) => "mulb";
            asm_binary_op (mcf::IMULB) => "imulb";
            asm_binary_op (mcf::BTSW) => "btsw";
            asm_binary_op (mcf::BTCW) => "btcw";
            asm_binary_op (mcf::BTRW) => "btrw";
            asm_binary_op (mcf::BTSL) => "btsl";
            asm_binary_op (mcf::BTCL) => "btcl";
            asm_binary_op (mcf::BTRL) => "btrl";
            asm_binary_op (mcf::ROLW) => "rolw";
            asm_binary_op (mcf::RORW) => "rorw";
            asm_binary_op (mcf::ROLL) => "roll";
            asm_binary_op (mcf::RORL) => "rorl";
            asm_binary_op (mcf::XCHGB) => "xchgb";
            asm_binary_op (mcf::XCHGW) => "xchgw";
            asm_binary_op (mcf::XCHGL) => "xchgl";
            asm_binary_op (mcf::LOCK_ADCW) => "lock\n\tadcw";
            asm_binary_op (mcf::LOCK_ADCL) => "lock\n\tadcl";
            asm_binary_op (mcf::LOCK_ADDW) => "lock\n\taddw";
            asm_binary_op (mcf::LOCK_ADDL) => "lock\n\taddl";
            asm_binary_op (mcf::LOCK_ANDW) => "lock\n\tandw";
            asm_binary_op (mcf::LOCK_ANDL) => "lock\n\tandl";
            asm_binary_op (mcf::LOCK_BTSW) => "lock\n\tbtsw";
            asm_binary_op (mcf::LOCK_BTSL) => "lock\n\tbtsl";
            asm_binary_op (mcf::LOCK_BTRW) => "lock\n\tbtrw";
            asm_binary_op (mcf::LOCK_BTRL) => "lock\n\tbtrl";
            asm_binary_op (mcf::LOCK_BTCW) => "lock\n\tbtcw";
            asm_binary_op (mcf::LOCK_BTCL) => "lock\n\tbtcl";
            asm_binary_op (mcf::LOCK_ORW) => "lock\n\torw";
            asm_binary_op (mcf::LOCK_ORL) => "lock\n\torl";
            asm_binary_op (mcf::LOCK_SBBW) => "lock\n\tsbbw";
            asm_binary_op (mcf::LOCK_SBBL) => "lock\n\tsbbl";
            asm_binary_op (mcf::LOCK_SUBW) => "lock\n\tsubw";
            asm_binary_op (mcf::LOCK_SUBL) => "lock\n\tsubl";
            asm_binary_op (mcf::LOCK_XORW) => "lock\n\txorw";
            asm_binary_op (mcf::LOCK_XORL) => "lock\n\txorl";
            asm_binary_op (mcf::LOCK_XADDB) => "lock\n\txaddb";
            asm_binary_op (mcf::LOCK_XADDW) => "lock\n\txaddw";
            asm_binary_op (mcf::LOCK_XADDL) => "lock\n\txaddl";
        end

        also
        fun put_binary_op x 
            =
            emit (asm_binary_op x)

        also
        fun asm_mult_div_op (mcf::IMULL1) => "imull";
            asm_mult_div_op (mcf::MULL1) => "mull";
            asm_mult_div_op (mcf::IDIVL1) => "idivl";
            asm_mult_div_op (mcf::DIVL1) => "divl";
        end

        also
        fun put_mult_div_op x 
            =
            emit (asm_mult_div_op x)

        also
        fun asm_unary_op (mcf::DECL) => "decl";
            asm_unary_op (mcf::INCL) => "incl";
            asm_unary_op (mcf::NEGL) => "negl";
            asm_unary_op (mcf::NOTL) => "notl";
            asm_unary_op (mcf::DECW) => "decw";
            asm_unary_op (mcf::INCW) => "incw";
            asm_unary_op (mcf::NEGW) => "negw";
            asm_unary_op (mcf::NOTW) => "notw";
            asm_unary_op (mcf::DECB) => "decb";
            asm_unary_op (mcf::INCB) => "incb";
            asm_unary_op (mcf::NEGB) => "negb";
            asm_unary_op (mcf::NOTB) => "notb";
            asm_unary_op (mcf::LOCK_DECL) => "lock\n\tdecl";
            asm_unary_op (mcf::LOCK_INCL) => "lock\n\tincl";
            asm_unary_op (mcf::LOCK_NEGL) => "lock\n\tnegl";
            asm_unary_op (mcf::LOCK_NOTL) => "lock\n\tnotl";
        end

        also
        fun put_unary_op x 
            =
            emit (asm_unary_op x)

        also
        fun asm_shift_op (mcf::SHLDL) => "shldl";
            asm_shift_op (mcf::SHRDL) => "shrdl";
        end

        also
        fun put_shift_op x 
            =
            emit (asm_shift_op x)

        also
        fun asm_bit_op (mcf::BTW) => "btw";
            asm_bit_op (mcf::BTL) => "btl";
            asm_bit_op (mcf::LOCK_BTW) => "lock\n\tbtw";
            asm_bit_op (mcf::LOCK_BTL) => "lock\n\tbtl";
        end

        also
        fun put_bit_op x 
            =
            emit (asm_bit_op x)

        also
        fun asm_move (mcf::MOVL) => "movl";
            asm_move (mcf::MOVB) => "movb";
            asm_move (mcf::MOVW) => "movw";
            asm_move (mcf::MOVSWL) => "movswl";
            asm_move (mcf::MOVZWL) => "movzwl";
            asm_move (mcf::MOVSBL) => "movsbl";
            asm_move (mcf::MOVZBL) => "movzbl";
        end

        also
        fun put_move x 
            =
            emit (asm_move x)

        also
        fun asm_fbin_op (mcf::FADDP) => "faddp";
            asm_fbin_op (mcf::FADDS) => "fadds";
            asm_fbin_op (mcf::FMULP) => "fmulp";
            asm_fbin_op (mcf::FMULS) => "fmuls";
            asm_fbin_op (mcf::FCOMS) => "fcoms";
            asm_fbin_op (mcf::FCOMPS) => "fcomps";
            asm_fbin_op (mcf::FSUBP) => "fsubp";
            asm_fbin_op (mcf::FSUBS) => "fsubs";
            asm_fbin_op (mcf::FSUBRP) => "fsubrp";
            asm_fbin_op (mcf::FSUBRS) => "fsubrs";
            asm_fbin_op (mcf::FDIVP) => "fdivp";
            asm_fbin_op (mcf::FDIVS) => "fdivs";
            asm_fbin_op (mcf::FDIVRP) => "fdivrp";
            asm_fbin_op (mcf::FDIVRS) => "fdivrs";
            asm_fbin_op (mcf::FADDL) => "faddl";
            asm_fbin_op (mcf::FMULL) => "fmull";
            asm_fbin_op (mcf::FCOML) => "fcoml";
            asm_fbin_op (mcf::FCOMPL) => "fcompl";
            asm_fbin_op (mcf::FSUBL) => "fsubl";
            asm_fbin_op (mcf::FSUBRL) => "fsubrl";
            asm_fbin_op (mcf::FDIVL) => "fdivl";
            asm_fbin_op (mcf::FDIVRL) => "fdivrl";
        end

        also
        fun put_fbin_op x 
            =
            emit (asm_fbin_op x)

        also
        fun asm_fibin_op (mcf::FIADDS) => "fiadds";
            asm_fibin_op (mcf::FIMULS) => "fimuls";
            asm_fibin_op (mcf::FICOMS) => "ficoms";
            asm_fibin_op (mcf::FICOMPS) => "ficomps";
            asm_fibin_op (mcf::FISUBS) => "fisubs";
            asm_fibin_op (mcf::FISUBRS) => "fisubrs";
            asm_fibin_op (mcf::FIDIVS) => "fidivs";
            asm_fibin_op (mcf::FIDIVRS) => "fidivrs";
            asm_fibin_op (mcf::FIADDL) => "fiaddl";
            asm_fibin_op (mcf::FIMULL) => "fimull";
            asm_fibin_op (mcf::FICOML) => "ficoml";
            asm_fibin_op (mcf::FICOMPL) => "ficompl";
            asm_fibin_op (mcf::FISUBL) => "fisubl";
            asm_fibin_op (mcf::FISUBRL) => "fisubrl";
            asm_fibin_op (mcf::FIDIVL) => "fidivl";
            asm_fibin_op (mcf::FIDIVRL) => "fidivrl";
        end

        also
        fun put_fibin_op x 
            =
            emit (asm_fibin_op x)

        also
        fun asm_fun_op (mcf::FCHS) => "fchs";
            asm_fun_op (mcf::FABS) => "fabs";
            asm_fun_op (mcf::FTST) => "ftst";
            asm_fun_op (mcf::FXAM) => "fxam";
            asm_fun_op (mcf::FPTAN) => "fptan";
            asm_fun_op (mcf::FPATAN) => "fpatan";
            asm_fun_op (mcf::FXTRACT) => "fxtract";
            asm_fun_op (mcf::FPREM1) => "fprem1";
            asm_fun_op (mcf::FDECSTP) => "fdecstp";
            asm_fun_op (mcf::FINCSTP) => "fincstp";
            asm_fun_op (mcf::FPREM) => "fprem";
            asm_fun_op (mcf::FYL2XP1) => "fyl2xp1";
            asm_fun_op (mcf::FSQRT) => "fsqrt";
            asm_fun_op (mcf::FSINCOS) => "fsincos";
            asm_fun_op (mcf::FRNDINT) => "frndint";
            asm_fun_op (mcf::FSCALE) => "fscale";
            asm_fun_op (mcf::FSIN) => "fsin";
            asm_fun_op (mcf::FCOS) => "fcos";
        end

        also
        fun put_fun_op x 
            =
            emit (asm_fun_op x)

        also
        fun asm_fenv_op (mcf::FLDENV) => "fldenv";
            asm_fenv_op (mcf::FNLDENV) => "fnldenv";
            asm_fenv_op (mcf::FSTENV) => "fstenv";
            asm_fenv_op (mcf::FNSTENV) => "fnstenv";
        end

        also
        fun put_fenv_op x 
            =
            emit (asm_fenv_op x)

        also
        fun asm_fsize (mcf::FP32) => "s";
            asm_fsize (mcf::FP64) => "l";
            asm_fsize (mcf::FP80) => "t";
        end

        also
        fun put_fsize x 
            =
            emit (asm_fsize x)

        also
        fun asm_isize (mcf::INT8) => "8";
            asm_isize (mcf::INT16) => "16";
            asm_isize (mcf::INT1) => "32";
            asm_isize (mcf::INT2) => "64";
        end

        also
        fun put_isize x 
            =
            emit (asm_isize x);

###line 788.8 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun ramreg r 
            =
            ramregs::ramreg { reg => r, 
                              base => null_or::the ramreg_base
                            }
        ;

###line 790.8 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun put_int1 i 
            =
            {   
###line 792.9 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
                s = one_word_int::to_string i;

###line 793.9 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
                s = if (i >= 0)   s;
                    else   ("-" + (string::substring (s, 1, (size s) - 1)));
                    fi;

                emit s;
            };

###line 797.8 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        my { min_register_id => stoffset, 
             ...
           }
            = rgk::get_id_range_for_physical_register_kind rkj::FLOAT_REGISTER;

###line 799.8 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun put_scale 0 => emit "1";
            put_scale 1 => emit "2";
            put_scale 2 => emit "4";
            put_scale 3 => emit "8";
            put_scale _ => error "put_scale";
        end

        also
        fun e_immed (mcf::IMMED i) => put_int1 i;
            e_immed (mcf::IMMED_LABEL lambda_expression) => put_label_expression lambda_expression;
            e_immed _ => error "e_immed";
        end

        also
        fun put_operand opn 
            =
            case opn
                #
                mcf::IMMED i => {   emit "$"; 
                                    put_int1 i; 
                                };
                mcf::IMMED_LABEL lambda_expression => {   emit "$"; 
                                                          put_label_expression lambda_expression; 
                                                      };
                mcf::LABEL_EA le => put_label_expression le;
                mcf::RELATIVE _ => error "put_operand";
                mcf::DIRECT r => put_register r;
                mcf::RAMREG r => put_operand (ramreg opn);
                mcf::ST f => put_register f;
                mcf::FPR float_register => {   emit "%f"; 
                                               emit (int::to_string (rkj::intrakind_register_id_of float_register)); 
                                           };
                mcf::FDIRECT f => put_operand (ramreg opn);
                mcf::DISPLACE { base, 
                                disp, 
                                ramregion, 
                                ...
                              }
                    => {   put_disp disp; 
                           emit "("; 
                           put_register base; 
                           emit ")"; 
                           put_ramregion ramregion; 
                       };
                mcf::INDEXED { base, 
                               index, 
                               scale, 
                               disp, 
                               ramregion, 
                               ...
                             }
                    => {   put_disp disp; 
                           emit "("; 
                           case base
                               #
                               NULL => ();
                               THE base => put_register base;
                           esac; 
                           comma (); 
                           put_register index; 
                           comma (); 
                           put_scale scale; 
                           emit ")"; 
                           put_ramregion ramregion; 
                       };
            esac

        also
        fun put_operand8 (mcf::DIRECT my_register) => emit (rkj::register_to_string' { my_register, 
                                                                                       size_in_bits => 8
                                                                                     }
                                                           );
            put_operand8 opn => put_operand opn;
        end

        also
        fun put_disp (mcf::IMMED 0) => ();
            put_disp (mcf::IMMED i) => put_int1 i;
            put_disp (mcf::IMMED_LABEL label_expression) => put_label_expression label_expression;
            put_disp _ => error "put_disp";
        end;

###line 847.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun gas_hack (mcf::IMMED_LABEL label_expression) => put_label_expression label_expression;
            gas_hack operand => {   emit "*"; 
                                    put_operand operand; 
                                };
        end;

###line 851.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun is_mem_operand (mcf::RAMREG _) => TRUE;
            is_mem_operand (mcf::FDIRECT f) => TRUE;
            is_mem_operand (mcf::LABEL_EA _) => TRUE;
            is_mem_operand (mcf::DISPLACE _) => TRUE;
            is_mem_operand (mcf::INDEXED _) => TRUE;
            is_mem_operand _ => FALSE;
        end;

###line 857.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun chop fbin_op 
            =
            {   
###line 858.10 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
                n = size fbin_op;

                case (char::to_lower (string::get_byte_as_char (fbin_op, n - 1)))
                    #
                    ('s' | 'l') => string::substring (fbin_op, 0, n - 1);
                    _   => fbin_op;
                esac;
            };

###line 864.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun is_st0 (mcf::ST reg) => (rkj::intrakind_register_id_of reg) == 0;
            is_st0 _ => FALSE;
        end;

###line 868.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"

        fun put_fbinary_op (bin_op, src, dst) 
            =
            if (is_mem_operand src)
                #
                put_fbin_op bin_op; 
                emit "\t"; 
                put_operand src; 
            else
                emit (chop (asm_fbin_op bin_op)); 
                emit "\t"; 
                case (is_st0 src, is_st0 dst)
                    #
                    (_, TRUE) => {   put_operand src; 
                                     emit ", %st"; 
                                 };
                    (TRUE, _) => {   emit "%st, "; 
                                     put_operand dst; 
                                 };
                    _   => error "put_fbinary_op";
                esac; 
            fi;

###line 878.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_dst = put_operand;

###line 879.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_src = put_operand;

###line 880.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_operand = put_operand;

###line 881.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_operand8 = put_operand8;

###line 882.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_rsrc = put_operand;

###line 883.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_lsrc = put_operand;

###line 884.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_address = put_operand;

###line 885.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_src1 = put_operand;

###line 886.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_ea = put_operand;

###line 887.2 "src/lib/compiler/back/low/intel32/intel32.architecture-description"
        put_count = put_operand;

        fun put_op' instruction 
            =
            case instruction
                #
                mcf::NOP => emit "nop";
                mcf::JMP (operand, list) => {   emit "jmp\t"; 
                                                gas_hack operand; 
                                            };
                mcf::JCC { cond, 
                           operand
                         }
                    => {   emit "j"; 
                           put_cond cond; 
                           emit "\t"; 
                           gas_hack operand; 
                       };
                mcf::CALL { operand, 
                            defs, 
                            uses, 
                            return, 
                            cuts_to, 
                            ramregion, 
                            pops
                          }
                    => {   emit "call\t"; 
                           gas_hack operand; 
                           put_ramregion ramregion; 
                           put_defs defs; 
                           put_uses uses; 
                           put_registerset ("return", return); 
                           put_cuts_to cuts_to; 
                       };
                mcf::ENTER { src1, 
                             src2
                           }
                    => {   emit "enter\t"; 
                           put_operand src1; 
                           emit ", "; 
                           put_operand src2; 
                       };
                mcf::LEAVE => emit "leave";
                mcf::RET option => {   emit "ret"; 
                                       case option
                                           #
                                           NULL => ();
                                           THE e => {   emit "\t"; 
                                                        put_operand e; 
                                                    };
                                       esac; 
                                   };
                mcf::MOVE { mv_op, 
                            src, 
                            dst
                          }
                    => {   put_move mv_op; 
                           emit "\t"; 
                           put_src src; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::LEA { r32, 
                           address
                         }
                    => {   emit "leal\t"; 
                           put_address address; 
                           emit ", "; 
                           put_register r32; 
                       };
                mcf::CMPL { lsrc, 
                            rsrc
                          }
                    => {   emit "cmpl\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::CMPW { lsrc, 
                            rsrc
                          }
                    => {   emit "cmpb\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::CMPB { lsrc, 
                            rsrc
                          }
                    => {   emit "cmpb\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::TESTL { lsrc, 
                             rsrc
                           }
                    => {   emit "testl\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::TESTW { lsrc, 
                             rsrc
                           }
                    => {   emit "testw\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::TESTB { lsrc, 
                             rsrc
                           }
                    => {   emit "testb\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::BITOP { bit_op, 
                             lsrc, 
                             rsrc
                           }
                    => {   put_bit_op bit_op; 
                           emit "\t"; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_lsrc lsrc; 
                       };
                mcf::BINARY { bin_op, 
                              src, 
                              dst
                            }
                    => case (src, bin_op)
                           #
                           (mcf::DIRECT _, (mcf::SARL | mcf::SHRL | mcf::SHLL | mcf::SARW | mcf::SHRW | mcf::SHLW | mcf::SARB | mcf::SHRB | mcf::SHLB)) => {   put_binary_op bin_op; 
                                                                                                                                                               emit "\t%cl, "; 
                                                                                                                                                               put_dst dst; 
                                                                                                                                                           };
                           _   => {   put_binary_op bin_op; 
                                      emit "\t"; 
                                      put_src src; 
                                      emit ", "; 
                                      put_dst dst; 
                                  };
                       esac;
                mcf::SHIFT { shift_op, 
                             src, 
                             dst, 
                             count
                           }
                    => case count
                           #
                           mcf::DIRECT ecx => {   put_shift_op shift_op; 
                                                  emit "\t"; 
                                                  put_src src; 
                                                  emit ", "; 
                                                  put_dst dst; 
                                              };
                           _   => {   put_shift_op shift_op; 
                                      emit "\t"; 
                                      put_src src; 
                                      emit ", "; 
                                      put_count count; 
                                      emit ", "; 
                                      put_dst dst; 
                                  };
                       esac;
                mcf::CMPXCHG { lock, 
                               size, 
                               src, 
                               dst
                             }
                    => {   if  lock
                               #
                               emit "lock\n\t"; 
                           fi; 
                           emit "cmpxchg"; 
                           case size
                               #
                               mcf::INT8 => emit "b";
                               mcf::INT16 => emit "w";
                               mcf::INT1 => emit "l";
                               mcf::INT2 => error "CMPXCHG: I64";
                           esac; 
                           {   emit "\t"; 
                               put_src src; 
                               emit ", "; 
                               put_dst dst; 
                           }; 
                       };
                mcf::MULTDIV { mult_div_op, 
                               src
                             }
                    => {   put_mult_div_op mult_div_op; 
                           emit "\t"; 
                           put_src src; 
                       };
                mcf::MUL3 { dst, 
                            src2, 
                            src1
                          }
                    => {   emit "imull\t$"; 
                           put_int1 src2; 
                           emit ", "; 
                           put_src1 src1; 
                           emit ", "; 
                           put_register dst; 
                       };
                mcf::UNARY { un_op, 
                             operand
                           }
                    => {   put_unary_op un_op; 
                           emit "\t"; 
                           put_operand operand; 
                       };
                mcf::SET { cond, 
                           operand
                         }
                    => {   emit "set"; 
                           put_cond cond; 
                           emit "\t"; 
                           put_operand8 operand; 
                       };
                mcf::CMOV { cond, 
                            src, 
                            dst
                          }
                    => {   emit "cmov"; 
                           put_cond cond; 
                           emit "\t"; 
                           put_src src; 
                           emit ", "; 
                           put_register dst; 
                       };
                mcf::PUSHL operand => {   emit "pushl\t"; 
                                          put_operand operand; 
                                      };
                mcf::PUSHW operand => {   emit "pushw\t"; 
                                          put_operand operand; 
                                      };
                mcf::PUSHB operand => {   emit "pushb\t"; 
                                          put_operand operand; 
                                      };
                mcf::PUSHFD => emit "pushfd";
                mcf::POPFD => emit "popfd";
                mcf::POP operand => {   emit "popl\t"; 
                                        put_operand operand; 
                                    };
                mcf::CDQ => emit "cdq";
                mcf::INTO => emit "into";
                mcf::FBINARY { bin_op, 
                               src, 
                               dst
                             }
                    => put_fbinary_op (bin_op, src, dst);
                mcf::FIBINARY { bin_op, 
                                src
                              }
                    => {   put_fibin_op bin_op; 
                           emit "\t"; 
                           put_src src; 
                       };
                mcf::FUNARY fun_op => put_fun_op fun_op;
                mcf::FUCOM operand => {   emit "fucom\t"; 
                                          put_operand operand; 
                                      };
                mcf::FUCOMP operand => {   emit "fucomp\t"; 
                                           put_operand operand; 
                                       };
                mcf::FUCOMPP => emit "fucompp";
                mcf::FCOMPP => emit "fcompp";
                mcf::FCOMI operand => {   emit "fcomi\t"; 
                                          put_operand operand; 
                                          emit ", %st"; 
                                      };
                mcf::FCOMIP operand => {   emit "fcomip\t"; 
                                           put_operand operand; 
                                           emit ", %st"; 
                                       };
                mcf::FUCOMI operand => {   emit "fucomi\t"; 
                                           put_operand operand; 
                                           emit ", %st"; 
                                       };
                mcf::FUCOMIP operand => {   emit "fucomip\t"; 
                                            put_operand operand; 
                                            emit ", %st"; 
                                        };
                mcf::FXCH { operand } => {   emit "fxch\t"; 
                                             put_register operand; 
                                         };
                mcf::FSTPL operand => case operand
                                          #
                                          mcf::ST _ => {   emit "fstp\t"; 
                                                           put_operand operand; 
                                                       };
                                          _   => {   emit "fstpl\t"; 
                                                     put_operand operand; 
                                                 };
                                      esac;
                mcf::FSTPS operand => {   emit "fstps\t"; 
                                          put_operand operand; 
                                      };
                mcf::FSTPT operand => {   emit "fstps\t"; 
                                          put_operand operand; 
                                      };
                mcf::FSTL operand => case operand
                                         #
                                         mcf::ST _ => {   emit "fst\t"; 
                                                          put_operand operand; 
                                                      };
                                         _   => {   emit "fstl\t"; 
                                                    put_operand operand; 
                                                };
                                     esac;
                mcf::FSTS operand => {   emit "fsts\t"; 
                                         put_operand operand; 
                                     };
                mcf::FLD1 => emit "fld1";
                mcf::FLDL2E => emit "fldl2e";
                mcf::FLDL2T => emit "fldl2t";
                mcf::FLDLG2 => emit "fldlg2";
                mcf::FLDLN2 => emit "fldln2";
                mcf::FLDPI => emit "fldpi";
                mcf::FLDZ => emit "fldz";
                mcf::FLDL operand => case operand
                                         #
                                         mcf::ST _ => {   emit "fld\t"; 
                                                          put_operand operand; 
                                                      };
                                         _   => {   emit "fldl\t"; 
                                                    put_operand operand; 
                                                };
                                     esac;
                mcf::FLDS operand => {   emit "flds\t"; 
                                         put_operand operand; 
                                     };
                mcf::FLDT operand => {   emit "fldt\t"; 
                                         put_operand operand; 
                                     };
                mcf::FILD operand => {   emit "fild\t"; 
                                         put_operand operand; 
                                     };
                mcf::FILDL operand => {   emit "fildl\t"; 
                                          put_operand operand; 
                                      };
                mcf::FILDLL operand => {   emit "fildll\t"; 
                                           put_operand operand; 
                                       };
                mcf::FNSTSW => emit "fnstsw";
                mcf::FENV { fenv_op, 
                            operand
                          }
                    => {   put_fenv_op fenv_op; 
                           emit "\t"; 
                           put_operand operand; 
                       };
                mcf::FMOVE { fsize, 
                             src, 
                             dst
                           }
                    => {   emit "fmove"; 
                           put_fsize fsize; 
                           emit "\t"; 
                           put_src src; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::FILOAD { isize, 
                              ea, 
                              dst
                            }
                    => {   emit "fiload"; 
                           put_isize isize; 
                           emit "\t"; 
                           put_ea ea; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::FBINOP { fsize, 
                              bin_op, 
                              lsrc, 
                              rsrc, 
                              dst
                            }
                    => {   put_fbin_op bin_op; 
                           put_fsize fsize; 
                           emit "\t"; 
                           put_lsrc lsrc; 
                           emit ", "; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::FIBINOP { isize, 
                               bin_op, 
                               lsrc, 
                               rsrc, 
                               dst
                             }
                    => {   put_fibin_op bin_op; 
                           put_isize isize; 
                           emit "\t"; 
                           put_lsrc lsrc; 
                           emit ", "; 
                           put_rsrc rsrc; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::FUNOP { fsize, 
                             un_op, 
                             src, 
                             dst
                           }
                    => {   put_fun_op un_op; 
                           put_fsize fsize; 
                           emit "\t"; 
                           put_src src; 
                           emit ", "; 
                           put_dst dst; 
                       };
                mcf::FCMP { i, 
                            fsize, 
                            lsrc, 
                            rsrc
                          }
                    => {   if  i
                               #
                               emit "fcmpi"; 
                           else
                               emit "fcmp"; 
                           fi; 
                           {   put_fsize fsize; 
                               emit "\t"; 
                               put_lsrc lsrc; 
                               emit ", "; 
                               put_rsrc rsrc; 
                           }; 
                       };
                mcf::SAHF => emit "sahf";
                mcf::LAHF => emit "lahf";
                mcf::SOURCE { } => emit "source";
                mcf::SINK { } => emit "sink";
                mcf::PHI { } => emit "phi";
            esac;
                        tab ();
                        put_op' instruction;
                        nl ();
                    }                                           # fun emitter
        
                also
                fun put_indented_instruction  instruction
                    =
                    {   indent ();
                        put_op instruction;
                        nl ();
                    }
        
                also
                fun put_instructions instructions
                    =
                    apply if *indent_copies   put_indented_instruction;
                          else put_op;
                          fi
                          instructions
        
                also
                fun put_op (mcf::NOTE { op, note } )
                        =>
                        {   put_comment (note::to_string note);
                            nl ();
                            put_op op;
                        };
        
                    put_op (mcf::LIVE { regs, spilled } )
                        =>
                        put_comment("live= " + rkj::cls::codetemplists_to_string regs +
                            "spilled= " + rkj::cls::codetemplists_to_string spilled);
        
                    put_op (mcf::DEAD { regs, spilled } )
                        =>
                        put_comment("dead= " + rkj::cls::codetemplists_to_string regs +                 # 'dead' here was 'killed' -- is there a critical difference?
                            "spilled= " + rkj::cls::codetemplists_to_string spilled);
        
                    put_op (mcf::BASE_OP i)
                        =>
                        emitter i;
        
                    put_op (mcf::COPY { kind=>rkj::INT_REGISTER, size_in_bits, src, dst, tmp } )
                        =>
                        put_instructions (crm::compile_int_register_moves { tmp, src, dst } );
        
                    put_op (mcf::COPY { kind=>rkj::FLOAT_REGISTER, size_in_bits, src, dst, tmp } )
                        =>
                        put_instructions (crm::compile_float_register_moves { tmp, src, dst } );
        
                    put_op _
                        =>
                        error "put_op";
                end;
        
                
                {
                  start_new_cccomponent => init,
                  put_pseudo_op,
                  put_op,
                  get_completed_cccomponent => fail,
                  put_private_label,
                  put_public_label,
                  put_comment,
                  put_fn_liveout_info => do_nothing,
                  put_bblock_note,
                  get_notes
                };
            };                                                                          # fun make_codebuffer
        end;                                                                            # stipulate
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext