Annotation of tme/ic/sparc/sparc-rc-chain.c, revision 1.1.1.1

1.1       root        1: /* $Id: sparc-rc-chain.c,v 1.2 2010/02/14 15:17:56 fredette Exp $ */
                      2: 
                      3: /* ic/sparc/sparc-rc-chain.c - SPARC recode chain support: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2009 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #if TME_SPARC_RECODE_SIZE(ic) == TME_RECODE_SIZE_32
                     37: 
                     38: _TME_RCSID("$Id: sparc-rc-chain.c,v 1.2 2010/02/14 15:17:56 fredette Exp $");
                     39: 
                     40: /* macros: */
                     41: 
                     42: /* rename various things by the architecture size: */
                     43: #define _tme_sparc_recode_chain_src_key _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_chain_src_key)
                     44: #define _tme_sparc_recode_chain_insns_thunk _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_chain_insns_thunk)
                     45: #define _tme_sparc_recode_chain_fixup _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_chain_fixup)
                     46: #define tme_sparc_recode_chain_tlb_update _TME_SPARC_RECODE_SIZE(tme_sparc,_recode_chain_tlb_update)
                     47: #define _tme_sparc_recode_chain_init _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_chain_init)
                     48: 
                     49: #endif /* TME_SPARC_RECODE_SIZE(ic) == TME_RECODE_SIZE_32 */
                     50: 
                     51: /* if the given PC can be converted into a source key on a cache-valid
                     52:    page, this returns the source key, otherwise this returns
                     53:    TME_SPARC_RECODE_SRC_KEY_UNDEF: */
                     54: static tme_sparc_recode_src_key_t
                     55: _tme_sparc_recode_chain_src_key(const struct tme_sparc * const ic,
                     56:                                tme_sparc_ireg_t address)
                     57: {
                     58:   tme_uint32_t tlb_hash;
                     59:   const struct tme_sparc_tlb *itlb;
                     60:   const tme_shared tme_uint8_t *src;
                     61:   tme_bus_context_t context;
                     62:   const struct tme_sparc_recode_cacheable *cacheable;
                     63:   tme_sparc_recode_src_key_t src_key;
                     64:   tme_uint32_t pstate;
                     65:   unsigned long page_index;
                     66: 
                     67:   /* hash the address into an instruction TLB entry: */
                     68:   tlb_hash
                     69:     = TME_SPARC_TLB_HASH(ic,
                     70:                         ic->tme_sparc_memory_context_default,
                     71:                         address);
                     72:   itlb = &ic->tme_sparc_tlbs[TME_SPARC_ITLB_ENTRY(ic, tlb_hash)];
                     73: 
                     74:   /* if this instruction TLB entry doesn't cover the address: */
                     75:   if (__tme_predict_false(address < (tme_sparc_ireg_t) itlb->tme_sparc_tlb_addr_first
                     76:                          || address > (tme_sparc_ireg_t) itlb->tme_sparc_tlb_addr_last)) {
                     77: 
                     78:     /* this PC has no source key: */
                     79:     return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                     80:   }
                     81: 
                     82:   /* if this instruction TLB entry doesn't allow fast reading: */
                     83:   src = itlb->tme_sparc_tlb_emulator_off_read;
                     84:   if (__tme_predict_false(src == TME_EMULATOR_OFF_UNDEF)) {
                     85: 
                     86:     /* this PC has no source key: */
                     87:     return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                     88:   }
                     89: 
                     90:   /* assume that this instruction TLB entry is valid and covers, and
                     91:      make a pointer to the instruction: */
                     92:   src += address;
                     93: 
                     94:   /* if this instruction TLB entry isn't valid: */
                     95:   /* NB: here, we check validity without busying the TLB entry first,
                     96:      to keep things simple (since this may be the current instruction
                     97:      TLB entry, and already busy).  this is OK because we don't really
                     98:      depend on the entry being valid - we only check for validity on
                     99:      the off chance that an invalid TLB entry appears to cover this
                    100:      address, context and ASI.
                    101: 
                    102:      the instruction TLB entry could become immediately invalid after
                    103:      this point, without affecting correctness, since we're only using
                    104:      the translated address to check the cache-valid bit and maybe do
                    105:      a lookup in the source key hash.  if this instruction TLB entry
                    106:      isn't already busy, before doing anything with the result of this
                    107:      lookup, the instruction TLB entry will be busied and checked for
                    108:      validity as normal: */
                    109:   if (tme_bus_tlb_is_invalid(&itlb->tme_sparc_tlb_bus_tlb)) {
                    110: 
                    111:     /* this PC has no source key: */
                    112:     return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                    113:   }
                    114: 
                    115:   /* if this instruction TLB entry doesn't cover this context or
                    116:      ASI: */
                    117:   context = itlb->tme_sparc_tlb_context;
                    118:   if (__tme_predict_false((context <= ic->tme_sparc_memory_context_max
                    119:                           && context != ic->tme_sparc_memory_context_default)
                    120:                          || !TME_SPARC_TLB_ASI_MASK_OK(itlb, ic->tme_sparc_asi_mask_insn))) {
                    121: 
                    122:     /* this PC has no source key: */
                    123:     return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                    124:   }
                    125: 
                    126:   /* search for a cacheable that contains this source address: */
                    127:   cacheable = ic->tme_sparc_recode_cacheable_first;
                    128:   for (;;) {
                    129: 
                    130:     /* assume that this cacheable contains this source address, and get the
                    131:        source address key relative to the start of the cacheable: */
                    132:     src_key = src - cacheable->tme_sparc_recode_cacheable_contents;
                    133: 
                    134:     /* if this cacheable doesn't contain this source address: */
                    135:     if (__tme_predict_false(src_key
                    136:                            >= cacheable->tme_sparc_recode_cacheable_size)) {
                    137: 
                    138:       /* if we have run out of cacheables: */
                    139:       if (__tme_predict_false(cacheable != &ic->tme_sparc_recode_cacheables[0])) {
                    140: 
                    141:        /* this PC has no source key: */
                    142:        return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                    143:       }
                    144: 
                    145:       /* try the next cacheable: */
                    146:       cacheable--;
                    147:       continue;
                    148:     }
                    149: 
                    150:     break;
                    151:   }
                    152: 
                    153:   /* make the absolute source address key by adding in the first
                    154:      source address key in this cacheable: */
                    155:   src_key += cacheable->tme_sparc_recode_cacheable_src_key_first;
                    156:   assert ((src_key % sizeof(tme_uint32_t)) == 0);
                    157: 
                    158:   /* make the index for the page containing this source address: */
                    159:   page_index = src_key >> ic->tme_sparc_tlb_page_size_log2;
                    160: 
                    161:   /* if the valid bit for this page is no longer set: */
                    162:   /* NB: this isn't needed by _tme_sparc_recode_chain_fixup(), because
                    163:      each instructions thunk checks its own page valid bit, but this
                    164:      is needed by tme_sparc_recode_insn_assist_redispatch(): */
                    165:   if (__tme_predict_false(((cacheable->tme_sparc_recode_cacheable_valids[page_index / 8])
                    166:                           & TME_BIT(page_index % 8)) == 0)) {
                    167: 
                    168:     /* this PC has no source key: */
                    169:     return (TME_SPARC_RECODE_SRC_KEY_UNDEF);
                    170:   }
                    171: 
                    172:   /* if this is a v9 CPU: */
                    173:   if (TME_SPARC_VERSION(ic) >= 9) {
                    174: 
                    175:     /* add PSTATE.AM and PSTATE.CLE to the source address key: */
                    176:     pstate = ic->tme_sparc64_ireg_pstate;
                    177:     if (pstate & TME_SPARC64_PSTATE_AM) {
                    178:       src_key += TME_SPARC64_RECODE_SRC_KEY_FLAG_AM;
                    179:     }
                    180:     if (pstate & TME_SPARC64_PSTATE_CLE) {
                    181:       src_key += TME_SPARC64_RECODE_SRC_KEY_FLAG_CLE;
                    182:     }
                    183:   }
                    184: 
                    185:   /* the source address key must be defined: */
                    186:   assert (src_key != TME_SPARC_RECODE_SRC_KEY_UNDEF);
                    187:   return (src_key);
                    188: }
                    189: 
                    190: /* this looks up an instructions thunk for a PC: */
                    191: static tme_recode_thunk_off_t
                    192: _tme_sparc_recode_chain_insns_thunk(const struct tme_sparc * const ic,
                    193:                                    tme_sparc_ireg_t address)
                    194: {
                    195:   tme_sparc_recode_src_key_t src_key;
                    196:   unsigned long src_hash_i;
                    197:   signed int src_hash_probe;
                    198:   tme_sparc_recode_src_key_t src_key_other;
                    199:   tme_recode_thunk_off_t insns_thunk;
                    200: 
                    201:   /* if this PC has no source key: */
                    202:   src_key = _tme_sparc_recode_chain_src_key(ic, address);
                    203:   if (__tme_predict_false(src_key == TME_SPARC_RECODE_SRC_KEY_UNDEF)) {
                    204: 
                    205:     /* the lookup fails: */
                    206:     return (0);
                    207:   }
                    208: 
                    209:   /* hash the source address key: */
                    210:   src_hash_i
                    211:     = ((((src_key
                    212:          / sizeof(tme_uint32_t))
                    213:         % TME_SPARC_RECODE_SRC_HASH_MODULUS)
                    214:        * TME_SPARC_RECODE_SRC_HASH_SIZE_SET)
                    215:        + (TME_SPARC_RECODE_SRC_HASH_SIZE_SET
                    216:          - 1));
                    217: 
                    218:   /* search for the source address key in the hash: */
                    219:   src_hash_probe = TME_SPARC_RECODE_SRC_HASH_SIZE_PROBE;
                    220:   for (;;) {
                    221: 
                    222:     /* get the source address key at this position: */
                    223:     src_key_other
                    224:       = (ic->tme_sparc_recode_src_hash
                    225:         [src_hash_i / TME_SPARC_RECODE_SRC_HASH_SIZE_ELEMENT]
                    226:         .tme_sparc_recode_src_hash_keys
                    227:         [src_hash_i % TME_SPARC_RECODE_SRC_HASH_SIZE_ELEMENT]);
                    228: 
                    229:     /* if we found the source address key, stop now: */
                    230:     if (src_key_other == src_key) {
                    231:       break;
                    232:     }
                    233: 
                    234:     /* if this position in the hash is free: */
                    235:     if (src_key_other == TME_SPARC_RECODE_SRC_KEY_UNDEF) {
                    236: 
                    237:       /* the lookup fails: */
                    238:       return (0);
                    239:     }
                    240: 
                    241:     /* if we have searched enough: */
                    242:     if (__tme_predict_false(--src_hash_probe < 0)) {
                    243: 
                    244:       /* XXX FIXME - add a counter here? */
                    245: 
                    246:       /* the lookup fails: */
                    247:       return (0);
                    248:     }
                    249: 
                    250:     /* move to the next position to search: */
                    251:     if (__tme_predict_false(((signed long) --src_hash_i) < 0)) {
                    252:       src_hash_i
                    253:        = ((TME_SPARC_RECODE_SRC_HASH_MODULUS
                    254:            * TME_SPARC_RECODE_SRC_HASH_SIZE_SET)
                    255:           - 1);
                    256:     }
                    257:   }
                    258: 
                    259:   /* assume that this source address has been recoded, and get the
                    260:      instructions thunk: */
                    261:   insns_thunk
                    262:     = (ic->tme_sparc_recode_src_hash
                    263:        [src_hash_i / TME_SPARC_RECODE_SRC_HASH_SIZE_ELEMENT]
                    264:        .tme_sparc_recode_src_hash_values
                    265:        [src_hash_i % TME_SPARC_RECODE_SRC_HASH_SIZE_ELEMENT]);
                    266: 
                    267:   /* if the source address has not been recoded yet: */
                    268:   if (__tme_predict_false(insns_thunk & TME_BIT(0))) {
                    269: 
                    270:     /* the lookup fails: */
                    271:     return (0);
                    272:   }
                    273: 
                    274:   /* the lookup succeeds: */
                    275:   return (insns_thunk);
                    276: }
                    277: 
                    278: /* this tries to fix up a chain: */
                    279: static tme_recode_thunk_off_t
                    280: _tme_sparc_recode_chain_fixup(struct tme_ic * const _ic,
                    281:                              tme_recode_thunk_off_t const chain_fixup,
                    282:                              tme_uint32_t const chain_info)
                    283: {
                    284:   struct tme_sparc *ic;
                    285:   tme_recode_thunk_off_t insns_thunk_next;
                    286:   tme_recode_thunk_off_t insns_thunk_return;
                    287: 
                    288:   /* we can't chain if we're verifying: */
                    289:   if (_tme_sparc_recode_verify_on) {
                    290: 
                    291:     /* the fixup fails: */
                    292:     return (0);
                    293:   }
                    294: 
                    295:   /* recover our ic: */
                    296:   ic = (struct tme_sparc *) _ic;
                    297: 
                    298:   /* if the next PC has not been recoded: */
                    299:   insns_thunk_next
                    300:     = _tme_sparc_recode_chain_insns_thunk(ic,
                    301:                                          ic->tme_sparc_ireg(TME_SPARC_IREG_PC_NEXT));
                    302:   if (insns_thunk_next == 0) {
                    303: 
                    304:     /* the fixup fails: */
                    305:     return (0);
                    306:   }
                    307: 
                    308:   /* if this chain is a call: */
                    309:   if (chain_info & TME_RECODE_CHAIN_INFO_CALL) {
                    310: 
                    311:     /* if the standard return address has not been recoded: */
                    312:     /* NB: PC currently points to the branch delay slot after the
                    313:        call.  the standard return address is the next instruction
                    314:        after that: */
                    315:     insns_thunk_return
                    316:       = _tme_sparc_recode_chain_insns_thunk(ic,
                    317:                                            (ic->tme_sparc_ireg(TME_SPARC_IREG_PC)
                    318:                                             + sizeof(tme_uint32_t)));
                    319:     if (insns_thunk_return == 0) {
                    320: 
                    321:       /* the fixup fails: */
                    322:       return (0);
                    323:     }
                    324:   }
                    325: 
                    326:   /* otherwise, this chain is not a call: */
                    327:   else {
                    328: 
                    329:     /* silence uninitialized variable warnings: */
                    330:     insns_thunk_return = 0;
                    331:   }
                    332: 
                    333:   /* fix up the chain: */
                    334:   return (tme_recode_chain_fixup(ic->tme_sparc_recode_ic,
                    335:                                 chain_fixup,
                    336:                                 chain_info,
                    337:                                 insns_thunk_next,
                    338:                                 insns_thunk_return));
                    339: }
                    340: 
                    341: /* this updates a recode ITLB entry: */
                    342: void
                    343: tme_sparc_recode_chain_tlb_update(struct tme_sparc *ic,
                    344:                                  const struct tme_sparc_ls *ls)
                    345: {
                    346:   struct tme_sparc_tlb *itlb;
                    347:   struct _TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,/**/) *recode_itlb;
                    348:   tme_uint32_t tlb_flags_chain;
                    349:   tme_uint32_t itlb_page_size;
                    350:   tme_sparc_ireg_t recode_itlb_page;
                    351: 
                    352:   /* get the sparc ITLB entry: */
                    353:   itlb = ls->tme_sparc_ls_tlb;
                    354: 
                    355:   /* get the recode ITLB entry: */
                    356:   recode_itlb = &ic->_TME_SPARC_RECODE_SIZE(tme_sparc_recode_tlb,s)[ls->tme_sparc_ls_tlb_i];
                    357: 
                    358:   /* assume that this recode ITLB entry will assist all fetches
                    359:      (this mask includes at least
                    360:      TME_SPARC_RECODE_TLB_FLAG_CHAIN_USER(ic), and
                    361:      TME_SPARC_RECODE_TLB_FLAG_CHAIN_PRIV(ic): */
                    362:   tlb_flags_chain = TME_RECODE_TLB_FLAGS_MASK(ic->tme_sparc_recode_ic);
                    363: 
                    364:   /* get our ITLB page size: */
                    365:   itlb_page_size = (1 << ic->tme_sparc_tlb_page_size_log2);
                    366: 
                    367:   /* update the recode ITLB entry page: */
                    368:   recode_itlb_page = ls->_TME_SPARC_RECODE_SIZE(tme_sparc_ls_address,/**/) & (0 - (tme_sparc_ireg_t) itlb_page_size);
                    369:   recode_itlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_page) = recode_itlb_page;
                    370: 
                    371:   /* if the sparc ITLB entry covers an entire page for one or more
                    372:      normal ASIs and allows fast reading: */
                    373:   /* NB: we don't check if verification is on, like
                    374:      tme_sparc_recode_ls_tlb_update() does, because instruction
                    375:      fetches aren't verified: */
                    376:   if ((((tme_sparc_ireg_t) itlb->tme_sparc_tlb_addr_first)
                    377:        <= recode_itlb_page)
                    378:       && ((recode_itlb_page | (itlb_page_size - 1))
                    379:          <= ((tme_sparc_ireg_t) itlb->tme_sparc_tlb_addr_last))
                    380:       && (itlb->tme_sparc_tlb_asi_mask & TME_SPARC_ASI_MASK_FLAG_SPECIAL) == 0
                    381:       && itlb->tme_sparc_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF) {
                    382: 
                    383:     /* limit the sparc ITLB entry to covering only the single recode
                    384:        page, like the recode ITLB entry does.  this only affects
                    385:        large-page sparc ITLB entries.
                    386: 
                    387:        if we didn't do this, and left a large-page sparc ITLB entry
                    388:        covering more than the one recode page, when a chain far would
                    389:        take a recode ITLB miss on an address actually covered by the
                    390:        large-page corresponding sparc ITLB entry (i.e., miss for an
                    391:        address that aliases to the same sparc/recode ITLB entries for
                    392:        the address we're handling now, where both are in the large
                    393:        page), _TME_SPARC_EXECUTE_NAME() would refuse to do an ITLB
                    394:        refill, and would just try to run the recode instructions thunk
                    395:        again, which would miss again, leading to an endless loop.
                    396: 
                    397:        limiting the sparc ITLB entry like this somewhat hurts the
                    398:        performance of the regular _TME_SPARC_EXECUTE_NAME() executor,
                    399:        which normally would stick with a large-page ITLB entry for as
                    400:        long as possible (even for PCs that wouldn't hash to that
                    401:        entry), but this will only be felt when not running recode
                    402:        instruction thunks, which hopefully won't be often: */
                    403:     itlb->tme_sparc_tlb_addr_first = recode_itlb_page;
                    404:     itlb->tme_sparc_tlb_addr_last = (recode_itlb_page | (itlb_page_size - 1));
                    405: 
                    406:     /* update the recode ITLB entry page memory pointer: */
                    407:     recode_itlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_memory)
                    408:       = (itlb->tme_sparc_tlb_emulator_off_read
                    409:         + recode_itlb_page);
                    410: 
                    411:     /* if this sparc ITLB entry allows user fetches: */
                    412:     if (TME_SPARC_TLB_ASI_MASK_OK(itlb, 
                    413:                                  (TME_SPARC_VERSION(ic) >= 9
                    414:                                   ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    415:                                   : TME_SPARC32_ASI_MASK_UI))) {
                    416: 
                    417:       /* this recode ITLB entry won't need an assist for user
                    418:         fetches: */
                    419:       tlb_flags_chain -= TME_SPARC_RECODE_TLB_FLAG_CHAIN_USER(ic);
                    420:     }
                    421: 
                    422:     /* if this sparc ITLB entry allows privileged/supervisor
                    423:        fetches: */
                    424:     if (TME_SPARC_TLB_ASI_MASK_OK(itlb, 
                    425:                                  (TME_SPARC_VERSION(ic) >= 9
                    426:                                   ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(!TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    427:                                   : TME_SPARC32_ASI_MASK_SI))) {
                    428: 
                    429:       /* this recode ITLB entry won't need an assist for
                    430:         privileged/supervisor fetches: */
                    431:       tlb_flags_chain -= TME_SPARC_RECODE_TLB_FLAG_CHAIN_PRIV(ic);
                    432:     }
                    433: 
                    434:     /* update the recode ITLB entry context: */
                    435:     recode_itlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_context)
                    436:       = itlb->tme_sparc_tlb_context;
                    437: 
                    438:     /* if this sparc ITLB entry matches any context: */
                    439:     if (itlb->tme_sparc_tlb_context > ic->tme_sparc_memory_context_max) {
                    440: 
                    441:       /* this recode ITLB entry doesn't need an assist for fetches
                    442:         whose context mismatches the recode ITLB entry: */
                    443:       tlb_flags_chain -= TME_RECODE_TLB_FLAG_CONTEXT_MISMATCH(ic);
                    444:     }
                    445:   }
                    446: 
                    447:   /* update the recode ITLB entry flags: */
                    448:   recode_itlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_flags) = tlb_flags_chain;
                    449: }
                    450: 
                    451: /* this initializes for chaining: */
                    452: static void
                    453: _tme_sparc_recode_chain_init(struct tme_sparc *ic)
                    454: {
                    455:   struct tme_recode_chain chain;
                    456:   struct tme_recode_address_type *chain_address_type;
                    457: 
                    458:   /* set the offset of the pointer to the token for the current
                    459:      instruction TLB entry: */
                    460:   ic->tme_sparc_recode_ic->tme_recode_ic_itlb_current_token_offset
                    461:     = (((char *) &ic->_tme_sparc_itlb_current_token)
                    462:        - (char *) ic);
                    463: 
                    464:   /* set the chain fixup function: */
                    465:   ic->tme_sparc_recode_ic->tme_recode_ic_chain_fixup
                    466:     = _tme_sparc_recode_chain_fixup;
                    467: 
                    468:   /* set the offset of the chain counter: */
                    469:   ic->tme_sparc_recode_ic->tme_recode_ic_chain_counter_offset
                    470:     = (((char *) &ic->_tme_sparc_instruction_burst_remaining)
                    471:        - (char *) ic);
                    472: 
                    473:   /* set the size of the chain return address stack: */
                    474:   ic->tme_sparc_recode_ic->tme_recode_ic_chain_ras_size
                    475:     = TME_ARRAY_ELS(ic->_tme_sparc_recode_chain_ras);
                    476: 
                    477:   /* set the offset of the chain return address stack: */
                    478:   ic->tme_sparc_recode_ic->tme_recode_ic_chain_ras_offset
                    479:     = (((char *) &ic->_tme_sparc_recode_chain_ras)
                    480:        - (char *) ic);
                    481: 
                    482:   /* set the offset of the chain return address stack pointer: */
                    483:   ic->tme_sparc_recode_ic->tme_recode_ic_chain_ras_pointer_offset
                    484:     = (((char *) &ic->_tme_sparc_recode_chain_ras_pointer)
                    485:        - (char *) ic);
                    486: 
                    487:   /* make the chain thunk: */
                    488:   chain.tme_recode_chain_reg_guest = TME_SPARC_IREG_PC_NEXT;
                    489:   chain_address_type = &chain.tme_recode_chain_address_type;
                    490:   chain_address_type->tme_recode_address_type_context_ic_offset
                    491:     = (((char *) &ic->tme_sparc_memory_context_default) - ((char *) ic));
                    492:   chain_address_type->tme_recode_address_type_context_size = TME_RECODE_SIZE_16;
                    493:   chain_address_type->tme_recode_address_type_size = TME_SPARC_RECODE_SIZE(ic);
                    494:   chain_address_type->tme_recode_address_type_signed = FALSE;
                    495:   chain_address_type->tme_recode_address_type_align_min = sizeof(tme_uint32_t);
                    496:   /* NB: TME_RECODE_RW_FLAG_CONTEXT_MISMATCH() will get set
                    497:      automatically as needed by the chain thunk; there's no need to
                    498:      set it here: */
                    499:   chain_address_type->tme_recode_address_type_tlb_flags
                    500:     = (TME_SPARC_RECODE_TLB_FLAG_CHAIN_USER(ic)
                    501:        | TME_SPARC_RECODE_TLB_FLAG_CHAIN_PRIV(ic));
                    502:   chain_address_type->tme_recode_address_type_tlb_flags_ic_offset
                    503:     = (((char *) &ic->tme_sparc_recode_chain_tlb_flags) - ((char *) ic));
                    504:   chain_address_type->tme_recode_address_type_mask_tlb_index
                    505:     = ((_TME_SPARC_ITLB_HASH_SIZE - 1)
                    506:        * ic->tme_sparc_recode_ic->tme_recode_ic_tlb_page_size);
                    507:   chain_address_type->tme_recode_address_type_tlb0_ic_offset
                    508:     = (((char *) &ic->_TME_SPARC_RECODE_SIZE(tme_sparc_recode_tlb,s)[TME_SPARC_ITLB_ENTRY(ic, 0)])
                    509:        - (char *) ic);
                    510:   ic->tme_sparc_recode_insns_group.tme_recode_insns_group_chain_thunk
                    511:     = tme_recode_chain_thunk(ic->tme_sparc_recode_ic, &chain);
                    512: 
                    513:   /* clear the return address stack: */
                    514:   tme_recode_chain_ras_clear(ic->tme_sparc_recode_ic,
                    515:                             &ic->tme_sparc_ic);
                    516: }

unix.superglobalmegacorp.com

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