## 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.pkgherein
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;