|
|
1.1 root 1: #! /bin/sh
2:
1.1.1.2 ! root 3: # $Id: sparc-insns-auto.sh,v 1.10 2010/06/05 16:13:41 fredette Exp $
1.1 root 4:
5: # ic/sparc/sparc-insns-auto.sh - automatically generates C code
6: # for many SPARC emulation instructions:
7:
8: #
9: # Copyright (c) 2005 Matt Fredette
10: # All rights reserved.
11: #
12: # Redistribution and use in source and binary forms, with or without
13: # modification, are permitted provided that the following conditions
14: # are met:
15: # 1. Redistributions of source code must retain the above copyright
16: # notice, this list of conditions and the following disclaimer.
17: # 2. Redistributions in binary form must reproduce the above copyright
18: # notice, this list of conditions and the following disclaimer in the
19: # documentation and/or other materials provided with the distribution.
20: # 3. All advertising materials mentioning features or use of this software
21: # must display the following acknowledgement:
22: # This product includes software developed by Matt Fredette.
23: # 4. The name of the author may not be used to endorse or promote products
24: # derived from this software without specific prior written permission.
25: #
26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29: # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: # POSSIBILITY OF SUCH DAMAGE.
37: #
38:
39: header=false
40:
41: for option
42: do
43: case $option in
44: --header) header=true ;;
45: esac
46: done
47:
48: PROG=`basename $0`
49: cat <<EOF
50: /* automatically generated by $PROG, do not edit! */
1.1.1.2 ! root 51: _TME_RCSID("\$Id: sparc-insns-auto.sh,v 1.10 2010/06/05 16:13:41 fredette Exp $");
1.1 root 52:
53: EOF
54: if $header; then :; else
55: cat <<EOF
56: #include "sparc-impl.h"
1.1.1.2 ! root 57:
! 58: /* an all-bits-zero float for use with _tme_sparc*_fpu_mem_fpreg(): */
! 59: #if TME_FLOAT_FORMAT_NULL != 0
! 60: #error "TME_FLOAT_FORMAT_NULL changed"
! 61: #endif
! 62: static struct tme_float _tme_sparc_float_null;
1.1 root 63: EOF
64: fi
65:
66: # permute over architecture:
67: #
1.1.1.2 ! root 68: for arch in 32 64; do
1.1 root 69:
70: # the sparc64 support depends on a 64-bit integer type:
71: #
72: if test ${arch} = 64; then
73: echo ""
74: echo "#ifdef TME_HAVE_INT64_T"
75: fi
76:
77: # get the name of the register with the integer condition codes, a
78: # shift value for 32-bit registers, and the architecture version:
79: #
80: if test ${arch} = 32; then
81: ccr=32_PSR
82: ccr_ireg='tme_sparc32_ireg_psr'
83: reg32_shift=''
84: version=8
85: else
86: ccr=64_CCR
87: ccr_ireg='tme_sparc64_ireg_ccr'
88: reg32_shift=' << 1'
89: version=9
90: fi
91:
92: # fix the architecture version:
93: #
94: if $header; then :; else
95: echo ""
96: echo "#undef TME_SPARC_VERSION"
97: echo "#define TME_SPARC_VERSION(ic) (${version})"
98: fi
99:
100: # the alternate ASI function:
101: #
102: if $header; then :; else
1.1.1.2 ! root 103: echo ""
1.1 root 104: echo "static tme_uint32_t"
105: echo "_tme_sparc${arch}_alternate_asi_mask(struct tme_sparc *ic)"
106: echo "{"
107: echo " unsigned int asi_data;"
1.1.1.2 ! root 108: echo " unsigned int asi_mask_flags;"
1.1 root 109: echo " tme_uint32_t asi_mask_data;"
110: echo ""
111: echo " /* get the ASI, assuming that the i bit is zero: */"
112: echo " asi_data = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xff << 5));"
113: if test ${arch} = 32; then
114: echo ""
115: echo " /* this is a privileged instruction: */"
116: echo " TME_SPARC_INSN_PRIV;"
117: echo ""
118: echo " /* if the i bit is one, this is an illegal instruction: */"
119: echo " if (__tme_predict_false(TME_SPARC_INSN & TME_BIT(13))) {"
1.1.1.2 ! root 120: echo " TME_SPARC_INSN_ILL(ic);"
1.1 root 121: echo " }"
122: echo ""
1.1.1.2 ! root 123: echo " /* get the flags for this ASI: */"
! 124: echo " asi_mask_flags = ic->tme_sparc_asis[asi_data].tme_sparc_asi_mask_flags;"
! 125: echo ""
! 126: echo " /* make the ASI mask: */"
! 127: echo " if (asi_mask_flags & TME_SPARC32_ASI_MASK_FLAG_SPECIAL) {"
! 128: echo " asi_mask_data"
! 129: echo " = TME_SPARC_ASI_MASK_SPECIAL(asi_data, TRUE);"
! 130: echo " }"
! 131: echo " else {"
! 132: echo " asi_mask_data = TME_SPARC32_ASI_MASK(asi_data, asi_data);"
1.1 root 133: echo " }"
134: else
135: echo ""
136: echo " /* if the i bit is one, use the address space in the ASI register: */"
137: echo " if (TME_SPARC_INSN & TME_BIT(13)) {"
1.1.1.2 ! root 138: echo " asi_data = ic->tme_sparc64_ireg_asi;"
1.1 root 139: echo " }"
140: echo ""
1.1.1.2 ! root 141: echo " /* get the flags for this ASI: */"
! 142: echo " asi_mask_flags = ic->tme_sparc_asis[asi_data].tme_sparc_asi_mask_flags;"
1.1 root 143:
144: echo ""
1.1.1.2 ! root 145: echo " /* if this is a nonprivileged access: */"
1.1 root 146: echo " if (!TME_SPARC_PRIV(ic)) {"
147: echo ""
1.1.1.2 ! root 148: echo " /* if this is a restricted ASI: */"
! 149: echo " if (__tme_predict_false((asi_data & TME_SPARC64_ASI_FLAG_UNRESTRICTED) == 0)) {"
! 150: echo ""
! 151: echo " /* force a slow load or store, which will generate the"
! 152: echo " privileged_action trap: */"
! 153: echo " asi_mask_flags |= TME_SPARC_ASI_MASK_FLAG_UNDEF;"
1.1 root 154: echo " }"
1.1.1.2 ! root 155: echo ""
! 156: echo " /* force a nonprivileged access with the ASI: */"
! 157: echo " asi_mask_flags |= TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER;"
! 158: echo " }"
! 159: echo ""
! 160: echo " /* make the ASI mask: */"
! 161: echo " if (asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_SPECIAL) {"
! 162: echo " asi_mask_data"
! 163: echo " = (asi_mask_flags"
! 164: echo " + TME_SPARC_ASI_MASK_SPECIAL(asi_data,"
! 165: echo " ((asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER) == 0)));"
! 166: echo " }"
! 167: echo " else {"
! 168: echo " asi_mask_data = TME_SPARC64_ASI_MASK(asi_data, asi_mask_flags);"
1.1 root 169: echo " }"
170: fi
171: echo ""
1.1.1.2 ! root 172: echo " /* if this ASI has a special handler: */"
! 173: echo " if (__tme_predict_false(ic->tme_sparc_asis[TME_SPARC_ASI_MASK_WHICH(asi_mask_data)].tme_sparc_asi_handler != 0)) {"
! 174: echo ""
! 175: echo " /* force a slow load or store, which will call the special handler: */"
! 176: echo " asi_mask_data |= TME_SPARC_ASI_MASK_FLAG_UNDEF;"
! 177: echo " }"
! 178: echo ""
1.1 root 179: echo " return (asi_mask_data);"
180: echo "}"
181: fi
182:
1.1.1.2 ! root 183: # the FPU load and store common function:
! 184: #
! 185: if $header; then :; else
! 186: echo ""
! 187: echo "static struct tme_float *"
! 188: echo "_tme_sparc${arch}_fpu_mem_fpreg(struct tme_sparc *ic,"
! 189: echo " tme_uint32_t misaligned,"
! 190: echo " struct tme_float *float_buffer)"
! 191: echo "{"
! 192: echo " unsigned int float_format;"
! 193: echo " unsigned int fpreg_format;"
! 194: echo " tme_uint32_t fp_store;"
! 195: echo " unsigned int fpu_mode;"
! 196: echo " unsigned int fpreg_number;"
! 197: echo ""
! 198: echo " /* NB: this checks for various traps by their priority order: */"
! 199: echo ""
! 200: echo " TME_SPARC_INSN_FPU_ENABLED;"
! 201: echo ""
! 202: echo " /* get the floating-point format: */"
! 203: echo " float_format = float_buffer->tme_float_format;"
! 204: echo ""
! 205: echo " /* convert the floating-point format into the ieee754"
! 206: echo " floating-point register file format: */"
! 207: echo "#if (TME_FLOAT_FORMAT_NULL | TME_IEEE754_FPREG_FORMAT_NULL) != 0"
! 208: echo "#error \"TME_FLOAT_FORMAT_ or TME_IEEE754_FPREG_FORMAT_ values changed\""
! 209: echo "#endif"
! 210: echo "#if TME_FLOAT_FORMAT_IEEE754_SINGLE < TME_IEEE754_FPREG_FORMAT_SINGLE"
! 211: echo "#error \"TME_FLOAT_FORMAT_ or TME_IEEE754_FPREG_FORMAT_ values changed\""
! 212: echo "#endif"
! 213: echo "#if (TME_FLOAT_FORMAT_IEEE754_SINGLE / TME_IEEE754_FPREG_FORMAT_SINGLE) != (TME_FLOAT_FORMAT_IEEE754_DOUBLE / TME_IEEE754_FPREG_FORMAT_DOUBLE)"
! 214: echo "#error \"TME_FLOAT_FORMAT_ or TME_IEEE754_FPREG_FORMAT_ values changed\""
! 215: echo "#endif"
! 216: echo " assert (float_format == TME_FLOAT_FORMAT_NULL"
! 217: echo " || float_format == TME_FLOAT_FORMAT_IEEE754_SINGLE"
! 218: echo " || float_format == TME_FLOAT_FORMAT_IEEE754_DOUBLE);"
! 219: echo " fpreg_format = float_format / (TME_FLOAT_FORMAT_IEEE754_SINGLE / TME_IEEE754_FPREG_FORMAT_SINGLE);"
! 220: echo ""
! 221: echo " /* if the memory address is misaligned, return the"
! 222: echo " float buffer now. the eventual load or store will"
! 223: echo " cause the mem_address_not_aligned trap: */"
! 224: echo ""
! 225: echo " /* if the memory address is misaligned: */"
! 226: echo "#if TME_IEEE754_FPREG_FORMAT_NULL != 0 || TME_IEEE754_FPREG_FORMAT_SINGLE != 1 || TME_IEEE754_FPREG_FORMAT_DOUBLE != 2 || TME_IEEE754_FPREG_FORMAT_QUAD != 4"
! 227: echo "#error \"TME_IEEE754_FPREG_FORMAT_ values changed\""
! 228: echo "#endif"
! 229: echo " assert (fpreg_format == TME_IEEE754_FPREG_FORMAT_NULL"
! 230: echo " || fpreg_format == TME_IEEE754_FPREG_FORMAT_SINGLE"
! 231: echo " || fpreg_format == TME_IEEE754_FPREG_FORMAT_DOUBLE"
! 232: echo " || fpreg_format == TME_IEEE754_FPREG_FORMAT_QUAD);"
! 233: echo " misaligned &= ((sizeof(tme_uint32_t) * fpreg_format) - 1);"
! 234: echo " if (__tme_predict_false(misaligned)) {"
! 235: echo ""
! 236: if test ${arch} = 32; then
! 237: echo " return (float_buffer);"
! 238: else
! 239: echo " /* if the memory address is not even 32-bit aligned, or"
! 240: echo " if this SPARC doesn't support loads and stores of this"
! 241: echo " size at 32-bit alignment: */"
! 242: echo " if (misaligned != sizeof(tme_uint32_t)"
! 243: echo "#if TME_IEEE754_FPREG_FORMAT_SINGLE != 1 || (TME_SPARC_MEMORY_FLAG_HAS_LDDF_STDF_32 * TME_IEEE754_FPREG_FORMAT_DOUBLE) != TME_SPARC_MEMORY_FLAG_HAS_LDQF_STQF_32"
! 244: echo "#error \"TME_IEEE754_FPREG_FORMAT_ or TME_SPARC_MEMORY_FLAG_ values changed\""
! 245: echo "#endif"
! 246: echo " || (TME_SPARC_MEMORY_FLAGS(ic)"
! 247: echo " & (TME_SPARC_MEMORY_FLAG_HAS_LDDF_STDF_32 * fpreg_format)) == 0) {"
! 248: echo ""
! 249: echo " return (float_buffer);"
! 250: echo " }"
! 251: fi
! 252: echo " }"
! 253: echo ""
! 254: echo " /* see if this is a floating-point load or store: */"
! 255: echo " /* NB: all of the floating-point instructions that use"
! 256: echo " this preamble have bit two of op3 clear for a load,"
! 257: echo " and set for a store: */"
! 258: echo " fp_store = (TME_SPARC_INSN & TME_BIT(19 + 2));"
! 259: echo ""
! 260: echo " /* if the FPU isn't in execute mode: */"
! 261: echo " fpu_mode = ic->tme_sparc_fpu_mode;"
! 262: echo " if (__tme_predict_false(fpu_mode != TME_SPARC_FPU_MODE_EXECUTE)) {"
! 263: echo ""
! 264: echo " /* if this is a floating-point load, or if this is a"
! 265: echo " floating-point store and a floating-point exception"
! 266: echo " is pending: */"
! 267: echo " if (!fp_store"
! 268: echo " || fpu_mode == TME_SPARC_FPU_MODE_EXCEPTION_PENDING) {"
! 269: echo ""
! 270: echo " /* do an FPU exception check: */"
! 271: echo " tme_sparc_fpu_exception_check(ic);"
! 272: echo " }"
! 273: echo " }"
! 274: echo ""
! 275: echo " /* if this is not a load or store of a floating-point register: */"
! 276: echo " if (fpreg_format == TME_IEEE754_FPREG_FORMAT_NULL) {"
! 277: echo " return (float_buffer);"
! 278: echo " }"
! 279: echo ""
! 280: echo " /* decode rd: */"
! 281: echo " fpreg_number"
! 282: echo " = tme_sparc_fpu_fpreg_decode(ic,"
! 283: echo " TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN,"
! 284: echo " TME_SPARC_FORMAT3_MASK_RD),"
! 285: echo " fpreg_format);"
! 286: echo ""
! 287: echo " /* make sure this floating-point register has the right precision: */"
! 288: echo " tme_sparc_fpu_fpreg_format(ic, fpreg_number, fpreg_format | TME_IEEE754_FPREG_FORMAT_BUILTIN);"
! 289: echo ""
! 290: echo " /* if this is a floating-point load: */"
! 291: echo " if (!fp_store) {"
! 292: echo ""
! 293: echo " /* mark rd as dirty: */"
! 294: echo " TME_SPARC_FPU_DIRTY(ic, fpreg_number);"
! 295: echo " }"
! 296: echo ""
! 297: echo " /* return the floating-point register: */"
! 298: echo " return (&ic->tme_sparc_fpu_fpregs[fpreg_number]);"
! 299: echo "}"
! 300: echo "#define _tme_sparc${arch}_fpu_mem(ic) \\"
! 301: echo " do { _tme_sparc${arch}_fpu_mem_fpreg(ic, 0, &_tme_sparc_float_null); } while (/* CONSTCOND */ 0)"
! 302: fi
! 303:
1.1 root 304: # permute over instruction:
305: #
1.1.1.2 ! root 306: case ${arch} in
! 307: 32) insns_arch= ;;
! 308: 64) insns_arch="ldx stx ldqf stqf ldxa stxa ldfa lddfa stfa stdfa ldqfa stqfa casa casxa mulx sdivx udivx" ;;
! 309: esac
1.1 root 310: for insn in \
311: add \
312: addcc \
313: sub \
314: subcc \
315: or \
316: orcc \
317: orn \
318: orncc \
319: and \
320: andcc \
321: andn \
322: andncc \
323: xor \
324: xorcc \
325: xnor \
326: xnorcc \
327: addx \
328: addxcc \
329: subx \
330: subxcc \
331: taddcc taddcctv \
332: tsubcc tsubcctv \
333: umul umulcc smul smulcc \
334: udiv udivcc sdiv sdivcc \
335: sll \
336: srl \
337: sra \
338: ldb stb \
339: ldh sth \
340: ld st \
341: ldd std \
342: ldstub ldstuba swap swapa \
343: ldba stba \
344: ldha stha \
345: lda sta \
346: ldda stda \
347: jmpl \
348: ldf lddf ldfsr \
349: stf stdf stfsr \
1.1.1.2 ! root 350: fpop1 fpop2 \
1.1 root 351: mulscc \
1.1.1.2 ! root 352: ${insns_arch} \
1.1 root 353: ; do
354:
355: # if we're making the header, just emit declarations:
356: #
357: if $header; then
358: echo "TME_SPARC_FORMAT3_DECL(tme_sparc${arch}_${insn}, tme_uint${arch}_t);"
359: continue
360: fi
361:
362: # an ALU instruction:
363: #
364: case ${insn} in
365: add | sub | or | orn | and | andn | xor | xnor | \
366: addx | subx | umul | smul | udiv | sdiv)
367: cc=false
368: ;;
369: addcc | subcc | orcc | orncc | andcc | andncc | xorcc | xnorcc | \
370: addxcc | subxcc | umulcc | smulcc | udivcc | sdivcc | \
371: taddcc | tsubcc | taddcctv | tsubcctv | \
372: mulscc)
373: cc=true
374: ;;
375: *)
376: cc=
377: ;;
378: esac
379: if test "x${cc}" != x; then
380:
381: # characterize each function:
382: #
383: sign=u ; size_src=${arch} ; size_dst=${arch} ; arith=logical ; with_c= ; tagged=
384: case "${insn}" in
385: add | addcc) op='src1 + src2' ; arith=add ;;
386: sub | subcc) op='src1 - src2' ; arith=sub ;;
387: or | orcc) op='src1 | src2' ;;
388: orn | orncc) op='src1 | ~src2' ;;
389: and | andcc) op='src1 & src2' ;;
390: andn | andncc) op='src1 & ~src2' ;;
391: xor | xorcc) op='src1 ^ src2' ;;
392: xnor | xnorcc) op='src1 ^ ~src2' ;;
393: addx | addxcc) op='src1 + src2' ; arith=add ; with_c=+ ;;
394: subx | subxcc) op='src1 - src2' ; arith=sub ; with_c=- ;;
395: taddcc) op='src1 + src2' ; arith=add ; tagged=x ;;
396: taddcctv) op='src1 + src2' ; arith=add ; tagged=tv ;;
397: tsubcc) op='src1 - src2' ; arith=sub ; tagged=x ;;
398: tsubcctv) op='src1 - src2' ; arith=sub ; tagged=tv ;;
399: umul | umulcc) arith=mul ; size_src=32 ;;
400: smul | smulcc) arith=mul ; size_src=32 ; sign= ;;
401: udiv | udivcc) arith=udiv ; size_src=32 ; size_dst=32 ;;
1.1.1.2 ! root 402: sdiv | sdivcc) arith=sdiv ; size_src=32 ; sign= ;;
1.1 root 403: mulscc) arith=add ; size_src=32 ; size_dst=32 ;;
404: *) echo "$0 internal error: unknown ALU function ${insn}" 1>&2 ; exit 1 ;;
405: esac
406:
407: # open the function:
408: #
409: echo ""
410: echo "/* this does a sparc${arch} \"${insn} SRC1, SRC2, DST\": */"
411: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
412: echo "{"
413:
414: # declare our locals:
415: #
416: echo " tme_${sign}int${size_src}_t src1;"
417: echo " tme_${sign}int${size_src}_t src2;"
418: echo " tme_${sign}int${size_dst}_t dst;"
419: case "${insn}" in
420: umul* | smul* | udiv* | sdiv*)
421: echo " tme_${sign}int64_t val64;"
422: ;;
423: mulscc)
424: echo " tme_uint32_t y;"
425: ;;
426: esac
427: if ${cc}; then
428: echo " tme_uint32_t cc;"
429: fi
1.1.1.2 ! root 430: cc_plus=
1.1 root 431:
432: echo ""
433: echo " /* get the operands: */"
434: echo " src1 = (tme_${sign}int${arch}_t) TME_SPARC_FORMAT3_RS1;"
435: echo " src2 = (tme_${sign}int${arch}_t) TME_SPARC_FORMAT3_RS2;"
436:
437: echo ""
438: echo " /* perform the operation: */"
439: case "${insn}" in
440: umul | umulcc | smul | smulcc)
441: echo " val64 = (((tme_${sign}int64_t) src1) * src2);"
442: echo " ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift}) = (((tme_uint64_t) val64) >> 32);"
443: echo " dst = ((tme_${sign}int64_t) val64);"
444: ;;
445: udiv | udivcc | sdiv | sdivcc)
1.1.1.2 ! root 446: echo " val64 = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift});"
! 447: echo " val64 = (val64 << 32) + (tme_uint32_t) src1;"
! 448: echo " if (__tme_predict_false(src2 == 0)) {"
! 449: echo " tme_sparc${arch}_trap(ic, TME_SPARC${arch}_TRAP_division_by_zero);"
! 450: echo " }"
1.1 root 451: echo " val64 /= src2;"
1.1.1.2 ! root 452: echo " dst = (tme_${sign}int32_t) val64;"
! 453: echo ""
! 454: echo " /* if the division overflowed: */"
! 455: echo " if (dst != val64) {"
! 456: echo ""
! 457: echo " /* return the largest appropriate value: */"
! 458: if test "x${sign}" = xu; then
! 459: echo " dst = 0xffffffff;"
! 460: else
! 461: echo " dst = (tme_int32_t) ((val64 < 0) + (tme_uint32_t) 0x7fffffff);"
! 462: fi
! 463: if ${cc}; then
! 464: echo ""
! 465: echo " /* set V: */"
! 466: echo " cc = TME_SPARC${ccr}_ICC_V;"
! 467: fi
! 468: echo " }"
! 469: if ${cc}; then
! 470: echo ""
! 471: echo " /* otherwise, the division didn't overflow: */"
! 472: echo " else {"
! 473: echo ""
! 474: echo " /* clear V: */"
! 475: echo " cc = !TME_SPARC${ccr}_ICC_V;"
! 476: echo " }"
! 477: cc_plus='+'
! 478: fi
1.1 root 479: ;;
480: mulscc)
481: echo ""
482: echo " /* \"(1) The multiplier is established as r[rs2] if the i field is zero, or "
483: echo " sign_ext(simm13) if the i field is one.\""
484: echo ""
485: echo " \"(3) If the least significant bit of the Y register = 1, the shifted"
486: echo " value from step (2) is added to the multiplier. If the LSB of the"
487: echo " Y register = 0, then 0 is added to the shifted value from step (2).\" */"
488: echo " y = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift});"
489: echo " if ((y & 1) == 0) {"
490: echo " src2 = 0;"
491: echo " }"
492: echo ""
493: echo " /* \"(6) The Y register is shifted right by one bit, with the LSB of the"
494: echo " unshifted r[rs1] replacing the MSB of Y.\" */"
495: echo " y >>= 1;"
496: echo " if (src1 & 1) {"
497: echo " y += 0x80000000;"
498: echo " }"
499: echo " ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y${reg32_shift}) = y;"
500: echo ""
501: echo " /* \"(2) A 32-bit value is computed by shifting r[rs1] right by one"
502: echo " bit with (N xor V) from the PSR replacing the high-order bit."
503: echo " (This is the proper sign for the previous partial product.)\" */"
504: echo " src1 >>= 1;"
505: echo " if (((ic->${ccr_ireg} ^ (ic->${ccr_ireg} * (TME_SPARC${ccr}_ICC_N / TME_SPARC${ccr}_ICC_V))) & TME_SPARC${ccr}_ICC_N) != 0) {"
506: echo " src1 += 0x80000000;"
507: echo " }"
508: echo ""
509: echo " /* \"(4) The sum from step (3) is written into r[rd].\" */"
510: echo " dst = src1 + src2;"
511: echo ""
512: echo " /* \"(5) The integer condition codes, icc, are updated according to the"
513: echo " addition performed in step (3).\" */"
514: ;;
515: *)
516: echo " dst = ${op};"
517: if test "x${with_c}" != x; then
518: echo " dst ${with_c}= ((ic->${ccr_ireg} & TME_SPARC${ccr}_ICC_C) != 0);"
519: fi
520: esac
521:
522: # unless this is a tagged-and-trap-on-overflow operation:
523: #
524: if test "x${tagged}" != xtv; then
525: echo ""
526: echo " /* store the destination: */"
527: echo " TME_SPARC_FORMAT3_RD = (tme_${sign}int${arch}_t) dst;"
528: fi
529:
530: # if this instruction modifies the condition codes:
531: #
532: if ${cc}; then
533:
534: # set the 32-bit, and possibly the 64-bit, condition codes:
535: #
536: arch_cc=16
537: while test `expr ${arch_cc} \< ${arch}` = 1; do
538: arch_cc=`expr ${arch_cc} \* 2`
539:
540: case ${arch_cc} in
541: 32) xcc=ICC ;;
542: 64) xcc=XCC ;;
543: esac
544:
1.1.1.2 ! root 545: echo ""
! 546: echo " /* set Z if the destination is zero: */"
! 547: echo " cc ${cc_plus}= ((((tme_int${arch_cc}_t) dst) == 0) * TME_SPARC${ccr}_${xcc}_Z);"
! 548: cc_plus='+'
! 549:
! 550: if test `expr ${arch_cc} \<= ${size_dst}` = 1; then
1.1 root 551: echo ""
552: echo " /* set N if the destination is negative: */"
553: echo " cc += ((((tme_int${arch_cc}_t) dst) < 0) * TME_SPARC${ccr}_${xcc}_N);"
554: fi
555:
556: case $arith in
557: add)
558: ones="(((tme_${sign}int${arch_cc}_t) 0) - 1)"
559:
560: echo ""
561: echo " /* if the operands are the same sign, and the destination has"
562: echo " a different sign, set V: */"
563: echo " cc += ((((tme_int${arch_cc}_t) ((src2 ^ dst) & (src1 ^ (src2 ^ ${ones})))) < 0) * TME_SPARC${ccr}_${xcc}_V);"
564:
565: echo ""
566: echo " /* if src1 and src2 both have the high bit set, or if dst does"
567: echo " not have the high bit set and either src1 or src2 does, set C: */"
568: echo " cc += (((tme_int${arch_cc}_t) (((tme_uint${arch_cc}_t) (src1 & src2)) | ((((tme_uint${arch_cc}_t) dst) ^ ${ones}) & ((tme_uint${arch_cc}_t) (src1 | src2))))) < 0) * TME_SPARC${ccr}_${xcc}_C;"
569: ;;
570: sub)
571:
572: echo ""
573: echo " /* if the operands are different signs, and the destination has"
574: echo " a different sign from the first operand, set V: */"
575: echo " cc += ((((tme_int${arch_cc}_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC${ccr}_${xcc}_V);"
576:
577: echo ""
578: echo " /* if src2 is greater than src1, set C: */"
579: echo -n " cc += ((((tme_uint${arch_cc}_t) src2) > ((tme_uint${arch_cc}_t) src1))"
580: if test "x${with_c}" != x; then
581: echo -n " || (((tme_uint${arch_cc}_t) src2) == ((tme_uint${arch_cc}_t) src1) && (ic->${ccr_ireg} & TME_SPARC${ccr}_ICC_C))"
582: fi
583: echo ") * TME_SPARC${ccr}_${xcc}_C;"
584: ;;
585: logical | mul)
586: ;;
1.1.1.2 ! root 587: udiv | sdiv)
! 588: # the udivcc and sdivcc V are handled in the operation code
1.1 root 589: ;;
590: *) echo "$0 internal error: unknown arithmetic type ${arith}" 1>&2 ; exit 1 ;;
591: esac
592: done
593:
594: # if this is a tagged operation:
595: #
596: if test "x${tagged}" != x; then
597:
598: echo ""
599: echo " /* set V if bits zero or one of src1 or src2 are set: */"
600: echo " cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC${ccr}_ICC_V);"
601:
602: # if this is a tagged-and-trap-on-overflow operation:
603: #
604: if test "x${tagged}" = xtv; then
605:
606: echo ""
607: echo " /* trap on a tagged overflow: */"
608: echo " if (cc & TME_SPARC${ccr}_ICC_V) {"
1.1.1.2 ! root 609: echo " tme_sparc${arch}_trap(ic, TME_SPARC${arch}_TRAP_tag_overflow);"
1.1 root 610: echo " }"
611:
612: echo " /* store the destination: */"
613: echo " TME_SPARC_FORMAT3_RD = (tme_${sign}int${arch}_t) dst;"
614: fi
615: fi
616:
617: echo ""
618: echo " /* set the condition codes: */"
619: echo -n " ic->${ccr_ireg} = "
620: if test ${arch} = 32; then
621: echo -n "(ic->${ccr_ireg} & ~TME_SPARC32_PSR_ICC) | "
622: fi
623: echo "cc;"
624: fi
625:
626: echo ""
627: echo " TME_SPARC_INSN_OK;"
628: echo "}"
629: fi
630:
631: # a shift instruction:
632: #
633: case ${insn} in
634: sll | srl | sra)
635:
636: # get the sign of this shift:
637: #
638: if test ${insn} = sra; then sign= ; else sign=u; fi
639:
640: echo ""
641: echo "/* the sparc${arch} ${insn} function: */"
642: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
643: echo "{"
644: echo " tme_${sign}int${arch}_t dst;"
645: echo " unsigned int count;"
646: echo ""
647: echo " /* get the value and the shift count: */"
648: echo " dst = TME_SPARC_FORMAT3_RS1;"
649: echo " count = TME_SPARC_FORMAT3_RS2;"
650:
651: # if we're on sparc64:
652: #
653: if test ${arch} = 64; then
654:
655: echo ""
656: echo " /* if the X bit is clear: */"
657: echo " if ((TME_SPARC_INSN & TME_BIT(12)) == 0) {"
658: echo ""
659: echo " /* limit the count: */"
660: echo " count %= 32;"
661: if test ${insn} != sll; then
662: echo ""
1.1.1.2 ! root 663: echo " /* clip the value to 32 bits: */"
! 664: echo " dst = (tme_${sign}int32_t) dst;"
1.1 root 665: fi
666: echo " }"
667: fi
668:
669: echo ""
670: echo " /* limit the count: */"
671: echo " count %= ${arch};"
672: echo ""
673: echo " /* do the shift: */"
674: if test "${insn}" = sra; then
675: echo "#ifdef SHIFTSIGNED_INT${arch}_T"
676: fi
1.1.1.2 ! root 677: echo "#if defined(SHIFTMAX_INT${arch}_T) && (SHIFTMAX_INT${arch}_T < (${arch} - 1))"
1.1 root 678: echo "#error \"cannot do full shifts of a tme_int${arch}_t\""
679: echo "#endif /* (SHIFTMAX_INT${arch}_T < (${arch} - 1)) */"
680: if test ${insn} = sll; then
681: echo " dst <<= count;"
682: else
683: echo " dst >>= count;"
684: fi
685: if test "${insn}" = sra; then
686: echo "#else /* !SHIFTSIGNED_INT${arch}_T */"
687: echo " for (; count-- > 0; ) {"
688: echo " dst = (dst & ~((tme_${sign}int${arch}_t) 1)) / 2;"
689: echo " }"
690: echo "#endif /* !SHIFTSIGNED_INT${arch}_T */"
691: fi
692:
693: echo ""
694: echo " /* store the destination: */"
695: echo " TME_SPARC_FORMAT3_RD = dst;"
696: echo ""
697: echo " TME_SPARC_INSN_OK;"
698: echo "}"
699: ;;
700: esac
701:
1.1.1.2 ! root 702: # the sdivx, udivx, and mulx instructions:
! 703: #
! 704: case ${insn} in
! 705: sdivx) sign= ;;
! 706: udivx | mulx) sign=u ;;
! 707: *) sign=x ;;
! 708: esac
! 709: if test "x${sign}" != xx; then
! 710: echo ""
! 711: echo "/* the sparc${arch} ${insn} function: */"
! 712: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
! 713: echo "{"
! 714: echo " tme_${sign}int64_t src1;"
! 715: echo " tme_${sign}int64_t src2;"
! 716: echo " tme_${sign}int64_t dst;"
! 717: echo ""
! 718: echo " /* get the operands: */"
! 719: echo " src1 = TME_SPARC_FORMAT3_RS1;"
! 720: echo " src2 = TME_SPARC_FORMAT3_RS2;"
! 721: echo ""
! 722: echo " /* do the ${insn}: */"
! 723: if test ${insn} = mulx; then
! 724: echo " dst = src1 * src2;"
! 725: else
! 726: echo " if (__tme_predict_false(src2 == 0)) {"
! 727: echo " tme_sparc${arch}_trap(ic, TME_SPARC${arch}_TRAP_division_by_zero);"
! 728: echo " }"
! 729: if test ${insn} = sdivx; then
! 730: echo " dst = (src2 == -1 && src1 == (((tme_int64_t) 1) << 63) ? src1 : src1 / src2);"
! 731: else
! 732: echo " dst = src1 / src2;"
! 733: fi
! 734: fi
! 735: echo ""
! 736: echo " TME_SPARC_FORMAT3_RD = dst;"
! 737: echo " TME_SPARC_INSN_OK;"
! 738: echo "}"
! 739: fi
! 740:
1.1 root 741: # a load or store instruction:
742: #
743: size=
744: case "${insn}" in
745: ldb | stb | ldstub | ldba | stba | ldstuba) size=8 ;;
746: ldh | sth | ldha | stha) size=16 ;;
747: ld | st | swap | lda | sta | swapa) size=32 ;;
748: ldd | std | ldda | stda) size=32 ;;
1.1.1.2 ! root 749: ldx | stx | ldxa | stxa | casxa) size=64 ;;
! 750: casa) size=32 ;;
1.1 root 751: esac
752: if test "x${size}" != x; then
753:
754: # set the alternate space indication:
755: #
756: case "${insn}" in
757: *a) alternate=true ;;
758: *) alternate=false ;;
759: esac
760:
761: # set the atomic and double indications:
762: #
763: atomic=false
764: double=false
765: case "${insn}" in
1.1.1.2 ! root 766: ldstub | ldstuba | swap | swapa | casa | casxa) atomic=true ;;
1.1 root 767: ldd* | std*) double=true ; size=64 ;;
768: esac
769:
770: # if this is only a load, we are reading, otherwise we are writing:
771: #
772: cycle=write
773: capcycle=WRITE
774: slow=store
775: case "${insn}" in
776: ldstub*) ;;
777: ld*)
778: cycle=read
779: capcycle=READ
780: slow=load
781: ;;
782: esac
783:
784: # start the instruction:
785: #
786: echo ""
787: echo "/* this does a sparc${arch} ${insn}: */"
788: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
789: echo "{"
790:
791: # our locals:
792: #
793: if ${alternate}; then
794: echo " tme_uint32_t asi_mask_data;"
795: asi_mask_data=asi_mask_data
796: else
797: asi_mask_data="ic->tme_sparc_asi_mask_data"
798: fi
799: echo " tme_uint${arch}_t address;"
1.1.1.2 ! root 800: if test ${arch} = 64 && ${alternate}; then
! 801: echo " tme_bus_context_t context;"
! 802: context=context
! 803: else
! 804: context="ic->tme_sparc_memory_context_default"
! 805: fi
! 806: echo " tme_uint32_t asi_mask_flags_slow;"
1.1 root 807: echo " struct tme_sparc_tlb *dtlb;"
808: echo -n " "
809: if test ${slow} = load; then echo -n "const "; fi
810: echo "tme_shared tme_uint8_t *memory;"
1.1.1.2 ! root 811: echo " tme_bus_context_t dtlb_context;"
! 812: echo " tme_uint32_t endian_little;"
! 813: case "${insn}" in
! 814: ldd* | std* | swap*) echo " tme_uint32_t value32;" ;;
! 815: ldstub*) ;;
! 816: cas*a)
! 817: echo " unsigned int reg_rs2;"
! 818: echo " tme_uint${size}_t value_compare${size};"
! 819: echo " tme_uint${size}_t value_swap${size};"
! 820: echo " tme_uint${size}_t value_read${size};"
! 821: ;;
! 822: ld*)
! 823: echo " tme_uint${size}_t value${size};"
! 824: size_extend=${arch}
! 825: if test `expr ${size} \< ${arch}` = 1; then
! 826: if test `expr ${size} \< 32` = 1; then size_extend=32; fi
! 827: echo " tme_uint${size_extend}_t value${size_extend};"
! 828: fi
! 829: ;;
! 830: st*) echo " tme_uint${size}_t value${size};" ;;
! 831: esac
1.1 root 832:
833: if ${alternate}; then
834: echo ""
835: echo " /* get the alternate ASI mask: */"
836: echo " asi_mask_data = _tme_sparc${arch}_alternate_asi_mask(ic);"
837: fi
838:
839: echo ""
840: echo " /* get the address: */"
1.1.1.2 ! root 841: case "${insn}" in
! 842: cas*a) echo " address = TME_SPARC_FORMAT3_RS1;" ;;
! 843: *) echo " address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;" ;;
! 844: esac
! 845: if test ${arch} = 64; then
! 846: echo " address &= ic->tme_sparc_address_mask;"
! 847: fi
1.1 root 848:
849: echo ""
850: echo "#ifdef _TME_SPARC_STATS"
851: echo " /* track statistics: */"
852: echo " ic->tme_sparc_stats.tme_sparc_stats_memory_total++;"
853: echo "#endif /* _TME_SPARC_STATS */"
854:
1.1.1.2 ! root 855: echo ""
! 856: echo " /* verify and maybe replay this transfer: */"
! 857: if ${double}; then verify_size=32; else verify_size=${size}; fi
! 858: case "${insn}" in
! 859: ld*) verify_flags=TME_SPARC_RECODE_VERIFY_MEM_LOAD ;;
! 860: swap* | cas*a) verify_flags="TME_SPARC_RECODE_VERIFY_MEM_LOAD | TME_SPARC_RECODE_VERIFY_MEM_STORE" ;;
! 861: st*) verify_flags=TME_SPARC_RECODE_VERIFY_MEM_STORE ;;
! 862: *) verify_flags= ;;
! 863: esac
! 864: echo " tme_sparc_recode_verify_mem(ic, &TME_SPARC_FORMAT3_RD,"
! 865: echo " ${asi_mask_data}, address,"
! 866: echo " (TME_RECODE_SIZE_${verify_size}"
! 867: echo " | ${verify_flags}));"
! 868: if ${double}; then
! 869: echo " tme_sparc_recode_verify_mem(ic, &TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch}),"
! 870: echo " ${asi_mask_data}, address + sizeof(tme_uint32_t),"
! 871: echo " (TME_RECODE_SIZE_${verify_size}"
! 872: echo " | ${verify_flags}));"
! 873: fi
! 874: echo " if (tme_sparc_recode_verify_replay_last_pc(ic) != 0) {"
! 875: echo " TME_SPARC_INSN_OK;"
! 876: echo " }"
! 877:
1.1 root 878: # if this is some kind of a store, except for an ldstub:
879: #
880: case "${insn}" in
881: std*)
882: echo ""
883: echo " /* log the values stored: */"
884: echo " tme_sparc_log(ic, 1000, TME_OK, "
885: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 886: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%08\" TME_PRIx32 \" 0x%08\" TME_PRIx32),"
! 887: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
1.1 root 888: echo " address,"
889: echo " (tme_uint32_t) TME_SPARC_FORMAT3_RD,"
1.1.1.2 ! root 890: echo " (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch})));"
1.1 root 891: ;;
1.1.1.2 ! root 892: st* | swap* | cas*a)
1.1 root 893: echo ""
894: echo " /* log the value stored: */"
895: echo " tme_sparc_log(ic, 1000, TME_OK, "
896: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 897: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%0"`expr ${size} / 4`"\" TME_PRIx${size}),"
! 898: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
1.1 root 899: echo " address,"
900: echo " (tme_uint${size}_t) TME_SPARC_FORMAT3_RD));"
901: ;;
902: esac
903:
1.1.1.2 ! root 904: if test "${context}" = context; then
! 905: echo ""
! 906: echo " /* get the context: */"
! 907: if test ${arch} = 64; then
! 908: echo " context = ic->tme_sparc_memory_context_primary;"
! 909: echo " if (__tme_predict_false(${asi_mask_data}"
! 910: echo " & (TME_SPARC64_ASI_FLAG_SECONDARY"
! 911: echo " + TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS))) {"
! 912: echo " if (${asi_mask_data} & TME_SPARC64_ASI_FLAG_SECONDARY) {"
! 913: echo " context = ic->tme_sparc_memory_context_secondary;"
! 914: echo " }"
! 915: echo " else if (TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_NUCLEUS) {"
! 916: echo " context = 0;"
! 917: echo " }"
! 918: echo " }"
! 919: fi
! 920: fi
! 921:
! 922: echo ""
! 923: echo " /* assume that no DTLB ASI mask flags will require a slow ${slow}: */"
! 924: echo " asi_mask_flags_slow = 0;"
! 925: if test ${arch} = 64; then
! 926:
! 927: echo ""
! 928: if test ${slow} != load || ${atomic}; then
! 929: echo " /* a ${insn} traps on no-fault addresses: */"
! 930: else
! 931: echo " /* a ${insn} without a no-fault ASI traps on no-fault addresses: */"
! 932: fi
! 933: echo " asi_mask_flags_slow |= TME_SPARC64_ASI_FLAG_NO_FAULT;"
! 934: if ${atomic}; then
! 935: echo ""
! 936: echo " /* a ${insn} traps on uncacheable addresses with side-effects: */"
! 937: echo " asi_mask_flags_slow |= TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE;"
! 938: fi
! 939:
! 940: if ${alternate}; then
! 941: echo ""
! 942: echo " /* if this ${insn} is using a no-fault ASI: */"
! 943: echo " if (__tme_predict_false(${asi_mask_data} & TME_SPARC64_ASI_FLAG_NO_FAULT)) {"
! 944: echo ""
! 945: if test ${slow} != load || ${atomic}; then
! 946: echo " /* a ${insn} with a no-fault ASI traps: */"
! 947: echo " asi_mask_flags_slow = 0 - (tme_uint32_t) 1;"
! 948: else
! 949: echo " /* a ${insn} with a no-fault ASI traps on addresses with side-effects: */"
! 950: echo " asi_mask_flags_slow = TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS;"
! 951: fi
! 952: echo " }"
! 953: fi
! 954: fi
! 955:
1.1 root 956: echo ""
957: echo " /* get and busy the DTLB entry: */"
1.1.1.2 ! root 958: echo " dtlb = &ic->tme_sparc_tlbs[TME_SPARC_DTLB_ENTRY(ic, TME_SPARC_TLB_HASH(ic, ${context}, address))];"
1.1 root 959: echo " tme_sparc_tlb_busy(dtlb);"
960:
961: echo ""
962: echo " /* assume that this DTLB applies and allows fast transfers: */"
963: echo " memory = dtlb->tme_sparc_tlb_emulator_off_${cycle};"
964:
965: echo ""
1.1.1.2 ! root 966: echo " /* if this DTLB matches any context, it matches this context: */"
! 967: echo " dtlb_context = dtlb->tme_sparc_tlb_context;"
! 968: echo " if (dtlb_context > ic->tme_sparc_memory_context_max) {"
! 969: echo " dtlb_context = ${context};"
! 970: echo " }"
! 971:
! 972: echo ""
1.1 root 973: echo " /* we must call the slow ${slow} function if: */"
974: echo " if (__tme_predict_false("
975: echo ""
976: echo " /* the DTLB entry is invalid: */"
977: echo " tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)"
978: echo ""
1.1.1.2 ! root 979: echo " /* the DTLB entry does not match the context: */"
! 980: echo " || dtlb_context != ${context}"
! 981: echo ""
1.1 root 982: echo " /* the DTLB entry does not cover the needed addresses: */"
1.1.1.2 ! root 983: echo " || (address < (tme_bus_addr${arch}_t) dtlb->tme_sparc_tlb_addr_first)"
! 984: echo " || ((address + ((${size} / 8) - 1)) > (tme_bus_addr${arch}_t) dtlb->tme_sparc_tlb_addr_last)"
1.1 root 985: echo ""
986: echo " /* the DTLB entry does not cover the needed address space: */"
987: echo " || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ${asi_mask_data}))"
988: echo ""
1.1.1.2 ! root 989: echo " /* the DTLB entry can't be used for a fast ${insn}: */"
! 990: echo " || (dtlb->tme_sparc_tlb_asi_mask & asi_mask_flags_slow) != 0"
! 991: echo ""
1.1 root 992: echo " /* the DTLB entry does not allow fast transfers: */"
993: if $atomic; then
994: echo " || (memory != dtlb->tme_sparc_tlb_emulator_off_read)"
995: fi
996: echo " || (memory == TME_EMULATOR_OFF_UNDEF)"
997: if test ${size} != 8; then
998: echo ""
999: echo " /* the address is misaligned: */"
1000: echo " || ((address % (${size} / 8)) != 0)"
1001: fi
1002: if ${double}; then
1003: echo ""
1004: echo " /* the destination register number is odd: */"
1005: echo " || ((TME_SPARC_INSN & TME_BIT(25)) != 0)"
1006: fi
1007: echo ""
1008: echo " )) {"
1009:
1010: echo ""
1011: echo " /* call the slow ${slow} function: */"
1.1.1.2 ! root 1012: echo " memory = tme_sparc${arch}_ls(ic,"
! 1013: echo " address,"
! 1014: echo " &TME_SPARC_FORMAT3_RD,"
! 1015: echo -n " (TME_SPARC_LSINFO_OP_"
1.1 root 1016: if ${atomic}; then
1.1.1.2 ! root 1017: echo "ATOMIC"
! 1018: elif test ${slow} = store; then
! 1019: echo "ST"
! 1020: else
! 1021: echo "LD"
1.1 root 1022: fi
1.1.1.2 ! root 1023: echo -n " | "
! 1024: case ${insn} in
! 1025: ldd* | std*)
! 1026: echo "TME_SPARC_LSINFO_LDD_STD"
! 1027: echo -n " | "
! 1028: ;;
! 1029: esac
1.1 root 1030: if ${alternate}; then
1.1.1.2 ! root 1031: echo "TME_SPARC_LSINFO_ASI(TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF))"
! 1032: echo " | TME_SPARC_LSINFO_A"
! 1033: echo -n " | "
1.1 root 1034: fi
1035: echo "(${size} / 8)));"
1036:
1.1.1.2 ! root 1037: if test ${slow} = store || ${alternate}; then
1.1 root 1038: echo ""
1.1.1.2 ! root 1039: echo " /* if the slow ${slow} function did the transfer: */"
1.1 root 1040: echo " if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {"
1.1.1.2 ! root 1041: echo ""
! 1042: echo " /* unbusy the TLB entry; */"
1.1 root 1043: echo " tme_sparc_tlb_unbusy(dtlb);"
1.1.1.2 ! root 1044:
! 1045: # if this is some kind of a load, log the value loaded:
! 1046: #
! 1047: case ${insn} in
! 1048: ldd*)
! 1049: echo ""
! 1050: echo " /* log the value loaded: */"
! 1051: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD);"
! 1052: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch}));"
! 1053: echo " tme_sparc_log(ic, 1000, TME_OK,"
! 1054: echo " (TME_SPARC_LOG_HANDLE(ic),"
! 1055: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \" 0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \"\"),"
! 1056: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
! 1057: echo " address,"
! 1058: echo " TME_SPARC_FORMAT3_RD,"
! 1059: echo " TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch})));"
! 1060: ;;
! 1061: ld* | ldstub* | swap* | cas*a)
! 1062: echo ""
! 1063: echo " /* log the value loaded: */"
! 1064: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD);"
! 1065: echo " tme_sparc_log(ic, 1000, TME_OK,"
! 1066: echo " (TME_SPARC_LOG_HANDLE(ic),"
! 1067: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%0"`expr ${size} / 4`"\" TME_PRIx${arch}),"
! 1068: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
! 1069: echo " address,"
! 1070: echo " TME_SPARC_FORMAT3_RD));"
! 1071: ;;
! 1072: esac
! 1073: echo ""
1.1 root 1074: echo " TME_SPARC_INSN_OK;"
1075: echo " }"
1076: fi
1077: echo " }"
1078:
1079: echo ""
1.1.1.2 ! root 1080: echo " /* get the byte order of this transfer: */"
! 1081: if test ${arch} = 32; then
! 1082: echo " endian_little = FALSE;"
! 1083: elif test ${arch} = 64; then
! 1084: echo " endian_little = ${asi_mask_data} & TME_SPARC64_ASI_FLAG_LITTLE;"
! 1085: echo " if (__tme_predict_false(dtlb->tme_sparc_tlb_asi_mask & TME_SPARC64_ASI_FLAG_LITTLE)) {"
! 1086: echo " if (TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_INVERT_ENDIAN) {"
! 1087: echo " endian_little ^= TME_SPARC64_ASI_FLAG_LITTLE;"
! 1088: echo " }"
! 1089: echo " else {"
! 1090: echo " assert (FALSE);"
! 1091: echo " }"
! 1092: echo " }"
! 1093: fi
! 1094:
! 1095: echo ""
1.1 root 1096: echo " /* do the fast transfer: */"
1097: echo " memory += address;"
1098:
1099: # dispatch on the instruction:
1100: #
1101: case "${insn}" in
1102: ldd*)
1.1.1.2 ! root 1103: echo " value32 = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint${arch}_t));"
! 1104: echo " value32 = (endian_little ? tme_letoh_u32(value32) : tme_betoh_u32(value32));"
! 1105: echo " TME_SPARC_FORMAT3_RD = value32;"
! 1106: echo " value32 = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 1, sizeof(tme_uint${arch}_t));"
! 1107: echo " value32 = (endian_little ? tme_letoh_u32(value32) : tme_betoh_u32(value32));"
! 1108: echo " TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch}) = value32;"
1.1 root 1109: ;;
1110: std*)
1.1.1.2 ! root 1111: echo " value32 = TME_SPARC_FORMAT3_RD;"
! 1112: echo " value32 = (endian_little ? tme_htole_u32(value32) : tme_htobe_u32(value32));"
! 1113: echo " tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value32, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint${arch}_t));"
! 1114: echo " value32 = TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch});"
! 1115: echo " value32 = (endian_little ? tme_htole_u32(value32) : tme_htobe_u32(value32));"
! 1116: echo " tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value32, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 1, sizeof(tme_uint${arch}_t));"
1.1 root 1117: ;;
1118: ldstub*)
1.1.1.2 ! root 1119: echo " TME_SPARC_FORMAT3_RD = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));"
1.1 root 1120: ;;
1121: swap*)
1.1.1.2 ! root 1122: echo " value32 = TME_SPARC_FORMAT3_RD;"
! 1123: echo " value32 = (endian_little ? tme_htole_u32(value32) : tme_htobe_u32(value32));"
! 1124: echo " value32 = tme_memory_atomic_xchg32((tme_shared tme_uint${size}_t *) memory, value32, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));"
! 1125: echo " value32 = (endian_little ? tme_letoh_u32(value32) : tme_betoh_u32(value32));"
! 1126: echo " TME_SPARC_FORMAT3_RD = value32;"
! 1127: ;;
! 1128: cas*a)
! 1129: echo " reg_rs2 = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RS2);"
! 1130: echo " TME_SPARC_REG_INDEX(ic, reg_rs2);"
! 1131: echo " value_compare${size} = ic->tme_sparc_ireg_uint${arch}(reg_rs2);"
! 1132: echo " value_compare${size} = (endian_little ? tme_htole_u${size}(value_compare${size}) : tme_htobe_u${size}(value_compare${size}));"
! 1133: echo " value_swap${size} = TME_SPARC_FORMAT3_RD;"
! 1134: echo " value_swap${size} = (endian_little ? tme_htole_u${size}(value_swap${size}) : tme_htobe_u${size}(value_swap${size}));"
! 1135: echo " value_read${size} = tme_memory_atomic_cx${size}((tme_shared tme_uint${size}_t *) memory, value_compare${size}, value_swap${size}, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint${size}_t));"
! 1136: echo " value_read${size} = (endian_little ? tme_letoh_u${size}(value_read${size}) : tme_betoh_u${size}(value_read${size}));"
! 1137: echo " TME_SPARC_FORMAT3_RD = value_read${size};"
1.1 root 1138: ;;
1139: ld*)
1.1.1.2 ! root 1140: echo " value${size} = tme_memory_bus_read${size}((const tme_shared tme_uint${size}_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint${size}_t), sizeof(tme_uint${arch}_t));"
1.1 root 1141: if test ${size} != 8; then
1.1.1.2 ! root 1142: echo " value${size} = (endian_little ? tme_letoh_u${size}(value${size}) : tme_betoh_u${size}(value${size}));"
1.1 root 1143: fi
1.1.1.2 ! root 1144: if test `expr ${size} \< ${arch}` = 1; then
! 1145: echo ""
! 1146: echo " /* possibly sign-extend the loaded value: */"
! 1147: echo " value${size_extend} = value${size};"
! 1148: echo " if (TME_SPARC_INSN & TME_BIT(22)) {"
! 1149: echo " value${size_extend} = (tme_uint${size_extend}_t) (tme_int${size_extend}_t) (tme_int${size}_t) value${size_extend};"
! 1150: echo " }"
! 1151: fi
! 1152: echo " TME_SPARC_FORMAT3_RD = (tme_uint${arch}_t) (tme_int${arch}_t) (tme_int${size_extend}_t) value${size_extend};"
1.1 root 1153: ;;
1154: st*)
1.1.1.2 ! root 1155: echo " value${size} = TME_SPARC_FORMAT3_RD;"
! 1156: if test ${size} != 8; then
! 1157: echo " value${size} = (endian_little ? tme_htole_u${size}(value${size}) : tme_htobe_u${size}(value${size}));"
! 1158: fi
! 1159: echo " tme_memory_bus_write${size}((tme_shared tme_uint${size}_t *) memory, value${size}, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint${size}_t), sizeof(tme_uint${arch}_t));"
1.1 root 1160: ;;
1161: *) echo "$PROG internal error: unknown memory insn ${insn}" 1>&2 ; exit 1 ;;
1162: esac
1163:
1164: echo ""
1165: echo " /* unbusy the DTLB entry: */"
1166: echo " tme_sparc_tlb_unbusy(dtlb);"
1167:
1168: # if this is some kind of a load, log the value loaded:
1169: #
1170: case ${insn} in
1171: ldd*)
1172: echo ""
1173: echo " /* log the value loaded: */"
1.1.1.2 ! root 1174: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD);"
! 1175: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch}));"
1.1 root 1176: echo " tme_sparc_log(ic, 1000, TME_OK,"
1177: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 1178: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \" 0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \"\"),"
! 1179: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
1.1 root 1180: echo " address,"
1.1.1.2 ! root 1181: echo " TME_SPARC_FORMAT3_RD,"
! 1182: echo " TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch})));"
1.1 root 1183: ;;
1.1.1.2 ! root 1184: ld* | ldstub* | swap* | cas*a)
1.1 root 1185: echo ""
1186: echo " /* log the value loaded: */"
1.1.1.2 ! root 1187: echo " tme_sparc_recode_verify_mem_load(ic, &TME_SPARC_FORMAT3_RD);"
1.1 root 1188: echo " tme_sparc_log(ic, 1000, TME_OK,"
1189: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 1190: echo " _(\"${insn}\t0x%02x:0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch} \":\t0x%0"`expr ${size} / 4`"\" TME_PRIx${arch}),"
! 1191: echo " TME_SPARC_ASI_MASK_WHICH(${asi_mask_data} & ~TME_SPARC_ASI_MASK_FLAG_UNDEF),"
1.1 root 1192: echo " address,"
1193: echo " TME_SPARC_FORMAT3_RD));"
1194: ;;
1195: esac
1196:
1197: echo ""
1198: echo " TME_SPARC_INSN_OK;"
1199: echo "}"
1200: fi
1201:
1202: # the jmpl instruction:
1203: #
1204: if test ${insn} = jmpl; then
1205:
1206: echo ""
1207: echo "/* this does a sparc${arch} ${insn}: */"
1208: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1209: echo "{"
1210: echo " tme_uint${arch}_t pc_next_next;"
1.1.1.2 ! root 1211: echo " tme_uint32_t ls_faults;"
1.1 root 1212: echo ""
1213: echo " /* \"The JMPL instruction causes a register-indirect delayed control"
1214: echo " transfer to the address given by r[rs1] + r[rs2] if the i field is"
1215: echo " zero, or r[rs1] + sign_ext(simm13) if the i field is one. The JMPL"
1216: echo " instruction copies the PC, which contains the address of the JMPL"
1217: echo " instruction, into register r[rd]. If either of the low-order two"
1218: echo " bits of the jump address is nonzero, a mem_address_not_aligned"
1219: echo " trap occurs.\" */"
1220: echo ""
1.1.1.2 ! root 1221: echo " /* get the target address: */"
1.1 root 1222: echo " pc_next_next = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;"
1.1.1.2 ! root 1223: if test ${arch} = 64; then
! 1224: echo " pc_next_next &= ic->tme_sparc_address_mask;"
! 1225: fi
! 1226: echo ""
! 1227: echo " /* set the delayed control transfer: */"
! 1228: echo " ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_PC_NEXT_NEXT) = pc_next_next;"
! 1229: echo ""
! 1230: echo " /* check the target address: */"
! 1231: echo " ls_faults = TME_SPARC_LS_FAULT_NONE;"
! 1232: if test ${arch} = 64; then
! 1233: echo " if (__tme_predict_false((pc_next_next"
! 1234: echo " + ic->tme_sparc${arch}_ireg_va_hole_start)"
! 1235: echo " > ((ic->tme_sparc${arch}_ireg_va_hole_start * 2) - 1))) {"
! 1236: echo " ls_faults += TME_SPARC64_LS_FAULT_VA_RANGE_NNPC;"
! 1237: echo " }"
! 1238: fi
1.1 root 1239: echo " if (__tme_predict_false((pc_next_next % sizeof(tme_uint32_t)) != 0)) {"
1.1.1.2 ! root 1240: echo " ls_faults += TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;"
! 1241: echo " }"
! 1242: echo " if (__tme_predict_false(ls_faults != TME_SPARC_LS_FAULT_NONE)) {"
! 1243: echo " tme_sparc_nnpc_trap(ic, ls_faults);"
1.1 root 1244: echo " }"
1245: echo ""
1246: echo " /* write the PC of the jmpl into r[rd]: */"
1247: echo " TME_SPARC_FORMAT3_RD = ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_PC);"
1248: echo ""
1249: echo " /* log an indirect call instruction, which has 15 (%o7) for rd: */"
1250: echo " if (TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD) == 15) {"
1251: echo " tme_sparc_log(ic, 250, TME_OK,"
1252: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 1253: echo " _(\"call 0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch}),"
1.1 root 1254: echo " pc_next_next));"
1255: echo " }"
1256: echo ""
1257: echo " /* log a ret or retl instruction, which has 0 (%g0) for rd,"
1258: echo " either 31 (%i7) or 15 (%o7) for rs1, and 8 for simm13: */"
1259: echo " else if ((TME_SPARC_INSN | (16 << 14))"
1260: echo " == ((tme_uint32_t) (0x2 << 30) | (0 << 25) | (0x38 << 19) | (31 << 14) | (0x1 << 13) | 8)) {"
1261: echo " tme_sparc_log(ic, 250, TME_OK,"
1262: echo " (TME_SPARC_LOG_HANDLE(ic),"
1.1.1.2 ! root 1263: echo " _(\"retl 0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch}),"
1.1 root 1264: echo " pc_next_next));"
1265: echo " }"
1266: echo ""
1267: echo " TME_SPARC_INSN_OK;"
1268: echo "}"
1269: fi
1270:
1.1.1.2 ! root 1271: # this may be an alternate-space version of a floating-point
! 1272: # load or store instruction:
! 1273: #
! 1274: case ${insn} in *a) alternate=a ;; *) alternate= ;; esac
! 1275:
1.1 root 1276: # the ldf instruction:
1277: #
1.1.1.2 ! root 1278: if test ${insn} = "ldf${alternate}"; then
1.1 root 1279:
1280: echo ""
1281: echo "/* this does a sparc${arch} ${insn}: */"
1282: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1283: echo "{"
1.1.1.2 ! root 1284: echo " tme_uint32_t misaligned;"
! 1285: echo " struct tme_float float_buffer;"
! 1286: echo " struct tme_float *fpreg;"
! 1287: echo ""
! 1288: echo " /* get the least significant 32 bits of the address: */"
! 1289: echo " misaligned = TME_SPARC_FORMAT3_RS1;"
! 1290: echo " misaligned += (tme_uint32_t) TME_SPARC_FORMAT3_RS2;"
! 1291: if test "${arch}${alternate}" = 64a; then
! 1292: echo ""
! 1293: echo " /* see if the address is misaligned for the ASI: */"
! 1294: echo " misaligned = (*ic->_tme_sparc_ls_asi_misaligned)(ic, misaligned);"
! 1295: fi
1.1 root 1296: echo ""
1297: echo " /* decode rd: */"
1.1.1.2 ! root 1298: echo " float_buffer.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;"
! 1299: echo " fpreg"
! 1300: echo " = _tme_sparc${arch}_fpu_mem_fpreg(ic,"
! 1301: echo " misaligned,"
! 1302: echo " &float_buffer);"
1.1 root 1303: echo ""
1304: echo " /* do the load: */"
1.1.1.2 ! root 1305: echo " tme_sparc${arch}_ld${alternate}(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
1.1 root 1306: echo ""
1307: echo " /* set the floating-point register value: */"
1.1.1.2 ! root 1308: echo " assert (fpreg != &float_buffer);"
! 1309: echo " fpreg->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;"
! 1310: echo " fpreg->tme_float_value_ieee754_single"
1.1 root 1311: echo " = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift});"
1312: echo ""
1313: echo " TME_SPARC_INSN_OK;"
1314: echo "}"
1315: fi
1316:
1317: # the stf instruction:
1318: #
1.1.1.2 ! root 1319: if test ${insn} = "stf${alternate}"; then
1.1 root 1320:
1321: echo ""
1322: echo "/* this does a sparc${arch} ${insn}: */"
1323: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1324: echo "{"
1.1.1.2 ! root 1325: echo " tme_uint32_t misaligned;"
! 1326: echo " struct tme_float float_buffer;"
! 1327: echo " const struct tme_float *fpreg;"
1.1 root 1328: echo " const tme_uint32_t *value_single;"
1329: echo ""
1.1.1.2 ! root 1330: echo " /* get the least significant 32 bits of the address: */"
! 1331: echo " misaligned = TME_SPARC_FORMAT3_RS1;"
! 1332: echo " misaligned += (tme_uint32_t) TME_SPARC_FORMAT3_RS2;"
! 1333: if test "${arch}${alternate}" = 64a; then
! 1334: echo ""
! 1335: echo " /* see if the address is misaligned for the ASI: */"
! 1336: echo " misaligned = (*ic->_tme_sparc_ls_asi_misaligned)(ic, misaligned);"
! 1337: fi
1.1 root 1338: echo ""
1339: echo " /* decode rd: */"
1.1.1.2 ! root 1340: echo " float_buffer.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;"
! 1341: echo " fpreg"
! 1342: echo " = _tme_sparc${arch}_fpu_mem_fpreg(ic,"
! 1343: echo " misaligned,"
! 1344: echo " &float_buffer);"
1.1 root 1345: echo ""
1346: echo " /* get this single floating-point register in IEEE754 single-precision format: */"
1.1.1.2 ! root 1347: echo " value_single = tme_ieee754_single_value_get(fpreg, &float_buffer.tme_float_value_ieee754_single);"
1.1 root 1348: echo ""
1349: echo " /* set the floating-point register value: */"
1350: echo " ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}) = *value_single;"
1351: echo ""
1352: echo " /* do the store: */"
1.1.1.2 ! root 1353: echo " tme_sparc${arch}_st${alternate}(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
1.1 root 1354: echo ""
1.1.1.2 ! root 1355: echo " assert (fpreg != &float_buffer);"
1.1 root 1356: echo " TME_SPARC_INSN_OK;"
1357: echo "}"
1358: fi
1359:
1360: # the lddf instruction:
1361: #
1.1.1.2 ! root 1362: if test ${insn} = "lddf${alternate}"; then
1.1 root 1363:
1364: echo ""
1365: echo "/* this does a sparc${arch} ${insn}: */"
1366: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1367: echo "{"
1.1.1.2 ! root 1368: echo " tme_uint${arch}_t address;"
! 1369: echo " tme_uint32_t misaligned;"
! 1370: echo " struct tme_float float_buffer;"
! 1371: echo " struct tme_float *fpreg;"
! 1372: if test ${arch} != 32; then
! 1373: echo " tme_uint${arch}_t offset;"
! 1374: fi
1.1 root 1375: echo ""
1.1.1.2 ! root 1376: echo " /* get the address: */"
! 1377: echo " address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;"
1.1 root 1378: echo ""
1.1.1.2 ! root 1379: echo " /* get the least significant 32 bits of the address: */"
! 1380: echo " misaligned = address;"
! 1381: if test "${arch}${alternate}" = 64a; then
! 1382: echo ""
! 1383: echo " /* see if the address is misaligned for the ASI: */"
! 1384: echo " misaligned = (*ic->_tme_sparc_ls_asi_misaligned)(ic, misaligned);"
! 1385: fi
1.1 root 1386: echo ""
1.1.1.2 ! root 1387: echo " /* decode rd: */"
! 1388: echo " float_buffer.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
! 1389: echo " fpreg"
! 1390: echo " = _tme_sparc${arch}_fpu_mem_fpreg(ic,"
! 1391: echo " misaligned,"
! 1392: echo " &float_buffer);"
! 1393: echo ""
! 1394: if test ${arch} = 32; then
! 1395: echo " /* do the load: */"
! 1396: echo " tme_sparc${arch}_ldd(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
! 1397: echo ""
! 1398: echo " /* set the double floating-point register value: */"
! 1399: echo " assert (fpreg != &float_buffer);"
! 1400: echo " fpreg->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
! 1401: echo " fpreg->tme_float_value_ieee754_double.tme_value64_uint32_hi"
! 1402: echo " = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 0);"
! 1403: echo " fpreg->tme_float_value_ieee754_double.tme_value64_uint32_lo"
! 1404: echo " = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1);"
! 1405: else
! 1406: echo " /* if bit two of the address is set, and this SPARC supports"
! 1407: echo " 32-bit-aligned ${insn} instructions: */"
! 1408: echo " if ((misaligned & sizeof(tme_uint32_t))"
! 1409: echo " && fpreg != &float_buffer) {"
! 1410: echo ""
! 1411: echo " /* do two 32-bit loads: */"
! 1412: echo " offset = sizeof(tme_uint32_t) * 0;"
! 1413: echo " tme_sparc${arch}_ld${alternate}(ic, &address, &offset, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX + 0));"
! 1414: echo " offset = sizeof(tme_uint32_t) * 1;"
! 1415: echo " tme_sparc${arch}_ld${alternate}(ic, &address, &offset, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX + 1));"
! 1416: echo ""
! 1417: echo " /* set the double floating-point register value: */"
! 1418: echo " fpreg->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
! 1419: echo " fpreg->tme_float_value_ieee754_double.tme_value64_uint32_hi"
! 1420: echo " = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX + 0);"
! 1421: echo " fpreg->tme_float_value_ieee754_double.tme_value64_uint32_lo"
! 1422: echo " = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX + 1);"
! 1423: echo " }"
! 1424: echo ""
! 1425: echo " /* otherwise, bit two of the address is not set, or this SPARC"
! 1426: echo " doesn't support 32-bit-aligned ${insn} instructions: */"
! 1427: echo " else {"
! 1428: echo ""
! 1429: echo " /* do an ldx${alternate}-style load: */"
! 1430: echo " tme_sparc${arch}_ldx${alternate}(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
! 1431: echo ""
! 1432: echo " /* set the double floating-point register value: */"
! 1433: echo " assert (fpreg != &float_buffer);"
! 1434: echo " fpreg->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
! 1435: echo " fpreg->tme_float_value_ieee754_double.tme_value64_uint"
! 1436: echo " = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX);"
! 1437: echo " }"
! 1438: fi
1.1 root 1439: echo ""
1440: echo " TME_SPARC_INSN_OK;"
1441: echo "}"
1442: fi
1443:
1444: # the stdf instruction:
1445: #
1.1.1.2 ! root 1446: if test ${insn} = "stdf${alternate}"; then
1.1 root 1447:
1448: echo ""
1449: echo "/* this does a sparc${arch} ${insn}: */"
1450: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1451: echo "{"
1.1.1.2 ! root 1452: echo " tme_uint${arch}_t address;"
! 1453: echo " tme_uint32_t misaligned;"
! 1454: echo " struct tme_float float_buffer;"
! 1455: echo " struct tme_float *fpreg;"
1.1 root 1456: echo " const union tme_value64 *value_double;"
1.1.1.2 ! root 1457: if test ${arch} != 32; then
! 1458: echo " tme_uint${arch}_t offset;"
! 1459: fi
1.1 root 1460: echo ""
1.1.1.2 ! root 1461: echo " /* get the address: */"
! 1462: echo " address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;"
1.1 root 1463: echo ""
1.1.1.2 ! root 1464: echo " /* get the least significant 32 bits of the address: */"
! 1465: echo " misaligned = address;"
! 1466: if test "${arch}${alternate}" = 64a; then
! 1467: echo ""
! 1468: echo " /* see if the address is misaligned for the ASI: */"
! 1469: echo " misaligned = (*ic->_tme_sparc_ls_asi_misaligned)(ic, misaligned);"
! 1470: fi
1.1 root 1471: echo ""
1.1.1.2 ! root 1472: echo " /* decode rd: */"
! 1473: echo " float_buffer.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;"
! 1474: echo " fpreg"
! 1475: echo " = _tme_sparc${arch}_fpu_mem_fpreg(ic,"
! 1476: echo " misaligned,"
! 1477: echo " &float_buffer);"
1.1 root 1478: echo ""
1479: echo " /* get this double floating-point register in IEEE754 double-precision format: */"
1.1.1.2 ! root 1480: echo " value_double = tme_ieee754_double_value_get(fpreg, &float_buffer.tme_float_value_ieee754_double);"
1.1 root 1481: echo ""
1.1.1.2 ! root 1482: if test ${arch} = 32; then
! 1483: echo " /* set the floating-point register value: */"
! 1484: echo " ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 0)"
! 1485: echo " = value_double->tme_value64_uint32_hi;"
! 1486: echo " ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1)"
! 1487: echo " = value_double->tme_value64_uint32_lo;"
! 1488: echo ""
! 1489: echo " /* do the store: */"
! 1490: echo " tme_sparc${arch}_std(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}));"
! 1491: else
! 1492: echo " /* if bit two of the address is set, and this SPARC supports"
! 1493: echo " 32-bit-aligned ${insn} instructions: */"
! 1494: echo " if ((misaligned & sizeof(tme_uint32_t))"
! 1495: echo " && fpreg != &float_buffer) {"
! 1496: echo ""
! 1497: echo " /* set the floating-point register value: */"
! 1498: echo " ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX + 0)"
! 1499: echo " = value_double->tme_value64_uint32_hi;"
! 1500: echo " ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX + 1)"
! 1501: echo " = value_double->tme_value64_uint32_lo;"
! 1502: echo ""
! 1503: echo " /* do two 32-bit stores: */"
! 1504: echo " offset = sizeof(tme_uint32_t) * 0;"
! 1505: echo " tme_sparc${arch}_st${alternate}(ic, &address, &offset, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX + 0));"
! 1506: echo " offset = sizeof(tme_uint32_t) * 1;"
! 1507: echo " tme_sparc${arch}_st${alternate}(ic, &address, &offset, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX + 1));"
! 1508: echo " }"
! 1509: echo ""
! 1510: echo " /* otherwise, bit two of the address is not set, or this SPARC"
! 1511: echo " doesn't support 32-bit-aligned ${insn} instructions: */"
! 1512: echo " else {"
! 1513: echo ""
! 1514: echo " /* set the floating-point register value: */"
! 1515: echo " ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX)"
! 1516: echo " = value_double->tme_value64_uint;"
! 1517: echo ""
! 1518: echo " /* do an stx${alternate}-style store: */"
! 1519: echo " tme_sparc${arch}_stx${alternate}(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
! 1520: echo " }"
! 1521: fi
1.1 root 1522: echo ""
1.1.1.2 ! root 1523: echo " assert (fpreg != &float_buffer);"
1.1 root 1524: echo " TME_SPARC_INSN_OK;"
1525: echo "}"
1526: fi
1527:
1528: # the ldfsr instruction:
1529: #
1530: if test ${insn} = ldfsr; then
1531:
1532: echo ""
1533: echo "/* this does a sparc${arch} ${insn}: */"
1534: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1535: echo "{"
1536: echo " tme_uint32_t fsr;"
1.1.1.2 ! root 1537: if test ${arch} != 32; then
! 1538: echo " tme_uint32_t reg_rd;"
! 1539: echo ""
! 1540: echo " /* see if this is an ldfsr or an ldxfsr: */"
! 1541: echo " reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
! 1542: echo " if (__tme_predict_false(reg_rd > 1)) {"
! 1543: echo " TME_SPARC_INSN_ILL(ic);"
! 1544: echo " }"
! 1545: fi
1.1 root 1546: echo ""
1.1.1.2 ! root 1547: echo " _tme_sparc${arch}_fpu_mem(ic);"
1.1 root 1548: echo ""
1.1.1.2 ! root 1549: if test ${arch} = 32; then
! 1550: echo " /* do the load: */"
! 1551: else
! 1552: echo " /* if this is an ldxfsr: */"
! 1553: echo " if (reg_rd == 1) {"
! 1554: echo ""
! 1555: echo " /* do the load: */"
! 1556: echo " tme_sparc${arch}_ldx(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
! 1557: echo ""
! 1558: echo " /* update the extended FSR: */"
! 1559: echo " ic->tme_sparc_fpu_xfsr"
! 1560: echo " = (ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1)"
! 1561: echo " & 0x3f /* fcc3 .. fcc1 */);"
! 1562: echo " }"
! 1563: echo ""
! 1564: echo " /* otherwise, this is an ldfsr. do the load: */"
! 1565: echo " else"
! 1566: echo -n " "
! 1567: fi
! 1568: echo " tme_sparc${arch}_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
1.1 root 1569: echo ""
1570: echo " /* update the FSR: */"
1571: echo " fsr = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift});"
1572: echo " /* \"An LDFSR instruction does not affect ftt.\" */"
1573: echo " /* \"The LDFSR instruction does not affect qne.\" */"
1574: echo " fsr &= ~(TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE);"
1575: echo " ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & (TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE)) | fsr;"
1576: echo ""
1577: echo " TME_SPARC_INSN_OK;"
1578: echo "}"
1579: fi
1580:
1581: # the stfsr instruction:
1582: #
1583: if test ${insn} = stfsr; then
1584:
1585: echo ""
1586: echo "/* this does a sparc${arch} ${insn}: */"
1587: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1588: echo "{"
1.1.1.2 ! root 1589: if test ${arch} = 64; then
! 1590: echo " tme_uint32_t reg_rd;"
! 1591: echo ""
! 1592: echo " /* see if this is an stfsr or an stxfsr: */"
! 1593: echo " reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);"
! 1594: echo " if (__tme_predict_false(reg_rd > 1)) {"
! 1595: echo " TME_SPARC_INSN_ILL(ic);"
! 1596: echo " }"
! 1597: fi
1.1 root 1598: echo ""
1.1.1.2 ! root 1599: echo " _tme_sparc${arch}_fpu_mem(ic);"
1.1 root 1600: echo ""
1601: echo " /* set the FSR value to store: */"
1602: echo " ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX${reg32_shift}) = ic->tme_sparc_fpu_fsr;"
1603: echo ""
1.1.1.2 ! root 1604: if test ${arch} = 32; then
! 1605: echo " /* do the store: */"
! 1606: else
! 1607: echo " /* if this is an stxfsr: */"
! 1608: echo " if (reg_rd == 1) {"
! 1609: echo ""
! 1610: echo " /* set in the extended FSR to store and do the store: */"
! 1611: echo " ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX${reg32_shift}) + 1) = ic->tme_sparc_fpu_xfsr;"
! 1612: echo " tme_sparc${arch}_stx(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
! 1613: echo " }"
! 1614: echo ""
! 1615: echo " /* otherwise, this is a stfsr. do the store: */"
! 1616: echo " else"
! 1617: echo -n " "
! 1618: fi
! 1619: echo " tme_sparc${arch}_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint${arch}(TME_SPARC_IREG_FPX));"
1.1 root 1620: echo ""
1621: echo " TME_SPARC_INSN_OK;"
1622: echo "}"
1623: fi
1624:
1625: # the fpop1 and fpop2 instructions:
1626: #
1627: if test ${insn} = fpop1 || test ${insn} = fpop2; then
1628:
1629: echo ""
1630: echo "/* this does a sparc${arch} ${insn}: */"
1631: echo "TME_SPARC_FORMAT3(tme_sparc${arch}_${insn}, tme_uint${arch}_t)"
1632: echo "{"
1633: echo " TME_SPARC_INSN_FPU;"
1634: echo " tme_sparc_fpu_${insn}(ic);"
1635: echo " TME_SPARC_INSN_OK;"
1636: echo "}"
1637: fi
1638:
1639: done
1640:
1.1.1.2 ! root 1641: # the slow atomic function:
! 1642: #
! 1643: if $header; then
! 1644: echo "void tme_sparc${arch}_atomic _TME_P((struct tme_sparc *, struct tme_sparc_ls *));"
! 1645: else
! 1646: echo ""
! 1647: echo "/* this does a slow atomic operation: */"
! 1648: echo "void"
! 1649: echo "tme_sparc${arch}_atomic(struct tme_sparc *ic, struct tme_sparc_ls *ls)"
! 1650: echo "{"
! 1651: echo " tme_uint32_t endian_little;"
! 1652: echo " tme_uint32_t insn;"
! 1653: if test ${arch} = 64; then
! 1654: echo " tme_uint${arch}_t value${arch};"
! 1655: echo " tme_uint${arch}_t value_swap${arch};"
! 1656: echo " unsigned int reg_rs2;"
! 1657: fi
! 1658: echo " tme_uint32_t value32;"
! 1659: echo " tme_uint32_t value_swap32;"
! 1660: echo " tme_uint32_t size;"
! 1661: echo ""
! 1662: echo " /* if this is the beginning of the operation: */"
! 1663: echo " if (ls->tme_sparc_ls_state == 0) {"
! 1664: echo ""
! 1665: echo " /* start the load part of the operation: */"
! 1666: echo " ls->tme_sparc_ls_state = ls->tme_sparc_ls_size;"
! 1667: echo " assert (ls->tme_sparc_ls_state != 0"
! 1668: echo " && (ls->tme_sparc_ls_state & TME_BIT(7)) == 0);"
! 1669: echo ""
! 1670: echo " /* the load must start at the beginning of the buffer: */"
! 1671: echo " assert (ls->tme_sparc_ls_buffer_offset == 0);"
! 1672: echo " }"
! 1673: echo ""
! 1674: echo " /* if this is the load part of the operation: */"
! 1675: echo " if ((ls->tme_sparc_ls_state & TME_BIT(7)) == 0) {"
! 1676: echo ""
! 1677: echo " /* do one slow load cycle: */"
! 1678: echo " tme_sparc${arch}_load(ic, ls);"
! 1679: echo ""
! 1680: echo " /* if the slow load cycle did not load all of the data: */"
! 1681: echo " if (__tme_predict_false(ls->tme_sparc_ls_size != 0)) {"
! 1682: echo " return;"
! 1683: echo " }"
! 1684: echo ""
! 1685: echo " /* get the byte order of this transfer: */"
! 1686: if test ${arch} = 32; then
! 1687: echo " endian_little = FALSE;"
! 1688: else
! 1689: echo " endian_little = ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE;"
! 1690: fi
! 1691: echo ""
! 1692: echo " /* dispatch on the op3 of the instruction: */"
! 1693: echo " insn = TME_SPARC_INSN;"
! 1694: echo " switch ((insn >> 19) & 0x3f) {"
! 1695: if test ${arch} = 64; then
! 1696: for size in 32 64; do
! 1697: echo ""
! 1698: if test ${size} = 32; then
! 1699: echo " case 0x3c: /* casa */"
! 1700: else
! 1701: echo " case 0x3e: /* casxa */"
! 1702: fi
! 1703: echo ""
! 1704: echo " /* finish the load part of the compare and swap: */"
! 1705: echo " assert (ls->tme_sparc_ls_state == sizeof(tme_uint${size}_t));"
! 1706: echo " value${size} = ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer${size}s[0];"
! 1707: echo " value_swap${size} = *ls->tme_sparc_ls_rd64;"
! 1708: echo " if (endian_little) {"
! 1709: echo " value${size} = tme_letoh_u${size}(value${size});"
! 1710: echo " value_swap${size} = tme_htole_u${size}(value_swap${size});"
! 1711: echo " }"
! 1712: echo " else {"
! 1713: echo " value${size} = tme_betoh_u${size}(value${size});"
! 1714: echo " value_swap${size} = tme_htobe_u${size}(value_swap${size});"
! 1715: echo " }"
! 1716: echo " *ls->tme_sparc_ls_rd64 = value${size};"
! 1717: echo ""
! 1718: echo " /* if the comparison fails: */"
! 1719: echo " reg_rs2 = TME_FIELD_MASK_EXTRACTU(insn, TME_SPARC_FORMAT3_MASK_RS2);"
! 1720: echo " TME_SPARC_REG_INDEX(ic, reg_rs2);"
! 1721: echo " if (value${size} != (tme_uint${size}_t) ic->tme_sparc_ireg_uint${arch}(reg_rs2)) {"
! 1722: echo " return;"
! 1723: echo " }"
! 1724: echo ""
! 1725: echo " /* start the store part of the compare and swap: */"
! 1726: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer${size}s[0] = value_swap${size};"
! 1727: echo " break;"
! 1728: done
! 1729: fi
! 1730: echo ""
! 1731: echo " case 0x0d: /* ldstub */"
! 1732: echo " case 0x1d: /* ldstuba */"
! 1733: echo ""
! 1734: echo " /* finish the load part of the ldstub: */"
! 1735: echo " assert (ls->tme_sparc_ls_state == sizeof(tme_uint8_t));"
! 1736: echo " *ls->tme_sparc_ls_rd${arch} = ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s[0];"
! 1737: echo ""
! 1738: echo " /* start the store part of the ldstub: */"
! 1739: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s[0] = 0xff;"
! 1740: echo " break;"
! 1741: echo ""
! 1742: echo " /* otherwise, this must be swap: */"
! 1743: echo " default:"
! 1744: echo " assert (((insn >> 19) & 0x2f) == 0x0f /* swap, swapa */);"
! 1745: echo ""
! 1746: echo " /* finish the load part of the swap: */"
! 1747: echo " assert (ls->tme_sparc_ls_state == sizeof(tme_uint32_t));"
! 1748: echo " value32 = ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer32s[0];"
! 1749: echo " value_swap32 = *ls->tme_sparc_ls_rd${arch};"
! 1750: echo " if (endian_little) {"
! 1751: echo " value32 = tme_letoh_u32(value32);"
! 1752: echo " value_swap32 = tme_htole_u32(value32);"
! 1753: echo " }"
! 1754: echo " else {"
! 1755: echo " value32 = tme_betoh_u32(value32);"
! 1756: echo " value_swap32 = tme_htobe_u32(value32);"
! 1757: echo " }"
! 1758: echo " *ls->tme_sparc_ls_rd${arch} = value32;"
! 1759: echo ""
! 1760: echo " /* start the store part of the swap: */"
! 1761: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer32s[0] = value_swap32;"
! 1762: echo " break;"
! 1763: echo " }"
! 1764: echo ""
! 1765: echo " /* start the store part of the operation: */"
! 1766: echo " size = ls->tme_sparc_ls_state;"
! 1767: echo " ls->tme_sparc_ls_address${arch} -= size;"
! 1768: echo " ls->tme_sparc_ls_size = size;"
! 1769: echo " ls->tme_sparc_ls_buffer_offset = 0;"
! 1770: echo " ls->tme_sparc_ls_state = size | TME_BIT(7);"
! 1771: echo " }"
! 1772: echo ""
! 1773: echo " /* this is the store part of the operation: */"
! 1774: echo ""
! 1775: echo " /* do one slow store cycle: */"
! 1776: echo " tme_sparc${arch}_store(ic, ls);"
! 1777: echo ""
! 1778: echo " /* if the slow store cycle did not store all of the data: */"
! 1779: echo " if (__tme_predict_false(ls->tme_sparc_ls_size != 0)) {"
! 1780: echo " return;"
! 1781: echo " }"
! 1782: echo "}"
! 1783: fi
! 1784:
1.1 root 1785: # the slow load and store functions:
1786: #
1787: for slow in load store; do
1788:
1789: if test ${slow} = load; then
1790: cycle="read"
1791: capcycle="READ"
1792: else
1793: cycle="write"
1794: capcycle="WRITE"
1.1.1.2 ! root 1795: fi
! 1796: if $header; then
! 1797: echo "void tme_sparc${arch}_${slow} _TME_P((struct tme_sparc *, struct tme_sparc_ls *));"
! 1798: continue
1.1 root 1799: fi
1800:
1801: echo ""
1.1.1.2 ! root 1802: echo "/* this does one slow ${slow} cycle: */"
! 1803: echo "void"
1.1 root 1804: echo "tme_sparc${arch}_${slow}(struct tme_sparc *ic, "
1.1.1.2 ! root 1805: echo " struct tme_sparc_ls *ls)"
1.1 root 1806: echo "{"
1807:
1808: # our locals:
1809: #
1.1.1.2 ! root 1810: echo " struct tme_sparc_tlb *tlb;"
! 1811: echo " tme_uint${arch}_t address;"
! 1812: echo " unsigned int cycle_size;"
1.1 root 1813: echo " tme_bus_addr_t physical_address;"
1814: echo " int shift;"
1815: echo " int err;"
1.1.1.2 ! root 1816:
! 1817: echo ""
! 1818: echo " /* get the TLB entry: */"
! 1819: echo " tlb = ls->tme_sparc_ls_tlb;"
! 1820: echo ""
! 1821: echo " /* the TLB entry must be busy and valid: */"
! 1822: echo " assert (tme_bus_tlb_is_valid(&tlb->tme_sparc_tlb_bus_tlb));"
! 1823: echo ""
! 1824: echo " /* start the bus cycle structure: */"
! 1825: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_type = TME_BUS_CYCLE_${capcycle};"
! 1826: echo ""
! 1827: echo " /* get the buffer: */"
! 1828: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_buffer = &ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s[ls->tme_sparc_ls_buffer_offset];"
! 1829: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_buffer_increment = 1;"
! 1830: echo ""
! 1831: echo " /* get the current address: */"
! 1832: echo " address = ls->tme_sparc_ls_address${arch};"
! 1833: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_address = address;"
! 1834: echo ""
! 1835: echo " /* start the cycle size: */"
! 1836: echo " cycle_size = ls->tme_sparc_ls_size;"
! 1837: echo " assert (cycle_size > 0);"
! 1838: echo " cycle_size--;"
! 1839: echo " cycle_size = TME_MIN(cycle_size, (((tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_last) - address)) + 1;"
! 1840: echo ""
! 1841: echo " /* if this TLB entry allows fast ${cycle}s: */"
! 1842: echo " if (__tme_predict_true(tlb->tme_sparc_tlb_emulator_off_${cycle} != TME_EMULATOR_OFF_UNDEF)) {"
! 1843: echo ""
! 1844: echo " /* do a ${cycle}: */"
! 1845: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size = cycle_size;"
! 1846: echo " tme_memory_bus_${cycle}_buffer((tlb->tme_sparc_tlb_emulator_off_${cycle} + (tme_uint${arch}_t) ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_address),"
! 1847: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_buffer,"
! 1848: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size,"
! 1849: echo " tlb->tme_sparc_tlb_bus_rwlock,"
! 1850: echo " sizeof(tme_uint8_t),"
! 1851: echo " sizeof(tme_uint${arch}_t));"
! 1852: echo " }"
! 1853: echo ""
! 1854: echo " /* otherwise, this TLB entry does not allow fast ${cycle}s: */"
! 1855: echo " else {"
! 1856: echo ""
! 1857: echo " /* finish the cycle size: */"
! 1858: echo " cycle_size = TME_MIN(cycle_size, 1 + ((~ (unsigned int) address) % sizeof(tme_uint${arch}_t)));"
! 1859: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size = cycle_size;"
! 1860: echo ""
! 1861: echo " /* form the physical address for the bus cycle handler: */"
! 1862: echo " physical_address = ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_address;"
! 1863: echo " physical_address += tlb->tme_sparc_tlb_addr_offset;"
! 1864: echo " shift = tlb->tme_sparc_tlb_addr_shift;"
! 1865: echo " if (shift < 0) {"
! 1866: echo " physical_address <<= (0 - shift);"
! 1867: echo " }"
! 1868: echo " else if (shift > 0) {"
! 1869: echo " physical_address >>= shift;"
! 1870: echo " }"
! 1871: echo " ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_address = physical_address;"
! 1872: echo ""
! 1873: echo " /* finish the bus cycle structure: */"
! 1874: echo " (*ic->_tme_sparc_ls_bus_cycle)(ic, ls);"
! 1875:
! 1876: echo " tme_sparc_log(ic, 10000, TME_OK,"
! 1877: echo " (TME_SPARC_LOG_HANDLE(ic),"
! 1878: echo " _(\"cycle-${slow}%u\t0x%0"`expr ${arch} / 4`"\" TME_PRIx${arch}),"
! 1879: echo " (unsigned int) (ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size * 8),"
! 1880: echo " (tme_bus_addr${arch}_t) ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_address));"
! 1881:
! 1882: echo ""
! 1883: echo " /* callout the bus cycle: */"
! 1884: echo " tme_sparc_tlb_unbusy(tlb);"
! 1885: echo " tme_sparc_callout_unlock(ic);"
! 1886: echo " err = (*tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle)"
! 1887: echo " (tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private,"
! 1888: echo " &ls->tme_sparc_ls_bus_cycle);"
! 1889: echo " tme_sparc_callout_relock(ic);"
! 1890: echo " tme_sparc_tlb_busy(tlb);"
! 1891: echo ""
! 1892: echo " /* the TLB entry can't have been invalidated before the ${slow}: */"
! 1893: echo " assert (err != EBADF);"
! 1894: echo ""
! 1895: echo " /* if the bus cycle didn't complete normally: */"
! 1896: echo " if (err != TME_OK) {"
! 1897: echo ""
! 1898: echo " /* if a real bus fault may have happened, instead of"
! 1899: echo " some synchronous event: */"
! 1900: echo " if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {"
! 1901: echo ""
! 1902: echo " /* call the bus fault handlers: */"
! 1903: echo " err = tme_bus_tlb_fault(&tlb->tme_sparc_tlb_bus_tlb, &ls->tme_sparc_ls_bus_cycle, err);"
! 1904: echo " }"
! 1905: echo ""
! 1906: echo " /* if some synchronous event has happened: */"
! 1907: echo " if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {"
! 1908: echo ""
! 1909: echo " /* after the currently executing instruction finishes, check"
! 1910: echo " for external resets, halts, or interrupts: */"
! 1911: echo " ic->_tme_sparc_instruction_burst_remaining = 0;"
! 1912: echo " ic->_tme_sparc_instruction_burst_other = TRUE;"
! 1913: echo " }"
! 1914: echo ""
! 1915: echo " /* otherwise, if no real bus fault happened: */"
! 1916: echo " else if (err == TME_OK) {"
! 1917: echo ""
! 1918: echo " /* nothing to do */"
! 1919: echo " }"
! 1920: echo ""
! 1921: echo " /* otherwise, a real bus fault happened: */"
! 1922: echo " else {"
! 1923: echo " (*ic->_tme_sparc_ls_bus_fault)(ic, ls, err);"
! 1924: echo " return;"
! 1925: echo " }"
! 1926: echo " }"
! 1927: echo " }"
! 1928:
! 1929: echo ""
! 1930: echo " /* some data must have been transferred: */"
! 1931: echo " assert (ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size > 0);"
! 1932:
1.1 root 1933: if test ${slow} = store; then
1.1.1.2 ! root 1934: echo ""
! 1935: echo " /* if this was an atomic operation: */"
! 1936: echo " if (__tme_predict_false(ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ATOMIC)) {"
! 1937: echo ""
! 1938: echo " /* we do not support atomic operations in TLB entries that"
! 1939: echo " do not support both fast reads and fast writes. assuming"
! 1940: echo " that all atomic operations are to regular memory, we"
! 1941: echo " should always get fast read and fast write TLBs. when"
! 1942: echo " we do not, it should only be because the memory has been"
! 1943: echo " made read-only in the MMU. the write above was supposed"
! 1944: echo " to cause a fault (with the instruction rerun later with"
! 1945: echo " a fast read and fast write TLB entry), but instead it"
! 1946: echo " succeeded and transferred some data. we have modified"
! 1947: echo " memory and cannot recover: */"
! 1948: echo " abort();"
! 1949: echo " }"
1.1 root 1950: fi
1951:
1952: echo ""
1.1.1.2 ! root 1953: echo " /* update: */"
! 1954: echo " cycle_size = ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size;"
! 1955: echo " ls->tme_sparc_ls_address${arch} += cycle_size;"
! 1956: echo " ls->tme_sparc_ls_buffer_offset += cycle_size;"
! 1957: echo " ls->tme_sparc_ls_size -= cycle_size;"
! 1958: echo "}"
! 1959: done
1.1 root 1960:
1.1.1.2 ! root 1961: # the load/store function:
! 1962: #
! 1963: if $header; then
! 1964: echo "tme_shared tme_uint8_t *tme_sparc${arch}_ls _TME_P((struct tme_sparc *, tme_uint${arch}_t, tme_uint${arch}_t *, tme_uint32_t));"
! 1965: else
1.1 root 1966:
1967: echo ""
1.1.1.2 ! root 1968: echo "/* this does a slow load or store: */"
! 1969: echo "tme_shared tme_uint8_t *"
! 1970: echo "tme_sparc${arch}_ls(struct tme_sparc *ic,"
! 1971: echo " tme_uint${arch}_t const address_first,"
! 1972: echo " tme_uint${arch}_t *_rd,"
! 1973: echo " tme_uint32_t lsinfo)"
! 1974: echo "{"
! 1975: echo " struct tme_sparc_ls ls;"
! 1976: echo " tme_uint32_t size;"
! 1977: echo " tme_uint32_t asi;"
! 1978: echo " tme_uint32_t asi_mask_flags;"
! 1979: echo " tme_uint32_t asi_mask;"
! 1980: echo " tme_bus_context_t context;"
! 1981: echo " tme_uint32_t tlb_hash;"
! 1982: echo " unsigned long tlb_i;"
! 1983: echo " unsigned long handler_i;"
! 1984: echo " struct tme_sparc_tlb *tlb;"
! 1985: echo " unsigned int cycle_type;"
! 1986: echo " tme_uint${arch}_t address;"
! 1987: echo " void (*address_map) _TME_P((struct tme_sparc *, struct tme_sparc_ls *));"
! 1988: echo " tme_bus_addr_t address_bus;"
! 1989: echo " int rc;"
! 1990: echo " const tme_shared tme_uint8_t *emulator_off;"
! 1991: echo " unsigned int buffer_offset;"
! 1992: echo " tme_uint${arch}_t value;"
! 1993: echo " tme_uint32_t value32;"
! 1994: echo ""
! 1995: echo " /* we must not be replaying instructions: */"
! 1996: echo " assert (tme_sparc_recode_verify_replay_last_pc(ic) == 0);"
! 1997: echo ""
! 1998: echo " /* initialize the pointer to the rd register: */"
! 1999: echo " ls.tme_sparc_ls_rd${arch} = _rd;"
! 2000: echo ""
! 2001: echo "#ifndef NDEBUG"
! 2002: echo ""
! 2003: echo " /* initialize the cycle function: */"
! 2004: echo " ls.tme_sparc_ls_cycle = NULL;"
! 2005: echo ""
! 2006: echo " /* initialize the TLB entry pointer: */"
! 2007: echo " ls.tme_sparc_ls_tlb = NULL;"
! 2008: echo ""
! 2009: echo "#endif /* NDEBUG */"
! 2010: echo ""
! 2011: echo " /* initialize the faults: */"
! 2012: echo " ls.tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;"
! 2013: echo ""
! 2014: echo " /* initialize the address: */"
! 2015: echo " ls.tme_sparc_ls_address${arch} = address_first;"
! 2016: echo ""
! 2017: echo " /* initialize the size: */"
! 2018: echo " size = TME_SPARC_LSINFO_WHICH_SIZE(lsinfo);"
! 2019: echo " ls.tme_sparc_ls_size = size;"
! 2020: echo ""
! 2021: echo " /* initialize the info: */"
! 2022: echo " ls.tme_sparc_ls_lsinfo = lsinfo;"
! 2023: echo ""
1.1 root 2024: echo " /* if the address is not aligned: */"
1.1.1.2 ! root 2025: echo " if (__tme_predict_false(((size - 1) & (tme_uint32_t) address_first) != 0)) {"
! 2026: echo " ls.tme_sparc_ls_faults |= TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;"
1.1 root 2027: echo " }"
2028: echo ""
1.1.1.2 ! root 2029: echo " /* otherwise, the address is aligned: */"
! 2030: echo " else {"
1.1 root 2031: echo ""
1.1.1.2 ! root 2032: echo " /* the transfer must not cross a 32-bit boundary: */"
! 2033: echo " assert ((size - 1) <= (tme_uint32_t) ~address_first);"
1.1 root 2034: echo " }"
1.1.1.2 ! root 2035: echo ""
! 2036: echo " /* initialize the address map: */"
! 2037: echo " ls.tme_sparc_ls_address_map = ic->_tme_sparc_ls_address_map;"
! 2038: echo ""
! 2039: echo " /* if this is a ldd, ldda, std, or stda, or an instruction"
! 2040: echo " that loads or stores in the same way: */"
! 2041: echo " if (lsinfo & TME_SPARC_LSINFO_LDD_STD) {"
! 2042: echo ""
! 2043: echo " /* if the rd register is odd: */"
! 2044: echo " /* NB: we don't check the rd field in the instruction,"
! 2045: echo " because the register number there might be encoded"
! 2046: echo " in some way, or the architecture might ignore bit"
! 2047: echo " zero in the rd field (for example, the sparc32 lddf)."
! 2048: echo " instead, we test the rd register pointer: */"
! 2049: echo " if (__tme_predict_false((ls.tme_sparc_ls_rd${arch}"
! 2050: echo " - ic->tme_sparc_ic.tme_ic_iregs.tme_ic_iregs_uint${arch}s)"
! 2051: echo " % 2)) {"
! 2052: echo " ls.tme_sparc_ls_faults |= TME_SPARC_LS_FAULT_LDD_STD_RD_ODD;"
! 2053: echo " }"
1.1 root 2054: echo " }"
1.1.1.2 ! root 2055:
! 2056: echo ""
! 2057: echo " /* if the ASI has been specified: */"
! 2058: echo " if (lsinfo & TME_SPARC_LSINFO_A) {"
! 2059: echo ""
! 2060: echo " /* get the ASI: */"
! 2061: echo " asi = TME_SPARC_LSINFO_WHICH_ASI(lsinfo);"
! 2062: echo ""
! 2063: echo " /* get the flags for this ASI: */"
! 2064: echo " asi_mask_flags = ic->tme_sparc_asis[asi].tme_sparc_asi_mask_flags;"
! 2065: echo ""
! 2066: if test ${arch} = 32; then
! 2067: echo " /* make the ASI mask: */"
! 2068: echo " if (asi_mask_flags & TME_SPARC32_ASI_MASK_FLAG_SPECIAL) {"
! 2069: echo " asi_mask"
! 2070: echo " = TME_SPARC_ASI_MASK_SPECIAL(asi, TRUE);"
! 2071: echo " }"
! 2072: echo " else {"
! 2073: echo " asi_mask = TME_SPARC32_ASI_MASK(asi, asi);"
! 2074: echo " }"
! 2075: elif test ${arch} = 64; then
! 2076: echo " /* if this is a nonprivileged access: */"
! 2077: echo " if (!TME_SPARC_PRIV(ic)) {"
! 2078: echo ""
! 2079: echo " /* if this is a restricted ASI: */"
! 2080: echo " if (__tme_predict_false((asi & TME_SPARC64_ASI_FLAG_UNRESTRICTED) == 0)) {"
! 2081: echo " ls.tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_PRIVILEGED_ASI;"
! 2082: echo " }"
1.1 root 2083: echo ""
1.1.1.2 ! root 2084: echo " /* force a nonprivileged access with the ASI: */"
! 2085: echo " asi_mask_flags |= TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER;"
! 2086: echo " }"
! 2087: echo ""
! 2088: echo " /* make the ASI mask: */"
! 2089: echo " if (asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_SPECIAL) {"
! 2090: echo " asi_mask"
! 2091: echo " = (asi_mask_flags"
! 2092: echo " + TME_SPARC_ASI_MASK_SPECIAL(asi,"
! 2093: echo " (asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER) == 0));"
! 2094: echo " }"
! 2095: echo " else {"
! 2096: echo " asi_mask = TME_SPARC64_ASI_MASK(asi, asi_mask_flags);"
! 2097: echo " }"
! 2098: fi
! 2099: echo " ls.tme_sparc_ls_asi_mask = asi_mask;"
! 2100: if test ${arch} = 64; then
! 2101: echo ""
! 2102: echo " /* if this is a no-fault ASI with a non-load instruction: */"
! 2103: echo " if (asi_mask & TME_SPARC64_ASI_FLAG_NO_FAULT) {"
! 2104: echo " if (__tme_predict_false(lsinfo & (TME_SPARC_LSINFO_OP_ST | TME_SPARC_LSINFO_OP_ATOMIC))) {"
! 2105: echo " ls.tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_NO_FAULT_NON_LOAD;"
! 2106: echo " }"
! 2107: echo " }"
1.1 root 2108: fi
2109: echo ""
1.1.1.2 ! root 2110: echo " /* get the context for the alternate address space: */"
! 2111: if test ${arch} = 32; then
! 2112: echo " context = ic->tme_sparc_memory_context_default;"
! 2113: elif test ${arch} = 64; then
! 2114: echo " context = ic->tme_sparc_memory_context_primary;"
! 2115: echo " if (asi_mask & TME_SPARC64_ASI_FLAG_SECONDARY) {"
! 2116: echo " context = ic->tme_sparc_memory_context_secondary;"
! 2117: echo " }"
! 2118: echo " if (__tme_predict_false(asi_mask & TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS)) {"
! 2119: echo " if (TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_NUCLEUS) {"
! 2120: echo " context = 0;"
! 2121: echo " }"
! 2122: echo " }"
! 2123: fi
! 2124: echo " ls.tme_sparc_ls_context = context;"
1.1 root 2125: echo ""
1.1.1.2 ! root 2126: echo " /* get the default TLB entry index: */"
! 2127: echo " tlb_hash = TME_SPARC_TLB_HASH(ic, context, address_first);"
! 2128: echo " if (lsinfo & TME_SPARC_LSINFO_OP_FETCH) {"
! 2129: echo " tlb_i = TME_SPARC_ITLB_ENTRY(ic, tlb_hash);"
! 2130: echo " }"
! 2131: echo " else {"
! 2132: echo " tlb_i = TME_SPARC_DTLB_ENTRY(ic, tlb_hash);"
! 2133: echo " }"
! 2134: echo " ls.tme_sparc_ls_tlb_i = tlb_i;"
1.1 root 2135: echo ""
1.1.1.2 ! root 2136: echo " /* call any special handler for this ASI: */"
! 2137: echo " handler_i = ic->tme_sparc_asis[TME_SPARC_ASI_MASK_WHICH(asi_mask)].tme_sparc_asi_handler;"
! 2138: echo " if (__tme_predict_false(handler_i != 0)) {"
! 2139: echo " (*ic->_tme_sparc_ls_asi_handlers[handler_i])(ic, &ls);"
1.1 root 2140: echo " }"
1.1.1.2 ! root 2141: echo ""
! 2142: echo " /* get the final TLB entry index: */"
! 2143: echo " tlb_i = ls.tme_sparc_ls_tlb_i;"
! 2144: echo " }"
1.1 root 2145:
2146: echo ""
1.1.1.2 ! root 2147: echo " /* otherwise, the ASI has not been specified: */"
! 2148: echo " else {"
1.1 root 2149: echo ""
1.1.1.2 ! root 2150: echo " /* get the ASI mask: */"
! 2151: echo " asi_mask = ic->tme_sparc_asi_mask_data;"
! 2152: echo ""
! 2153: echo " /* add in any ASI mask flags from the instruction: */"
! 2154: if test ${arch} = 64; then
! 2155: echo " /* NB: initially, TME_SPARC64_ASI_FLAG_NO_FAULT is the"
! 2156: echo " only flag allowed, and only the flush instruction"
! 2157: echo " can use it: */"
1.1 root 2158: fi
1.1.1.2 ! root 2159: echo " assert (TME_SPARC_LSINFO_WHICH_ASI_FLAGS(lsinfo) == 0"
! 2160: if test ${arch} = 64; then
! 2161: echo " || (TME_SPARC_LSINFO_WHICH_ASI_FLAGS(lsinfo) == TME_SPARC64_ASI_FLAG_NO_FAULT"
! 2162: echo " && ((ic->_tme_sparc_insn >> 19) & 0x3f) == 0x3b)"
! 2163: fi
! 2164: echo " );"
! 2165: echo " asi_mask |= TME_SPARC_LSINFO_WHICH_ASI_FLAGS(lsinfo);"
1.1 root 2166: echo ""
1.1.1.2 ! root 2167: echo " /* set the ASI mask: */"
! 2168: echo " ls.tme_sparc_ls_asi_mask = asi_mask;"
! 2169: echo ""
! 2170: echo " /* get the context: */"
! 2171: echo " context = ic->tme_sparc_memory_context_default;"
! 2172: echo " ls.tme_sparc_ls_context = context;"
! 2173: echo ""
! 2174: echo " /* this must not be a fetch: */"
! 2175: echo " assert ((lsinfo & TME_SPARC_LSINFO_OP_FETCH) == 0);"
! 2176: echo ""
! 2177: echo " /* get the TLB entry index: */"
! 2178: echo " tlb_hash = TME_SPARC_TLB_HASH(ic, context, address_first);"
! 2179: echo " tlb_i = TME_SPARC_DTLB_ENTRY(ic, tlb_hash);"
! 2180: echo " ls.tme_sparc_ls_tlb_i = tlb_i;"
! 2181: echo " }"
! 2182:
! 2183: echo ""
! 2184: echo " /* get the TLB entry pointer: */"
! 2185: echo " tlb = &ic->tme_sparc_tlbs[tlb_i];"
! 2186: echo " ls.tme_sparc_ls_tlb = tlb;"
! 2187:
! 2188: echo ""
! 2189: echo " /* get the cycle type: */"
! 2190: echo " /* NB: we deliberately set this once, now, since the lsinfo"
! 2191: echo " may change once we start transferring: */"
! 2192: echo " cycle_type"
! 2193: echo " = ((lsinfo"
! 2194: echo " & (TME_SPARC_LSINFO_OP_ST"
! 2195: echo " | TME_SPARC_LSINFO_OP_ATOMIC))"
! 2196: echo " ? TME_BUS_CYCLE_WRITE"
! 2197: echo " : TME_BUS_CYCLE_READ);"
! 2198:
! 2199: echo ""
! 2200: echo " /* loop until the transfer is complete: */"
! 2201: echo " for (;;) {"
! 2202:
! 2203: echo ""
! 2204: echo " /* if we have faulted: */"
! 2205: echo " if (__tme_predict_false(ls.tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {"
! 2206: echo ""
! 2207: echo " /* unbusy this TLB, since the trap function may not return: */"
! 2208: echo " tme_bus_tlb_unbusy(&tlb->tme_sparc_tlb_bus_tlb);"
! 2209: echo ""
! 2210: echo " /* call the trap function, which will not return if it traps: */"
! 2211: echo " (*ic->_tme_sparc_ls_trap)(ic, &ls);"
! 2212: echo ""
! 2213: echo " /* rebusy this TLB: */"
! 2214: echo " tme_bus_tlb_busy(&tlb->tme_sparc_tlb_bus_tlb);"
1.1 root 2215: echo ""
1.1.1.2 ! root 2216: echo " /* since the trap function returned, it must have cleared the fault: */"
! 2217: echo " assert (ls.tme_sparc_ls_faults == TME_SPARC_LS_FAULT_NONE);"
1.1 root 2218: echo " }"
1.1.1.2 ! root 2219:
1.1 root 2220: echo ""
1.1.1.2 ! root 2221: echo " /* if the transfer is complete, stop now: */"
! 2222: echo " if (__tme_predict_false(ls.tme_sparc_ls_size == 0)) {"
! 2223: echo " break;"
! 2224: echo " }"
! 2225:
! 2226: echo ""
! 2227: echo " /* get the current address: */"
! 2228: echo " address = ls.tme_sparc_ls_address${arch};"
! 2229:
! 2230: echo ""
! 2231: echo " /* if this TLB entry does not apply or is invalid: */"
! 2232: echo " if ((tlb->tme_sparc_tlb_context != ls.tme_sparc_ls_context"
! 2233: echo " && tlb->tme_sparc_tlb_context <= ic->tme_sparc_memory_context_max)"
! 2234: echo " || address < (tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_first"
! 2235: echo " || address > (tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_last"
! 2236: echo " || !TME_SPARC_TLB_ASI_MASK_OK(tlb, ls.tme_sparc_ls_asi_mask)"
! 2237: echo " || ((tlb->tme_sparc_tlb_cycles_ok & cycle_type) == 0"
! 2238: echo " && (cycle_type == TME_BUS_CYCLE_READ"
! 2239: echo " ? tlb->tme_sparc_tlb_emulator_off_read"
! 2240: echo " : tlb->tme_sparc_tlb_emulator_off_write) == TME_EMULATOR_OFF_UNDEF)"
! 2241: echo " || tme_bus_tlb_is_invalid(&tlb->tme_sparc_tlb_bus_tlb)) {"
! 2242: echo ""
! 2243: echo " /* unbusy this TLB entry for filling: */"
! 2244: echo " tme_bus_tlb_unbusy_fill(&tlb->tme_sparc_tlb_bus_tlb);"
! 2245: echo ""
! 2246: echo " /* if we haven't mapped this address yet: */"
! 2247: echo " address_map = ls.tme_sparc_ls_address_map;"
! 2248: echo " if (address_map != NULL) {"
! 2249: echo " ls.tme_sparc_ls_address_map = NULL;"
! 2250: echo ""
! 2251: echo " /* count this mapping: */"
! 2252: echo " if (ls.tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_FETCH) {"
! 2253: echo " TME_SPARC_STAT(ic, tme_sparc_stats_itlb_map);"
! 2254: echo " }"
! 2255: echo " else {"
! 2256: echo " TME_SPARC_STAT(ic, tme_sparc_stats_dtlb_map);"
! 2257: echo " }"
! 2258: echo ""
! 2259: echo " /* initialize the ASI mask and context on this TLB entry: */"
! 2260: echo " /* NB that the ASI mask will likely be updated by either the"
! 2261: echo " address mapping or the TLB fill: */"
! 2262: echo " tlb->tme_sparc_tlb_asi_mask"
! 2263: echo " = (ls.tme_sparc_ls_asi_mask"
! 2264: echo " & ~TME_SPARC_ASI_MASK_FLAGS_AVAIL);"
! 2265: echo " tlb->tme_sparc_tlb_context = ls.tme_sparc_ls_context;"
! 2266: echo ""
! 2267: echo " /* NB: if the address mapping traps, we won't get a chance"
! 2268: echo " to finish updating this TLB entry, which is currently in"
! 2269: echo " an inconsistent state - but not necessarily an unusable"
! 2270: echo " state. poison it to be unusable, including any recode"
! 2271: echo " TLB entry: */"
! 2272: echo " tlb->tme_sparc_tlb_addr_first = 1;"
! 2273: echo " tlb->tme_sparc_tlb_addr_last = 0;"
! 2274: echo "#if TME_SPARC_HAVE_RECODE(ic)"
! 2275: echo " if (ls.tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_FETCH) {"
! 2276: echo " tme_sparc${arch}_recode_chain_tlb_update(ic, &ls);"
! 2277: echo " }"
! 2278: echo " else {"
! 2279: echo " tme_sparc${arch}_recode_ls_tlb_update(ic, &ls);"
! 2280: echo " }"
! 2281: echo "#endif /* TME_SPARC_HAVE_RECODE(ic) */"
! 2282: echo ""
! 2283: echo "#ifndef NDEBUG"
! 2284: echo ""
! 2285: echo " /* initialize the mapping TLB entry: */"
! 2286: echo " ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_first = 0 - (tme_bus_addr_t) 1;"
! 2287: echo " ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_last = 0 - (tme_bus_addr_t) 2;"
! 2288: echo " ls.tme_sparc_ls_tlb_map.tme_bus_tlb_cycles_ok = 0;"
! 2289: echo " ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset = 0 - (tme_bus_addr_t) 1;"
! 2290: echo ""
! 2291: echo "#endif /* !NDEBUG */"
1.1 root 2292: echo ""
1.1.1.2 ! root 2293: echo " /* map the address: */"
! 2294: echo " (*address_map)(ic, &ls);"
! 2295: echo ""
! 2296: echo " /* the address mapping must do any trapping itself: */"
! 2297: echo " assert (ls.tme_sparc_ls_faults == TME_SPARC_LS_FAULT_NONE);"
! 2298: echo ""
! 2299: echo " /* if the address mapping completed the transfer: */"
! 2300: echo " if (__tme_predict_false(ls.tme_sparc_ls_size == 0)) {"
! 2301: echo ""
! 2302: echo " /* rebusy the TLB entry: */"
! 2303: echo " tme_sparc_tlb_busy(tlb);"
! 2304: echo ""
! 2305: echo " /* stop now: */"
! 2306: echo " break;"
! 2307: echo " }"
! 2308: echo ""
! 2309: echo " /* the mapping must have actually made a mapping: */"
! 2310: echo " assert (ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_first != 0 - (tme_bus_addr_t) 1);"
! 2311: echo " assert (ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_last != 0 - (tme_bus_addr_t) 2);"
! 2312: echo " assert (ls.tme_sparc_ls_tlb_map.tme_bus_tlb_cycles_ok != 0);"
! 2313: echo " assert (ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset != 0 - (tme_bus_addr_t) 1);"
1.1 root 2314: echo " }"
1.1.1.2 ! root 2315: echo ""
! 2316: echo " /* count this fill: */"
! 2317: echo " if (ls.tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_FETCH) {"
! 2318: echo " TME_SPARC_STAT(ic, tme_sparc_stats_itlb_fill);"
1.1 root 2319: echo " }"
1.1.1.2 ! root 2320: echo " else {"
! 2321: echo " TME_SPARC_STAT(ic, tme_sparc_stats_dtlb_fill);"
! 2322: echo " }"
! 2323: echo ""
! 2324: echo " /* get the bus address: */"
! 2325: echo " address_bus = ls.tme_sparc_ls_address${arch} + ls.tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset;"
1.1 root 2326: echo ""
1.1.1.2 ! root 2327: echo " /* fill the TLB entry: */"
1.1 root 2328: echo " tme_sparc_callout_unlock(ic);"
1.1.1.2 ! root 2329: echo " rc = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill)"
! 2330: echo " (ic->_tme_sparc_bus_connection,"
! 2331: echo " tlb,"
! 2332: echo " ls.tme_sparc_ls_asi_mask,"
! 2333: echo " address_bus,"
! 2334: echo " cycle_type);"
! 2335: echo " assert (rc == TME_OK);"
1.1 root 2336: echo " tme_sparc_callout_relock(ic);"
2337: echo ""
1.1.1.2 ! root 2338: echo " /* map the TLB entry: */"
! 2339: echo " tme_bus_tlb_map(&tlb->tme_sparc_tlb_bus_tlb, address_bus,"
! 2340: echo " &ls.tme_sparc_ls_tlb_map, ls.tme_sparc_ls_address${arch});"
! 2341: echo ""
! 2342: echo " /* update any recode TLB entry: */"
! 2343: echo "#if TME_SPARC_HAVE_RECODE(ic)"
! 2344: echo " if (ls.tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_FETCH) {"
! 2345: echo " tme_sparc${arch}_recode_chain_tlb_update(ic, &ls);"
! 2346: echo " }"
! 2347: echo " else {"
! 2348: echo " tme_sparc${arch}_recode_ls_tlb_update(ic, &ls);"
! 2349: echo " }"
! 2350: echo "#endif /* TME_SPARC_HAVE_RECODE(ic) */"
! 2351: echo ""
! 2352: echo " /* rebusy the TLB entry: */"
! 2353: echo " tme_sparc_tlb_busy(tlb);"
! 2354: echo ""
! 2355: echo " /* if this TLB entry is already invalid: */"
! 2356: echo " if (tme_bus_tlb_is_invalid(&tlb->tme_sparc_tlb_bus_tlb)) {"
! 2357: echo " continue;"
1.1 root 2358: echo " }"
1.1.1.2 ! root 2359: echo " }"
! 2360:
1.1 root 2361: echo ""
1.1.1.2 ! root 2362: echo " /* this TLB entry must apply: */"
! 2363: echo " assert ((tlb->tme_sparc_tlb_context == ls.tme_sparc_ls_context"
! 2364: echo " || tlb->tme_sparc_tlb_context > ic->tme_sparc_memory_context_max)"
! 2365: echo " && ls.tme_sparc_ls_address${arch} >= (tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_first"
! 2366: echo " && ls.tme_sparc_ls_address${arch} <= (tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_last"
! 2367: echo " && ((tlb->tme_sparc_tlb_cycles_ok & cycle_type)"
! 2368: echo " || (cycle_type == TME_BUS_CYCLE_READ"
! 2369: echo " ? tlb->tme_sparc_tlb_emulator_off_read"
! 2370: echo " : tlb->tme_sparc_tlb_emulator_off_write) != TME_EMULATOR_OFF_UNDEF)"
! 2371: echo " && TME_SPARC_TLB_ASI_MASK_OK(tlb, ls.tme_sparc_ls_asi_mask));"
! 2372:
! 2373: echo ""
! 2374: echo " /* get the current lsinfo: */"
! 2375: echo " lsinfo = ls.tme_sparc_ls_lsinfo;"
! 2376:
! 2377: echo ""
! 2378: echo " /* if we have to check the TLB: */"
! 2379: echo " if (__tme_predict_true((lsinfo & TME_SPARC_LSINFO_NO_CHECK_TLB) == 0)) {"
! 2380: echo ""
! 2381: echo " /* get the ASI mask for this TLB entry: */"
! 2382: echo " asi_mask = tlb->tme_sparc_tlb_asi_mask;"
! 2383: if test ${arch} = 64; then
! 2384: echo ""
! 2385: echo " /* if this TLB entry is for no-fault accesses only: */"
! 2386: echo " if (__tme_predict_false(asi_mask & TME_SPARC64_ASI_FLAG_NO_FAULT)) {"
! 2387: echo ""
! 2388: echo " /* if this access is not using a no-fault ASI: */"
! 2389: echo " if (__tme_predict_false((ls.tme_sparc_ls_asi_mask & TME_SPARC64_ASI_FLAG_NO_FAULT) == 0)) {"
! 2390: echo " ls.tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_NO_FAULT_FAULT;"
! 2391: echo " continue;"
! 2392: echo " }"
! 2393: echo " }"
! 2394: echo ""
! 2395: echo " /* if this TLB entry is for addresses with side effects: */"
! 2396: echo " if (asi_mask & TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS) {"
! 2397: echo ""
! 2398: echo " /* if this access is using a no-fault ASI: */"
! 2399: echo " /* NB: a flush may be implemented as a load with a no-fault ASI: */"
! 2400: echo " if (__tme_predict_false(ls.tme_sparc_ls_asi_mask & TME_SPARC64_ASI_FLAG_NO_FAULT)) {"
! 2401: echo " ls.tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_SIDE_EFFECTS;"
! 2402: echo " continue;"
! 2403: echo " }"
! 2404: echo " }"
! 2405: echo ""
! 2406: echo " /* if this TLB entry is for uncacheable addresses: */"
! 2407: echo " if (asi_mask & TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE) {"
! 2408: echo ""
! 2409: echo " /* if this is an atomic access: */"
! 2410: echo " if (__tme_predict_false(lsinfo & TME_SPARC_LSINFO_OP_ATOMIC)) {"
! 2411: echo " ls.tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_UNCACHEABLE;"
! 2412: echo " continue;"
! 2413: echo " }"
! 2414: echo " }"
! 2415: echo ""
! 2416: echo " /* see if this is a little-endian instruction: */"
! 2417: echo " lsinfo"
! 2418: echo " = ((lsinfo"
! 2419: echo " & ~TME_SPARC_LSINFO_ENDIAN_LITTLE)"
! 2420: echo " + ((ls.tme_sparc_ls_asi_mask"
! 2421: echo " & TME_SPARC64_ASI_FLAG_LITTLE)"
! 2422: echo "#if TME_SPARC_LSINFO_ENDIAN_LITTLE < TME_SPARC64_ASI_FLAG_LITTLE"
! 2423: echo "#error \"TME_SPARC_LSINFO_ENDIAN_ values changed\""
! 2424: echo "#endif"
! 2425: echo " * (TME_SPARC_LSINFO_ENDIAN_LITTLE"
! 2426: echo " / TME_SPARC64_ASI_FLAG_LITTLE)));"
! 2427: echo ""
! 2428: echo " /* if this TLB entry has its little-endian bit set: */"
! 2429: echo " if (__tme_predict_false(asi_mask & TME_SPARC64_ASI_FLAG_LITTLE)) {"
! 2430: echo " assert (TME_SPARC_MEMORY_FLAGS(ic) & TME_SPARC_MEMORY_FLAG_HAS_INVERT_ENDIAN);"
! 2431: echo " if (TRUE) {"
! 2432: echo " lsinfo ^= TME_SPARC_LSINFO_ENDIAN_LITTLE;"
! 2433: echo " }"
! 2434: echo " }"
! 2435: fi
! 2436: echo " }"
! 2437:
1.1 root 2438: echo ""
1.1.1.2 ! root 2439: echo " /* if we might not have to call a slow cycle function: */"
! 2440: echo " if (__tme_predict_true((lsinfo & TME_SPARC_LSINFO_SLOW_CYCLES) == 0)) {"
1.1 root 2441: echo ""
1.1.1.2 ! root 2442: echo " /* if this TLB entry allows fast transfer of all of the addresses: */"
! 2443: echo " if (__tme_predict_true(((tme_bus_addr${arch}_t) tlb->tme_sparc_tlb_addr_last) >= (address_first + (ls.tme_sparc_ls_size - 1)))) {"
! 2444: echo " emulator_off = tlb->tme_sparc_tlb_emulator_off_read;"
! 2445: echo " if (lsinfo & TME_SPARC_LSINFO_OP_ST) {"
! 2446: echo " emulator_off = tlb->tme_sparc_tlb_emulator_off_write;"
! 2447: echo " }"
! 2448: echo " if (__tme_predict_true(emulator_off != TME_EMULATOR_OFF_UNDEF"
! 2449: echo " && (((lsinfo & TME_SPARC_LSINFO_OP_ATOMIC) == 0)"
! 2450: echo " || emulator_off == tlb->tme_sparc_tlb_emulator_off_write))) {"
! 2451: echo ""
! 2452: echo " /* return and let our caller do the transfer: */"
! 2453: echo " /* NB: we break const here: */"
! 2454: echo " return ((tme_shared tme_uint8_t *) emulator_off);"
1.1 root 2455: echo " }"
1.1.1.2 ! root 2456: echo " }"
! 2457: echo ""
! 2458: echo " /* we have to call a slow cycle function: */"
! 2459: echo " lsinfo |= TME_SPARC_LSINFO_SLOW_CYCLES;"
! 2460: echo " assert (ls.tme_sparc_ls_cycle == NULL);"
! 2461: if test ${arch} = 32; then
! 2462: endian_little="FALSE"
! 2463: else
! 2464: endian_little="(lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE)"
! 2465: fi
! 2466: echo ""
! 2467: echo " /* assume that this operation will transfer the start of the buffer: */"
! 2468: echo " buffer_offset = 0;"
1.1 root 2469: echo ""
1.1.1.2 ! root 2470: echo " /* assume that this is a load or a fetch: */"
! 2471: echo " ls.tme_sparc_ls_cycle = tme_sparc${arch}_load;"
1.1 root 2472: echo ""
1.1.1.2 ! root 2473: echo " /* if this is a store: */"
! 2474: echo " if (lsinfo & TME_SPARC_LSINFO_OP_ST) {"
! 2475: echo ""
! 2476: echo " /* put the (first) register to store in the memory buffer: */"
! 2477: echo " value = TME_SPARC_FORMAT3_RD;"
! 2478: echo " value = (${endian_little} ? tme_htole_u${arch}(value) : tme_htobe_u${arch}(value));"
! 2479: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer${arch}s[0] = value;"
! 2480: echo ""
! 2481: echo " /* find the offset in the memory buffer corresponding to the"
! 2482: echo " first address: */"
! 2483: echo " buffer_offset = sizeof(tme_uint${arch}_t) - ls.tme_sparc_ls_size;"
! 2484: echo " if (${endian_little}) {"
! 2485: echo " buffer_offset = 0;"
1.1 root 2486: echo " }"
1.1.1.2 ! root 2487:
1.1 root 2488: echo ""
1.1.1.2 ! root 2489: echo " /* if this is a std or stda: */"
! 2490: echo " if (lsinfo & TME_SPARC_LSINFO_LDD_STD) {"
! 2491: echo ""
! 2492: echo " /* put the odd 32-bit register to store in the memory buffer"
! 2493: echo " after the even 32-bit register. exactly where this is depends"
! 2494: echo " on the architecture and on the byte order of the store: */"
! 2495: echo " value32 = TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint${arch});"
! 2496: echo " if (${endian_little}) {"
! 2497: echo " value32 = tme_htole_u32(value32);"
! 2498: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer32s[1] = value32;"
! 2499: echo " buffer_offset = 0;"
! 2500: echo " }"
! 2501: echo " else {"
! 2502: echo " value32 = tme_htobe_u32(value32);"
! 2503: echo " ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer32s[(${arch} / 32)] = value32;"
! 2504: echo " buffer_offset = sizeof(tme_uint${arch}_t) - sizeof(tme_uint32_t);"
1.1 root 2505: echo " }"
2506: echo " }"
1.1.1.2 ! root 2507: echo ""
! 2508: echo " /* set the cycle function: */"
! 2509: echo " ls.tme_sparc_ls_cycle = tme_sparc${arch}_store;"
1.1 root 2510: echo " }"
1.1.1.2 ! root 2511: echo ""
! 2512: echo " /* otherwise, if this is an atomic: */"
! 2513: echo " else if (lsinfo & TME_SPARC_LSINFO_OP_ATOMIC) {"
! 2514: echo ""
! 2515: echo " /* set the cycle function: */"
! 2516: echo " ls.tme_sparc_ls_cycle = tme_sparc${arch}_atomic;"
! 2517: echo " }"
! 2518: echo ""
! 2519: echo " /* set the buffer offset for the (first) slow cycle: */"
! 2520: echo " ls.tme_sparc_ls_buffer_offset = buffer_offset;"
! 2521: echo ""
! 2522: echo " /* clear the state for this operation: */"
! 2523: echo " ls.tme_sparc_ls_state = 0;"
1.1 root 2524: echo " }"
2525:
2526: echo ""
1.1.1.2 ! root 2527: echo " /* assume that we won't have to check the TLB again: */"
! 2528: echo " ls.tme_sparc_ls_lsinfo = lsinfo | TME_SPARC_LSINFO_NO_CHECK_TLB;"
1.1 root 2529:
1.1.1.2 ! root 2530: echo " /* call the slow cycle function: */"
! 2531: echo " (*ls.tme_sparc_ls_cycle)(ic, &ls);"
! 2532: echo " }"
1.1 root 2533: echo ""
1.1.1.2 ! root 2534: echo " /* if this was a load that has already completed, a store,"
! 2535: echo " or an atomic, make sure our caller doesn't try to complete"
! 2536: echo " a fast transfer: */"
! 2537: echo " if (ls.tme_sparc_ls_lsinfo"
! 2538: echo " & (TME_SPARC_LSINFO_LD_COMPLETED"
! 2539: echo " | TME_SPARC_LSINFO_OP_ST"
! 2540: echo " | TME_SPARC_LSINFO_OP_ATOMIC)) {"
! 2541: echo " return (TME_EMULATOR_OFF_UNDEF);"
! 2542: echo " }"
! 2543: echo ""
! 2544: echo " /* otherwise, this was a load that did slow cycles into the"
! 2545: echo " memory buffer and hasn't updated rd yet. return a pointer"
! 2546: echo " to the memory buffer so our caller can complete the load: */"
! 2547: echo " return (ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s"
! 2548: echo " - address_first);"
1.1 root 2549: echo "}"
1.1.1.2 ! root 2550: fi
1.1 root 2551:
2552: # unfix the architecture version:
2553: #
2554: if $header; then :; else
2555: echo ""
2556: echo "#undef TME_SPARC_VERSION"
2557: echo "#define TME_SPARC_VERSION(ic) _TME_SPARC_VERSION(ic)"
2558: fi
2559:
2560: # the sparc64 support depends on a 64-bit integer type:
2561: #
2562: if test ${arch} = 64; then
2563: echo ""
2564: echo "#endif /* TME_HAVE_INT64_T */"
2565: fi
2566: done
2567:
2568: # done:
2569: #
2570: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.