Annotation of tme/ic/m68k/m68k-misc-auto.sh, revision 1.1.1.3

1.1       root        1: #! /bin/sh
                      2: 
1.1.1.3 ! root        3: # $Id: m68k-misc-auto.sh,v 1.11 2007/02/16 02:50:23 fredette Exp $
1.1       root        4: 
                      5: # ic/m68k/m68k-misc-auto.sh - automatically generates C code 
                      6: # for miscellaneous m68k emulation support:
                      7: 
                      8: #
                      9: # Copyright (c) 2002, 2003 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: EOF
                     52: 
                     53: # we need our own inclusion protection, since the instruction word
                     54: # fetch macros need to be multiply included:
                     55: if $header; then
                     56:     echo ""
                     57:     echo "#ifndef _IC_M68K_MISC_H"
                     58:     echo "#define _IC_M68K_MISC_H"
                     59: fi
                     60: 
                     61: # emit the register mapping macros:
                     62: if $header; then
                     63: 
                     64:     echo ""
                     65:     echo "/* the register mapping: */"
                     66:     echo "#define TME_M68K_IREG_UNDEF          (-1)"
                     67:     ireg32_next=0
                     68:     
                     69:     # NB: these are in a deliberate order, matching the order of
                     70:     # registers in instruction encodings:
                     71:     for regtype in d a; do
                     72:        capregtype=`echo ${regtype} | tr a-z A-Z`
                     73:        for regnum in 0 1 2 3 4 5 6 7; do
                     74:            echo "#define TME_M68K_IREG_${capregtype}${regnum}          (${ireg32_next})"
                     75:            echo "#define tme_m68k_ireg_${regtype}${regnum}             tme_m68k_ireg_uint32(TME_M68K_IREG_${capregtype}${regnum})"
                     76:            ireg32_next=`expr ${ireg32_next} + 1`
                     77:        done
                     78:     done
                     79: 
1.1.1.2   root       80:     # the current, next, and last program counter:
1.1       root       81:     echo "#define TME_M68K_IREG_PC             (${ireg32_next})"
                     82:     echo "#define tme_m68k_ireg_pc             tme_m68k_ireg_uint32(TME_M68K_IREG_PC)"
                     83:     ireg32_next=`expr ${ireg32_next} + 1`
                     84:     echo "#define TME_M68K_IREG_PC_NEXT                (${ireg32_next})"
                     85:     echo "#define tme_m68k_ireg_pc_next                tme_m68k_ireg_uint32(TME_M68K_IREG_PC_NEXT)"
                     86:     ireg32_next=`expr ${ireg32_next} + 1`
1.1.1.2   root       87:     echo "#define TME_M68K_IREG_PC_LAST                (${ireg32_next})"
                     88:     echo "#define tme_m68k_ireg_pc_last                tme_m68k_ireg_uint32(TME_M68K_IREG_PC_LAST)"
                     89:     ireg32_next=`expr ${ireg32_next} + 1`
1.1       root       90:     
                     91:     # the status register and ccr:
                     92:     echo "#define tme_m68k_ireg_sr             tme_m68k_ireg_uint16(${ireg32_next} << 1)"
                     93:     echo "#define tme_m68k_ireg_ccr            tme_m68k_ireg_uint8(${ireg32_next} << 2)"
                     94:     ireg32_next=`expr ${ireg32_next} + 1`
                     95: 
                     96:     # the shadow status register and format/offset word:
                     97:     echo "#define TME_M68K_IREG_SHADOW_SR      (${ireg32_next} << 1)"
                     98:     echo "#define tme_m68k_ireg_shadow_sr      tme_m68k_ireg_uint16(TME_M68K_IREG_SHADOW_SR)"
                     99:     echo "#define TME_M68K_IREG_FORMAT_OFFSET  ((${ireg32_next} << 1) + 1)"
                    100:     echo "#define tme_m68k_ireg_format_offset  tme_m68k_ireg_uint16(TME_M68K_IREG_FORMAT_OFFSET)"
                    101:     ireg32_next=`expr ${ireg32_next} + 1`
                    102: 
                    103:     # the memory buffers:
                    104:     for mem_which in x y z; do
                    105:        cap_mem_which=`echo ${mem_which} | tr a-z A-Z`
                    106:        echo "#define TME_M68K_IREG_MEM${cap_mem_which}32               (${ireg32_next})"
                    107:        echo "#define tme_m68k_ireg_mem${mem_which}32           tme_m68k_ireg_uint32(TME_M68K_IREG_MEM${cap_mem_which}32)"
                    108:        echo "#define TME_M68K_IREG_MEM${cap_mem_which}16               (${ireg32_next} << 1)"
                    109:        echo "#define tme_m68k_ireg_mem${mem_which}16           tme_m68k_ireg_uint16(TME_M68K_IREG_MEM${cap_mem_which}16)"
                    110:        echo "#define TME_M68K_IREG_MEM${cap_mem_which}8                (${ireg32_next} << 2)"
                    111:        echo "#define tme_m68k_ireg_mem${mem_which}8            tme_m68k_ireg_uint8(TME_M68K_IREG_MEM${cap_mem_which}8)"
                    112:        ireg32_next=`expr ${ireg32_next} + 1`
                    113:     done
                    114: 
                    115:     # the control registers:
