|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.