## backend-lowhalf-pwrpc32.pkg
#
# PowerPC-specific backend
# Compiled by:
#
src/lib/compiler/mythryl-compiler-support-for-pwrpc32.libstipulate
package irc = iterated_register_coalescing; # iterated_register_coalescing is from
src/lib/compiler/back/low/regor/iterated-register-coalescing.pkg package lem = lowhalf_error_message; # lowhalf_error_message is from
src/lib/compiler/back/low/control/lowhalf-error-message.pkg package cig = codetemp_interference_graph; # codetemp_interference_graph is from
src/lib/compiler/back/low/regor/codetemp-interference-graph.pkg package sma = supported_architectures; # supported_architectures is from
src/lib/compiler/front/basics/main/supported-architectures.pkg package treecode_form_pwrpc32
= treecode_form_g ( # treecode_form_g is from
src/lib/compiler/back/low/treecode/treecode-form-g.pkg #
package lac = late_constant; # late_constant is from
src/lib/compiler/back/low/main/nextcode/late-constant.pkg package rgn = nextcode_ramregions; # nextcode_ramregions is from
src/lib/compiler/back/low/main/nextcode/nextcode-ramregions.pkg package trx = treecode_extension_mythryl; # treecode_extension_mythryl is from
src/lib/compiler/back/low/main/nextcode/treecode-extension-mythryl.pkg );
package treecode_eval_pwrpc32
= treecode_eval_g ( # treecode_eval_g is from
src/lib/compiler/back/low/treecode/treecode-eval-g.pkg #
package tcf = treecode_form_pwrpc32;
#
fun eq _ _ = FALSE;
#
eq_rext = eq;
eq_fext = eq;
eq_ccext = eq;
eq_sext = eq;
);
package treecode_hash_pwrpc32
= treecode_hash_g ( # treecode_hash_g is from
src/lib/compiler/back/low/treecode/treecode-hash-g.pkg #
package tcf = treecode_form_pwrpc32;
#
fun h _ _ = 0u0;
#
hash_rext = h; hash_fext = h;
hash_ccext = h; hash_sext = h;
);
package gas_pseudo_ops_pwrpc32
= gas_pseudo_ops_pwrpc32_g (
#
package tcf = treecode_form_pwrpc32;
package tce = treecode_eval_pwrpc32;
);
package client_pseudo_ops_pwrpc32
= client_pseudo_ops_mythryl_g ( # client_pseudo_ops_mythryl_g is from
src/lib/compiler/back/low/main/nextcode/client-pseudo-ops-mythryl-g.pkg #
package bpo = gas_pseudo_ops_pwrpc32; # "bpo" == "base_pseudo_ops".
);
package pseudo_ops_pwrpc32
= pseudo_op_g ( # pseudo_op_g is from
src/lib/compiler/back/low/mcg/pseudo-op-g.pkg #
package cpo = client_pseudo_ops_pwrpc32; # "cpo" == "client_pseudo_ops".
);
package code_buffer_pwrpc32
= codebuffer_g ( # codebuffer_g is from
src/lib/compiler/back/low/code/codebuffer-g.pkg #
pseudo_ops_pwrpc32
);
package treecode_buffer_pwrpc32
= treecode_codebuffer_g ( # treecode_codebuffer_g is from
src/lib/compiler/back/low/treecode/treecode-codebuffer-g.pkg #
package tcf = treecode_form_pwrpc32;
package cst = code_buffer_pwrpc32;
);
# Machcode (abstract machine code) for powerpc architecture:
#
package machcode_pwrpc32
= machcode_pwrpc32_g ( # machcode_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/code/machcode-pwrpc32-g.codemade.pkg #
treecode_form_pwrpc32
);
package machcode_universals_pwrpc32
= machcode_universals_pwrpc32_g ( # machcode_universals_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/code/machcode-universals-pwrpc32-g.pkg #
package mcf = machcode_pwrpc32;
package tce = treecode_eval_pwrpc32;
package tch = treecode_hash_pwrpc32;
);
package compile_register_moves_pwrpc32
= compile_register_moves_pwrpc32_g ( # compile_register_moves_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/code/compile-register-moves-pwrpc32-g.pkg machcode_pwrpc32
);
package translate_machcode_to_asmcode_pwrpc32
= translate_machcode_to_asmcode_pwrpc32_g ( # translate_machcode_to_asmcode_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/emit/translate-machcode-to-asmcode-pwrpc32-g.codemade.pkg #
package mcf = machcode_pwrpc32;
package cst = code_buffer_pwrpc32;
package tce = treecode_eval_pwrpc32;
package crm = compile_register_moves_pwrpc32;
);
package translate_machcode_to_execode_pwrpc32
= translate_machcode_to_execode_pwrpc32_g ( # translate_machcode_to_execode_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/emit/translate-machcode-to-execode-pwrpc32-g.codemade.pkg #
package mcf = machcode_pwrpc32;
package pop = pseudo_ops_pwrpc32;
package cst = code_buffer_pwrpc32;
package tce = treecode_eval_pwrpc32;
package csb = code_segment_buffer; # code_segment_buffer is from
src/lib/compiler/execution/code-segments/code-segment-buffer.pkg );
# Flowgraph data package specialized to pwrpc32 instructions
#
package machcode_controlflow_graph_pwrpc32
= machcode_controlflow_graph_g ( # machcode_controlflow_graph_g is from
src/lib/compiler/back/low/mcg/machcode-controlflow-graph-g.pkg #
package mcf = machcode_pwrpc32;
# package pop = pseudo_ops_pwrpc32;
package meg = digraph_by_adjacency_list; # digraph_by_adjacency_list is from
src/lib/graph/digraph-by-adjacency-list.pkg package mu = machcode_universals_pwrpc32;
package ae = translate_machcode_to_asmcode_pwrpc32;
);
stipulate
package rkj = registerkinds_junk; # registerkinds_junk is from
src/lib/compiler/back/low/code/registerkinds-junk.pkg herein
package platform_register_info_pwrpw32
: (weak) Platform_Register_Info # Platform_Register_Info is from
src/lib/compiler/back/low/main/nextcode/platform-register-info.api {
# Exported tor client packages:
#
package tcf = treecode_form_pwrpc32;
package rgk = registerkinds_pwrpc32; # registerkinds_pwrpc32 is from
src/lib/compiler/back/low/pwrpc32/code/registerkinds-pwrpc32.codemade.pkg fun upto (from, to)
=
if (from > to) [];
else from ! (upto (from+1, to));
fi;
infix my upto ;
gp = registerkinds_pwrpc32::get_ith_int_hardware_register;
fp = registerkinds_pwrpc32::get_ith_float_hardware_register;
cc = registerkinds_pwrpc32::get_ith_hardware_register_of_kind rkj::FLAGS_REGISTER;
fun reg r = tcf::CODETEMP_INFO (32, gp r);
fun freg f = tcf::CODETEMP_INFO_FLOAT (64, fp f);
heap_is_exhausted__test
=
THE (tcf::CC (tcf::GTU, cc 0)); # A platform-specific test for (heap_allocation_pointer > heap_allocation_limit) ;
# this will be used in
src/lib/compiler/back/low/main/nextcode/emit-treecode-heapcleaner-calls-g.pkg # In this version we are only checking status bits set by a comparison done separately
# by code generated in
src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg virtual_framepointer = registerkinds_pwrpc32::make_int_codetemp_info ();
#
# This appears to violate the statement in XXX BUGGO FIXME
# http://www.smlnj.org//compiler-notes/omit-vfp.ps
# that "the virtual frame pointer cannot be allocated using [rgk::make_int_codetemp_info ()]..."
# "the virtual frame pointer must be allocated using [rgk::make_global_codetemp()]..."
#
# Note that
src/lib/compiler/back/low/main/intel32/backend-lowhalf-intel32-g.pkg # -- which is presumably much better tested -- does in fact use rgk::make_global_codetemp().
#
# If there's some architectural difference at work here, it should be commented.
vfptr = tcf::CODETEMP_INFO (32, virtual_framepointer);
stackptr = reg 1; # We use the stack lightly, mainly for calling C functions.
heap_allocation_pointer = reg 14; # We allot ram just by advancing this pointer. We use this very heavily -- every 10 instructions or so.
fun heap_allocation_limit _ = reg 15; # heap_allocation_pointer may not advance beyond this point.
fun heap_changelog_pointer _ = reg 16; # Every (pointer) update to the heap gets logged to this cons-cell list.
# (The heapcleaner scans this list to detect intergenerational pointers.)
fun stdlink _ = reg 17;
fun stdclos _ = reg 18;
fun stdarg _ = reg 19;
fun stdfate _ = reg 20;
fun exception_handler_register _ = reg 21;
fun current_thread_ptr _ = reg 22;
fun base_pointer _ = reg 23;
fun heapcleaner_link _ = tcf::CODETEMP_INFO (32, registerkinds_pwrpc32::lr);
fun framepointer _ = stackptr; # Holds current C stackframe, which holds pointers to runtime resources like the heapcleaner ("garbage collector"), which is written in C.
miscregs = map reg ([24, 25, 26, 27, 29, 30, 31] @ (3 upto 13));
calleesave = rw_vector::from_list (miscregs);
floatregs = map freg (1 upto 31);
savedfpregs = [];
available_int_registers
=
map un_reg
([stdlink FALSE, stdclos FALSE, stdarg FALSE,
stdfate FALSE] @ miscregs)
where
fun un_reg (tcf::CODETEMP_INFO (_, r))
=>
r;
un_reg _
=>
lem::error ("pwrpc32-nextcode-registers", "availR");
end;
end;
stipulate
package cos = rkj::cos; # "cos" == "colorset".
#
my --- = cos::difference_of_colorsets;
#
infix my --- ;
herein
all_regs = map gp (0 upto 31);
global_int_registers = cos::get_codetemps_in_colorset
#
( cos::make_colorset all_regs
---
cos::make_colorset available_int_registers
);
end;
available_float_registers = map fp (1 upto 31);
global_float_registers = [fp 0];
use_signed_heaplimit_check = FALSE;
address_width = 32;
# FIXME
ccall_caller_save_r = []; # no ccalls implemented yet
ccall_caller_save_f = []; # ...
};
end;
herein
package backend_lowhalf_pwrpc32
=
backend_lowhalf_g ( # backend_lowhalf_g is from
src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg #
package mp = machine_properties_pwrpc32; # machine_properties_pwrpc32 is from
src/lib/compiler/back/low/main/pwrpc32/machine-properties-pwrpc32.pkg abi_variant = NULL;
package t = treecode_form_pwrpc32;
#
package cpo = client_pseudo_ops_pwrpc32;
package pop = pseudo_ops_pwrpc32;
package trx = treecode_extension_mythryl; # treecode_extension_mythryl is from
src/lib/compiler/back/low/main/nextcode/treecode-extension-mythryl.pkg package pri = platform_register_info_pwrpw32;
package mu = machcode_universals_pwrpc32;
package ae = translate_machcode_to_asmcode_pwrpc32;
package crm = compile_register_moves_pwrpc32;
package cal # "cal" == "ccalls" (native C calls).
= ccalls_pwrpc32_mac_osx_g ( # ccalls_pwrpc32_mac_osx_g is from
src/lib/compiler/back/low/pwrpc32/ccalls/ccalls-pwrpc32-mac-osx-g.pkg #
package tcf = treecode_form_pwrpc32;
);
package fuf { # "fuf" == "free_up_framepointer".
#
package mcg = machcode_controlflow_graph_pwrpc32;
package mcf = machcode_pwrpc32;
#
virtual_framepointer = platform_register_info_pwrpw32::virtual_framepointer;
# no rewriting necessary, backend does not change sp
fun replace_framepointer_uses_with_stackpointer_in_machcode_controlflow_graph _ = ();
};
package t2m # "t2m" == "translate_treecode_to_machcode".
=
translate_treecode_to_machcode_pwrpc32_g ( # translate_treecode_to_machcode_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/treecode/translate-treecode-to-machcode-pwrpc32-g.pkg #
package mcf = machcode_pwrpc32;
# package treecode_form_pwrpc32
# = treecode_form_pwrpc32;
package pop
=
pseudo_instructions_pwrpc32_g ( # pseudo_instructions_pwrpc32_g is from
src/lib/compiler/back/low/main/pwrpc32/pseudo-instructions-pwrpc32-g.pkg #
package mcf = machcode_pwrpc32;
);
package txc
=
treecode_extension_compiler_mythryl_g ( # treecode_extension_compiler_mythryl_g is from
src/lib/compiler/back/low/main/nextcode/treecode-extension-compiler-mythryl-g.pkg #
package mcg = machcode_controlflow_graph_pwrpc32;
package tcs = treecode_buffer_pwrpc32;
);
bit64mode = FALSE; # 64-bit issue
mult_cost=REF 6; # An estimate
);
package jumps_pwrpc32
=
jump_size_ranges_pwrpc32_g ( # jump_size_ranges_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/jmp/jump-size-ranges-pwrpc32-g.pkg #
package mcf = machcode_pwrpc32;
package tce = treecode_eval_pwrpc32;
package crm = compile_register_moves_pwrpc32;
);
package sja # "sja" == "squash_jumps_and...".
= # squash_jumps_and_make_machinecode_bytevector_pwrpc32_g is from
src/lib/compiler/back/low/jmp/squash-jumps-and-write-code-to-code-segment-buffer-pwrpc32-g.pkg squash_jumps_and_make_machinecode_bytevector_pwrpc32_g (
#
package mcg = machcode_controlflow_graph_pwrpc32;
package jmp = jumps_pwrpc32;
package mu = machcode_universals_pwrpc32;
package xe = translate_machcode_to_execode_pwrpc32;
);
package ra # "ra" == "register_allocator".
=
regor_risc_g ( # regor_risc_g is from
src/lib/compiler/back/low/regor/regor-risc-g.pkg #
package mcf = machcode_pwrpc32;
package mcg = machcode_controlflow_graph_pwrpc32;
package mu = mu; # "mu" == "machcode_universals".
package rmi # "rmi" == "rewrite_machine_instructions".
=
instructions_rewrite_pwrpc32_g ( # instructions_rewrite_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/regor/instructions-rewrite-pwrpc32-g.pkg machcode_pwrpc32
);
package asi # "asi" == "architecture-specific spill instructions".
=
spill_instructions_pwrpc32_g ( # spill_instructions_pwrpc32_g is from
src/lib/compiler/back/low/pwrpc32/regor/spill-instructions-pwrpc32-g.pkg #
package mcf = machcode_pwrpc32;
);
package ae = translate_machcode_to_asmcode_pwrpc32;
package rsp = register_spilling_per_chaitin_heuristic; # register_spilling_per_chaitin_heuristic is from
src/lib/compiler/back/low/regor/register-spilling-per-chaitin-heuristic.pkg # "rsp" == "register_spilling_per_xxx_heuristic".
package spl # "spl" == "spill".
=
register_spilling_g ( # register_spilling_g is from
src/lib/compiler/back/low/regor/register-spilling-g.pkg #
package mu = mu; # "mu" == "machcode_universals".
package ae = translate_machcode_to_asmcode_pwrpc32; # "ae" == "asmcode_emitter".
);
package spill_table # Not an actual generic parameter.
=
spill_table_g ( # spill_table_g is from
src/lib/compiler/back/low/main/main/spill-table-g.pkg #
machine_properties_pwrpc32 # machine_properties_pwrpc32 is from
src/lib/compiler/back/low/main/pwrpc32/machine-properties-pwrpc32.pkg );
machine_architecture # PWRPC32/SPARC32/INTEL32.
=
machine_properties_pwrpc32::machine_architecture;
Spill_Operand_Kind = SPILL_LOC
| CONST_VAL;
Spill_Info = Void;
fun before_ra _
=
spill_table::spill_init();
sp = mcf::rgk::stackptr_r;
spill = nextcode_ramregions::spill;
fun pure _
=
FALSE;
# package nextcode_registers= platform_register_info_pwrpw32; # Not an actual generic parameter.
package rap { # "rap" == "register allocation parameters".
#
locally_allocated_hardware_registers = platform_register_info_pwrpw32::available_int_registers;
globally_allocated_hardware_registers = platform_register_info_pwrpw32::global_int_registers;
fun make_disp loc
=
t::LITERAL (t::mi::from_int (32, spill_table::get_reg_loc loc));
fun spill_loc { info, an, register, id }
=
{ operand => mcf::DISPLACE { base => sp,
disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT id),
ramregion => spill
},
kind => SPILL_LOC
};
mode = irc::no_optimization;
};
package fap { # "fap" == "floating point register allocation parameters".
#
locally_allocated_hardware_registers = platform_register_info_pwrpw32::available_float_registers;
globally_allocated_hardware_registers = platform_register_info_pwrpw32::global_float_registers;
fun make_disp loc
=
t::LITERAL (t::mi::from_int (32, spill_table::get_freg_loc loc));
fun spill_loc (s, an, loc)
=
mcf::DISPLACE { base => sp,
disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT loc),
ramregion => spill
};
mode = irc::no_optimization;
};
);
);
end;
## COPYRIGHT (c) 1999 Lucent Technologies, Bell Labs.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.