1.1.1.2   root      116:     for reg in usp isp msp sfc dfc vbr cacr caar; do
1.1       root      117:        capreg=`echo $reg | tr a-z A-Z`
                    118:        echo "#define TME_M68K_IREG_${capreg}           (${ireg32_next})"
                    119:        echo "#define tme_m68k_ireg_${reg}              tme_m68k_ireg_uint32(TME_M68K_IREG_${capreg})"
                    120:        ireg32_next=`expr ${ireg32_next} + 1`
                    121:     done
                    122: 
1.1.1.2   root      123:     # this is the count of variable 32-bit registers:
1.1       root      124:     echo "#define TME_M68K_IREG32_COUNT                (${ireg32_next})"
1.1.1.2   root      125: 
                    126:     # the immediate register.  there are actually three 32-bit
                    127:     # registers in a row, to allow the fpgen specop to fetch up to a
                    128:     # 96-bit immediate:
                    129:     echo "#define TME_M68K_IREG_IMM32          (${ireg32_next})"
                    130:     echo "#define tme_m68k_ireg_imm32          tme_m68k_ireg_uint32(TME_M68K_IREG_IMM32)"
1.1.1.3 ! root      131:     ireg32_next=`expr ${ireg32_next} + 3`
1.1.1.2   root      132: 
                    133:     # the effective address register:
                    134:     echo "#define TME_M68K_IREG_EA             (${ireg32_next})"
                    135:     echo "#define tme_m68k_ireg_ea             tme_m68k_ireg_uint32(TME_M68K_IREG_EA)"
                    136:     ireg32_next=`expr ${ireg32_next} + 1`
                    137: 
                    138:     # the constant registers:
                    139:     for reg in zero one two three four five six seven eight; do
                    140:        capreg=`echo $reg | tr a-z A-Z`
                    141:        echo "#define TME_M68K_IREG_${capreg}           (${ireg32_next})"
                    142:        ireg32_next=`expr ${ireg32_next} + 1`
                    143:     done
1.1       root      144: fi
                    145: 
                    146: # emit the flags->conditions mapping.  note that the nesting of the
                    147: # flag variables is deliberate, to make this array indexable with the
                    148: # condition code register:
                    149: if $header; then :; else
                    150:     echo ""
                    151:     echo "/* the flags->conditions mapping: */"
                    152:     echo "const tme_uint16_t _tme_m68k_conditions[32] = {"
                    153:     for xflag in 0 1; do
                    154:        for nflag in 0 1; do
                    155:            for zflag in 0 1; do
                    156:                for vflag in 0 1; do
                    157:                    for cflag in 0 1; do
                    158:                    
                    159:                        # the True condition:
                    160:                        echo -n "TME_BIT(TME_M68K_C_T)"
                    161:                        
                    162:                        # the High condition:
                    163:                        if test $cflag != 1 && test $zflag != 1; then
                    164:                            echo -n " | TME_BIT(TME_M68K_C_HI)"
                    165:                        fi
                    166:                        
                    167:                        # the Low or Same condition:
                    168:                        if test $cflag = 1 || test $zflag = 1; then
                    169:                            echo -n " | TME_BIT(TME_M68K_C_LS)"
                    170:                        fi
                    171:                        
                    172:                        # the Carry Clear and Carry Set conditions:
                    173:                        if test $cflag != 1; then
                    174:                            echo -n " | TME_BIT(TME_M68K_C_CC)"
                    175:                        else
                    176:                            echo -n " | TME_BIT(TME_M68K_C_CS)"
                    177:                        fi
                    178:                        
                    179:                        # the Not Equal and Equal conditions:
                    180:                        if test $zflag != 1; then
                    181:                            echo -n " | TME_BIT(TME_M68K_C_NE)"
                    182:                        else
                    183:                            echo -n " | TME_BIT(TME_M68K_C_EQ)"
                    184:                        fi
                    185:                        
                    186:                        # the Overflow Clear and Overflow Set conditions:
                    187:                        if test $vflag != 1; then
                    188:                            echo -n " | TME_BIT(TME_M68K_C_VC)"
                    189:                        else
                    190:                            echo -n " | TME_BIT(TME_M68K_C_VS)"
                    191:                        fi
                    192:                        
                    193:                        # the Plus and Minus conditions:
                    194:                        if test $nflag != 1; then
                    195:                            echo -n " | TME_BIT(TME_M68K_C_PL)"
                    196:                        else
                    197:                            echo -n " | TME_BIT(TME_M68K_C_MI)"
                    198:                        fi
                    199:                        
                    200:                        # the Greater or Equal condition:
                    201:                        if (test $nflag = 1 && test $vflag = 1) || \
                    202:                           (test $nflag != 1 && test $vflag != 1); then
                    203:                            echo -n " | TME_BIT(TME_M68K_C_GE)"
                    204:                        fi
                    205:                        
                    206:                        # the Less Than condition:
                    207:                        if (test $nflag = 1 && test $vflag != 1) || \
                    208:                           (test $nflag != 1 && test $vflag = 1); then
                    209:                            echo -n " | TME_BIT(TME_M68K_C_LT)"
                    210:                        fi
                    211: 
                    212:                        # the Greater Than condition:
                    213:                        if (test $nflag = 1 && test $vflag = 1 && test $zflag != 1) || \
                    214:                           (test $nflag != 1 && test $vflag != 1 && test $zflag != 1); then
                    215:                            echo -n " | TME_BIT(TME_M68K_C_GT)"
                    216:                        fi
                    217:                    
                    218:                        # the Less Than or Equal condition:
                    219:                        if test $zflag = 1 || \
                    220:                           (test $nflag = 1 && test $vflag != 1) || \
                    221:                           (test $nflag != 1 && test $vflag = 1); then
                    222:                            echo -n " | TME_BIT(TME_M68K_C_LE)"
                    223:                        fi
                    224: 
                    225:                        echo ","
                    226:                    done
                    227:                done
                    228:            done
                    229:        done
                    230:     done
                    231:     echo "};"
                    232: fi
                    233: 
                    234: # emit the instruction word fetch macros:
                    235: if $header; then
                    236: 
