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

1.1       root        1: /* $Id: sparc-rc-ls.c,v 1.6 2010/06/05 17:08:57 fredette Exp $ */
                      2: 
                      3: /* ic/sparc/sparc-rc-cc.c - SPARC recode ld/st support: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2008 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-ls.c,v 1.6 2010/06/05 17:08:57 fredette Exp $");
                     39: 
                     40: /* macros: */
                     41: 
                     42: /* rename various things by the architecture size: */
                     43: #define _tme_sparc_recode_ls_assist_check _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_ls_assist_check)
                     44: #define _tme_sparc_recode_ls_assist_ld _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_ls_assist_ld)
                     45: #define _tme_sparc_recode_ls_assist_st _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_ls_assist_st)
                     46: #define tme_sparc_recode_ls_tlb_update _TME_SPARC_RECODE_SIZE(tme_sparc,_recode_ls_tlb_update)
                     47: #define _tme_sparc_recode_ls_init _TME_SPARC_RECODE_SIZE(_tme_sparc,_recode_ls_init)
                     48: 
                     49: #endif /* TME_SPARC_RECODE_SIZE(ic) == TME_RECODE_SIZE_32 */
                     50: 
                     51: /* this checks whether a load or store needs an assist: */
                     52: void
                     53: _tme_sparc_recode_ls_assist_check(const struct tme_sparc *ic,
                     54:                                  tme_recode_uguest_t recode_address,
                     55:                                  int assisted)
                     56: {
                     57:   tme_uint32_t sparc_insn;
                     58:   unsigned int reg_rs2;
                     59:   tme_sparc_ireg_t sparc_address;
                     60:   unsigned int reg_rs1;
                     61:   tme_uint32_t sparc_opcode;
                     62:   tme_bus_context_t context;
                     63:   tme_uint32_t asi_mask_flags_assist;
                     64:   unsigned int asi;
                     65:   tme_uint32_t asi_mask_flags;
                     66:   const struct tme_sparc_tlb *dtlb;
                     67:   tme_uint32_t asi_mask;
                     68:   tme_uint32_t dtlb_page_size;
                     69:   tme_sparc_ireg_t sparc_page;
                     70: 
                     71:   /* get the instruction: */
                     72:   sparc_insn = ic->_tme_sparc_insn;
                     73: 
                     74:   /* if the i bit is zero: */
                     75:   if ((sparc_insn & TME_BIT(13)) == 0) {
                     76: 
                     77:     /* decode rs2: */
                     78:     reg_rs2 = TME_FIELD_MASK_EXTRACTU(sparc_insn, TME_SPARC_FORMAT3_MASK_RS2);
                     79:     TME_SPARC_REG_INDEX(ic, reg_rs2);
                     80:     sparc_address = ic->tme_sparc_ireg(reg_rs2);
                     81:   }
                     82: 
                     83:   /* otherwise, the i bit is one: */
                     84:   else {
                     85: 
                     86:     /* decode simm13: */
                     87:     sparc_address = TME_FIELD_MASK_EXTRACTS(sparc_insn, (tme_sparc_ireg_t) 0x1fff);
                     88:   }
                     89: 
                     90:   /* decode rs1: */
                     91:   reg_rs1 = TME_FIELD_MASK_EXTRACTU(sparc_insn, TME_SPARC_FORMAT3_MASK_RS1);
                     92:   TME_SPARC_REG_INDEX(ic, reg_rs1);
                     93:   sparc_address += ic->tme_sparc_ireg(reg_rs1);
                     94: 
                     95:   /* mask the addresses: */
                     96:   if (TME_SPARC_VERSION(ic) >= 9) {
                     97:     sparc_address &= ic->tme_sparc_address_mask;
                     98:     recode_address &= ic->tme_sparc_address_mask;
                     99:   }
                    100: 
                    101:   /* check the address: */
                    102:   assert (sparc_address == (tme_sparc_ireg_t) recode_address);
                    103: 
                    104:   /* if this instruction is being assisted, return now: */
                    105:   if (assisted) {
                    106:     return;
                    107:   }
                    108: 
                    109:   /* the verifier must not be on: */
                    110:   assert (!_tme_sparc_recode_verify_on);
                    111: 
                    112:   /* get the instruction opcode: */
                    113:   sparc_opcode = TME_FIELD_MASK_EXTRACTU(sparc_insn, (0x3f << 19));
                    114: 
                    115:   /* the address must be aligned: */
                    116:   assert ((sparc_address
                    117:           & ((TME_SPARC_VERSION(ic) >= 9
                    118:               && (sparc_opcode == 0x0b /* v9: ldx */
                    119:                   || sparc_opcode == 0x0e))
                    120:              ? (sizeof(tme_sparc_ireg_t) - 1)
                    121:              : ((sparc_opcode - 1)
                    122:                 & (sizeof(tme_uint32_t) - 1)))) == 0);
                    123: 
                    124:   /* assume that this load or store uses the default context: */
                    125:   context = ic->tme_sparc_memory_context_default;
                    126:   
                    127:   /* assume that only DTLB ASI mask flags for special ASIs must be assisted: */
                    128:   asi_mask_flags_assist = TME_SPARC_ASI_MASK_FLAG_SPECIAL;
                    129: 
                    130:   /* if this is a v9 CPU, assume that a load or store to a no-fault
                    131:      address must be assisted: */
                    132:   if (TME_SPARC_VERSION(ic) >= 9) {
                    133:     asi_mask_flags_assist += TME_SPARC64_ASI_FLAG_NO_FAULT;
                    134:   }
                    135: 
                    136:   /* if this is a load or store with an alternate space: */
                    137:   if (__tme_predict_false(sparc_insn & TME_BIT(19 + 4))) {
                    138: 
                    139:     /* get the ASI: */
                    140:     asi = ((TME_SPARC_VERSION(ic) >= 9
                    141:            && (sparc_insn & TME_BIT(13)))
                    142:           ? ic->tme_sparc64_ireg_asi
                    143:           : TME_FIELD_MASK_EXTRACTU(sparc_insn, (0xff << 5)));
                    144: 
                    145:     /* get the flags for this ASI: */
                    146:     asi_mask_flags = ic->tme_sparc_asis[asi].tme_sparc_asi_mask_flags;
                    147: 
                    148:     /* if this is a v9 CPU: */
                    149:     if (TME_SPARC_VERSION(ic) >= 9) {
                    150: 
                    151:       /* get the context: */
                    152:       context
                    153:        = (((TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_NUCLEUS)
                    154:            && (asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS))
                    155:           ? 0
                    156:           : (asi_mask_flags & TME_SPARC64_ASI_FLAG_SECONDARY)
                    157:           ? ic->tme_sparc_memory_context_secondary
                    158:           : ic->tme_sparc_memory_context_primary);
                    159:     }
                    160: 
                    161:     /* this must be a load from an alternate space: */
                    162:     assert ((sparc_insn & TME_BIT(19 + 2)) == 0);
                    163: 
                    164:     /* this must be a v9 CPU: */
                    165:     assert (TME_SPARC_VERSION(ic) >= 9);
                    166: 
                    167:     /* this v9 CPU must not be in nucleus context: */
                    168:     /* NB: this implies that when a v9 CPU is in nucleus context, even
                    169:        loads that specify an immediate no-fault ASI are assisted: */
                    170:     assert ((TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_NUCLEUS) == 0
                    171:            || ic->tme_sparc64_ireg_tl == 0);
                    172: 
                    173:     /* this ASI must be the default data ASI with the no-fault bit
                    174:        set: */
                    175:     assert (asi 
                    176:            == (TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data)
                    177:                + TME_SPARC64_ASI_FLAG_NO_FAULT));
                    178: 
                    179:     /* this load doesn't necessarily need an assist if it's to a
                    180:        no-fault address: */
                    181:     asi_mask_flags_assist -= TME_SPARC64_ASI_FLAG_NO_FAULT;
                    182:   }
                    183: 
                    184:   /* get the DTLB entry: */
                    185:   dtlb = &ic->tme_sparc_tlbs[TME_SPARC_DTLB_ENTRY(ic, TME_SPARC_TLB_HASH(ic, context, sparc_address))];
                    186: 
                    187:   /* the DTLB entry must be valid: */
                    188:   assert (!tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb));
                    189: 
                    190:   /* the DTLB entry must match the context: */
                    191:   assert (dtlb->tme_sparc_tlb_context == context
                    192:          || dtlb->tme_sparc_tlb_context > ic->tme_sparc_memory_context_max);
                    193: 
                    194:   /* the DTLB entry must cover the page: */
                    195:   dtlb_page_size = (1 << ic->tme_sparc_tlb_page_size_log2);
                    196:   sparc_page = sparc_address & (0 - (tme_sparc_ireg_t) dtlb_page_size);
                    197:   assert ((((tme_sparc_ireg_t) dtlb->tme_sparc_tlb_addr_first)
                    198:           <= sparc_page)
                    199:          && (((tme_sparc_ireg_t) dtlb->tme_sparc_tlb_addr_last)
                    200:              >= (sparc_page + dtlb_page_size - 1)));
                    201: 
                    202:   /* if the DTLB entry doesn't allow this privilege load or store: */
                    203:   asi_mask
                    204:     = (TME_SPARC_VERSION(ic) >= 9
                    205:        ? (TME_SPARC_PRIV(ic)
                    206:          ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(!TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    207:          : TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER))
                    208:        : (TME_SPARC_PRIV(ic)
                    209:          ? TME_SPARC32_ASI_MASK_SD
                    210:          : TME_SPARC32_ASI_MASK_UD));
                    211:   assert (TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask));
                    212: 
                    213:   /* the DTLB entry ASI flags must not require an assist: */
                    214:   assert ((dtlb->tme_sparc_tlb_asi_mask
                    215:           & asi_mask_flags_assist) == 0);
                    216: 
                    217:   /* the DTLB entry must allow the fast load or store, and if this is
                    218:      a store, it must not allow fast loads, or it must allow both to
                    219:      the same memory: */
                    220:   assert ((sparc_insn & TME_BIT(19 + 2))
                    221:          ? (dtlb->tme_sparc_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF
                    222:             && (dtlb->tme_sparc_tlb_emulator_off_read == TME_EMULATOR_OFF_UNDEF
                    223:                 || dtlb->tme_sparc_tlb_emulator_off_read == dtlb->tme_sparc_tlb_emulator_off_write))
                    224:          : (dtlb->tme_sparc_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF));
                    225: }
                    226: 
                    227: /* the assist function for ld instructions: */
                    228: static tme_recode_uguest_t
                    229: _tme_sparc_recode_ls_assist_ld(struct tme_ic *_ic,
                    230:                               tme_recode_uguest_t address)
                    231: {
                    232:   struct tme_sparc *ic;
                    233:   tme_uint32_t sparc_insn;
                    234:   tme_uint32_t sparc_opcode;
                    235:   int insn_is_ld;
                    236:   unsigned int reg_rd;
                    237: #if TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic)
                    238:   tme_sparc_ireg_t rs1_buffer;
                    239: #endif /* TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic) */
                    240:   tme_sparc_ireg_t rs2;
                    241:   tme_sparc_ireg_t *_rs1;
                    242: 
                    243:   /* recover our ic: */
                    244:   ic = (struct tme_sparc *) _ic;
                    245: 
                    246:   TME_SPARC_STAT(ic, tme_sparc_stats_recode_assist_ld);
                    247: 
                    248:   /* set PC_next_next from PC_next: */
                    249:   ic->tme_sparc_ireg(TME_SPARC_IREG_PC_NEXT_NEXT)
                    250:     = (ic->tme_sparc_ireg(TME_SPARC_IREG_PC_NEXT)
                    251:        + sizeof(tme_uint32_t));
                    252: 
                    253:   /* get the instruction: */
                    254:   sparc_insn = tme_sparc_recode_insn_current(ic);
                    255:   ic->_tme_sparc_insn = sparc_insn;
                    256: 
                    257:   /* see if this instruction is a load: */
                    258:   sparc_opcode = 0x40 + TME_FIELD_MASK_EXTRACTU(sparc_insn, (0x3f << 19));
                    259:   insn_is_ld
                    260:     = (sparc_insn >= 0xc0000000
                    261:        && _tme_sparc_recode_insn_opmap[sparc_opcode] == TME_SPARC_RECODE_INSN_LD);
                    262: 
                    263:   /* if this is a cooperative threading system: */
                    264:   if (TME_THREADS_COOPERATIVE) {
                    265: 
                    266:     /* this instruction must be the original load instruction from
                    267:        when the instructions thunk was recoded.  we have no way to
                    268:        confirm this.  if it's not, because this is a cooperative
                    269:        threading system, that means that either
                    270:        tme_sparc_recode_insn_assist_redispatch(), or
                    271:        tme_sparc_recode(), or the host chain in failed to detect that
                    272:        the page containing this PC is no longer cache-valid: */
                    273:     assert (insn_is_ld);
                    274:   }
                    275: 
                    276:   /* otherwise, this isn't a cooperative threading system: */
                    277:   else {
                    278: 
                    279:     /* if this isn't a load instruction: */
                    280:     if (__tme_predict_false(!insn_is_ld)) {
                    281:       abort();
                    282:     }
                    283: 
                    284:     /* otherwise, this is a load instruction: */
                    285: 
                    286:     /* NB: it's possible that this load instruction is not the
                    287:        original load instruction from when the instructions thunk was
                    288:        recoded.  we have no way of knowing if it is or isn't.  if it
                    289:        isn't, this new load instruction may have different rs1, rs2,
                    290:        and rd fields than the original load instruction: */
                    291:     abort();
                    292:   }
                    293: 
                    294:   TME_SPARC_STAT(ic, tme_sparc_stats_recode_assist_opcode[sparc_opcode]);
                    295: 
                    296:   /* decode rd: */
                    297:   reg_rd = TME_FIELD_MASK_EXTRACTU(sparc_insn, TME_SPARC_FORMAT3_MASK_RD);
                    298:   TME_SPARC_REG_INDEX(ic, reg_rd);
                    299: 
                    300:   /* run the instruction: */
                    301:   rs2 = 0;
                    302: #if TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic)
                    303:   rs1_buffer = address;
                    304:   _rs1 = &rs1_buffer;
                    305: #else  /* TME_RECODE_SIZE_GUEST_MAX == TME_SPARC_RECODE_SIZE(ic) */
                    306:   _rs1 = &address;
                    307: #endif /* TME_RECODE_SIZE_GUEST_MAX == TME_SPARC_RECODE_SIZE(ic) */
                    308: #ifdef _TME_SPARC_RECODE_VERIFY
                    309:   _tme_sparc_recode_ls_assist_check(ic, *_rs1, TRUE);
                    310: #endif /* _TME_SPARC_RECODE_VERIFY */
                    311:   (*ic->_tme_sparc_execute_opmap[sparc_opcode])
                    312:     (ic,
                    313:      _rs1,
                    314:      &rs2,
                    315:      &ic->tme_sparc_ireg(reg_rd));
                    316: 
                    317:   /* set %g0 to zero, in case the instruction changed it: */
                    318:   ic->tme_sparc_ireg(TME_SPARC_G0_OFFSET(ic) + TME_SPARC_IREG_G0) = 0;
                    319: 
                    320:   /* do any required redispatch: */
                    321:   /* NB: in a noncooperative threading system, this will do any needed
                    322:      redispatch after we executed a new load instruction that is
                    323:      different from the original load instruction from when the
                    324:      instructions thunk was recoded.  in that case, we can't return to
                    325:      the instructions thunk since it will take our return value for
                    326:      the rd register in the original instruction, not for the rd
                    327:      register in the new instruction: */
                    328:   /* NB: in any threading system, this will do any needed redispatch
                    329:      after a load instruction changes the state of the system such
                    330:      that we can't return to the instructions thunk.  this is very
                    331:      unusual: */
                    332:   tme_sparc_recode_insn_assist_redispatch(ic);
                    333: 
                    334:   /* return the result: */
                    335:   return (ic->tme_sparc_ireg(reg_rd));
                    336: }
                    337: 
                    338: /* the assist function for st instructions: */
                    339: static void
                    340: _tme_sparc_recode_ls_assist_st(struct tme_ic *_ic,
                    341:                               tme_recode_uguest_t address,
                    342:                               tme_recode_uguest_t rd)
                    343: {
                    344:   struct tme_sparc *ic;
                    345:   tme_uint32_t sparc_insn;
                    346:   tme_uint32_t sparc_opcode;
                    347:   int insn_is_st;
                    348: #if TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic)
                    349:   tme_sparc_ireg_t rs1_buffer;
                    350:   tme_sparc_ireg_t rd_buffer;
                    351: #endif /* TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic) */
                    352:   tme_sparc_ireg_t *_rs1;
                    353:   tme_sparc_ireg_t rs2;
                    354:   tme_sparc_ireg_t *_rd;
                    355: 
                    356:   /* recover our ic: */
                    357:   ic = (struct tme_sparc *) _ic;
                    358: 
                    359:   TME_SPARC_STAT(ic, tme_sparc_stats_recode_assist_st);
                    360: 
                    361:   /* set PC_next_next from PC_next: */
                    362:   ic->tme_sparc_ireg(TME_SPARC_IREG_PC_NEXT_NEXT)
                    363:     = (ic->tme_sparc_ireg(TME_SPARC_IREG_PC_NEXT)
                    364:        + sizeof(tme_uint32_t));
                    365: 
                    366:   /* get the instruction: */
                    367:   sparc_insn = tme_sparc_recode_insn_current(ic);
                    368:   ic->_tme_sparc_insn = sparc_insn;
                    369: 
                    370:   /* see if this instruction is a store: */
                    371:   sparc_opcode = (0x40 + TME_FIELD_MASK_EXTRACTU(sparc_insn, (0x3f << 19)));
                    372:   insn_is_st
                    373:     = (sparc_insn >= 0xc0000000
                    374:        && _tme_sparc_recode_insn_opmap[sparc_opcode] == TME_SPARC_RECODE_INSN_ST);
                    375: 
                    376:   /* if this is a cooperative threading system: */
                    377:   if (TME_THREADS_COOPERATIVE) {
                    378: 
                    379:     /* this instruction must be the original store instruction from
                    380:        when the instructions thunk was recoded.  we have no way to
                    381:        confirm this.  if it's not, because this is a cooperative
                    382:        threading system, that means that either
                    383:        tme_sparc_recode_insn_assist_redispatch(), or
                    384:        tme_sparc_recode(), or the host chain in failed to detect that
                    385:        the page containing this PC is no longer cache-valid: */
                    386:     assert (insn_is_st);
                    387:   }
                    388: 
                    389:   /* otherwise, this isn't a cooperative threading system: */
                    390:   else {
                    391: 
                    392:     /* if this isn't a store instruction: */
                    393:     if (__tme_predict_false(!insn_is_st)) {
                    394:       abort();
                    395:     }
                    396: 
                    397:     /* otherwise, this is a store instruction: */
                    398: 
                    399:     /* NB: it's possible that this store instruction is not the
                    400:        original store instruction from when the instructions thunk was
                    401:        recoded.  we have no way of knowing if it is or isn't.  if it
                    402:        isn't, this new store instruction may have different rs1, rs2,
                    403:        and rd fields than the original store instruction: */
                    404:     abort();
                    405:   }
                    406: 
                    407:   TME_SPARC_STAT(ic, tme_sparc_stats_recode_assist_opcode[sparc_opcode]);
                    408: 
                    409:   /* run the store instruction: */
                    410:   rs2 = 0;
                    411: #if TME_RECODE_SIZE_GUEST_MAX > TME_SPARC_RECODE_SIZE(ic)
                    412:   rs1_buffer = address;
                    413:   rd_buffer = rd;
                    414:   _rs1 = &rs1_buffer;
                    415:   _rd = &rd_buffer;
                    416: #else  /* TME_RECODE_SIZE_GUEST_MAX == TME_SPARC_RECODE_SIZE(ic) */
                    417:   _rs1 = &address;
                    418:   _rd = &rd;
                    419: #endif /* TME_RECODE_SIZE_GUEST_MAX == TME_SPARC_RECODE_SIZE(ic) */
                    420: #ifdef _TME_SPARC_RECODE_VERIFY
                    421:   _tme_sparc_recode_ls_assist_check(ic, *_rs1, TRUE);
                    422: #endif /* _TME_SPARC_RECODE_VERIFY */
                    423:   (*ic->_tme_sparc_execute_opmap[sparc_opcode])
                    424:     (ic, _rs1, &rs2, _rd);
                    425: 
                    426:   /* return no result: */
                    427:   tme_sparc_recode_insn_assist_redispatch(ic);
                    428: }
                    429: 
                    430: /* this updates a recode DTLB entry: */
                    431: void
                    432: tme_sparc_recode_ls_tlb_update(struct tme_sparc *ic,
                    433:                               const struct tme_sparc_ls *ls)
                    434: {
                    435:   const struct tme_sparc_tlb *dtlb;
                    436:   tme_uint32_t dtlb_page_size;
                    437:   struct _TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,/**/) *recode_tlb;
                    438:   tme_uint32_t rw_flags_tlb;
                    439:   tme_sparc_ireg_t recode_tlb_page;
                    440: 
                    441:   /* get the sparc DTLB entry: */
                    442:   dtlb = ls->tme_sparc_ls_tlb;
                    443: 
                    444:   /* get the recode DTLB entry: */
                    445:   recode_tlb = &ic->_TME_SPARC_RECODE_SIZE(tme_sparc_recode_tlb,s)[ls->tme_sparc_ls_tlb_i];
                    446: 
                    447:   /* assume that this recode DTLB entry will assist all loads and
                    448:      stores (this mask includes at least
                    449:      TME_SPARC_RECODE_TLB_FLAG_LD_USER(ic),
                    450:      TME_SPARC_RECODE_TLB_FLAG_LD_PRIV(ic),
                    451:      TME_SPARC_RECODE_TLB_FLAG_ST_USER(ic), and
                    452:      TME_SPARC_RECODE_TLB_FLAG_ST_PRIV(ic)): */
                    453:   rw_flags_tlb = TME_RECODE_TLB_FLAGS_MASK(ic->tme_sparc_recode_ic);
                    454: 
                    455:   /* get our DTLB page size: */
                    456:   dtlb_page_size = (1 << ic->tme_sparc_tlb_page_size_log2);
                    457: 
                    458:   /* update the recode DTLB entry page: */
                    459:   recode_tlb_page = ls->_TME_SPARC_RECODE_SIZE(tme_sparc_ls_address,/**/) & (0 - (tme_sparc_ireg_t) dtlb_page_size);
                    460:   recode_tlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_page) = recode_tlb_page;
                    461: 
                    462:   /* if the sparc DTLB entry covers an entire page for one or more
                    463:      normal ASIs, and verification isn't on: */
                    464:   if ((((tme_sparc_ireg_t) dtlb->tme_sparc_tlb_addr_first)
                    465:        <= recode_tlb_page)
                    466:       && ((recode_tlb_page | (dtlb_page_size - 1))
                    467:          <= ((tme_sparc_ireg_t) dtlb->tme_sparc_tlb_addr_last))
                    468:       && (dtlb->tme_sparc_tlb_asi_mask & TME_SPARC_ASI_MASK_FLAG_SPECIAL) == 0
                    469:       && !_tme_sparc_recode_verify_on) {
                    470: 
                    471:     /* if the sparc DTLB entry allows fast reading: */
                    472:     if (dtlb->tme_sparc_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF) {
                    473: 
                    474:       /* update the recode DTLB entry page memory pointer: */
                    475:       recode_tlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_memory)
                    476:        = (dtlb->tme_sparc_tlb_emulator_off_read
                    477:           + recode_tlb_page);
                    478: 
                    479:       /* if this sparc DTLB entry allows user loads: */
                    480:       if (TME_SPARC_TLB_ASI_MASK_OK(dtlb, 
                    481:                                    (TME_SPARC_VERSION(ic) >= 9
                    482:                                     ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    483:                                     : TME_SPARC32_ASI_MASK_UD))) {
                    484: 
                    485:        /* this recode DTLB entry probably won't need an assist for
                    486:           user loads (a sparc DTLB entry with side-effects will
                    487:           override this): */
                    488:        rw_flags_tlb
                    489:          -= TME_SPARC_RECODE_TLB_FLAG_LD_USER(ic);
                    490:       }
                    491: 
                    492:       /* if this sparc DTLB entry allows privileged/supervisor
                    493:         loads: */
                    494:       if (TME_SPARC_TLB_ASI_MASK_OK(dtlb, 
                    495:                                    (TME_SPARC_VERSION(ic) >= 9
                    496:                                     ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(!TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    497:                                     : TME_SPARC32_ASI_MASK_SD))) {
                    498: 
                    499:        /* this recode DTLB entry probably won't need an assist for
                    500:           privileged/supervisor loads (a sparc DTLB entry with
                    501:           side-effects will override this): */
                    502:        rw_flags_tlb
                    503:          -= TME_SPARC_RECODE_TLB_FLAG_LD_PRIV(ic);
                    504:       }
                    505:     }
                    506: 
                    507:     /* if the sparc DTLB entry allows fast writing, and it either
                    508:        doesn't allow fast reading or the fast read and write pointers
                    509:        are the same: */
                    510:     if (dtlb->tme_sparc_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF
                    511:        && (dtlb->tme_sparc_tlb_emulator_off_read == TME_EMULATOR_OFF_UNDEF
                    512:            || dtlb->tme_sparc_tlb_emulator_off_write == dtlb->tme_sparc_tlb_emulator_off_read)) {
                    513: 
                    514:       /* update the recode DTLB entry page memory pointer: */
                    515:       recode_tlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_memory)
                    516:        = (dtlb->tme_sparc_tlb_emulator_off_write
                    517:           + recode_tlb_page);
                    518: 
                    519:       /* if this sparc DTLB entry allows user stores: */
                    520:       if (TME_SPARC_TLB_ASI_MASK_OK(dtlb, 
                    521:                                    (TME_SPARC_VERSION(ic) >= 9
                    522:                                     ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    523:                                     : TME_SPARC32_ASI_MASK_UD))) {
                    524: 
                    525:        /* this recode DTLB entry probably won't need an assist for
                    526:           user stores (a sparc DTLB entry with side-effects will
                    527:           override this): */
                    528:        rw_flags_tlb
                    529:          -= TME_SPARC_RECODE_TLB_FLAG_ST_USER(ic);
                    530:       }
                    531: 
                    532:       /* if this sparc DTLB entry allows privileged/supervisor
                    533:         stores: */
                    534:       if (TME_SPARC_TLB_ASI_MASK_OK(dtlb, 
                    535:                                    (TME_SPARC_VERSION(ic) >= 9
                    536:                                     ? TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(!TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER)
                    537:                                     : TME_SPARC32_ASI_MASK_SD))) {
                    538: 
                    539:        /* this recode DTLB entry probably won't need an assist for
                    540:           privileged/supervisor stores (a sparc DTLB entry with
                    541:           side-effects will override this): */
                    542:        rw_flags_tlb
                    543:          -= TME_SPARC_RECODE_TLB_FLAG_ST_PRIV(ic);
                    544:       }
                    545:     }
                    546: 
                    547:     /* this recode DTLB entry needs an assist for no-fault loads when
                    548:        the ASI register is not loaded with the correct default
                    549:        no-fault ASI: */
                    550:     assert (rw_flags_tlb & TME_SPARC_RECODE_TLB_FLAG_LD_NF(ic));
                    551: 
                    552:     /* if this sparc DTLB entry does not only allow no-fault loads: */
                    553:     if (TME_SPARC_VERSION(ic) < 9
                    554:        || (dtlb->tme_sparc_tlb_asi_mask & TME_SPARC64_ASI_FLAG_NO_FAULT) == 0) {
                    555: 
                    556:       /* this recode DTLB entry doesn't need an assist for faulting
                    557:         loads: */
                    558:       rw_flags_tlb -= TME_SPARC_RECODE_TLB_FLAG_LD_F(ic);
                    559:     }
                    560: 
                    561:     /* if this sparc DTLB entry is for addresses with side-effects
                    562:        (regardless of whether or not the sparc DTLB entry allows fast
                    563:        reads and/or writes): */
                    564:     if (TME_SPARC_VERSION(ic) >= 9
                    565:        && (dtlb->tme_sparc_tlb_asi_mask & TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS)) {
                    566: 
                    567:       /* this recode DTLB entry needs an assist for all loads and stores: */
                    568:       rw_flags_tlb
                    569:        |= (TME_SPARC_RECODE_TLB_FLAG_LD_USER(ic)
                    570:            | TME_SPARC_RECODE_TLB_FLAG_LD_PRIV(ic)
                    571:            | TME_SPARC_RECODE_TLB_FLAG_ST_USER(ic)
                    572:            | TME_SPARC_RECODE_TLB_FLAG_ST_PRIV(ic));
                    573:     }
                    574: 
                    575:     /* if this is sparc32, or if this sparc64 MMU has an invert-endian bit: */
                    576:     if (TME_SPARC_VERSION(ic) < 9
                    577:        || (TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_INVERT_ENDIAN)) {
                    578: 
                    579:       /* this recode DTLB entry doesn't need an assist for loads and
                    580:         stores based on their explicit endianness: */
                    581:       rw_flags_tlb
                    582:        -= (TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_BIG(ic)
                    583:            + TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_LITTLE(ic));
                    584: 
                    585:       /* if this is sparc32, or if this sparc64 DTLB entry's
                    586:         invert-endian bit is not set: */
                    587:       if (TME_SPARC_VERSION(ic) < 9
                    588:          || (dtlb->tme_sparc_tlb_asi_mask & TME_SPARC64_ASI_FLAG_LITTLE) == 0) {
                    589: 
                    590:        /* this recode DTLB entry doesn't need an assist for loads and
                    591:           stores to invert their endianness: */
                    592:        rw_flags_tlb
                    593:          -= TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_INVERT(ic);
                    594:       }
                    595:     }
                    596: 
                    597:     /* otherwise, we don't know how this v9 MMU affects endianness: */
                    598:     else {
                    599:       assert (FALSE);
                    600:     }
                    601: 
                    602:     /* update the recode DTLB entry context: */
                    603:     recode_tlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_context)
                    604:       = dtlb->tme_sparc_tlb_context;
                    605: 
                    606:     /* if this sparc DTLB entry matches any context: */
                    607:     if (dtlb->tme_sparc_tlb_context > ic->tme_sparc_memory_context_max) {
                    608: 
                    609:       /* this recode DTLB entry doesn't need an assist for loads and
                    610:         stores whose context mismatches the recode DTLB entry: */
                    611:       rw_flags_tlb
                    612:        -= TME_RECODE_TLB_FLAG_CONTEXT_MISMATCH(ic);
                    613:     }
                    614:   }
                    615: 
                    616:   /* update the recode DTLB entry read/write flags: */
                    617:   recode_tlb->_TME_SPARC_RECODE_SIZE(tme_recode_tlb_c16_a,_flags) = rw_flags_tlb;
                    618: }
                    619: 
                    620: /* this initializes for ld and st instructions: */
                    621: static void
                    622: _tme_sparc_recode_ls_init(struct tme_sparc *ic)
                    623: {
                    624:   signed long rw_thunk_index;
                    625:   struct tme_recode_rw rw;
                    626:   tme_uint32_t sparc_opcode_ldu;
                    627:   tme_uint32_t sparc_opcode_st;
                    628:   tme_uint32_t rw_flags_insn_common;
                    629:   tme_uint32_t rw_flags_insn;
                    630:   unsigned int other_signed;
                    631:   unsigned int no_fault;
                    632: 
                    633:   /* initialize the array of read/write thunks: */
                    634:   for (rw_thunk_index = 0;
                    635:        rw_thunk_index < TME_ARRAY_ELS(ic->tme_sparc_recode_rw_thunks);
                    636:        rw_thunk_index++) {
                    637:     ic->tme_sparc_recode_rw_thunks[rw_thunk_index] = NULL;
                    638:   }
                    639: 
                    640:   /* make the common read/write structure for all sizes: */
                    641:   rw.tme_recode_rw_bus_boundary = TME_BIT(TME_SPARC_RECODE_SIZE(ic) - TME_RECODE_SIZE_8);
                    642:   rw.tme_recode_rw_address_type.tme_recode_address_type_context_ic_offset
                    643:     = (((char *) &ic->tme_sparc_memory_context_default) - (char *) ic);
                    644:   rw.tme_recode_rw_address_type.tme_recode_address_type_context_size
                    645:     = TME_RECODE_SIZE_16;
                    646:   rw.tme_recode_rw_address_type.tme_recode_address_type_signed = FALSE;
                    647:   rw.tme_recode_rw_address_type.tme_recode_address_type_tlb_flags_ic_offset
                    648:     = (((char *) &ic->tme_sparc_recode_rw_tlb_flags) - (char *) ic);
                    649:   rw.tme_recode_rw_address_type.tme_recode_address_type_mask_tlb_index
                    650:     = ((_TME_SPARC_DTLB_HASH_SIZE - 1)
                    651:        * ic->tme_sparc_recode_ic->tme_recode_ic_tlb_page_size);
                    652:   rw.tme_recode_rw_address_type.tme_recode_address_type_tlb0_ic_offset
                    653:     = (((char *) &ic->_tme_sparc_tlb_tokens_u) - (char *) ic);
                    654: 
                    655:   /* initialize the read/write structure for the first ld and st
                    656:      instructions: */
                    657:   rw.tme_recode_rw_address_type.tme_recode_address_type_size = TME_SPARC_RECODE_SIZE(ic);
                    658:   rw.tme_recode_rw_memory_endian = TME_ENDIAN_BIG;
                    659:   rw.tme_recode_rw_memory_size = TME_RECODE_SIZE_8;
                    660:   for (;;) {
                    661: 
                    662:     /* get the sparc ld/st opcodes for this size: */
                    663:     sparc_opcode_ldu = TME_BIT(rw.tme_recode_rw_memory_size - TME_RECODE_SIZE_8) % sizeof(tme_uint32_t);
                    664:     sparc_opcode_st = sparc_opcode_ldu + 4;
                    665:     if (TME_SPARC_VERSION(ic) >= 9
                    666:        && rw.tme_recode_rw_memory_size == TME_SPARC_RECODE_SIZE(ic)) {
                    667:       sparc_opcode_ldu = 0x0b; /* v9: ldx */
                    668:       sparc_opcode_st = 0x0e; /* v9: stx */
                    669:     }
                    670: 
                    671:     /* make the common read/write structure for this size: */
                    672:     rw.tme_recode_rw_address_type.tme_recode_address_type_align_min
                    673:       = TME_BIT(rw.tme_recode_rw_memory_size - TME_RECODE_SIZE_8);
                    674: 
                    675:     /* start the common read/write structure flags: */
                    676:     rw_flags_insn_common = 0;
                    677: 
                    678:     /* all loads and stores will need an assist when they encounter a
                    679:        recode TLB entry from the wrong context: */
                    680:     /* NB: TME_RECODE_TLB_FLAG_CONTEXT_MISMATCH() will get set
                    681:        automatically as needed by the read/write thunk; there's no
                    682:        need to set it here: */
                    683: 
                    684:     /* all loads and stores will need an assist when they encounter a
                    685:        recode TLB entry that inverts their endianness: */
                    686:     rw_flags_insn_common |= TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_INVERT(ic);
                    687: 
                    688:     /* all loads and stores will need an assist when they encounter a
                    689:        recode TLB entry that doesn't allow their endianness: */
                    690:     rw_flags_insn_common
                    691:       |= (rw.tme_recode_rw_memory_endian == TME_ENDIAN_BIG
                    692:          ? TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_BIG(ic)
                    693:          : TME_SPARC_RECODE_TLB_FLAG_LS_ENDIAN_LITTLE(ic));
                    694: 
                    695:     /* make the common structure for loads: */
                    696:     rw.tme_recode_rw_write = FALSE;
                    697:     rw.tme_recode_rw_reg_size = TME_SPARC_RECODE_SIZE(ic);
                    698:     rw.tme_recode_rw_guest_func_read = _tme_sparc_recode_ls_assist_ld;
                    699: 
                    700:     /* set the signedness of the (first) ld instructions at this size
                    701:        that we will make a read thunk for: */
                    702:     /* NB: we assume that 8- and 32-bit loads are signed more often
                    703:        than not (because we assume that the C char and int types are
                    704:        used more often than the unsigned char and unsigned int types),
                    705:        so we make their thunks first, assuming that if we made them
                    706:        second, that they might reuse an unsigned thunk and then
                    707:        require extra sign-extension instructions in an instructions
                    708:        thunk: */
                    709:     rw.tme_recode_rw_memory_signed
                    710:       = (rw.tme_recode_rw_memory_size < TME_SPARC_RECODE_SIZE(ic)
                    711:         && (rw.tme_recode_rw_memory_size == TME_RECODE_SIZE_8
                    712:             || rw.tme_recode_rw_memory_size == TME_RECODE_SIZE_32));
                    713: 
                    714:     /* permute over signedness and no-fault, making the read thunk(s)
                    715:        for the ld instruction(s) with this size and endianness: */
                    716:     for (other_signed = 0;
                    717:         other_signed <= (rw.tme_recode_rw_memory_size < TME_SPARC_RECODE_SIZE(ic));
                    718:         other_signed++, rw.tme_recode_rw_memory_signed = !rw.tme_recode_rw_memory_signed) {
                    719:       for (no_fault = 0;
                    720:           no_fault <= (TME_SPARC_VERSION(ic) >= 9);
                    721:           no_fault++) {
                    722: 
                    723:        /* start the read structure flags: */
                    724:        rw_flags_insn = rw_flags_insn_common;
                    725: 
                    726:        /* this load will need an assist when it encounters a recode
                    727:           TLB entry that needs an assist on all loads (because the
                    728:           sparc TLB entry doesn't allow fast reads, or has
                    729:           side-effects) or doesn't allow loads at the current
                    730:           privilege level (at load instruction time, the and of the
                    731:           recode ic read/write flags will leave only one of these
                    732:           flags set): */
                    733:        rw_flags_insn
                    734:          |= (TME_SPARC_RECODE_TLB_FLAG_LD_USER(ic)
                    735:              | TME_SPARC_RECODE_TLB_FLAG_LD_PRIV(ic));
                    736: 
                    737:        /* if this is a no-fault load: */
                    738:        if (no_fault) {
                    739: 
                    740:          /* this no-fault load will need an assist when the ASI
                    741:             register is not loaded with the correct default no-fault
                    742:             ASI (at load instruction time, the and of the recode ic
                    743:             read/write flags will clear this bit if the ASI register
                    744:             is correct, and recode TLB entries always need this
                    745:             assist): */
                    746:          rw_flags_insn |= TME_SPARC_RECODE_TLB_FLAG_LD_NF(ic);
                    747:        }
                    748: 
                    749:        /* otherwise, this is a faulting load: */
                    750:        else {
                    751: 
                    752:          /* this faulting load will need an assist when it encounters
                    753:             a recode TLB entry that doesn't allow faulting loads
                    754:             (i.e., it only allows non-faulting loads): */
                    755:          rw_flags_insn |= TME_SPARC_RECODE_TLB_FLAG_LD_F(ic);
                    756:        }
                    757: 
                    758:        /* make the read thunk for this ld instruction: */
                    759:        rw.tme_recode_rw_address_type.tme_recode_address_type_tlb_flags = rw_flags_insn;
                    760:        ic->tme_sparc_recode_rw_thunks
                    761:          [TME_SPARC_RECODE_RW_THUNK_INDEX(ic,
                    762:                                           rw.tme_recode_rw_address_type.tme_recode_address_type_size,
                    763:                                           rw.tme_recode_rw_memory_endian,
                    764:                                           no_fault,
                    765:                                           (sparc_opcode_ldu
                    766:                                            + (8 * rw.tme_recode_rw_memory_signed)))]
                    767:          /* NB: for an 8-bit little-endian ld instructions, we reuse
                    768:             the 8-bit big-endian read thunk: */
                    769:          = ((rw.tme_recode_rw_memory_size == TME_RECODE_SIZE_8
                    770:              && rw.tme_recode_rw_memory_endian == TME_ENDIAN_LITTLE)
                    771:             ? (ic->tme_sparc_recode_rw_thunks
                    772:                [TME_SPARC_RECODE_RW_THUNK_INDEX(ic,
                    773:                                                 rw.tme_recode_rw_address_type.tme_recode_address_type_size,
                    774:                                                 TME_ENDIAN_BIG,
                    775:                                                 no_fault,
                    776:                                                 (sparc_opcode_ldu
                    777:                                                  + (8 * rw.tme_recode_rw_memory_signed)))])
                    778:             : tme_recode_rw_thunk(ic->tme_sparc_recode_ic, &rw));
                    779:       }
                    780:     }
                    781: 
                    782:     /* make the common structure for reads: */
                    783:     rw.tme_recode_rw_write = TRUE;
                    784:     rw.tme_recode_rw_reg_size = rw.tme_recode_rw_memory_size;
                    785:     rw.tme_recode_rw_guest_func_write = _tme_sparc_recode_ls_assist_st;
                    786: 
                    787:     /* start the write structure flags: */
                    788:     rw_flags_insn = rw_flags_insn_common;
                    789: 
                    790:     /* this store will need an assist when it encounters a recode TLB
                    791:        entry that needs an assist on all store (because the sparc TLB
                    792:        entry doesn't allow fast stores, or has side-effects, or only
                    793:        allows no-fault loads) or doesn't allow stores at the current
                    794:        privilege level (at store instruction time, the and of the
                    795:        recode ic read/write flags will leave only one of these flags
                    796:        set): */
                    797:     rw_flags_insn
                    798:       |= (TME_SPARC_RECODE_TLB_FLAG_ST_USER(ic)
                    799:          | TME_SPARC_RECODE_TLB_FLAG_ST_PRIV(ic));
                    800: 
                    801:     /* make the write thunk for this st instruction: */
                    802:     rw.tme_recode_rw_address_type.tme_recode_address_type_tlb_flags = rw_flags_insn;
                    803:     ic->tme_sparc_recode_rw_thunks
                    804:       [TME_SPARC_RECODE_RW_THUNK_INDEX(ic,
                    805:                                       rw.tme_recode_rw_address_type.tme_recode_address_type_size,
                    806:                                       rw.tme_recode_rw_memory_endian,
                    807:                                       FALSE,
                    808:                                       sparc_opcode_st)]
                    809:       /* NB: for an 8-bit little-endian st instruction, we reuse the
                    810:         8-bit big-endian write thunk: */
                    811:       = ((rw.tme_recode_rw_memory_size == TME_RECODE_SIZE_8
                    812:          && rw.tme_recode_rw_memory_endian == TME_ENDIAN_LITTLE)
                    813:         ? (ic->tme_sparc_recode_rw_thunks
                    814:            [TME_SPARC_RECODE_RW_THUNK_INDEX(ic,
                    815:                                             rw.tme_recode_rw_address_type.tme_recode_address_type_size,
                    816:                                             TME_ENDIAN_BIG,
                    817:                                             FALSE,
                    818:                                             sparc_opcode_st)])
                    819:         : tme_recode_rw_thunk(ic->tme_sparc_recode_ic, &rw));
                    820:   
                    821:     /* advance: */
                    822:     if (++rw.tme_recode_rw_memory_size > TME_SPARC_RECODE_SIZE(ic)) {
                    823:       rw.tme_recode_rw_memory_size = TME_RECODE_SIZE_8;
                    824:       if (rw.tme_recode_rw_memory_endian == TME_ENDIAN_BIG
                    825:          && TME_SPARC_VERSION(ic) >= 9) {
                    826:        rw.tme_recode_rw_memory_endian = TME_ENDIAN_LITTLE;
                    827:       }
                    828:       else {
                    829:        rw.tme_recode_rw_memory_endian = TME_ENDIAN_BIG;
                    830:        if (--rw.tme_recode_rw_address_type.tme_recode_address_type_size
                    831:            < (TME_SPARC_RECODE_SIZE(ic) - (TME_SPARC_VERSION(ic) >= 9))) {
                    832:          break;
                    833:        }
                    834:       }
                    835:     }
                    836:   }
                    837: }

unix.superglobalmegacorp.com

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