Annotation of tme/ic/sparc/sparc-insns-auto.sh, revision 1.1

1.1     ! root        1: #! /bin/sh
        !             2: 
        !             3: # $Id: sparc-insns-auto.sh,v 1.5 2007/03/29 01:16:09 fredette Exp $
        !             4: 
        !             5: # ic/sparc/sparc-insns-auto.sh - automatically generates C code 
        !             6: # for many SPARC emulation instructions:
        !             7: 
        !             8: #
        !             9: # Copyright (c) 2005 Matt Fredette
        !            10: # All rights reserved.
        !            11: #
        !            12: # Redistribution and use in source and binary forms, with or without
        !            13: # modification, are permitted provided that the following conditions
        !            14: # are met:
        !            15: # 1. Redistributions of source code must retain the above copyright
        !            16: #    notice, this list of conditions and the following disclaimer.
        !            17: # 2. Redistributions in binary form must reproduce the above copyright
        !            18: #    notice, this list of conditions and the following disclaimer in the
        !            19: #    documentation and/or other materials provided with the distribution.
        !            20: # 3. All advertising materials mentioning features or use of this software
        !            21: #    must display the following acknowledgement:
        !            22: #      This product includes software developed by Matt Fredette.
        !            23: # 4. The name of the author may not be used to endorse or promote products
        !            24: #    derived from this software without specific prior written permission.
        !            25: #
        !            26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            29: # DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            36: # POSSIBILITY OF SUCH DAMAGE.
        !            37: #
        !            38: 
        !            39: header=false
        !            40: 
        !            41: for option
        !            42: do
        !            43:     case $option in
        !            44:     --header) header=true ;;
        !            45:     esac
        !            46: done
        !            47: 
        !            48: PROG=`basename $0`
        !            49: cat <<EOF
        !            50: /* automatically generated by $PROG, do not edit! */
        !            51: _TME_RCSID("\$Id: sparc-insns-auto.sh,v 1.5 2007/03/29 01:16:09 fredette Exp $");
        !            52: 
        !            53: EOF
        !            54: if $header; then :; else
        !            55:     cat <<EOF
        !            56: #include "sparc-impl.h"
        !            57: EOF
        !            58: fi
        !            59: 
        !            60: # permute over architecture:
        !            61: #
        !            62: for arch in 32; do
        !            63: 
        !            64:     # the sparc64 support depends on a 64-bit integer type:
        !            65:     #
        !            66:     if test ${arch} = 64; then
        !            67:        echo ""
        !            68:        echo "#ifdef TME_HAVE_INT64_T"
        !            69:     fi
        !            70: 
        !            71:     # get the name of the register with the integer condition codes, a
        !            72:     # shift value for 32-bit registers, and the architecture version:
        !            73:     #
        !            74:     if test ${arch} = 32; then 
        !            75:        ccr=32_PSR
        !            76:        ccr_ireg='tme_sparc32_ireg_psr'
        !            77:        reg32_shift=''
        !            78:        version=8
        !            79:     else
        !            80:        ccr=64_CCR
        !            81:        ccr_ireg='tme_sparc64_ireg_ccr'
        !            82:        reg32_shift=' << 1'
        !            83:        version=9
        !            84:     fi
        !            85: 
        !            86:     # fix the architecture version:
        !            87:     #
        !            88:     if $header; then :; else
        !            89:        echo ""
        !            90:        echo "#undef TME_SPARC_VERSION"
        !            91:        echo "#define TME_SPARC_VERSION(ic) (${version})"
        !            92:     fi
        !            93: 
        !            94:     # the alternate ASI function:
        !            95:     #
        !            96:     if $header; then :; else
        !            97:        echo "static tme_uint32_t"
        !            98:        echo "_tme_sparc${arch}_alternate_asi_mask(struct tme_sparc *ic)"
        !            99:        echo "{"
        !           100:        echo "  unsigned int asi_data;"
        !           101:        echo "  tme_uint32_t asi_mask_data;"
        !           102:        echo ""
        !           103:        echo "  /* get the ASI, assuming that the i bit is zero: */"
        !           104:        echo "  asi_data = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xff << 5));"
        !           105:        if test ${arch} = 32; then
        !           106:            echo ""
        !           107:            echo "  /* this is a privileged instruction: */"
        !           108:            echo "  TME_SPARC_INSN_PRIV;"
        !           109:            echo ""
        !           110:            echo "  /* if the i bit is one, this is an illegal instruction: */"
        !           111:            echo "  if (__tme_predict_false(TME_SPARC_INSN & TME_BIT(13))) {"
        !           112:            echo "    TME_SPARC_INSN_ILL;"
        !           113:            echo "  }"
        !           114:            echo ""
        !           115:            echo "  /* map the ASI into an ASI mask: */"
        !           116:            echo "  switch (asi_data) {"
        !           117:            echo "  case TME_SPARC32_ASI_UI: asi_mask_data = TME_SPARC32_ASI_MASK_UI; break;"
        !           118:            echo "  case TME_SPARC32_ASI_UD: asi_mask_data = TME_SPARC32_ASI_MASK_UD; break;"
        !           119:            echo "  case TME_SPARC32_ASI_SI: asi_mask_data = TME_SPARC32_ASI_MASK_SI; break;"
        !           120:            echo "  case TME_SPARC32_ASI_SD: asi_mask_data = TME_SPARC32_ASI_MASK_SD; break;"
        !           121:            echo "  default: asi_mask_data = TME_SPARC_ASI_MASK(asi_data); break;"
        !           122:            echo "  }"
        !           123:        else
        !           124:            echo ""
        !           125:            echo "  /* if the i bit is one, use the address space in the ASI register: */"
        !           126:            echo "  if (TME_SPARC_INSN & TME_BIT(13)) {"
        !           127:            echo "    asi_data = ic->tme_sparc_ireg_asi;"
        !           128:            echo "  }"
        !           129:            echo ""
        !           130:            echo "  /* start the ASI mask: */"
        !           131:            echo "  asi_mask_data = TME_SPARC_ASI_MASK(asi_data);"
        !           132:            
        !           133:            echo ""
        !           134:            echo "  /* if this is an unpriviledged access: */"
        !           135:            echo "  if (!TME_SPARC_PRIV(ic)) {"
        !           136:            echo ""
        !           137:            echo "    /* this is a priviledge violation if bit 7 of the ASI is zero: */"
        !           138:            echo "    if (asi_data < 0x80) {"
        !           139:            echo "      TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_privileged_instruction);"
        !           140:            echo "    }"
        !           141:            echo "  }"
        !           142:        fi
        !           143:        echo ""
        !           144:        echo "  return (asi_mask_data);"
        !           145:        echo "}"
        !           146:     fi
        !           147: 
        !           148:     # permute over instruction:
        !           149:     #
        !           150:     for insn in \
        !           151:        add \
        !           152:        addcc \
        !           153:        sub \
        !           154:        subcc \
        !           155:        or \
        !           156:        orcc \
        !           157:        orn \
        !           158:        orncc \
        !           159:        and \
        !           160:        andcc \
        !           161:        andn \
        !           162:        andncc \
        !           163:        xor \
        !           164:        xorcc \
        !           165:        xnor \
        !           166:        xnorcc \
        !           167:        addx \
        !           168:        addxcc \
        !           169:        subx \
        !           170:        subxcc \
        !           171:        taddcc taddcctv \
        !           172:        tsubcc tsubcctv \
        !           173:        umul umulcc smul smulcc \
        !           174:        udiv udivcc sdiv sdivcc \
        !           175:        sll \
        !           176:        srl \
        !           177:        sra \
        !           178:        ldb stb \
        !           179:        ldh sth \
        !           180:        ld st \
        !           181:        ldd std \
        !           182:        ldstub ldstuba swap swapa \
        !           183:        ldba stba \
        !           184:        ldha stha \
        !           185:        lda sta \
        !           186:        ldda stda \
        !           187:        jmpl \
        !           188:        ldf lddf ldfsr \
        !           189:        stf stdf stfsr \
        !           190:        mulscc \
        !           191:        ; do
        !           192: 
        !           193:        # if we're making the header, just emit declarations:
        !           194:        #
        !           195:        if $header; then
        !           196:            echo "TME_SPARC_FORMAT3_DECL(tme_sparc${arch}_${insn}, tme_uint${arch}_t);"
        !           197:            continue
        !           198:        fi
        !           199: 
        !           200:        # an ALU instruction:
        !           201:        #
        !           202:        case ${insn} in
        !           203:        add | sub | or | orn | and | andn | xor | xnor | \
        !           204:        addx | subx | umul | smul | udiv | sdiv)
        !           205:            cc=false
        !           206:            ;;
        !           207:        addcc | subcc | orcc | orncc | andcc | andncc | xorcc | xnorcc | \
        !           208:        addxcc | subxcc | umulcc | smulcc | udivcc | sdivcc | \
        !           209:        taddcc | tsubcc | taddcctv | tsubcctv | \
        !           210:        mulscc)
        !           211:            cc=true
        !           212:            ;;
        !           213:        *)
        !           214:            cc=
        !           215:            ;;
        !           216:        esac
        !           217:        if test "x${cc}" != x; then
        !           218: 
        !           219:            # characterize each function:
        !           220:            #
        !           221:            sign=u ; size_src=${arch} ; size_dst=${arch} ; arith=logical ; with_c= ; tagged=
        !           222:            case "${insn}" in
        !           223:            add  | addcc)   op='src1 + src2' ; arith=add ;;
        !           224:            sub  | subcc)   op='src1 - src2' ; arith=sub ;;
        !           225:            or   | orcc)    op='src1 | src2' ;;
        !           226:            orn  | orncc)   op='src1 | ~src2' ;;
        !           227:            and  | andcc)   op='src1 & src2' ;;
        !           228:            andn | andncc)  op='src1 & ~src2' ;;
        !           229:            xor  | xorcc)   op='src1 ^ src2' ;;
        !           230:            xnor | xnorcc)  op='src1 ^ ~src2' ;;
        !           231:            addx | addxcc)  op='src1 + src2' ; arith=add ; with_c=+ ;;
        !           232:            subx | subxcc)  op='src1 - src2' ; arith=sub ; with_c=- ;;
        !           233:            taddcc)         op='src1 + src2' ; arith=add ; tagged=x ;;
        !           234:            taddcctv)       op='src1 + src2' ; arith=add ; tagged=tv ;;
        !           235:            tsubcc)         op='src1 - src2' ; arith=sub ; tagged=x ;;
        !           236:            tsubcctv)       op='src1 - src2' ; arith=sub ; tagged=tv ;;
        !           237:            umul | umulcc)  arith=mul ; size_src=32 ;;
        !           238:            smul | smulcc)  arith=mul ; size_src=32 ; sign= ;;
        !           239:            udiv | udivcc)  arith=udiv ; size_src=32 ; size_dst=32 ;;
        !           240:            sdiv | sdivcc)  arith=sdiv ; size_src=32 ; size_dst=32 ; sign= ;;
        !           241:            mulscc)         arith=add ; size_src=32 ; size_dst=32 ;;
        !           242:            *) echo "$0 internal error: unknown ALU function ${insn}" 1>&2 ; exit 1 ;;
        !           243:            esac
        !           244: 
        !           245:            # open the function:
        !           246:            #
        !           247:            echo ""
        !           248:            echo "/* this does a sparc${arch} \"${insn} SRC1, SRC2, DST\": */"
        !           249:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           250:            echo "{"
        !           251: 
        !           252:            # declare our locals:
        !           253:            #
        !           254:            echo "  tme_${sign}int${size_src}_t src1;"
        !           255:            echo "  tme_${sign}int${size_src}_t src2;"
        !           256:            echo "  tme_${sign}int${size_dst}_t dst;"
        !           257:            case "${insn}" in
        !           258:            umul* | smul* | udiv* | sdiv*)
        !           259:                echo "  tme_${sign}int64_t val64;"
        !           260:                ;;
        !           261:            mulscc)
        !           262:                echo "  tme_uint32_t y;"
        !           263:                ;;
        !           264:            esac
        !           265:            if ${cc}; then
        !           266:                echo "  tme_uint32_t cc;"
        !           267:            fi
        !           268: 
        !           269:            echo ""
        !           270:            echo "  /* get the operands: */"
        !           271:            echo "  src1 = (tme_${sign}int${arch}_t) TME_SPARC_FORMAT3_RS1;"
        !           272:            echo "  src2 = (tme_${sign}int${arch}_t) TME_SPARC_FORMAT3_RS2;"
        !           273: 
        !           274:            echo ""
        !           275:            echo "  /* perform the operation: */"
        !           276:            case "${insn}" in
        !           277:            umul | umulcc | smul | smulcc)
        !           278:                echo "  val64 = (((tme_${sign}int64_t) src1) * src2);"
        !           279:                echo "  ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift}) = (((tme_uint64_t) val64) >> 32);"
        !           280:                echo "  dst = ((tme_${sign}int64_t) val64);"
        !           281:                ;;
        !           282:            udiv | udivcc | sdiv | sdivcc)
        !           283:                echo "  val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift})) << 32) | ((tme_uint32_t) src1));"
        !           284:                echo "  val64 /= src2;"
        !           285:                echo "  /* XXX FIXME - overflow handling is missing here: */"
        !           286:                echo "  dst = val64;"
        !           287:                ;;
        !           288:            mulscc)
        !           289:                echo ""
        !           290:                echo "  /* \"(1) The multiplier is established as r[rs2] if the i field is zero, or "
        !           291:                echo "     sign_ext(simm13) if the i field is one.\""
        !           292:                echo ""
        !           293:                echo "     \"(3) If the least significant bit of the Y register = 1, the shifted"
        !           294:                echo "     value from step (2) is added to the multiplier. If the LSB of the"
        !           295:                echo "     Y register = 0, then 0 is added to the shifted value from step (2).\" */"
        !           296:                echo "  y = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift});"
        !           297:                echo "  if ((y & 1) == 0) {"
        !           298:                echo "    src2 = 0;"
        !           299:                echo "  }"
        !           300:                echo ""
        !           301:                echo "  /* \"(6) The Y register is shifted right by one bit, with the LSB of the"
        !           302:                echo "     unshifted r[rs1] replacing the MSB of Y.\" */"
        !           303:                echo "  y >>= 1;"
        !           304:                echo "  if (src1 & 1) {"
        !           305:                echo "    y += 0x80000000;"
        !           306:                echo "  }"
        !           307:                echo "  ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift}) = y;"
        !           308:                echo ""
        !           309:                echo "  /* \"(2) A 32-bit value is computed by shifting r[rs1] right by one"
        !           310:                echo "     bit with (N xor V) from the PSR replacing the high-order bit."
        !           311:                echo "     (This is the proper sign for the previous partial product.)\" */"
        !           312:                echo "  src1 >>= 1;"
        !           313:                echo "  if (((ic->${ccr_ireg} ^ (ic->${ccr_ireg} * (TME_SPARC${ccr}_ICC_N / TME_SPARC${ccr}_ICC_V))) & TME_SPARC${ccr}_ICC_N) != 0) {"
        !           314:                echo "    src1 += 0x80000000;"
        !           315:                echo "  }"
        !           316:                echo ""
        !           317:                echo "  /* \"(4) The sum from step (3) is written into r[rd].\" */"
        !           318:                echo "  dst = src1 + src2;"
        !           319:                echo ""
        !           320:                echo "  /* \"(5) The integer condition codes, icc, are updated according to the"
        !           321:                echo "     addition performed in step (3).\" */"
        !           322:                ;;
        !           323:            *)
        !           324:                echo "  dst = ${op};"
        !           325:                if test "x${with_c}" != x; then
        !           326:                    echo "  dst ${with_c}= ((ic->${ccr_ireg} & TME_SPARC${ccr}_ICC_C) != 0);"
        !           327:                fi
        !           328:            esac
        !           329: 
        !           330:            # unless this is a tagged-and-trap-on-overflow operation:
        !           331:            #
        !           332:            if test "x${tagged}" != xtv; then
        !           333:                echo ""
        !           334:                echo "  /* store the destination: */"
        !           335:                echo "  TME_SPARC_FORMAT3_RD = (tme_${sign}int${arch}_t) dst;"
        !           336:            fi
        !           337: 
        !           338:            # if this instruction modifies the condition codes:
        !           339:            #
        !           340:            if ${cc}; then
        !           341: 
        !           342:                echo ""
        !           343:                echo "  /* set Z if the destination is zero: */"
        !           344:                echo -n "  cc = ((dst == 0) * (TME_SPARC${ccr}_ICC_Z"
        !           345:                if test ${arch} = 64; then
        !           346:                    echo -n " + TME_SPARC${ccr}_XCC_Z"
        !           347:                fi
        !           348:                echo "));"
        !           349: 
        !           350:                # set the 32-bit, and possibly the 64-bit, condition codes:
        !           351:                #
        !           352:                arch_cc=16
        !           353:                while test `expr ${arch_cc} \< ${arch}` = 1; do
        !           354:                    arch_cc=`expr ${arch_cc} \* 2`
        !           355: 
        !           356:                    case ${arch_cc} in
        !           357:                    32) xcc=ICC ;;
        !           358:                    64) xcc=XCC ;;
        !           359:                    esac
        !           360: 
        !           361:                    if test `expr ${arch_cc} \<= ${size_dst}` = 1 || test "x${sign}" = xs; then
        !           362:                        echo ""
        !           363:                        echo "  /* set N if the destination is negative: */"
        !           364:                        echo "  cc += ((((tme_int${arch_cc}_t) dst) < 0) * TME_SPARC${ccr}_${xcc}_N);"
        !           365:                    fi
        !           366: 
        !           367:                    case $arith in
        !           368:                    add)
        !           369:                        ones="(((tme_${sign}int${arch_cc}_t) 0) - 1)"
        !           370: 
        !           371:                        echo ""
        !           372:                        echo "  /* if the operands are the same sign, and the destination has"
        !           373:                        echo "     a different sign, set V: */"
        !           374:                        echo "  cc += ((((tme_int${arch_cc}_t) ((src2 ^ dst) & (src1 ^ (src2 ^ ${ones})))) < 0) * TME_SPARC${ccr}_${xcc}_V);"
        !           375: 
        !           376:                        echo ""
        !           377:                        echo "  /* if src1 and src2 both have the high bit set, or if dst does"
        !           378:                        echo "     not have the high bit set and either src1 or src2 does, set C: */"
        !           379:                        echo "  cc += (((tme_int${arch_cc}_t) (((tme_uint${arch_cc}_t) (src1 & src2)) | ((((tme_uint${arch_cc}_t) dst) ^ ${ones}) & ((tme_uint${arch_cc}_t) (src1 | src2))))) < 0) * TME_SPARC${ccr}_${xcc}_C;"
        !           380:                        ;;
        !           381:                    sub) 
        !           382: 
        !           383:                        echo ""
        !           384:                        echo "  /* if the operands are different signs, and the destination has"
        !           385:                        echo "     a different sign from the first operand, set V: */"
        !           386:                        echo "  cc += ((((tme_int${arch_cc}_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC${ccr}_${xcc}_V);"
        !           387: 
        !           388:                        echo ""
        !           389:                        echo "  /* if src2 is greater than src1, set C: */"
        !           390:                        echo -n "  cc += ((((tme_uint${arch_cc}_t) src2) > ((tme_uint${arch_cc}_t) src1))"
        !           391:                        if test "x${with_c}" != x; then
        !           392:                            echo -n " || (((tme_uint${arch_cc}_t) src2) == ((tme_uint${arch_cc}_t) src1) && (ic->${ccr_ireg} & TME_SPARC${ccr}_ICC_C))"
        !           393:                        fi
        !           394:                        echo ") * TME_SPARC${ccr}_${xcc}_C;"
        !           395:                        ;;
        !           396:                    logical | mul)
        !           397:                        ;;
        !           398:                    udiv)
        !           399:                        ;;
        !           400:                    sdiv)
        !           401:                        ;;
        !           402:                    *) echo "$0 internal error: unknown arithmetic type ${arith}" 1>&2 ; exit 1 ;;
        !           403:                    esac
        !           404:                done
        !           405:                
        !           406:                # if this is a tagged operation:
        !           407:                #
        !           408:                if test "x${tagged}" != x; then
        !           409: 
        !           410:                    echo ""
        !           411:                    echo "  /* set V if bits zero or one of src1 or src2 are set: */"
        !           412:                    echo "  cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC${ccr}_ICC_V);"
        !           413: 
        !           414:                    # if this is a tagged-and-trap-on-overflow operation:
        !           415:                    #
        !           416:                    if test "x${tagged}" = xtv; then
        !           417: 
        !           418:                        echo ""
        !           419:                        echo "  /* trap on a tagged overflow: */"
        !           420:                        echo "  if (cc & TME_SPARC${ccr}_ICC_V) {"
        !           421:                        echo "    tme_sparc${arch}_trap(ic, TME_SPARC_TRAP_tag_overflow);"
        !           422:                        echo "  }"
        !           423: 
        !           424:                        echo "  /* store the destination: */"
        !           425:                        echo "  TME_SPARC_FORMAT3_RD = (tme_${sign}int${arch}_t) dst;"
        !           426:                    fi
        !           427:                fi
        !           428: 
        !           429:                echo ""
        !           430:                echo "  /* set the condition codes: */"
        !           431:                echo -n "  ic->${ccr_ireg} = "
        !           432:                if test ${arch} = 32; then
        !           433:                    echo -n "(ic->${ccr_ireg} & ~TME_SPARC32_PSR_ICC) | "
        !           434:                fi
        !           435:                echo "cc;"
        !           436:            fi
        !           437: 
        !           438:            echo ""
        !           439:            echo "  TME_SPARC_INSN_OK;"
        !           440:            echo "}"
        !           441:        fi
        !           442: 
        !           443:        # a shift instruction:
        !           444:        #
        !           445:        case ${insn} in
        !           446:        sll | srl | sra)
        !           447: 
        !           448:            # get the sign of this shift:
        !           449:            #
        !           450:            if test ${insn} = sra; then sign= ; else sign=u; fi
        !           451: 
        !           452:            echo ""
        !           453:            echo "/* the sparc${arch} ${insn} function: */"
        !           454:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           455:            echo "{"
        !           456:            echo "  tme_${sign}int${arch}_t dst;"
        !           457:            echo "  unsigned int count;"
        !           458:            echo ""
        !           459:            echo "  /* get the value and the shift count: */"
        !           460:            echo "  dst = TME_SPARC_FORMAT3_RS1;"
        !           461:            echo "  count = TME_SPARC_FORMAT3_RS2;"
        !           462: 
        !           463:            # if we're on sparc64:
        !           464:            #
        !           465:            if test ${arch} = 64; then
        !           466: 
        !           467:                echo ""
        !           468:                echo "  /* if the X bit is clear: */"
        !           469:                echo "  if ((TME_SPARC_INSN & TME_BIT(12)) == 0) {"
        !           470:                echo ""
        !           471:                echo "    /* limit the count: */"
        !           472:                echo "    count %= 32;"
        !           473:                if test ${insn} != sll; then
        !           474:                    echo ""
        !           475:                    echo "  /* clip the value to 32 bits: */"
        !           476:                    echo "  dst = (tme_${sign}int32_t) dst;"
        !           477:                fi
        !           478:                echo "  }"
        !           479:            fi
        !           480: 
        !           481:            echo ""
        !           482:            echo "  /* limit the count: */"
        !           483:            echo "  count %= ${arch};"
        !           484:            echo ""
        !           485:            echo "  /* do the shift: */"
        !           486:            if test "${insn}" = sra; then
        !           487:                echo "#ifdef SHIFTSIGNED_INT${arch}_T"
        !           488:            fi
        !           489:            echo "#if (SHIFTMAX_INT${arch}_T < (${arch} - 1))"
        !           490:            echo "#error \"cannot do full shifts of a tme_int${arch}_t\""
        !           491:            echo "#endif /* (SHIFTMAX_INT${arch}_T < (${arch} - 1)) */"
        !           492:            if test ${insn} = sll; then
        !           493:                echo "  dst <<= count;"
        !           494:            else
        !           495:                echo "  dst >>= count;"
        !           496:            fi
        !           497:            if test "${insn}" = sra; then
        !           498:                echo "#else  /* !SHIFTSIGNED_INT${arch}_T */"
        !           499:                echo "  for (; count-- > 0; ) {"
        !           500:                echo "    dst = (dst & ~((tme_${sign}int${arch}_t) 1)) / 2;"
        !           501:                echo "  }"
        !           502:                echo "#endif /* !SHIFTSIGNED_INT${arch}_T */"
        !           503:            fi
        !           504:            
        !           505:            echo ""
        !           506:            echo "  /* store the destination: */"
        !           507:            echo "  TME_SPARC_FORMAT3_RD = dst;"
        !           508:            echo ""
        !           509:            echo "  TME_SPARC_INSN_OK;"
        !           510:            echo "}"
        !           511:            ;;
        !           512:        esac
        !           513: 
        !           514:        # a load or store instruction:
        !           515:        #
        !           516:        size=
        !           517:        case "${insn}" in
        !           518:        ldb | stb | ldstub | ldba | stba | ldstuba) size=8 ;;
        !           519:        ldh | sth | ldha | stha) size=16 ;;
        !           520:        ld | st | swap | lda | sta | swapa) size=32 ;;
        !           521:        ldd | std | ldda | stda) size=32 ;;
        !           522:        esac
        !           523:        if test "x${size}" != x; then
        !           524: 
        !           525:            # set the alternate space indication:
        !           526:            #
        !           527:            case "${insn}" in
        !           528:            *a) alternate=true ;;
        !           529:            *) alternate=false ;;
        !           530:            esac
        !           531: 
        !           532:            # set the atomic and double indications:
        !           533:            #
        !           534:            atomic=false
        !           535:            double=false
        !           536:            case "${insn}" in
        !           537:            ldstub | ldstuba | swap | swapa) atomic=true ;;
        !           538:            ldd* | std*) double=true ; size=64 ;;
        !           539:            esac
        !           540: 
        !           541:            # if this is only a load, we are reading, otherwise we are writing:
        !           542:            #
        !           543:            cycle=write
        !           544:            capcycle=WRITE
        !           545:            slow=store
        !           546:            case "${insn}" in
        !           547:            ldstub*) ;;
        !           548:            ld*) 
        !           549:                cycle=read
        !           550:                capcycle=READ
        !           551:                slow=load
        !           552:                ;;
        !           553:            esac
        !           554: 
        !           555:            # start the instruction:
        !           556:            #
        !           557:            echo ""
        !           558:            echo "/* this does a sparc${arch} ${insn}: */"
        !           559:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           560:            echo "{"
        !           561: 
        !           562:            # our locals:
        !           563:            #
        !           564:            if ${alternate}; then
        !           565:                echo "  tme_uint32_t asi_mask_data;"
        !           566:                asi_mask_data=asi_mask_data
        !           567:            else
        !           568:                asi_mask_data="ic->tme_sparc_asi_mask_data"
        !           569:            fi
        !           570:            echo "  tme_uint${arch}_t address;"
        !           571:            echo "  struct tme_sparc_tlb *dtlb;"
        !           572:            echo -n "  "
        !           573:            if test ${slow} = load; then echo -n "const "; fi
        !           574:            echo "tme_shared tme_uint8_t *memory;"
        !           575:            echo "  tme_uint${arch}_t value;"
        !           576: 
        !           577:            if ${alternate}; then
        !           578:                echo ""
        !           579:                echo "  /* get the alternate ASI mask: */"
        !           580:                echo "  asi_mask_data = _tme_sparc${arch}_alternate_asi_mask(ic);"
        !           581:            fi
        !           582: 
        !           583:            echo ""
        !           584:            echo "  /* get the address: */"
        !           585:            echo "  address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;"
        !           586:                
        !           587:            echo ""
        !           588:            echo "#ifdef _TME_SPARC_STATS"
        !           589:            echo "  /* track statistics: */"
        !           590:            echo "  ic->tme_sparc_stats.tme_sparc_stats_memory_total++;"
        !           591:            echo "#endif /* _TME_SPARC_STATS */"
        !           592: 
        !           593:            # if this is some kind of a store, except for an ldstub:
        !           594:            #
        !           595:            case "${insn}" in
        !           596:            std*)
        !           597:                echo ""
        !           598:                echo "  /* log the values stored: */"
        !           599:                # XXX FIXME - we can't verify a std yet:
        !           600:                #
        !           601:                echo "  tme_sparc_log(ic, 1000, TME_OK, "
        !           602:                echo "               (TME_SPARC_LOG_HANDLE(ic),"
        !           603:                echo "                _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"x:\t0x%08x 0x%08x\"),"
        !           604:                echo "                TME_SPARC_ASI_MASK_WHICH(${asi_mask_data}),"
        !           605:                echo "                address,"
        !           606:                echo "                (tme_uint32_t) TME_SPARC_FORMAT3_RD,"
        !           607:                echo "                (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));"
        !           608:                ;;
        !           609:            st* | swap*)
        !           610:                echo ""
        !           611:                echo "  /* log the value stored: */"
        !           612:                echo "  tme_sparc_verify_mem${size}(ic, ${asi_mask_data}, address, (tme_uint${size}_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);"
        !           613:                echo "  tme_sparc_log(ic, 1000, TME_OK, "
        !           614:                echo "               (TME_SPARC_LOG_HANDLE(ic),"
        !           615:                echo "                _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"x:\t0x%0"`expr ${size} / 4`"x\"),"
        !           616:                echo "                TME_SPARC_ASI_MASK_WHICH(${asi_mask_data}),"
        !           617:                echo "                address,"
        !           618:                echo "                (tme_uint${size}_t) TME_SPARC_FORMAT3_RD));"
        !           619:                ;;
        !           620:            esac
        !           621: 
        !           622:            echo ""
        !           623:            echo "  /* get and busy the DTLB entry: */"
        !           624:            echo "  dtlb = TME_SPARC_DTLB_ENTRY(ic, address);"
        !           625:            echo "  tme_sparc_tlb_busy(dtlb);"
        !           626: 
        !           627:            echo ""
        !           628:            echo "  /* assume that this DTLB applies and allows fast transfers: */"
        !           629:            echo "  memory = dtlb->tme_sparc_tlb_emulator_off_${cycle};"
        !           630: 
        !           631:            echo ""
        !           632:            echo "  /* we must call the slow ${slow} function if: */"
        !           633:            echo "  if (__tme_predict_false("
        !           634:            echo ""
        !           635:            echo "                          /* the DTLB entry is invalid: */"
        !           636:            echo "                          tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)"
        !           637:            echo ""
        !           638:            echo "                          /* the DTLB entry does not cover the needed addresses: */"
        !           639:            echo "                          || (dtlb->tme_sparc_tlb_addr_first > address)"
        !           640:            echo "                          || (dtlb->tme_sparc_tlb_addr_last < (address + ((${size} / 8) - 1)))"
        !           641:            echo ""
        !           642:            echo "                          /* the DTLB entry does not cover the needed address space: */"
        !           643:            echo "                          || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ${asi_mask_data}))"
        !           644:            echo ""
        !           645:            echo "                          /* the DTLB entry does not allow fast transfers: */"
        !           646:            if $atomic; then
        !           647:                echo "                          || (memory != dtlb->tme_sparc_tlb_emulator_off_read)"
        !           648:            fi
        !           649:            echo "                          || (memory == TME_EMULATOR_OFF_UNDEF)"
        !           650:            if test ${size} != 8; then
        !           651:                echo ""
        !           652:                echo "                          /* the address is misaligned: */"
        !           653:                echo "                          || ((address % (${size} / 8)) != 0)"
        !           654:            fi
        !           655:            if ${double}; then
        !           656:                echo ""
        !           657:                echo "                          /* the destination register number is odd: */"
        !           658:                echo "                          || ((TME_SPARC_INSN & TME_BIT(25)) != 0)"
        !           659:            fi
        !           660:            echo ""
        !           661:            echo "                          )) {"
        !           662: 
        !           663:            echo ""
        !           664:            echo "    /* call the slow ${slow} function: */"
        !           665:            echo "    memory = tme_sparc${arch}_${slow}(ic,"
        !           666:            echo "                               address,"
        !           667:            if test ${slow} = store; then
        !           668:                echo "                               &TME_SPARC_FORMAT3_RD,"
        !           669:            fi
        !           670:            echo -n "                               ("
        !           671:            if ${atomic}; then
        !           672:                echo "TME_SPARC_SLOW_FLAG_ATOMIC"
        !           673:                echo -n "                                | "
        !           674:            fi
        !           675:            if ${alternate}; then
        !           676:                echo "TME_SPARC_SLOW_FLAG_A"
        !           677:                echo -n "                                | "
        !           678:            fi
        !           679:            echo "(${size} / 8)));"
        !           680:            
        !           681:            if test ${slow} = store; then
        !           682:                echo ""
        !           683:                echo "    /* if the slow ${slow} function did the transfer, return now: */"
        !           684:                echo "    if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {"
        !           685:                echo "      tme_sparc_tlb_unbusy(dtlb);"
        !           686:                echo "      TME_SPARC_INSN_OK;"
        !           687:                echo "    }"
        !           688:            fi
        !           689:            echo "  }"
        !           690: 
        !           691:            echo ""
        !           692:            echo "  /* do the fast transfer: */"
        !           693:            echo "  memory += address;"
        !           694: 
        !           695:            # dispatch on the instruction:
        !           696:            #
        !           697:            case "${insn}" in
        !           698:            ldd*)
        !           699:                if test ${arch} = 32; then
        !           700:                    echo "  value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint${arch}_t));"
        !           701:                    echo "  TME_SPARC_FORMAT3_RD = tme_betoh_u32(value);"
        !           702:                    echo "  value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint${arch}_t));"
        !           703:                    echo "  TME_SPARC_FORMAT3_RD_ODD = tme_betoh_u32(value);"
        !           704:                else
        !           705:                    echo "$PROG fatal: need ${insn} support for sparc${arch}" 1>&2
        !           706:                    exit 1
        !           707:                fi
        !           708:                ;;
        !           709:            std*)
        !           710:                if test ${arch} = 32; then
        !           711:                    echo "  value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);"
        !           712:                    echo "  tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint${arch}_t));"
        !           713:                    echo "  value = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD);"
        !           714:                    echo "  tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint${arch}_t));"
        !           715:                else
        !           716:                    echo "$PROG fatal: need ${insn} support for sparc${arch}" 1>&2
        !           717:                    exit 1
        !           718:                fi
        !           719:                ;;
        !           720:            ldstub*)
        !           721:                echo "  value = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));"
        !           722:                ;;
        !           723:            swap*)
        !           724:                echo "  value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);"
        !           725:                echo "  value = tme_memory_atomic_xchg32((tme_shared tme_uint${size}_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));"
        !           726:                ;;
        !           727:            ld*)
        !           728:                echo "  value = tme_memory_bus_read${size}((const tme_shared tme_uint${size}_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint${size}_t), sizeof(tme_uint${arch}_t));"
        !           729:                if test ${size} != 8; then
        !           730:                    echo "  value = tme_betoh_u${size}(value);"
        !           731:                fi
        !           732:                ;;
        !           733:            st*)
        !           734:                if test ${size} = 8; then swap_st= ; else swap_st="tme_htobe_u${size}"; fi
        !           735:                echo "  value = ${swap_st}(TME_SPARC_FORMAT3_RD);"
        !           736:                echo "  tme_memory_bus_write${size}((tme_shared tme_uint${size}_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint${size}_t), sizeof(tme_uint${arch}_t));"
        !           737:                ;;
        !           738:            *) echo "$PROG internal error: unknown memory insn ${insn}" 1>&2 ; exit 1 ;;
        !           739:            esac
        !           740: 
        !           741:            echo ""
        !           742:            echo "  /* unbusy the DTLB entry: */"
        !           743:            echo "  tme_sparc_tlb_unbusy(dtlb);"
        !           744: 
        !           745:            case "${insn}" in
        !           746:            ldd*) ;;
        !           747:            ld* | swap*)
        !           748:                if test `expr ${size} \< ${arch}` = 1; then
        !           749:                    echo ""
        !           750:                    echo "  /* possibly sign-extend the loaded value: */"
        !           751:                    echo "  if (TME_SPARC_INSN & TME_BIT(22)) {"
        !           752:                    echo "    value = (tme_uint${arch}_t) (tme_int${arch}_t) (tme_int${size}_t) value;"
        !           753:                    echo "  }"
        !           754:                fi
        !           755:                echo ""
        !           756:                echo "  /* set the loaded value: */"
        !           757:                echo "  TME_SPARC_FORMAT3_RD = value;"
        !           758:                ;;
        !           759:            esac
        !           760:                
        !           761:            # if this is some kind of a load, log the value loaded:
        !           762:            #
        !           763:            case ${insn} in
        !           764:            ldd*)
        !           765:                echo ""
        !           766:                echo "  /* log the value loaded: */"
        !           767:                # XXX FIXME - we can't verify a ldd yet:
        !           768:                #
        !           769:                echo "  tme_sparc_log(ic, 1000, TME_OK,"
        !           770:                echo "               (TME_SPARC_LOG_HANDLE(ic),"
        !           771:                echo "                _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"x:\t0x%08x 0x%08x\"),"
        !           772:                echo "                TME_SPARC_ASI_MASK_WHICH(${asi_mask_data}),"
        !           773:                echo "                address,"
        !           774:                echo "                (tme_uint32_t) TME_SPARC_FORMAT3_RD,"
        !           775:                echo "                (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));"
        !           776:                ;;
        !           777:            ld* | ldstub* | swap*)
        !           778:                echo ""
        !           779:                echo "  /* log the value loaded: */"
        !           780:                echo "  tme_sparc_verify_mem${size}(ic, ${asi_mask_data}, address, (tme_uint${size}_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);"
        !           781:                echo "  tme_sparc_log(ic, 1000, TME_OK,"
        !           782:                echo "               (TME_SPARC_LOG_HANDLE(ic),"
        !           783:                echo "                _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"x:\t0x%0"`expr ${arch} / 4`"x\"),"
        !           784:                echo "                TME_SPARC_ASI_MASK_WHICH(${asi_mask_data}),"
        !           785:                echo "                address,"
        !           786:                echo "                TME_SPARC_FORMAT3_RD));"
        !           787:                ;;
        !           788:            esac
        !           789: 
        !           790:            echo ""
        !           791:            echo "  TME_SPARC_INSN_OK;"
        !           792:            echo "}"
        !           793:        fi
        !           794: 
        !           795:        # the jmpl instruction:
        !           796:        #
        !           797:        if test ${insn} = jmpl; then
        !           798: 
        !           799:            echo ""
        !           800:            echo "/* this does a sparc${arch} ${insn}: */"
        !           801:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           802:            echo "{"
        !           803:            echo "  tme_uint${arch}_t pc_next_next;"
        !           804:            echo ""
        !           805:            echo "  /* \"The JMPL instruction causes a register-indirect delayed control"
        !           806:            echo "     transfer to the address given by r[rs1] + r[rs2] if the i field is"
        !           807:            echo "     zero, or r[rs1] + sign_ext(simm13) if the i field is one. The JMPL"
        !           808:            echo "     instruction copies the PC, which contains the address of the JMPL"
        !           809:            echo "     instruction, into register r[rd]. If either of the low-order two"
        !           810:            echo "     bits of the jump address is nonzero, a mem_address_not_aligned"
        !           811:            echo "     trap occurs.\" */"
        !           812:            echo ""
        !           813:            echo "  pc_next_next = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;"
        !           814:            echo "  if (__tme_predict_false((pc_next_next % sizeof(tme_uint32_t)) != 0)) {"
        !           815:            echo "    TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_mem_address_not_aligned);"
        !           816:            echo "  }"
        !           817:            echo ""
        !           818:            echo "  /* write the PC of the jmpl into r[rd]: */"
        !           819:            echo "  TME_SPARC_FORMAT3_RD = ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_PC);"
        !           820:            echo ""
        !           821:            echo "  /* log an indirect call instruction, which has 15 (%o7) for rd: */"
        !           822:            echo "  if (TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD) == 15) {"
        !           823:            echo "    tme_sparc_log(ic, 250, TME_OK,"
        !           824:            echo "                  (TME_SPARC_LOG_HANDLE(ic),"
        !           825:            echo "                   _(\"call 0x%08x\"),"
        !           826:            echo "                   pc_next_next));"
        !           827:            echo "  }"
        !           828:            echo ""
        !           829:            echo "  /* log a ret or retl instruction, which has 0 (%g0) for rd,"
        !           830:            echo "     either 31 (%i7) or 15 (%o7) for rs1, and 8 for simm13: */"
        !           831:            echo "  else if ((TME_SPARC_INSN | (16 << 14))"
        !           832:            echo "           == ((tme_uint32_t) (0x2 << 30) | (0 << 25) | (0x38 << 19) | (31 << 14) | (0x1 << 13) | 8)) {"
        !           833:            echo "    tme_sparc_log(ic, 250, TME_OK,"
        !           834:            echo "                  (TME_SPARC_LOG_HANDLE(ic),"
        !           835:            echo "                   _(\"retl 0x%08x\"),"
        !           836:            echo "                   pc_next_next));"
        !           837:            echo "  }"
        !           838:            echo ""
        !           839:            echo "  /* set the delayed control transfer: */"
        !           840:            echo "  ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_PC_NEXT_NEXT) = pc_next_next;"
        !           841:            echo ""
        !           842:            echo "  TME_SPARC_INSN_OK;"
        !           843:            echo "}"
        !           844:        fi
        !           845: 
        !           846:        # the ldf instruction:
        !           847:        #
        !           848:        if test ${insn} = ldf; then
        !           849: 
        !           850:            echo ""
        !           851:            echo "/* this does a sparc${arch} ${insn}: */"
        !           852:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           853:            echo "{"
        !           854:            echo "  unsigned int fpreg_number;"
        !           855:            echo ""
        !           856:            echo "  TME_SPARC_INSN_FPU;"
        !           857:            echo ""
        !           858:            echo "  /* decode rd: */"
        !           859:            echo "  fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
        !           860:            echo ""
        !           861:            echo "  /* make sure this floating-point register is single-precision: */"
        !           862:            echo "  tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);"
        !           863:            echo ""
        !           864:            echo "  /* do the load: */"
        !           865:            echo "  tme_sparc${arch}_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !           866:            echo ""
        !           867:            echo "  /* set the floating-point register value: */"
        !           868:            echo "  ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;"
        !           869:            echo "  ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_single"
        !           870:            echo "    = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift});"
        !           871:            echo ""
        !           872:            echo "  TME_SPARC_INSN_OK;"
        !           873:            echo "}"
        !           874:        fi
        !           875: 
        !           876:        # the stf instruction:
        !           877:        #
        !           878:        if test ${insn} = stf; then
        !           879: 
        !           880:            echo ""
        !           881:            echo "/* this does a sparc${arch} ${insn}: */"
        !           882:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           883:            echo "{"
        !           884:            echo "  unsigned int fpreg_number;"
        !           885:            echo "  const tme_uint32_t *value_single;"
        !           886:            echo "  tme_uint32_t value_single_buffer;"
        !           887:            echo ""
        !           888:            echo "  TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t));"
        !           889:            echo ""
        !           890:            echo "  /* decode rd: */"
        !           891:            echo "  fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
        !           892:            echo ""
        !           893:            echo "  /* make sure this floating-point register is single-precision: */"
        !           894:            echo "  tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);"
        !           895:            echo ""
        !           896:            echo "  /* get this single floating-point register in IEEE754 single-precision format: */"
        !           897:            echo "  value_single = tme_ieee754_single_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_single_buffer);"
        !           898:            echo ""
        !           899:            echo "  /* set the floating-point register value: */"
        !           900:            echo "  ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}) = *value_single;"
        !           901:            echo ""
        !           902:            echo "  /* do the store: */"
        !           903:            echo "  tme_sparc${arch}_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !           904:            echo ""
        !           905:            echo "  TME_SPARC_INSN_OK;"
        !           906:            echo "}"
        !           907:        fi
        !           908: 
        !           909:        # the lddf instruction:
        !           910:        #
        !           911:        if test ${insn} = lddf; then
        !           912: 
        !           913:            echo ""
        !           914:            echo "/* this does a sparc${arch} ${insn}: */"
        !           915:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           916:            echo "{"
        !           917:            echo "  unsigned int fpreg_number;"
        !           918:            echo ""
        !           919:            echo "  TME_SPARC_INSN_FPU;"
        !           920:            echo ""
        !           921:            echo "  /* decode rd: */"
        !           922:            echo "  fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
        !           923:            echo ""
        !           924:            echo "  /* make sure rd is aligned: */"
        !           925:            echo "  if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) {"
        !           926:            echo "    fpreg_number -= 1;"
        !           927:            echo "  }"
        !           928:            echo ""
        !           929:            echo "  /* make sure that the double floating-point register is double-precision: */"
        !           930:            echo "  tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);"
        !           931:            echo ""
        !           932:            echo "  /* do the load: */"
        !           933:            echo "  tme_sparc${arch}_ldd(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !           934:            echo ""
        !           935:            echo "  /* set the double floating-point register value: */"
        !           936:            echo "  ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
        !           937:            echo "  ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_hi"
        !           938:            echo "    = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 0);"
        !           939:            echo "  ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_lo"
        !           940:            echo "    = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1);"
        !           941:            echo ""
        !           942:            echo "  TME_SPARC_INSN_OK;"
        !           943:            echo "}"
        !           944:        fi
        !           945: 
        !           946:        # the stdf instruction:
        !           947:        #
        !           948:        if test ${insn} = stdf; then
        !           949: 
        !           950:            echo ""
        !           951:            echo "/* this does a sparc${arch} ${insn}: */"
        !           952:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           953:            echo "{"
        !           954:            echo "  unsigned int fpreg_number;"
        !           955:            echo "  const union tme_value64 *value_double;"
        !           956:            echo "  union tme_value64 value_double_buffer;"
        !           957:            echo ""
        !           958:            echo "  TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t) * 2);"
        !           959:            echo ""
        !           960:            echo "  /* decode rd: */"
        !           961:            echo "  fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
        !           962:            echo ""
        !           963:            echo "  /* make sure rd is aligned: */"
        !           964:            echo "  if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) {"
        !           965:            echo "    fpreg_number -= 1;"
        !           966:            echo "  }"
        !           967:            echo ""
        !           968:            echo "  /* make sure the double floating-point register is double-precision: */"
        !           969:            echo "  tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);"
        !           970:            echo ""
        !           971:            echo "  /* get this double floating-point register in IEEE754 double-precision format: */"
        !           972:            echo "  value_double = tme_ieee754_double_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_double_buffer);"
        !           973:            echo ""
        !           974:            echo "  /* set the floating-point register value: */"
        !           975:            echo "  ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 0)"
        !           976:            echo "    = value_double->tme_value64_uint32_hi;"
        !           977:            echo "  ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1)"
        !           978:            echo "    = value_double->tme_value64_uint32_lo;"
        !           979:            echo ""
        !           980:            echo "  /* do the store: */"
        !           981:            echo "  tme_sparc${arch}_std(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !           982:            echo ""
        !           983:            echo "  TME_SPARC_INSN_OK;"
        !           984:            echo "}"
        !           985:        fi
        !           986: 
        !           987:        # the ldfsr instruction:
        !           988:        #
        !           989:        if test ${insn} = ldfsr; then
        !           990: 
        !           991:            echo ""
        !           992:            echo "/* this does a sparc${arch} ${insn}: */"
        !           993:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !           994:            echo "{"
        !           995:            echo "  tme_uint32_t fsr;"
        !           996:            echo ""
        !           997:            echo "  TME_SPARC_INSN_FPU;"
        !           998:            echo ""
        !           999:            echo "  /* do the load: */"
        !          1000:            echo "  tme_sparc${arch}_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !          1001:            echo ""
        !          1002:            echo "  /* update the FSR: */"
        !          1003:            echo "  fsr = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift});"
        !          1004:            echo "  /* \"An LDFSR instruction does not affect ftt.\" */"
        !          1005:            echo "  /* \"The LDFSR instruction does not affect qne.\" */"
        !          1006:            echo "  fsr &= ~(TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE);"
        !          1007:            echo "  ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & (TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE)) | fsr;"
        !          1008:            echo ""
        !          1009:            echo "  TME_SPARC_INSN_OK;"
        !          1010:            echo "}"
        !          1011:        fi
        !          1012: 
        !          1013:        # the stfsr instruction:
        !          1014:        #
        !          1015:        if test ${insn} = stfsr; then
        !          1016: 
        !          1017:            echo ""
        !          1018:            echo "/* this does a sparc${arch} ${insn}: */"
        !          1019:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !          1020:            echo "{"
        !          1021:            echo ""
        !          1022:            echo "  TME_SPARC_INSN_FPU_STORE(sizeof(ic->tme_sparc_fpu_fsr));"
        !          1023:            echo ""
        !          1024:            echo "  /* set the FSR value to store: */"
        !          1025:            echo "  ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}) = ic->tme_sparc_fpu_fsr;"
        !          1026:            echo ""
        !          1027:            echo "  /* do the store: */"
        !          1028:            echo "  tme_sparc${arch}_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
        !          1029:            echo ""
        !          1030:            echo "  TME_SPARC_INSN_OK;"
        !          1031:            echo "}"
        !          1032:        fi
        !          1033: 
        !          1034:        # the fpop1 and fpop2 instructions:
        !          1035:        #
        !          1036:        if test ${insn} = fpop1 || test ${insn} = fpop2; then
        !          1037: 
        !          1038:            echo ""
        !          1039:            echo "/* this does a sparc${arch} ${insn}: */"
        !          1040:            echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
        !          1041:            echo "{"
        !          1042:            echo "  TME_SPARC_INSN_FPU;"
        !          1043:            echo "  tme_sparc_fpu_${insn}(ic);"
        !          1044:            echo "  TME_SPARC_INSN_OK;"
        !          1045:            echo "}"
        !          1046:        fi
        !          1047: 
        !          1048:     done
        !          1049: 
        !          1050:     # the slow load and store functions:
        !          1051:     #
        !          1052:     for slow in load store; do
        !          1053: 
        !          1054:        if test ${slow} = load; then
        !          1055:            cycle="read"
        !          1056:            capcycle="READ"
        !          1057:            if $header; then
        !          1058:                echo "const tme_shared tme_uint8_t *tme_sparc${arch}_${slow} _TME_P((struct tme_sparc *, tme_uint${arch}_t, unsigned int));"
        !          1059:                continue
        !          1060:            fi
        !          1061:        else
        !          1062:            cycle="write"
        !          1063:            capcycle="WRITE"
        !          1064:            if $header; then
        !          1065:                echo "tme_shared tme_uint8_t *tme_sparc${arch}_${slow} _TME_P((struct tme_sparc *, tme_uint${arch}_t, const tme_uint${arch}_t *, unsigned int));"
        !          1066:                continue
        !          1067:            fi
        !          1068:        fi
        !          1069: 
        !          1070:        echo ""
        !          1071:        echo "/* this does a slow ${slow}: */"
        !          1072:        if test ${slow} = load; then echo -n "const "; fi
        !          1073:        echo "tme_shared tme_uint8_t *"
        !          1074:        echo "tme_sparc${arch}_${slow}(struct tme_sparc *ic, "
        !          1075:        echo "                  tme_uint${arch}_t address, "
        !          1076:        if test ${slow} = store; then
        !          1077:            echo "                  const tme_uint${arch}_t * const _rd,"
        !          1078:        fi
        !          1079:        echo "                  const unsigned int flags)"
        !          1080:        echo "{"
        !          1081: 
        !          1082:        # our locals:
        !          1083:        #
        !          1084:        echo "  unsigned int size;"
        !          1085:        echo "  tme_uint32_t asi_mask_data;"
        !          1086:        echo "  struct tme_sparc_tlb *dtlb;"
        !          1087:        echo "  tme_bus_addr_t physical_address;"
        !          1088:        echo "  int shift;"
        !          1089:        echo "  struct tme_bus_cycle cycle;"
        !          1090:        echo "  unsigned int transferred, resid, cycle_size;"
        !          1091:        echo "  unsigned int trap;"
        !          1092:        echo "  int err;"
        !          1093:        if test ${slow} = store; then
        !          1094:            echo "  tme_uint${arch}_t stored_registers[2];"
        !          1095:            echo "  const tme_uint8_t *buffer;"
        !          1096:            buffer=buffer
        !          1097:        else
        !          1098:            buffer="&ic->tme_sparc_memory_buffer[0]"
        !          1099:        fi
        !          1100: 
        !          1101:        echo ""
        !          1102:        echo "  /* get the transfer size.  we can do at most a 64-bit transfer: */"
        !          1103:        echo "  size = (flags % (sizeof(tme_uint64_t) * 2));"
        !          1104: 
        !          1105:        echo ""
        !          1106:        echo "  /* get the DTLB entry.  our caller has already busied it: */"
        !          1107:        echo "  dtlb = TME_SPARC_DTLB_ENTRY(ic, address);"
        !          1108: 
        !          1109:        echo ""
        !          1110:        echo "  /* if the address is not aligned: */"
        !          1111:        echo "  if (__tme_predict_false((address & (size - 1)) != 0)) {"
        !          1112:        echo "    tme_sparc_tlb_unbusy(dtlb);"
        !          1113:        echo "    tme_sparc${arch}_trap(ic, TME_SPARC_TRAP_mem_address_not_aligned);"
        !          1114:        echo "  }"
        !          1115: 
        !          1116:        echo ""
        !          1117:        echo "  /* if this is a ldd or a std (and not an lddf or an stdf)"
        !          1118:        echo "     and the destination register address is odd: */"
        !          1119:        echo "  /* NB: we detect lddf and stdf by testing bit 24 in the"
        !          1120:        echo "     instruction word: */"
        !          1121:        echo "  if (__tme_predict_false(size == (sizeof(tme_uint32_t) * 2)"
        !          1122:        echo "                          && (TME_SPARC_INSN & TME_BIT(25)) != 0"
        !          1123:        echo "                          && (TME_SPARC_INSN & TME_BIT(24)) == 0)) {"
        !          1124:        echo "    tme_sparc_tlb_unbusy(dtlb);"
        !          1125:        echo "    tme_sparc${arch}_trap(ic, TME_SPARC_TRAP_illegal_instruction);"
        !          1126:        echo "  }"
        !          1127:        
        !          1128:        echo ""
        !          1129:        echo "  /* get the ASI and its mask: */"
        !          1130:        echo "  asi_mask_data = ic->tme_sparc_asi_mask_data;"
        !          1131:        echo "  if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_INSN) != 0)) {"
        !          1132:        echo "    asi_mask_data = ic->tme_sparc_asi_mask_insn;"
        !          1133:        echo "  }"
        !          1134:        echo "  if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_A) != 0)) {"
        !          1135:        echo "    asi_mask_data = _tme_sparc${arch}_alternate_asi_mask(ic);"
        !          1136:        echo "  }"
        !          1137:                        
        !          1138:        if test ${slow} = store; then
        !          1139:            echo ""
        !          1140:            echo "  /* store big-endian versions of the registers to store in"
        !          1141:            echo "     a buffer.  we always assume that this is a std and copy"
        !          1142:            echo "     r[rd] and r[rd + 1] into the buffer: */"
        !          1143:            echo "  stored_registers[0] = tme_htobe_u${arch}(TME_SPARC_FORMAT3_RD);"
        !          1144:            echo "  stored_registers[1] = tme_htobe_u${arch}(TME_SPARC_FORMAT3_RD_ODD);"
        !          1145:            echo ""
        !          1146:            echo "  /* make the initial pointer into the buffer: */"
        !          1147:            echo "  buffer = (const tme_uint8_t *) stored_registers;"
        !          1148:            echo "  if (size < sizeof(tme_uint32_t)) {"
        !          1149:            echo "    buffer += sizeof(tme_uint32_t) - size;"
        !          1150:            echo "  }"
        !          1151:        fi
        !          1152:        echo ""
        !          1153:        echo "  /* loop until the ${slow} is completed: */"
        !          1154:        echo "  trap = TME_SPARC_TRAP_none;"
        !          1155:        echo "  transferred = 0;"
        !          1156:        echo "  do {"
        !          1157:        echo ""
        !          1158:        echo "    /* while the DTLB entry is invalid, or does not cover this address"
        !          1159:        echo "       and address space, or if it does not allow for slow or fast ${cycle}s: */"
        !          1160:        echo "    for (; (tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)"
        !          1161:        echo "            || (dtlb->tme_sparc_tlb_addr_first > address)"
        !          1162:        echo "            || (dtlb->tme_sparc_tlb_addr_last < address)"
        !          1163:        echo "            || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))"
        !          1164:        echo "            || (dtlb->tme_sparc_tlb_emulator_off_${cycle} == TME_EMULATOR_OFF_UNDEF"
        !          1165:        echo "                && (dtlb->tme_sparc_tlb_cycles_ok & TME_BUS_CYCLE_${capcycle}) == 0)); ) {"
        !          1166:        echo ""
        !          1167:        echo "      /* unbusy this DTLB entry for filling: */"
        !          1168:        echo "      tme_bus_tlb_unbusy_fill(&dtlb->tme_sparc_tlb_bus_tlb);"
        !          1169:        echo ""
        !          1170:        echo "      /* we never fill TLB entries on the stack because we never"
        !          1171:        echo "         callout multiple fills at the same time, so the global TLB"
        !          1172:        echo "         entry pointer always points back to the TLB entry.  this"
        !          1173:        echo "         also means that we do not have to call tme_bus_tlb_back()"
        !          1174:        echo "         after the fill: */"
        !          1175:        echo "      dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_global = &dtlb->tme_sparc_tlb_bus_tlb;"
        !          1176:        echo ""
        !          1177:        echo "      /* reload the DTLB entry: */"
        !          1178:        echo "      tme_sparc_callout_unlock(ic);"
        !          1179:        echo "#ifdef _TME_SPARC_STATS"
        !          1180:        echo "      ic->tme_sparc_stats.tme_sparc_stats_dtlb_fill++;"
        !          1181:        echo "#endif /* _TME_SPARC_STATS */"
        !          1182:        echo "      err = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill)"
        !          1183:        echo "        (ic->_tme_sparc_bus_connection,"
        !          1184:        echo "         dtlb,"
        !          1185:        echo "         asi_mask_data,"
        !          1186:        echo "         address,"
        !          1187:        echo "         TME_BUS_CYCLE_${capcycle});"
        !          1188:        echo "      assert (err == TME_OK);"
        !          1189:        echo "      tme_sparc_callout_relock(ic);"
        !          1190:        echo ""
        !          1191:        echo "      /* rebusy the DTLB entry: */"
        !          1192:        echo "      tme_sparc_tlb_busy(dtlb);"
        !          1193:        echo "    }"
        !          1194: 
        !          1195:        echo ""
        !          1196:        echo "    /* if this DTLB entry allows fast ${cycle}s: */"
        !          1197:        echo "    if (__tme_predict_true(dtlb->tme_sparc_tlb_emulator_off_${cycle} != TME_EMULATOR_OFF_UNDEF)) {"
        !          1198:        echo ""
        !          1199:        echo "      /* if we have not transferred anything yet, and this"
        !          1200:        echo "         DTLB entry covers all of the addresses and allows"
        !          1201:        echo "         fast transfers: */"
        !          1202:        echo "      if (__tme_predict_true(transferred == 0"
        !          1203:        echo "                             && dtlb->tme_sparc_tlb_addr_last >= address + (size - 1)"
        !          1204:        if test ${slow} = store; then
        !          1205:            echo ""
        !          1206:            echo "                           && ((flags & TME_SPARC_SLOW_FLAG_ATOMIC) == 0"
        !          1207:            echo -n "                               || dtlb->tme_sparc_tlb_emulator_off_read == dtlb->tme_sparc_tlb_emulator_off_${cycle})"
        !          1208:        fi
        !          1209:        echo ")) {"
        !          1210:        
        !          1211:        echo ""
        !          1212:        echo "        /* return and let our caller do the transfer: */"
        !          1213:        echo "        return (dtlb->tme_sparc_tlb_emulator_off_${cycle});"
        !          1214:        echo "      }"
        !          1215:        echo ""
        !          1216:        echo "      /* calculate the cycle size: */"
        !          1217:        echo "      cycle_size = (dtlb->tme_sparc_tlb_addr_last - address) + 1;"
        !          1218:        echo "      cycle_size = TME_MIN(cycle_size, sizeof(tme_uint${arch}_t) - (address % sizeof(tme_uint${arch}_t)));"
        !          1219:        echo "      cycle_size = TME_MIN(cycle_size, size - transferred);"
        !          1220:        echo "      cycle.tme_bus_cycle_size = cycle_size;"
        !          1221:        echo ""
        !          1222:        echo "      /* do a ${cycle}: */"
        !          1223:        echo "      tme_memory_bus_${cycle}_buffer((dtlb->tme_sparc_tlb_emulator_off_${cycle} + address),"
        !          1224:        echo "                                    (${buffer} + transferred),"
        !          1225:        echo "                                    cycle_size,"
        !          1226:        echo "                                    dtlb->tme_sparc_tlb_bus_rwlock,"
        !          1227:        echo "                                    sizeof(tme_uint8_t),"
        !          1228:        echo "                                    sizeof(tme_uint32_t));"
        !          1229:        echo "    }"
        !          1230:        echo ""
        !          1231:        echo "    /* otherwise, this DTLB entry does not allow fast ${cycle}s: */"
        !          1232:        echo "    else {"
        !          1233:        echo ""
        !          1234:        echo "      /* make the bus cycle structure: */"
        !          1235:        echo "      resid = size - transferred;"
        !          1236:        echo "      cycle.tme_bus_cycle_type = TME_BUS_CYCLE_${capcycle};"
        !          1237:        echo "      cycle.tme_bus_cycle_buffer = (tme_uint8_t *) (${buffer} + transferred);"
        !          1238:        echo "      cycle.tme_bus_cycle_buffer_increment = 1;"
        !          1239:        echo "      cycle_size = TME_MIN(resid, sizeof(tme_uint${arch}_t) - (address % sizeof(tme_uint${arch}_t)));"
        !          1240:        echo "      cycle.tme_bus_cycle_size = cycle_size;"
        !          1241:        echo "      cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS${arch}_LOG2);"
        !          1242:        echo "      cycle.tme_bus_cycle_lane_routing = "
        !          1243:        echo "        &tme_sparc${arch}_router[TME_SPARC_BUS_ROUTER_INDEX(TME_BUS${arch}_LOG2, cycle_size, address)];"
        !          1244:        echo ""
        !          1245:        echo "      /* form the physical address for the bus cycle handler: */"
        !          1246:        echo "      physical_address = dtlb->tme_sparc_tlb_addr_offset + address;"
        !          1247:        echo "      shift = dtlb->tme_sparc_tlb_addr_shift;"
        !          1248:        echo "      if (shift < 0) {"
        !          1249:        echo "        physical_address <<= (0 - shift);"
        !          1250:        echo "      }"
        !          1251:        echo "      else if (shift > 0) {"
        !          1252:        echo "        physical_address >>= shift;"
        !          1253:        echo "      }"
        !          1254:        echo "      cycle.tme_bus_cycle_address = physical_address;"
        !          1255: 
        !          1256:        echo ""
        !          1257:        echo "      /* callout the bus cycle: */"
        !          1258:        echo "      tme_sparc_tlb_unbusy(dtlb);"
        !          1259:        echo "      tme_sparc_callout_unlock(ic);"
        !          1260:        echo "      err = (*dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle)"
        !          1261:        echo "           (dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);"
        !          1262:        echo "      tme_sparc_callout_relock(ic);"
        !          1263:        echo "      tme_sparc_tlb_busy(dtlb);"
        !          1264:        echo ""
        !          1265:        echo "      /* if the TLB entry was invalidated before the ${slow}: */"
        !          1266:        echo "      if (err == EBADF"
        !          1267:        echo "          && tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)) {"
        !          1268:        echo "        cycle.tme_bus_cycle_size = 0;"
        !          1269:        echo "      }"
        !          1270:        echo ""
        !          1271:        echo "      /* otherwise, any other error might be a bus error: */"
        !          1272:        echo "      else if (err != TME_OK) {"
        !          1273:        echo ""
        !          1274:        echo "        /* if a real bus error may have happened, instead of"
        !          1275:        echo "           some synchronous event: */"
        !          1276:        echo "        if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {"
        !          1277:        echo ""
        !          1278:        echo "          /* call the bus fault handlers: */"
        !          1279:        echo "          err = tme_bus_tlb_fault(&dtlb->tme_sparc_tlb_bus_tlb, &cycle, err);"
        !          1280:        echo "        }"
        !          1281:        echo ""
        !          1282:        echo "        /* if some synchronous event has happened: */"
        !          1283:        echo "        if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {"
        !          1284:        echo ""
        !          1285:        echo "          /* after the currently executing instruction finishes, check"
        !          1286:        echo "             for external resets, halts, or interrupts: */"
        !          1287:        echo "          ic->_tme_sparc_instruction_burst_remaining = 0;"
        !          1288:        echo "        }"
        !          1289:        echo ""
        !          1290:        echo "        /* otherwise, if a real bus fault happened: */"
        !          1291:        echo "        else if (err != TME_OK) {"
        !          1292:        echo "          trap = (*ic->_tme_sparc_bus_fault)(ic, &cycle, flags, err);"
        !          1293:        echo "          if (trap != TME_SPARC_TRAP_none) {"
        !          1294:        echo "            break;"
        !          1295:        echo "          }"
        !          1296:        echo "        }"
        !          1297:        echo "      }"
        !          1298:        
        !          1299:        if test ${slow} = store; then
        !          1300:            echo ""
        !          1301:            echo "      /* if this was an atomic operation, and data was transferred: */"
        !          1302:            echo "      if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_ATOMIC) != 0"
        !          1303:            echo "                              && cycle.tme_bus_cycle_size > 0)) {"
        !          1304:            echo ""
        !          1305:            echo "        /* we do not support atomic operations in TLB entries that"
        !          1306:            echo "           do not support both fast reads and fast writes.  assuming"
        !          1307:            echo "           that all atomic operations are to regular memory, we"
        !          1308:            echo "           should always get fast read and fast write TLBs.  when"
        !          1309:            echo "           we do not, it should only be because the memory has been"
        !          1310:            echo "           made read-only in the MMU.  the write above was supposed"
        !          1311:            echo "           to cause a fault (with the instruction rerun later with"
        !          1312:            echo "           a fast read and fast write TLB entry), but instead it"
        !          1313:            echo "           succeeded and transferred some data.  we have modified"
        !          1314:            echo "           memory and cannot recover: */"
        !          1315:            echo "        abort();"
        !          1316:            echo "      }"
        !          1317:        fi
        !          1318:        echo "    }"
        !          1319: 
        !          1320:        echo ""
        !          1321:        echo "    /* update: */"
        !          1322:        echo "    address += cycle.tme_bus_cycle_size;"
        !          1323:        echo "    transferred += cycle.tme_bus_cycle_size;"
        !          1324:        echo "  } while (transferred < size);"
        !          1325:        
        !          1326:        echo ""
        !          1327:        echo "  /* if we faulted, start trap processing: */"
        !          1328:        echo "  if (__tme_predict_false(trap != TME_SPARC_TRAP_none)) {"
        !          1329:        echo "    tme_sparc_tlb_unbusy(dtlb);"
        !          1330:        echo "    tme_sparc${arch}_trap(ic, trap);"
        !          1331:        echo "  }"
        !          1332: 
        !          1333:        echo ""
        !          1334:        if test ${slow} = load; then
        !          1335:            echo "  return (ic->tme_sparc_memory_buffer - (address - size));"
        !          1336:        else
        !          1337:            echo "  return ((tme_uint8_t *) TME_EMULATOR_OFF_UNDEF);"
        !          1338:        fi
        !          1339:        echo "}"
        !          1340:     done
        !          1341: 
        !          1342:     # unfix the architecture version:
        !          1343:     #
        !          1344:     if $header; then :; else
        !          1345:        echo ""
        !          1346:        echo "#undef TME_SPARC_VERSION"
        !          1347:        echo "#define TME_SPARC_VERSION(ic) _TME_SPARC_VERSION(ic)"
        !          1348:     fi
        !          1349: 
        !          1350:     # the sparc64 support depends on a 64-bit integer type:
        !          1351:     #
        !          1352:     if test ${arch} = 64; then
        !          1353:        echo ""
        !          1354:        echo "#endif /* TME_HAVE_INT64_T */"
        !          1355:     fi
        !          1356: done
        !          1357: 
        !          1358: # done:
        !          1359: #
        !          1360: exit 0

unix.superglobalmegacorp.com

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