1.1.1.3 ! root      237:     # emit the simple signed and unsigned fetch macros:
        !           238:     #
        !           239:     echo ""
        !           240:     echo "/* the simple signed and unsigned fetch macros: */"
        !           241: 
        !           242:     # permute over size:
        !           243:     #
        !           244:     for size in 16 32; do
        !           245: 
        !           246:        # permute for signed or unsigned:
        !           247:        #
        !           248:        for capsign in U S; do
        !           249:            if test $capsign = U; then sign=u ; un=un ; else sign= ; un= ; fi
        !           250: 
        !           251:            echo "#define _TME_M68K_EXECUTE_FETCH_${capsign}${size}(v) \\"
        !           252:            echo "  _TME_M68K_EXECUTE_FETCH_${size}(tme_${sign}int${size}_t, v)"
        !           253:            if test ${size} = 16 && test ${capsign} = U; then
        !           254:                echo "#define _TME_M68K_EXECUTE_FETCH_${capsign}${size}_FIXED(v, field) \\"
        !           255:                echo "  _TME_M68K_EXECUTE_FETCH_${size}_FIXED(tme_${sign}int${size}_t, v, field)"
        !           256:            fi
        !           257:        done
        !           258:     done
        !           259: 
1.1       root      260:     echo ""
                    261:     echo "#endif /* _IC_M68K_MISC_H */"
                    262: 
                    263:     # permute for the fast vs. slow executors:
                    264:     for executor in fast slow; do
                    265: 
                    266:        echo ""
                    267:        echo -n "#if"
                    268:        if test $executor = slow; then echo -n "n"; fi
                    269:        echo "def _TME_M68K_EXECUTE_FAST"
                    270:        echo ""
                    271:        echo "/* these macros are for the ${executor} executor: */"
                    272: 
