# backend-lowhalf-sparc32.pkg
# Sparc-specific backend
# Compiled by:
#
src/lib/compiler/mythryl-compiler-support-for-sparc32.libstipulate
package irc = iterated_register_coalescing; # iterated_register_coalescing is from
src/lib/compiler/back/low/regor/iterated-register-coalescing.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_sparc32
=
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_sparc32; # treecode_extension_sparc32 is from
src/lib/compiler/back/low/main/sparc32/treecode-extension-sparc32.pkg );
package treecode_eval_sparc32
=
treecode_eval_g ( # treecode_eval_g is from
src/lib/compiler/back/low/treecode/treecode-eval-g.pkg #
package tcf = treecode_sparc32;
#
fun eq _ _ = FALSE;
#
eq_rext = eq;
eq_fext = eq;
eq_ccext = eq;
eq_sext = eq;
);
package treecode_hash_sparc32
=
treecode_hash_g ( # treecode_hash_g is from
src/lib/compiler/back/low/treecode/treecode-hash-g.pkg #
package tcf = treecode_sparc32;
#
fun h _ _ = 0u0;
#
hash_sext = h;
hash_rext = h;
hash_fext = h;
hash_ccext = h;
);
package gas_pseudo_ops_sparc32
=
gas_pseudo_ops_sparc32_g ( # gas_pseudo_ops_sparc32_g is from
src/lib/compiler/back/low/sparc32/mcg/gas-pseudo-ops-sparc32-g.pkg #
package tcf = treecode_sparc32;
package tce = treecode_eval_sparc32;
);
package client_pseudo_ops_sparc32
= 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_sparc32; # "bpo" == "base_pseudo_ops".
);
package pseudo_ops_sparc32
=
pseudo_op_g ( # pseudo_op_g is from
src/lib/compiler/back/low/mcg/pseudo-op-g.pkg #
package cpo = client_pseudo_ops_sparc32;
);
package code_buffer_sparc32
= codebuffer_g ( # codebuffer_g is from src/lib/compiler/back/low/code/codebuffer-g.pkg#
#
pseudo_ops_sparc32
);
package treecode_buffer_sparc32
= treecode_codebuffer_g ( # treecode_codebuffer_g is from
src/lib/compiler/back/low/treecode/treecode-codebuffer-g.pkg #
package tcf = treecode_sparc32;
package cst = code_buffer_sparc32;
);
# Specialized sparc instruction set
#
package machcode_sparc32
= machcode_sparc32_g ( # machcode_sparc32_g is from
src/lib/compiler/back/low/sparc32/code/machcode-sparc32-g.codemade.pkg #
treecode_sparc32
);
package pseudo_instructions_sparc32
= pseudo_instructions_sparc32_g ( # pseudo_instructions_sparc32_g is from
src/lib/compiler/back/low/main/sparc32/pseudo-instructions-sparc32-g.pkg #
machcode_sparc32
);
package machcode_universals_sparc32
= machcode_universals_sparc32_g ( # machcode_universals_sparc32_g is from
src/lib/compiler/back/low/sparc32/code/machcode-universals-sparc32-g.pkg #
package mcf = machcode_sparc32;
package tce = treecode_eval_sparc32;
package tch = treecode_hash_sparc32;
);
package compile_register_moves_sparc32
= compile_register_moves_sparc32_g ( # compile_register_moves_sparc32_g is from
src/lib/compiler/back/low/sparc32/code/compile-register-moves-sparc32-g.pkg #
machcode_sparc32
);
package translate_machcode_to_asmcode_sparc32
= translate_machcode_to_asmcode_sparc32_g ( # translate_machcode_to_asmcode_sparc32_g is from
src/lib/compiler/back/low/sparc32/emit/translate-machcode-to-asmcode-sparc32-g.codemade.pkg #
package mcf = machcode_sparc32;
package crm = compile_register_moves_sparc32;
package cst = code_buffer_sparc32;
package tce = treecode_eval_sparc32;
#
v9 = FALSE;
);
package execode_emitter_sparc32
=
translate_machcode_to_execode_sparc32_g ( # translate_machcode_to_execode_sparc32_g is from
src/lib/compiler/back/low/sparc32/emit/translate-machcode-to-execode-sparc32-g.codemade.pkg #
package mcf = machcode_sparc32;
package cst = code_buffer_sparc32;
package tce = treecode_eval_sparc32;
package csb = code_segment_buffer; # code_segment_buffer is from
src/lib/compiler/execution/code-segments/code-segment-buffer.pkg #
package asm_emitter = translate_machcode_to_asmcode_sparc32;
);
# Flowgraph data package specialized to Sparc instructions
#
package machcode_controlflow_graph_sparc32
= machcode_controlflow_graph_g ( # machcode_controlflow_graph_g is from
src/lib/compiler/back/low/mcg/machcode-controlflow-graph-g.pkg #
package mcf = machcode_sparc32;
# package pop = pseudo_ops_sparc32;
package meg = digraph_by_adjacency_list; # digraph_by_adjacency_list is from
src/lib/graph/digraph-by-adjacency-list.pkg package mu = machcode_universals_sparc32;
package ae = translate_machcode_to_asmcode_sparc32;
);
stipulate
package rkj = registerkinds_junk; # registerkinds_junk is from
src/lib/compiler/back/low/code/registerkinds-junk.pkg herein
package platform_register_info_sparc32
: (weak) Platform_Register_Info # Platform_Register_Info is from
src/lib/compiler/back/low/main/nextcode/platform-register-info.api {
# Export to client packages:
# # "tcf" == "treecode_form".
package tcf = treecode_sparc32;
package rgk = registerkinds_sparc32; # registerkinds_sparc32 is from
src/lib/compiler/back/low/sparc32/code/registerkinds-sparc32.codemade.pkg gp = rgk::get_ith_int_hardware_register;
fp = rgk::get_ith_float_hardware_register;
fun reg r = tcf::CODETEMP_INFO (32, gp r);
fun freg f = tcf::CODETEMP_INFO_FLOAT (64, fp f);
return_ptr = gp 15;
stipulate
stdarg0 = reg 24; # %i0
stdfate0 = reg 25; # %i1
stdclos0 = reg 26; # %i2
stdlink0 = reg 1; # %g1
#
base_pointer0 = reg 27; # %i3
heap_allocation_limit0 = reg 4; # %g4 # heap_allocation_pointer may not advance beyond this point.
current_thread_ptr0 = reg 29; # %i5
heap_changelog_pointer0 = reg 5; # %g5 # Every (pointer) update to the heap gets logged to this cons-cell list, to help the heapcleaner.
exception_handler_register0 = reg 7; # %g7
heapcleaner_link0 = tcf::CODETEMP_INFO (32, return_ptr);
framepointer0 = reg 30; # Holds current C stackframe, which holds pointers to runtime resources like the heapcleaner ("garbage collector"), which is written in C.
herein
virtual_framepointer = registerkinds_sparc32::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 is an actual architectural difference at work, it needs to be commented.
vfptr = tcf::CODETEMP_INFO (32, virtual_framepointer);
fun stdarg _ = stdarg0;
fun stdfate _ = stdfate0;
fun stdclos _ = stdclos0;
fun stdlink _ = stdlink0;
fun base_pointer _ = base_pointer0;
fun heap_allocation_limit _ = heap_allocation_limit0; # heap_allocation_pointer may not advance beyond this point.
fun current_thread_ptr _ = current_thread_ptr0;
heap_is_exhausted__test
=
THE (tcf::CC (tcf::GTU, rgk::psr)); /* %psr */ # 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 heap_allocation_pointer = reg (6); # %g6 # We allot ram just by advancing this pointer. We use this very heavily -- every 10 instructions or so.
# Note that no 'stackptr' is defined.
fun heap_changelog_pointer _ = heap_changelog_pointer0; # Every (pointer) update to the heap gets logged to this cons-cell list.
# (The heapcleaner scans this list to detect intergenerational pointers.)
fun exception_handler_register _ = exception_handler_register0;
fun heapcleaner_link _ = heapcleaner_link0;
fun framepointer _ = framepointer0; # Holds current C stackframe, which holds pointers to runtime resources like the heapcleaner ("garbage collector"), which is written in C.
# Warning %o2 is used as the asm_tmp
#
miscregs =
map reg
[2, 3, # %g2-%g3
8, 9, # %o0-%o1
16, 17, 18, 19, 20, 21, 22, 23, # %l0-%l7
28, 31, # %i4, %i6, %i7
11, 12, 13]; # %o3-%o5
calleesave = rw_vector::from_list miscregs;
# Note: We need at least one register for shuffling purposes.
#
fun fromto (n, m, inc)
=
if (n>m) [];
else n ! fromto (n+inc, m, inc);
fi;
floatregs = map freg (fromto (0, 31, 2));
savedfpregs = [];
stipulate
fun un_reg (tcf::CODETEMP_INFO (_, r)) => r;
un_reg _ => raise exception DIE "sparc-nextcode-registers: unREG";
end;
package cos = rkj::cos; # "cos" == "colorset".
--- = cos::difference_of_colorsets;
infix my --- ;
herein
all_regs = map gp (fromto (0, 31, 1));
available_int_registers
=
map un_reg ( [stdlink0, stdclos0, stdarg0, stdfate0, heapcleaner_link0]
@ miscregs
);
global_int_registers
=
cos::get_codetemps_in_colorset
#
( cos::make_colorset all_regs
---
cos::make_colorset available_int_registers
);
available_float_registers = map fp (fromto (0, 30, 2));
global_float_registers = [];
use_signed_heaplimit_check = FALSE;
address_width = 32;
ccall_caller_save_r
=
map un_reg [heap_allocation_limit0, heap_changelog_pointer0, exception_handler_register0, heap_allocation_pointer];
ccall_caller_save_f = [];
end;
end;
};
end;
herein
package backend_lowhalf_sparc32
=
backend_lowhalf_g ( # backend_lowhalf_g is from
src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg #
package mp = machine_properties_sparc32; # machine_properties_sparc32 is from
src/lib/compiler/back/low/main/sparc32/machine-properties-sparc32.pkg abi_variant = NULL;
#
package t = treecode_sparc32;
#
package cpo = client_pseudo_ops_sparc32;
package pop = pseudo_ops_sparc32;
#
package trx = treecode_extension_sparc32; # treecode_extension_sparc32 is from
src/lib/compiler/back/low/main/sparc32/treecode-extension-sparc32.pkg package pri = platform_register_info_sparc32;
package mu = machcode_universals_sparc32;
#
package ae = translate_machcode_to_asmcode_sparc32;
package crm = compile_register_moves_sparc32;
#
package cal # "cal" == "ccalls" (native C calls).
=
ccalls_sparc32_g ( # ccalls_sparc32_g is from
src/lib/compiler/back/low/sparc32/ccalls/ccalls-sparc32-g.pkg #
package tcf = treecode_sparc32;
#
fun ix x = x;
);
package fuf { # "fuf" == "free_up_framepointer".
#
package mcg = machcode_controlflow_graph_sparc32;
package mcf = machcode_sparc32;
#
virtual_framepointer = pri::virtual_framepointer;
# No rewriting necessary, backend
# uses %fp instead of %sp # Is that comment reversed? -- 2011-06-15 CrT
#
fun replace_framepointer_uses_with_stackpointer_in_machcode_controlflow_graph _ = ();
};
package t2m # "t2m" == "translate_treecode_to_machcode".
=
translate_treecode_to_machcode_sparc32_g ( # translate_treecode_to_machcode_sparc32_g is from
src/lib/compiler/back/low/sparc32/treecode/translate-treecode-to-machcode-sparc32-g.pkg #
package mcf = machcode_sparc32;
package psi = pseudo_instructions_sparc32;
package txc
=
treecode_extension_compiler_sparc32_g ( # treecode_extension_compiler_sparc32_g is from
src/lib/compiler/back/low/main/sparc32/treecode-extension-compiler-sparc32-g.pkg #
package mcf = machcode_sparc32;
package tcf = treecode_sparc32;
package tcs = treecode_buffer_sparc32;
package mcg = machcode_controlflow_graph_sparc32;
);
v9 = FALSE;
mulu_cost = REF 5;
mult_cost = REF 3;
divu_cost = REF 5;
divt_cost = REF 5;
registerwindow = REF FALSE;
use_br = REF FALSE;
);
package jumps_sparc32
=
jump_size_ranges_sparc32_g ( # jump_size_ranges_sparc32_g is from
src/lib/compiler/back/low/sparc32/jmp/jump-size-ranges-sparc32-g.pkg #
package mcf = machcode_sparc32;
package tce = treecode_eval_sparc32;
package crm = compile_register_moves_sparc32;
);
package sja # "sja" == "squash_jumps_and...".
= # squash_jumps_and_make_machinecode_bytevector_sparc32_g is from
src/lib/compiler/back/low/jmp/squash-jumps-and-write-code-to-code-segment-buffer-sparc32-g.pkg squash_jumps_and_make_machinecode_bytevector_sparc32_g (
#
package mcg = machcode_controlflow_graph_sparc32;
package jmp = jumps_sparc32;
package xe = execode_emitter_sparc32;
package mu = mu; # "mu" == "machcode_universals".
package ae = translate_machcode_to_asmcode_sparc32;
#
package dsp
=
delay_slots_sparc32_g ( # delay_slots_sparc32_g is from
src/lib/compiler/back/low/sparc32/jmp/delay-slots-sparc32-g.pkg #
package mcf = machcode_sparc32; # "mcf" == "machcode_form" (abstract machine code).
package mu = mu; # "mu" == "machcode_universals".
);
);
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_sparc32;
package mcg = machcode_controlflow_graph_sparc32;
package mu = mu; # "mu" == "machcode_universals".
#
package rmi # "rmi" == "rewrite_machine_instructions".
=
instructions_rewrite_sparc32_g ( # instructions_rewrite_sparc32_g is from
src/lib/compiler/back/low/sparc32/regor/instructions-rewrite-sparc32-g.pkg machcode_sparc32
);
package asi # "asi" == "architecture-specific spill instructions".
=
spill_instructions_sparc32_g ( # spill_instructions_sparc32_g is from
src/lib/compiler/back/low/sparc32/regor/spill-instructions-sparc32-g.pkg #
machcode_sparc32
);
package ae = translate_machcode_to_asmcode_sparc32; # "ae" == "asmcode_emitter".
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_sparc32; # "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_sparc32 # machine_properties_sparc32 is from
src/lib/compiler/back/low/main/sparc32/machine-properties-sparc32.pkg );
fp = machcode_sparc32::rgk::framepointer_r;
spill = nextcode_ramregions::spill;
Spill_Operand_Kind
=
SPILL_LOC
| CONST_VAL;
Spill_Info = Void;
fun before_ra _
=
spill_table::spill_init();
machine_architecture # PWRPC32/SPARC32/INTEL32.
=
machine_properties_sparc32::machine_architecture;
package i = machcode_sparc32;
fun pure (i::BASE_OP (i::LOAD _)) => TRUE;
pure (i::BASE_OP (i::FLOAD _)) => TRUE;
pure (i::BASE_OP (i::SETHI _)) => TRUE;
pure (i::BASE_OP (i::SHIFT _)) => TRUE;
pure (i::BASE_OP (i::FPOP1 _)) => TRUE;
pure (i::BASE_OP (i::FPOP2 _)) => TRUE;
#
pure (i::NOTE { op, ... } ) => pure op;
#
pure _ => FALSE;
end;
# Make copy:
#
package rap { # "rap" == "register allocation parameter".
#
locally_allocated_hardware_registers = platform_register_info_sparc32::available_int_registers;
globally_allocated_hardware_registers = platform_register_info_sparc32::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 }
=
{ kind => SPILL_LOC,
operand => i::DISPLACE {
base => fp,
disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT id),
ramregion => spill
}
};
mode = irc::no_optimization;
};
package fap { # "fap" == "floating point register allocation parameter".
#
locally_allocated_hardware_registers = platform_register_info_sparc32::available_float_registers;
globally_allocated_hardware_registers = platform_register_info_sparc32::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)
=
i::DISPLACE {
base => fp,
disp => make_disp (cig::SPILL_TO_FRESH_FRAME_SLOT loc),
ramregion => spill
};
mode = irc::no_optimization;
};
);
);
end;
## COPYRIGHT (c) 1998 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.