File:  [The Machine Emulator] / tme / ic / sparc / sparc-misc-auto.sh
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:43:56 2018 UTC (8 years, 2 months ago) by root
Branches: heeltoe, fredette, MAIN
CVS tags: tme-0_8heeltoe, tme-0_8, HEAD
tme-0.8

#! /bin/sh

# $Id: sparc-misc-auto.sh,v 1.1.1.2 2018/04/24 16:43:56 root Exp $

# ic/sparc/sparc-misc-auto.sh - automatically generates C code 
# for miscellaneous SPARC emulation support:

#
# Copyright (c) 2005 Matt Fredette
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Matt Fredette.
# 4. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

header=false

for option
do
    case $option in
    --header) header=true ;;
    esac
done

PROG=`basename $0`
cat <<EOF
/* automatically generated by $PROG, do not edit! */
EOF

# emit the register mapping macros:
if $header; then

    echo ""
    echo "/* the register mapping: */"
    echo "#define TME_SPARC_IREG_UNDEF		(-1)"
    ireg_next=0

    # all integer registers start from register number zero:
    #
    for regnum in 0 1 2 3 4 5 6 7; do
	echo "#define TME_SPARC_IREG_G${regnum}		(${ireg_next})"
	ireg_next=`expr ${ireg_next} + 1`
    done

    # all other registers start after the last register in the last
    # possible register window:
    #
    ireg_base='(TME_SPARC_WINDOWS_MAX * 16)'

    # the sparc64 alternate, MMU, and interrupt globals:
    #
    echo "#define TME_SPARC64_IREG_AG_G0	(${ireg_base} + ${ireg_next} + (8 * 0))"
    echo "#define TME_SPARC64_IREG_MG_G0	(${ireg_base} + ${ireg_next} + (8 * 1))"
    echo "#define TME_SPARC64_IREG_IG_G0	(${ireg_base} + ${ireg_next} + (8 * 2))"
    ireg_next=`expr ${ireg_next} + 24`

    # the current, next, and next-next program counter:
    #
    echo "#define TME_SPARC_IREG_PC		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`
    echo "#define TME_SPARC_IREG_PC_NEXT		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`
    echo "#define TME_SPARC_IREG_PC_NEXT_NEXT		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # the instruction register:
    #
    echo "#define TME_SPARC_IREG_INSN		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # some temporary registers:
    #
    echo "#define TME_SPARC_IREG_TMP(x)		(${ireg_base} + ${ireg_next} + (x))"
    ireg_next=`expr ${ireg_next} + 3`

    # the Y multiply/divide register:
    #
    echo "#define TME_SPARC_IREG_Y		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # the floating-point transfer registers.  since these are often
    # treated as 32-bit parts used to transfer 64- and 128-bit values,
    # this block of registers must be aligned to four.  NB that we
    # assume that ${ireg_base} is aligned to at least four:
    #
    while test `expr ${ireg_next} % 4` != 0; do ireg_next=`expr ${ireg_next} + 1`; done
    echo "#define TME_SPARC_IREG_FPX		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 4`
    
    # the sparc32 PSR, and the sparc64 PSTATE:
    #
    echo "#define TME_SPARC32_IREG_PSR		(${ireg_base} + ${ireg_next})"
    echo "#define tme_sparc32_ireg_psr		tme_sparc_ireg_uint32(TME_SPARC32_IREG_PSR)"
    echo "#define tme_sparc64_ireg_pstate	tme_sparc_ireg_uint32((${ireg_base} + ${ireg_next}) << 1)"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc32 WIM, and the common sparc64 register-window state registers:
    #
    echo "#define tme_sparc32_ireg_wim		tme_sparc_ireg_uint32(${ireg_base} + ${ireg_next})"
    echo "#define tme_sparc64_ireg_winstates	tme_sparc_ireg_uint32(((${ireg_base} + ${ireg_next}) << 1) + 0)"
    echo "#define TME_SPARC64_WINSTATES_CWP(x)		(((x) & 0x3f) << (8 * 0))"
    echo "#define tme_sparc64_ireg_cwp		tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 0)"
    echo "#define TME_SPARC64_WINSTATES_CANRESTORE(x)	(((x) & 0x3f) << (8 * 1))"
    echo "#define tme_sparc64_ireg_canrestore	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 1)"
    echo "#define TME_SPARC64_WINSTATES_CANSAVE(x)	(((x) & 0x3f) << (8 * 2))"
    echo "#define tme_sparc64_ireg_cansave	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 2)"
    echo "#define TME_SPARC64_WINSTATES_OTHERWIN(x)	(((x) & 0x3f) << (8 * 3))"
    echo "#define tme_sparc64_ireg_otherwin	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 3)"
    echo "#define tme_sparc64_ireg_winstates_mask tme_sparc_ireg_uint32(((${ireg_base} + ${ireg_next}) << 1) + 1)"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc32 TBR register, and the sparc64 TBA register:
    #
    echo "#define tme_sparc32_ireg_tbr		tme_sparc_ireg_uint32(${ireg_base} + ${ireg_next})"
    echo "#define tme_sparc64_ireg_tba		tme_sparc_ireg_uint64(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc64 trap PC, NPC, state, and type registers:
    #
    echo "#define tme_sparc64_ireg_tpc(tl)	tme_sparc_ireg_uint64(${ireg_base} + (TME_SPARC_TL_MAX * 0) + ${ireg_next} + ((tl) - 1))"
    echo "#define tme_sparc64_ireg_tnpc(tl)	tme_sparc_ireg_uint64(${ireg_base} + (TME_SPARC_TL_MAX * 1) + ${ireg_next} + ((tl) - 1))"
    echo "#define TME_SPARC64_IREG_TSTATE(tl)	(${ireg_base} + (TME_SPARC_TL_MAX * 2) + ${ireg_next} + ((tl) - 1))"
    echo "#define tme_sparc64_ireg_tstate(tl)	tme_sparc_ireg_uint64(TME_SPARC64_IREG_TSTATE(tl))"
    echo "#define tme_sparc64_ireg_tstate_ccr(tl) tme_sparc_ireg_uint8((TME_SPARC64_IREG_TSTATE(tl) << 3) + sizeof(tme_uint32_t))"
    echo "#if TME_SPARC_TL_MAX > 8"
    echo "#error \"TME_SPARC_TL_MAX changed\""
    echo "#endif"
    echo "#define tme_sparc64_ireg_tt(tl)	tme_sparc_ireg_uint8(((${ireg_base} + (TME_SPARC_TL_MAX * 3) + ${ireg_next}) << 3) + ((tl) - 1))"
    ireg_base="(${ireg_base} + (TME_SPARC_TL_MAX * 3) + 1)"

    # the sparc64 TL, PIL, ASI, FPRS, remaining register-window state registers, and TICK.NPT:
    #
    echo "#define tme_sparc64_ireg_tl		tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 0)"
    echo "#define tme_sparc64_ireg_pil		tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 1)"
    echo "#define tme_sparc64_ireg_asi		tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 2)"
    echo "#define tme_sparc64_ireg_fprs		tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 3)"
    echo "#define tme_sparc64_ireg_wstate	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 4)"
    echo "#define tme_sparc64_ireg_cleanwin	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 5)"
    echo "#define tme_sparc64_ireg_tick_npt	tme_sparc_ireg_uint8(((${ireg_base} + ${ireg_next}) << 3) + 6)"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc64 TICK (offset) register:
    #
    echo "#define tme_sparc64_ireg_tick_offset	tme_sparc_ireg_uint64(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc64 version register:
    #
    echo "#define tme_sparc64_ireg_ver		tme_sparc_ireg_uint64(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # the sparc64 CCR:
    # NB: this is a separate register for recode; can it maybe be combined
    # with the block of 8-bit registers above, as the first byte?
    #
    echo "#define TME_SPARC64_IREG_CCR		(${ireg_base} + ${ireg_next})"
    echo "#define tme_sparc64_ireg_ccr		tme_sparc_ireg_uint8(TME_SPARC64_IREG_CCR << 3)"
    ireg_next=`expr ${ireg_next} + 1`

    # our internal sparc64 RCC register:
    #
    echo "#define TME_SPARC64_IREG_RCC		(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`

    # our internal virtual address hole start:
    #
    echo "#define tme_sparc64_ireg_va_hole_start tme_sparc_ireg_uint64(${ireg_base} + ${ireg_next})"
    ireg_next=`expr ${ireg_next} + 1`
