1#!/bin/sh 2# 3# BEGIN LICENSE BLOCK 4# Version: CMPL 1.1 5# 6# The contents of this file are subject to the Cisco-style Mozilla Public 7# License Version 1.1 (the "License"); you may not use this file except 8# in compliance with the License. You may obtain a copy of the License 9# at www.eclipse-clp.org/license. 10# 11# Software distributed under the License is distributed on an "AS IS" 12# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 13# the License for the specific language governing rights and limitations 14# under the License. 15# 16# The Original Code is The ECLiPSe Constraint Logic Programming System. 17# The Initial Developer of the Original Code is Cisco Systems, Inc. 18# Portions created by the Initial Developer are 19# Copyright (C) 1992-2006 Cisco Systems, Inc. All Rights Reserved. 20# 21# Contributor(s): ___________________________________. 22# 23# END LICENSE BLOCK 24# 25# IDENTIFICATION opt_sun3.sh 26# 27# AUTHOR Joachim Schimpf 28# 29# DESCRIPTION A postprocessor to optimize the assembler source 30# that the SUN-3 C compiler generates from emu.c. 31# The main purpose is to turn the normal emulator 32# into a threaded code emulator. 33# 34# In order to make this postprocessor work, 35# emu.c must be compiled with 36# 37# cc [-O[12]] -DTHREADED ... -S emu.c 38# 39# -DNO_ESCAPE is not allowed! 40# 41# Haven't tried with GNU yet. 42# 43# USAGE opt_sun3.sh <infile> <outfile> 44# 45# NOTE Since the C compiler generates switch tables with relative offsets, 46# it cannot be used directly as the op_addr[] array. Therefore 47# we insert the label _opswitch_addr for the switch table. 48# When sepia is booted, the op_addr[] array must be computed from 49# the switch table (function opaddr_init()). This function is dependent 50# of the offset size (16 or 32 bit, according to cc's -J option) 51# and must be updated accordingly. This postprocessor can handle both. 52 53trap 'rm -f /tmp/opt?.$$' 0 2 54 55# 56# Optimizer pass 1 (analysis) 57# 58# find: 59# - the code labels of the opcode switch 60# - the label of the switch table 61# - the register that holds PP 62# 63 64cat > /tmp/opt1.$$ <<\'PASS1\' 65 66/L.+:/ { 67 thislabel = $1 68 words = 0 # check if a table follows 69 getline 70 while ($0 ~ /^\t\.(short|long)/) { 71 words++ 72 getline 73 } 74 if (words == 0) { # not a table 75 line1 = thislabel # this might be the switch label 76 } else if (words > 200) { # switch table found 77 loop1 = line1 # remember all the information 78 optable = thislabel 79 } 80} 81 82/^\tmovl\t.*_bip_error_code_.*/ { # an assignment to pp, remember the register 83 pp = substr($2, length($2)-1, 2) 84} 85 86END { 87 print pp # pass results to pass2 88 print loop1 89 print optable 90} 91'PASS1' 92 93# 94# Optimizer pass 2 (transformation) 95# 96# - replace jumps to the switch labels by threaded code jumps 97# - add the op_addr label to the switch table 98# 99 100cat > /tmp/opt2.$$ <<\'PASS2\' 101 102BEGIN { 103 getline 104 pp = $0 # e.g. "a5" 105 getline 106 loop1def = $0 107 loop1 = substr($0,1,length($0)-1) # e.g. "L504" 108 getline 109 optable = $0 # e.g. "L2000118:" 110} 111 112{ 113 if ($2 == loop1) { 114 if ($1 == "jra") { 115 print "\tmovl\t" pp "@+,a0" 116 print "\tjmp\ta0@" 117 } else { 118 print "\t" $1 "\tLnewloop1" 119 } 120 } else if ($1 == loop1def) { 121 print "Lnewloop1:" 122 print "\tmovl\t" pp "@+,a0" 123 print "\tjmp\ta0@" 124 print 125 } else if ($1 == optable) { 126 print "_opswitch_table:" 127 print 128 } else if (!already_printed && $1 == ".globl" && $2 == "_emulc") { 129 already_printed = 1 130 print "\t.globl\t_opswitch_table" 131 print 132 } else 133 print 134} 135'PASS2' 136 137# echo pass1 138awk -f /tmp/opt1.$$ $1 > $1.par 139# echo pass2 140awk -f /tmp/opt2.$$ $1.par $1 > $2 141# echo done 142