## make-sourcecode-for-translate-machcode-to-asmcode-xxx-g-package.pkg -- derived from ~/src/sml/nj/smlnj-110.60/MLRISC/Tools/ADL/mdl-gen-asm.sml
#
# This module generates the assembler of an architecture
# given an architecture description.
#
# This currently generates
#
src/lib/compiler/back/low/intel32/emit/translate-machcode-to-asmcode-intel32-g.codemade.pkg#
src/lib/compiler/back/low/pwrpc32/emit/translate-machcode-to-asmcode-pwrpc32-g.codemade.pkg#
src/lib/compiler/back/low/sparc32/emit/translate-machcode-to-asmcode-sparc32-g.codemade.pkg# Compiled by:
#
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.lib### "Why should I be worried about dying?
### It's not going to happen in my lifetime!"
###
### -- Raymond Smullyan
stipulate
package ard = architecture_description; # architecture_description is from
src/lib/compiler/back/low/tools/arch/architecture-description.pkgherein
api Make_Sourcecode_For_Translate_Machcode_To_Asmcode_Xxx_G_Package {
#
make_sourcecode_for_translate_machcode_to_asmcode_xxx_g_package
:
ard::Architecture_Description -> Void;
};
end;
# We are run-time invoked in:
#
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages-g.pkg# We are compile-time invoked in:
#
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.pkgstipulate
package ard = architecture_description; # architecture_description is from
src/lib/compiler/back/low/tools/arch/architecture-description.pkg package err = adl_error; # adl_error is from
src/lib/compiler/back/low/tools/line-number-db/adl-error.pkg package smj = sourcecode_making_junk; # sourcecode_making_junk is from
src/lib/compiler/back/low/tools/arch/sourcecode-making-junk.pkg package mst = adl_symboltable; # adl_symboltable is from
src/lib/compiler/back/low/tools/arch/adl-symboltable.pkg package raw = adl_raw_syntax_form; # adl_raw_syntax_form is from
src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-form.pkg package rrs = adl_rewrite_raw_syntax_parsetree; # adl_rewrite_raw_syntax_parsetree is from
src/lib/compiler/back/low/tools/adl-syntax/adl-rewrite-raw-syntax-parsetree.pkg package rsj = adl_raw_syntax_junk; # adl_raw_syntax_junk is from
src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-junk.pkg package rst = adl_raw_syntax_translation; # adl_raw_syntax_translation is from
src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-translation.pkg package spp = simple_prettyprinter; # simple_prettyprinter is from
src/lib/prettyprint/simple/simple-prettyprinter.pkg #
++ = spp::CONS; infix my ++ ;
alpha = spp::ALPHABETIC;
iblock = spp::INDENTED_BLOCK;
indent = spp::INDENT;
nl = spp::NEWLINE;
punct = spp::PUNCTUATION;
herein
package make_sourcecode_for_translate_machcode_to_asmcode_xxx_g_package
: (weak) Make_Sourcecode_For_Translate_Machcode_To_Asmcode_Xxx_G_Package
{
fun make_sourcecode_for_translate_machcode_to_asmcode_xxx_g_package architecture_description
=
smj::write_sourcecode_file
{
architecture_description,
created_by_package => "src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-asmcode-xxx-g-package.pkg",
#
subdir => "emit", # Relative to file containing architecture description.
make_filename => \\ architecture_name = sprintf "translate-machcode-to-asmcode-%s-g.codemade.pkg" architecture_name, # architecture_name can be "pwrpc32"
| "sparc32" | "intel32".
code => [ pkg_code ]
}
where
architecture_name = ard::architecture_name_of architecture_description; # "intel32"/"sparc32"/"pwrpc32"
archl = string::to_lower architecture_name;
archm = string::to_mixed architecture_name;
# Name of the generic and api:
#
# pkg_name = smj::make_package_name architecture_description "asm_emitter";
api_name = "Machcode_Codebuffer_Pp";
# Arguments of the generic:
#
args = [
"package cst: Codebuffer;\t\t\t\t\t\t\t# Codebuffer\t\t\tis from src/lib/compiler/back/low/code/codebuffer.api",
"",
sprintf "package mcf: Machcode_%s\t\t\t\t\t\t\t# Machcode_%s\t\tis from src/lib/compiler/back/low/%s/code/machcode-%s.codemade.api" archm archm archl archl,
" where",
" tcf == cst::pop::tcf;\t\t\t\t# \"tcf\" == \"treecode_form\".",
"",
sprintf "package crm: Compile_Register_Moves_%s\t\t\t\t\t# Compile_Register_Moves_%s\tis from src/lib/compiler/back/low/%s/code/compile-register-moves-%s.api" archm archm archl archl,
" where",
" mcf == mcf;",
"",
"package tce: Treecode_Eval\t\t\t\t\t\t\t# Treecode_Eval\t\t\tis from src/lib/compiler/back/low/treecode/treecode-eval.api",
" where",
" tcf == mcf::tcf;\t\t\t\t\t# \"tcf\" == \"treecode_form\".",
""
];
# Append to above the argument to the generic package 'Assembly'
# in our architecture description file, which will
# currently be one of
#
# src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description
# src/lib/compiler/back/low/sparc32/sparc32.architecture-description
# src/lib/compiler/back/low/intel32/intel32.architecture-description
#
# For intel32.architecture-description the appended part looks in SML syntax like
#
# structure mem_regs: Machcode_Address_Of_Ramreg_Intel32 where mcf = machcode_form
# val mem_reg_base: rkj.Register option
#
# which when translated into Mythryl syntax looks like:
#
# package mem_regs: Machcode_Address_Of_Ramreg_Intel32 where mcf == machcode_form;
# mem_reg_base: Null_Or( rkj::Codetemp_Info );
#
args = raw::SEQ_DECL
[ raw::VERBATIM_CODE args,
ard::generic_arg_of architecture_description "Assembly"
];
registerkinds = ard::registersets_of architecture_description; # Registerkinds declared by the user.
asm_case = ard::asm_case_of architecture_description; # Assembly case.
# How to make a string expression:
#
fun make_string s
=
rsj::string_constant_in_expression
#
case asm_case
#
raw::VERBATIM => s;
raw::LOWERCASE => string::map char::to_lower s;
raw::UPPERCASE => string::map char::to_upper s;
esac;
# The Instruction package:
#
symboltable = mst::find_package
(ard::symboltable_of architecture_description)
(raw::IDENT ([], "Instruction"));
# All sumtype definitions in this package:
#
sumtype_definitions
=
mst::sumtype_definitions symboltable;
# There are three assembly modes:
# EMIT: directly emit to stream
# ASM: convert to string
# NOTHING: do nothing
#
Mode = EMIT
| ASM | NOTHING;
# Find out which assembly mode a sumtype should use:
#
fun mode_of (raw::SUMTYPE { cbs, asm, ... } ) # "cbs" is "CONS bindings"
=>
loop (cbs, mode)
where
mode = if asm ASM;
else NOTHING;
fi;
# Where raw::CONSTRUCTOR.asm -> THE (raw::ASMASM a),
# search list a for raw::EXPASM.
# Return EMIT if found, else the given mode:
#
fun loop2 ([], m) => m;
loop2 (raw::EXPASM _ ! _, _) => EMIT;
loop2 (_ ! a, m) => loop2 (a, m);
end;
# Search a raw::SUMTYPE.cbs list;
# if any raw::CONSTRUCTOR.asm -> THE(raw::STRINGASM)
# or raw::CONSTRUCTOR.asm -> THE(raw::ASMASM a)
# then return ASM, except that a raw::EXPASM in 'a' means
# to return EMIT:
#
fun loop ([], m ) => m;
loop (_, EMIT) => EMIT;
#
loop (raw::CONSTRUCTOR { asm => NULL, ... } ! cbs, m) => loop (cbs, m);
loop (raw::CONSTRUCTOR { asm => THE (raw::STRINGASM _), ... } ! cbs, _) => loop (cbs, ASM);
loop (raw::CONSTRUCTOR { asm => THE (raw::ASMASM a), ... } ! cbs, m) => loop (cbs, loop2 (a, ASM));
end;
end;
mode_of _ => raise exception DIE "Bug: Unsupported case in mode_of";
end;
# How to emit special types:
#
fun put_type (id, raw::IDTY (raw::IDENT (prefix, t)), e)
=>
case (prefix, t)
#
([], "int" ) => rsj::app ("put_" + t, e);
([], "string" ) => rsj::app ("emit", e);
(["Constant"], "const" ) => rsj::app ("put_" + t, e);
(["Label"], "label" ) => rsj::app ("put_" + t, e);
(["treecode_form"], "label_expression") => rsj::app ("put_" + t, e);
(["Region"], "ramregion" ) => rsj::app ("put_" + t, e);
#
_ =>
{ fun f (db as raw::SUMTYPE { name=>id', ... }) => t == id' and mode_of db != NOTHING;
f _ => raise exception DIE "Bug: Unsupported case in put_type/f.";
end;
if (list::exists f sumtype_definitions) rsj::app ("put_" + t, e);
else rsj::app ("put_" + id, e);
fi;
};
esac;
put_type (_, raw::REGISTER_TYPE "registerset", e) => rsj::app ("put_registerset", e);
put_type (_, raw::REGISTER_TYPE k, e) => rsj::app ("put_register", e);
put_type (id, _, e) => rsj::app ("put_" + id, e);
end;
# Here we are driven by the contents of package "Instruction" in our
# architecture description file, which currently means one of
#
# src/lib/compiler/back/low/intel32/intel32.architecture-description
# src/lib/compiler/back/low/pwrpc32/pwrpc32.architecture-description
# src/lib/compiler/back/low/sparc32/sparc32.architecture-description
#
# For each sumtype "foo" defined in the package Instruction that
# has prettyprinting annotations attached we generate an assembly
# function "asm_foo" and an emit function "put_foo".
#
# Example such functions on intel32 include:
#
# 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)
#
fun make_asms ((db as raw::SUMTYPE { name, cbs, ... } ) ! dbs, fbs) # "dbs" == "sumtype bindings", "cbs" == "constructor bindings".
=>
case (mode_of db)
#
NOTHING => make_asms (dbs, fbs);
EMIT => make_asms (dbs, raw::FUN ("put_" + name, make_asm_fun (EMIT, cbs)) ! fbs);
ASM => make_asms (dbs, make_emit_fun name ! raw::FUN ("asm_" + name, make_asm_fun (ASM, cbs)) ! fbs);
esac;
make_asms ([], fbs) # "fbs" == "function bindings".
=>
reverse fbs;
make_asms _ => raise exception DIE "Bug: Unsupported case in make_asms";
end
# Here we're synthesizing raw syntax for
#
# fun put_foo x = emit (asm_foo x)
#
also
fun make_emit_fun id
=
raw::FUN ( "put_" + id,
[ raw::CLAUSE ( [raw::IDPAT "x"],
NULL,
rsj::app ("emit", rsj::app ("asm_" + id, rsj::id "x"))
)
]
)
# Here we're synthesizing raw syntax for
# something like
#
# 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
#
# given something like the
# src/lib/compiler/back/low/intel32/intel32.architecture-description
# declaration
#
# sumtype cond! =
# EQ "e" 0w4
| NE 0w5 | LT "l" 0w12 | LE 0w14 | GT "g" 0w15 | GE 0w13
#
| BB 0w2 | BE 0w6 | AA 0w7 | AE 0w3
#
| CC 0w2 | NC 0w3 | PP 0wxa | NP 0wxb
#
| OO 0w0 | NO 0w1
#
# parsed into raw-syntax form.
# Here:
# a simple string like "e" shows up as raw::CONSTRUCTOR.asm -> THE (raw::STRINGASM "e")
# a qualifier like asm: <expression> shows up as raw::CONSTRUCTOR.asm -> THE (raw::ASMASM [raw::EXPASM expression])
# a qualifier like ``this and <that>'' shows up as raw::CONSTRUCTOR.asm -> THE (raw::ASMASM [asms])
# where each asm is one of
# raw::EXPASM expression produced by <that> surface syntax where the brokets are literal sourcetext, not metanotation.
# raw::TEXTASM asmtext_t produced by running text inside the ``...'' but not inside any <...>.
# A raw::TEXTASM is a string constant;
# a raw::EXPASM is a string-valued expression to be evaluated at asmcode generation time.
also
fun make_asm_fun (mode, cbs) # "cbs" is "cons bindings"
=
map make_clause cbs
where
fun put_it e
=
if (mode == EMIT) rsj::app ("emit", e);
else e;
fi;
fun asm_to_expression e (raw::TEXTASM s)
=>
put_it (make_string s);
asm_to_expression e (raw::EXPASM (raw::ID_IN_EXPRESSION (raw::IDENT([], x))))
=>
{ (e x) -> (e, type);
#
put_type (x, type, e);
}
except e = err::fail ("unknown assembly field <" + x + ">");
asm_to_expression e''' (raw::EXPASM e)
=>
fns.rewrite_expression_parsetree e
where
fun rewrite_expression_node _ (raw::ASM_IN_EXPRESSION (raw::STRINGASM s)) => put_it (make_string s);
rewrite_expression_node _ (raw::ASM_IN_EXPRESSION (raw::ASMASM a)) => raw::SEQUENTIAL_EXPRESSIONS (map (asm_to_expression e''') a);
rewrite_expression_node _ e => e;
end;
fns = rrs::make_raw_syntax_parsetree_rewriters [ rrs::REWRITE_EXPRESSION_NODE rewrite_expression_node ];
end;
end;
# In terms of the above example, here we're
# generating raw-syntax clauses like
#
# (mcf::EQ) => "e";
#
# for the fun asm_cond.
#
# In the general case the lefthand-side of the clause
# can carry values (i.e., instruction fields) and the
# right-hand-side can compute arbitrary functions of them.
#
fun make_clause (cb as raw::CONSTRUCTOR { name, asm, ... } ) # "cb" == "constructor binding".
=
{ expression
=
case asm
#
NULL => put_it (make_string name);
THE (raw::STRINGASM s) => put_it (make_string s);
THE (raw::ASMASM a) => { cons_dict = rst::cons_namings cb;
raw::SEQUENTIAL_EXPRESSIONS (map (asm_to_expression cons_dict) a);
};
esac;
rst::map_cons_to_clause
{
prefix => ["mcf"], # Generates the "mcf::" prefixes on "mcf::EQ" etc in the above example.
pattern => \\ p = p, # rst::map_cons_to_pattern does everything we need, so we supply a no-op \\ here.
expression
}
cb;
};
end;
# Make asm_*/put_* fun pairs from sumtypes in
#
# foo.adl: package Instruction
#
# -- see comment on function 'make_asms':
#
asm_funs = raw::FUN_DECL (make_asms (sumtype_definitions, []));
# Main function for emitting an instruction:
#
put_instr_fun
=
{ instructions = ard::base_ops_of architecture_description;
#
rsj::fun_fn
( "put_op'",
raw::IDPAT "instruction",
raw::CASE_EXPRESSION (rsj::id "instruction", make_asm_fun (EMIT, instructions))
);
};
body =
[ raw::VERBATIM_CODE
[
"\t\t\t\t\t\t\t\t\t# Machcode_Codebuffer_Pp\t\tis from src/lib/compiler/back/low/emit/machcode-codebuffer-pp.api",
"",
"# Export to client packages:",
"#",
"package cst = cst;\t\t\t\t\t\t\t# \"cst\" == \"codestream\".",
"package mcf = mcf;\t\t\t\t\t\t\t# \"mcf\" == \"machcode_form\" (abstract machine code).",
"",
"stipulate",
" package rgk = mcf::rgk;\t\t# \"rgk\" == \"registerkinds\".",
" package tcf = mcf::tcf;\t\t# \"tcf\" == \"treecode_form\".",
" package pop = cst::pop;\t\t\t\t\t\t# \"pop\" == \"pseudo_op\".",
" package lac = mcf::lac;\t\t\t\t\t\t# \"lac\" == \"late_constant\".",
"herein",
"",
"include package asm_flags;\t\t\t\t\t\t\t# asm_flags\t\tis from src/lib/compiler/back/low/emit/asm-flags.pkg",
""
],
smj::error_handler architecture_description (\\ architecture_name = sprintf "translate_machcode_to_asmcode_%s_g" architecture_name),
raw::VERBATIM_CODE
[
"",
"fun make_codebuffer (pp: pp::Pp) format_annotations",
" =",
" { # stream = *asm_stream::asm_out_stream;\t\t\t\t# asm_stream\t\tis 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"
],
asm_funs,
ard::decl_of architecture_description "Assembly",
put_instr_fun,
raw::VERBATIM_CODE
[ " tab ();",
" put_op' instruction;",
" nl ();",
" }\t\t\t\t\t\t# 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 +\t\t\t# '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",
" };",
" };\t\t\t\t\t\t\t\t\t\t# fun make_codebuffer",
"end;\t\t\t\t\t\t\t\t\t\t# stipulate"
]
];
pkg_code
=
spp::CAT [
punct "# We are invoked by:", nl,
punct "#", nl,
punct (sprintf "# src/lib/compiler/back/low/main/%s/backend-lowhalf-%s%s.pkg" archl archl (archl=="intel32" ?? "-g" :: "")), nl,
punct "#", nl,
alpha "stipulate", nl,
iblock(indent++alpha "package lem = lowhalf_error_message;\t\t\t\t\t\t# lowhalf_error_message\t\tis from src/lib/compiler/back/low/control/lowhalf-error-message.pkg"), nl,
iblock(indent++alpha "package pp = standard_prettyprinter;\t\t\t\t\t\t# standard_prettyprinterl\t\tis from src/lib/prettyprint/big/src/standard-prettyprinter.pkg"), nl,
iblock(indent++alpha "package rkj = registerkinds_junk;\t\t\t\t\t\t# registerkinds_junk\t\tis from src/lib/compiler/back/low/code/registerkinds-junk.pkg"), nl,
alpha "herein", nl, nl,
iblock (indent ++ smj::make_generic'
architecture_description
(\\ architecture_name = sprintf "translate_machcode_to_asmcode_%s_g" architecture_name)
args
smj::WEAK_SEAL
api_name
body
),
alpha "end;", nl, nl
]
where
architecture_name = ard::architecture_name_of architecture_description; # "intel32"/"sparc32"/"pwrpc32"
archl = string::to_lower architecture_name;
archm = string::to_mixed architecture_name;
end;
end; # fun gen
}; # package make_sourcecode_for_translate_machcode_to_asmcode_xxx_g_package
end; # stipulate