Annotation of tme/ic/sparc/sparc-insns-auto.sh, revision 1.1.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.