1.1.1.3 ! root      273:        # permute over size:
        !           274:        #
        !           275:        for size in 16 32; do
        !           276: 
        !           277:            echo ""
        !           278:            echo "/* this fetches a ${size}-bit value for the ${executor} executor: */"
        !           279:            echo "#undef _TME_M68K_EXECUTE_FETCH_${size}"
        !           280:            echo "#define _TME_M68K_EXECUTE_FETCH_${size}(type, v) \\"
        !           281: 
        !           282:            if test $executor = slow; then
        !           283: 
        !           284:                # this expression gives the current fetch offset in the instruction:
        !           285:                #
        !           286:                offset_fetch="ic->_tme_m68k_insn_fetch_slow_next"
        !           287: 
        !           288:                echo "  /* macros for the ${executor} executor are simple, because \\"
        !           289:                echo "     tme_m68k_fetch${size}() takes care of all endianness, alignment, \\"
        !           290:                echo "     and atomic issues, and also stores the fetched value in the \\"
        !           291:                echo "     instruction fetch buffer (if a previous fetch before a fault \\"
        !           292:                echo "     didn't store all or part of it there already): */ \\"
        !           293:                echo "  (v) = (type) tme_m68k_fetch${size}(ic, linear_pc); \\"
        !           294:                echo "  linear_pc += sizeof(tme_uint${size}_t)"
        !           295:            
        !           296:            else
        !           297: 
        !           298:                # this expression gives the current fetch offset in the instruction:
        !           299:                #
        !           300:                offset_fetch="(fetch_fast_next - ic->_tme_m68k_insn_fetch_fast_start)"
        !           301:                
        !           302:                echo "  /* use the raw fetch macro to fetch the value into the variable, \\"
        !           303:                echo "     and then save it in the instruction buffer.  the save doesn't \\"
        !           304:                echo "     need to be atomic; no one else can see the instruction buffer. \\"
        !           305:                echo "     however, the raw fetch macro has already advanced fetch_fast_next, \\"
        !           306:                echo "     so we need to compensate for that here: */ \\"
        !           307:                echo "  __TME_M68K_EXECUTE_FETCH_${size}(type, v); \\"
        !           308:                echo "  tme_memory_write${size}(((tme_uint${size}_t *) ((((tme_uint8_t *) &ic->_tme_m68k_insn_fetch_buffer[0]) - sizeof(tme_uint${size}_t)) + ${offset_fetch})), (tme_uint${size}_t) (v), sizeof(tme_uint16_t))"
        !           309: 
        !           310:                echo ""
        !           311:                echo "/* this does a raw fetch of a ${size}-bit value for the ${executor} executor: */"
        !           312:                echo "#undef __TME_M68K_EXECUTE_FETCH_${size}"
        !           313:                echo "#define __TME_M68K_EXECUTE_FETCH_${size}(type, v) \\"
        !           314:                echo "  /* if we can't do the fast read, we need to redispatch: */ \\"
        !           315:                echo "  /* NB: checks in tme_m68k_go_slow(), and proper setting of \\"
        !           316:                echo "     ic->_tme_m68k_insn_fetch_fast_last in _TME_M68K_EXECUTE_NAME(), \\"
        !           317:                echo "     allow  us to do a simple pointer comparison here, for \\"
        !           318:                echo "     any fetch size: */ \\"
        !           319:                echo "  if (__tme_predict_false(fetch_fast_next > ic->_tme_m68k_insn_fetch_fast_last)) \\"
        !           320:                echo "    goto _tme_m68k_fast_fetch_failed; \\"
        !           321:                echo "  (v) = ((type) \\"
        !           322:                echo "         tme_betoh_u${size}(tme_memory_bus_read${size}((const tme_shared tme_uint${size}_t *) fetch_fast_next, \\"
        !           323:                echo "                                             tlb->tme_m68k_tlb_bus_rwlock, \\"
        !           324:                echo "                                             sizeof(tme_uint16_t), \\"
        !           325:                echo "                                             sizeof(tme_uint32_t)))); \\"
        !           326:                echo "  fetch_fast_next += sizeof(tme_uint${size}_t)"
        !           327:            fi
        !           328: 
        !           329:            # if this size doesn't get a fixed fetch macro, continue now:
        !           330:            #
        !           331:            if test ${size} != 16; then
        !           332:                continue
        !           333:            fi
        !           334: 
        !           335:            echo ""
        !           336:            echo "/* this fetches a ${size}-bit value at a fixed instruction position"
        !           337:            echo "   for the ${executor} executor: */"
        !           338:            echo "#undef _TME_M68K_EXECUTE_FETCH_${size}_FIXED"
        !           339:            echo "#define _TME_M68K_EXECUTE_FETCH_${size}_FIXED(type, v, field) \\"
        !           340:            echo "  assert(&((struct tme_m68k *) 0)->field \\"
        !           341:            echo "         == (type *) (((tme_uint8_t *) &((struct tme_m68k *) 0)->_tme_m68k_insn_fetch_buffer[0]) + ${offset_fetch})); \\"
        !           342:            echo -n "  "
        !           343:            if test ${executor} = fast; then echo -n _ ; fi
        !           344:            echo "_TME_M68K_EXECUTE_FETCH_${size}(type, v)"
1.1       root      345: 
                    346:        done
                    347: 
                    348:        echo ""
                    349:        echo -n "#endif /* "
                    350:        if test $executor = slow; then echo -n "!"; fi
                    351:        echo "_TME_M68K_EXECUTE_FAST */"
                    352:     done
                    353: fi
                    354: 
                    355: # done:
                    356: exit 0

unix.superglobalmegacorp.com

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