fi

# emit the integer condition codes->conditions mapping.  note that the
# nesting of the flag variables is deliberate, to make this array
# indexable with the condition codes value:
#
if $header; then :; else
    echo ""
    echo "/* the icc->conditions mapping: */"
    echo "const tme_uint8_t _tme_sparc_conds_icc[16] = {"
    for nflag in 0 1; do
	for zflag in 0 1; do
	    for vflag in 0 1; do
		for cflag in 0 1; do

		    # the Never condition:
		    #
		    echo -n "  0"
		    
		    # the Equal condition:
		    #
		    if test $zflag = 1; then
			echo -n "  | TME_BIT(1)"
		    fi
			
		    # the Less or Equal condition:
		    #
		    if test $zflag = 1 || test $nflag != $vflag; then
			echo -n "  | TME_BIT(2)"
		    fi

		    # the Less condition:
		    #
		    if test $nflag != $vflag; then
			echo -n "  | TME_BIT(3)"
		    fi

		    # the Less or Equal Unsigned condition:
		    #
		    if test $cflag = 1 || test $zflag = 1; then
			echo -n "  | TME_BIT(4)"
		    fi

		    # the Carry Set condition:
		    #
		    if test $cflag = 1; then
			echo -n "  | TME_BIT(5)"
		    fi

		    # the Negative condition:
		    #
		    if test $nflag = 1; then
			echo -n "  | TME_BIT(6)"
		    fi

		    # the Overflow Set condition:
		    #
		    if test $vflag = 1; then
			echo -n "  | TME_BIT(7)"
		    fi

		    echo ","
		done
	    done
	done
    done
    echo "};"
fi

# done:
#
exit 0

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.