Commit d014c98c8dce88c3b6cc19bd2e0e558900f5c1d0

Authored by bellard
1 parent a98fd896

sparc support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@119 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-i386.h
@@ -180,6 +180,12 @@ typedef struct CPUX86State { @@ -180,6 +180,12 @@ typedef struct CPUX86State {
180 180
181 /* emulator internal variables */ 181 /* emulator internal variables */
182 CPU86_LDouble ft0; 182 CPU86_LDouble ft0;
  183 + union {
  184 + float f;
  185 + double d;
  186 + int i32;
  187 + int64_t i64;
  188 + } fp_convert;
183 189
184 /* segments */ 190 /* segments */
185 uint32_t segs[6]; /* selector values */ 191 uint32_t segs[6]; /* selector values */
dyngen.c
@@ -65,6 +65,20 @@ @@ -65,6 +65,20 @@
65 #define elf_check_arch(x) ((x) == EM_IA_64) 65 #define elf_check_arch(x) ((x) == EM_IA_64)
66 #define ELF_USES_RELOCA 66 #define ELF_USES_RELOCA
67 67
  68 +#elif defined(HOST_SPARC)
  69 +
  70 +#define ELF_CLASS ELFCLASS32
  71 +#define ELF_ARCH EM_SPARC
  72 +#define elf_check_arch(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
  73 +#define ELF_USES_RELOCA
  74 +
  75 +#elif defined(HOST_SPARC64)
  76 +
  77 +#define ELF_CLASS ELFCLASS64
  78 +#define ELF_ARCH EM_SPARCV9
  79 +#define elf_check_arch(x) ((x) == EM_SPARCV9)
  80 +#define ELF_USES_RELOCA
  81 +
68 #else 82 #else
69 #error unsupported CPU - please update the code 83 #error unsupported CPU - please update the code
70 #endif 84 #endif
@@ -326,6 +340,47 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -326,6 +340,47 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
326 copy_size = p - p_start; 340 copy_size = p - p_start;
327 } 341 }
328 break; 342 break;
  343 + case EM_SPARC:
  344 + case EM_SPARC32PLUS:
  345 + {
  346 + uint8_t *p;
  347 + p = (void *)(p_end - 8);
  348 + if (p <= p_start)
  349 + error("empty code for %s", name);
  350 + if (get32((uint32_t *)(p_start + 0x0)) != 0x9de3bf98)
  351 + error("save %%sp,-104,%%sp expected at the start of %s "
  352 + "found [%08x]",
  353 + name, get32((uint32_t *)(p_start + 0x0)));
  354 + if (get32((uint32_t *)(p + 0x0)) != 0x81c7e008 ||
  355 + get32((uint32_t *)(p + 0x4)) != 0x81e80000)
  356 + error("ret; restore; expected at the end of %s found [%08x:%08x]",
  357 + name,
  358 + get32((uint32_t *)(p + 0x0)),
  359 + get32((uint32_t *)(p + 0x4)));
  360 +
  361 + copy_size = p - p_start;
  362 + }
  363 + break;
  364 + case EM_SPARCV9:
  365 + {
  366 + uint8_t *p;
  367 + p = (void *)(p_end - 8);
  368 + if (p <= p_start)
  369 + error("empty code for %s", name);
  370 + if (get32((uint32_t *)(p_start + 0x0)) != 0x9de3bf40)
  371 + error("save %%sp,-192,%%sp expected at the start of %s "
  372 + "found [%08x]",
  373 + name, get32((uint32_t *)(p_start + 0x0)));
  374 + if (get32((uint32_t *)(p + 0x0)) != 0x81cfe008 ||
  375 + get32((uint32_t *)(p + 0x4)) != 0x01000000)
  376 + error("rett %%i7+8; nop; expected at the end of %s "
  377 + "found [%08x:%08x]",
  378 + name,
  379 + get32((uint32_t *)(p + 0x0)),
  380 + get32((uint32_t *)(p + 0x4)));
  381 + copy_size = p - p_start;
  382 + }
  383 + break;
329 default: 384 default:
330 error("unknown ELF architecture"); 385 error("unknown ELF architecture");
331 } 386 }
@@ -375,6 +430,14 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -375,6 +430,14 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
375 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { 430 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
376 sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; 431 sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
377 if (!strstart(sym_name, "__op_param", &p)) { 432 if (!strstart(sym_name, "__op_param", &p)) {
  433 +#if defined(HOST_SPARC)
  434 + if (sym_name[0] == '.') {
  435 + fprintf(outfile,
  436 + "extern char __dot_%s __asm__(\"%s\");\n",
  437 + sym_name+1, sym_name);
  438 + continue;
  439 + }
  440 +#endif
378 fprintf(outfile, "extern char %s;\n", sym_name); 441 fprintf(outfile, "extern char %s;\n", sym_name);
379 } 442 }
380 } 443 }
@@ -554,6 +617,126 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -554,6 +617,126 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
554 } 617 }
555 } 618 }
556 } 619 }
  620 +#elif defined(HOST_SPARC)
  621 + {
  622 + char name[256];
  623 + int type;
  624 + int addend;
  625 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  626 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  627 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  628 + if (strstart(sym_name, "__op_param", &p)) {
  629 + snprintf(name, sizeof(name), "param%s", p);
  630 + } else {
  631 + if (sym_name[0] == '.')
  632 + snprintf(name, sizeof(name),
  633 + "(long)(&__dot_%s)",
  634 + sym_name + 1);
  635 + else
  636 + snprintf(name, sizeof(name),
  637 + "(long)(&%s)", sym_name);
  638 + }
  639 + type = ELF32_R_TYPE(rel->r_info);
  640 + addend = rel->r_addend;
  641 + switch(type) {
  642 + case R_SPARC_32:
  643 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
  644 + rel->r_offset - offset, name, addend);
  645 + break;
  646 + case R_SPARC_HI22:
  647 + fprintf(outfile,
  648 + " *(uint32_t *)(gen_code_ptr + %d) = "
  649 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  650 + " & ~0x3fffff) "
  651 + " | ((%s + %d) & 0x3fffff);\n",
  652 + rel->r_offset - offset,
  653 + rel->r_offset - offset,
  654 + name, addend);
  655 + break;
  656 + case R_SPARC_LO10:
  657 + fprintf(outfile,
  658 + " *(uint32_t *)(gen_code_ptr + %d) = "
  659 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  660 + " & ~0x3ff) "
  661 + " | ((%s + %d) & 0x3ff);\n",
  662 + rel->r_offset - offset,
  663 + rel->r_offset - offset,
  664 + name, addend);
  665 + break;
  666 + case R_SPARC_WDISP30:
  667 + fprintf(outfile,
  668 + " *(uint32_t *)(gen_code_ptr + %d) = "
  669 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  670 + " & ~0x3fffffff) "
  671 + " | ((((%s + %d) - (long)gen_code_ptr)>>2) "
  672 + " & 0x3fffffff);\n",
  673 + rel->r_offset - offset,
  674 + rel->r_offset - offset,
  675 + name, addend);
  676 + break;
  677 + default:
  678 + error("unsupported sparc relocation (%d)", type);
  679 + }
  680 + }
  681 + }
  682 + }
  683 +#elif defined(HOST_SPARC64)
  684 + {
  685 + char name[256];
  686 + int type;
  687 + int addend;
  688 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  689 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  690 + sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;
  691 + if (strstart(sym_name, "__op_param", &p)) {
  692 + snprintf(name, sizeof(name), "param%s", p);
  693 + } else {
  694 + snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
  695 + }
  696 + type = ELF64_R_TYPE(rel->r_info);
  697 + addend = rel->r_addend;
  698 + switch(type) {
  699 + case R_SPARC_32:
  700 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
  701 + rel->r_offset - offset, name, addend);
  702 + break;
  703 + case R_SPARC_HI22:
  704 + fprintf(outfile,
  705 + " *(uint32_t *)(gen_code_ptr + %d) = "
  706 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  707 + " & ~0x3fffff) "
  708 + " | ((%s + %d) & 0x3fffff);\n",
  709 + rel->r_offset - offset,
  710 + rel->r_offset - offset,
  711 + name, addend);
  712 + break;
  713 + case R_SPARC_LO10:
  714 + fprintf(outfile,
  715 + " *(uint32_t *)(gen_code_ptr + %d) = "
  716 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  717 + " & ~0x3ff) "
  718 + " | ((%s + %d) & 0x3ff);\n",
  719 + rel->r_offset - offset,
  720 + rel->r_offset - offset,
  721 + name, addend);
  722 + break;
  723 + case R_SPARC_WDISP30:
  724 + fprintf(outfile,
  725 + " *(uint32_t *)(gen_code_ptr + %d) = "
  726 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  727 + " & ~0x3fffffff) "
  728 + " | ((((%s + %d) - (long)gen_code_ptr)>>2) "
  729 + " & 0x3fffffff);\n",
  730 + rel->r_offset - offset,
  731 + rel->r_offset - offset,
  732 + name, addend);
  733 + break;
  734 + default:
  735 + error("unsupported sparc64 relocation (%d)", type);
  736 + }
  737 + }
  738 + }
  739 + }
557 #else 740 #else
558 #error unsupported CPU 741 #error unsupported CPU
559 #endif 742 #endif
@@ -759,6 +942,14 @@ fprintf(outfile, @@ -759,6 +942,14 @@ fprintf(outfile,
759 case EM_IA_64: 942 case EM_IA_64:
760 fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x00840008; /* br.ret.sptk.many b0;; */\n"); 943 fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x00840008; /* br.ret.sptk.many b0;; */\n");
761 break; 944 break;
  945 + case EM_SPARC:
  946 + case EM_SPARC32PLUS:
  947 + case EM_SPARCV9:
  948 + /* Fill the delay slot. */
  949 + fprintf(outfile, "*((uint32_t *)gen_code_ptr) = *((uint32_t *)gen_code_ptr - 1); /* delay slot */\n");
  950 + fprintf(outfile, "*((uint32_t *)gen_code_ptr - 1) = 0x81c3e008; /* retl */\n");
  951 + fprintf(outfile, "gen_code_ptr++;\n");
  952 + break;
762 default: 953 default:
763 error("unknown ELF architecture"); 954 error("unknown ELF architecture");
764 } 955 }
exec-i386.c
@@ -121,6 +121,20 @@ int testandset (int *p) @@ -121,6 +121,20 @@ int testandset (int *p)
121 } 121 }
122 #endif 122 #endif
123 123
  124 +#ifdef __sparc__
  125 +static inline int testandset (int *p)
  126 +{
  127 + int ret;
  128 +
  129 + __asm__ __volatile__("ldstub [%1], %0"
  130 + : "=r" (ret)
  131 + : "r" (p)
  132 + : "memory");
  133 +
  134 + return (ret ? 1 : 0);
  135 +}
  136 +#endif
  137 +
124 int global_cpu_lock = 0; 138 int global_cpu_lock = 0;
125 139
126 void cpu_lock(void) 140 void cpu_lock(void)
exec-i386.h
@@ -93,6 +93,7 @@ register unsigned int T0 asm(&quot;l0&quot;); @@ -93,6 +93,7 @@ register unsigned int T0 asm(&quot;l0&quot;);
93 register unsigned int T1 asm("l1"); 93 register unsigned int T1 asm("l1");
94 register unsigned int A0 asm("l2"); 94 register unsigned int A0 asm("l2");
95 register struct CPUX86State *env asm("l3"); 95 register struct CPUX86State *env asm("l3");
  96 +#define USE_FP_CONVERT
96 #endif 97 #endif
97 #ifdef __s390__ 98 #ifdef __s390__
98 register unsigned int T0 asm("r7"); 99 register unsigned int T0 asm("r7");
@@ -160,6 +161,10 @@ register struct CPUX86State *env asm(&quot;r27&quot;); @@ -160,6 +161,10 @@ register struct CPUX86State *env asm(&quot;r27&quot;);
160 #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7]) 161 #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
161 #define ST1 ST(1) 162 #define ST1 ST(1)
162 163
  164 +#ifdef USE_FP_CONVERT
  165 +#define FP_CONVERT (env->fp_convert)
  166 +#endif
  167 +
163 extern int __op_param1, __op_param2, __op_param3; 168 extern int __op_param1, __op_param2, __op_param3;
164 #define PARAM1 ((long)(&__op_param1)) 169 #define PARAM1 ((long)(&__op_param1))
165 #define PARAM2 ((long)(&__op_param2)) 170 #define PARAM2 ((long)(&__op_param2))
op-i386.c
@@ -1605,12 +1605,22 @@ typedef union { @@ -1605,12 +1605,22 @@ typedef union {
1605 1605
1606 void OPPROTO op_flds_FT0_A0(void) 1606 void OPPROTO op_flds_FT0_A0(void)
1607 { 1607 {
  1608 +#ifdef USE_FP_CONVERT
  1609 + FP_CONVERT.i32 = ldl((void *)A0);
  1610 + FT0 = FP_CONVERT.f;
  1611 +#else
1608 FT0 = ldfl((void *)A0); 1612 FT0 = ldfl((void *)A0);
  1613 +#endif
1609 } 1614 }
1610 1615
1611 void OPPROTO op_fldl_FT0_A0(void) 1616 void OPPROTO op_fldl_FT0_A0(void)
1612 { 1617 {
  1618 +#ifdef USE_FP_CONVERT
  1619 + FP_CONVERT.i64 = ldq((void *)A0);
  1620 + FT0 = FP_CONVERT.d;
  1621 +#else
1613 FT0 = ldfq((void *)A0); 1622 FT0 = ldfq((void *)A0);
  1623 +#endif
1614 } 1624 }
1615 1625
1616 /* helpers are needed to avoid static constant reference. XXX: find a better way */ 1626 /* helpers are needed to avoid static constant reference. XXX: find a better way */
@@ -1650,17 +1660,32 @@ void OPPROTO op_fildll_FT0_A0(void) @@ -1650,17 +1660,32 @@ void OPPROTO op_fildll_FT0_A0(void)
1650 1660
1651 void OPPROTO op_fild_FT0_A0(void) 1661 void OPPROTO op_fild_FT0_A0(void)
1652 { 1662 {
  1663 +#ifdef USE_FP_CONVERT
  1664 + FP_CONVERT.i32 = ldsw((void *)A0);
  1665 + FT0 = (CPU86_LDouble)FP_CONVERT.i32;
  1666 +#else
1653 FT0 = (CPU86_LDouble)ldsw((void *)A0); 1667 FT0 = (CPU86_LDouble)ldsw((void *)A0);
  1668 +#endif
1654 } 1669 }
1655 1670
1656 void OPPROTO op_fildl_FT0_A0(void) 1671 void OPPROTO op_fildl_FT0_A0(void)
1657 { 1672 {
  1673 +#ifdef USE_FP_CONVERT
  1674 + FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
  1675 + FT0 = (CPU86_LDouble)FP_CONVERT.i32;
  1676 +#else
1658 FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); 1677 FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1678 +#endif
1659 } 1679 }
1660 1680
1661 void OPPROTO op_fildll_FT0_A0(void) 1681 void OPPROTO op_fildll_FT0_A0(void)
1662 { 1682 {
  1683 +#ifdef USE_FP_CONVERT
  1684 + FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
  1685 + FT0 = (CPU86_LDouble)FP_CONVERT.i64;
  1686 +#else
1663 FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); 1687 FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1688 +#endif
1664 } 1689 }
1665 #endif 1690 #endif
1666 1691
@@ -1668,12 +1693,22 @@ void OPPROTO op_fildll_FT0_A0(void) @@ -1668,12 +1693,22 @@ void OPPROTO op_fildll_FT0_A0(void)
1668 1693
1669 void OPPROTO op_flds_ST0_A0(void) 1694 void OPPROTO op_flds_ST0_A0(void)
1670 { 1695 {
  1696 +#ifdef USE_FP_CONVERT
  1697 + FP_CONVERT.i32 = ldl((void *)A0);
  1698 + ST0 = FP_CONVERT.f;
  1699 +#else
1671 ST0 = ldfl((void *)A0); 1700 ST0 = ldfl((void *)A0);
  1701 +#endif
1672 } 1702 }
1673 1703
1674 void OPPROTO op_fldl_ST0_A0(void) 1704 void OPPROTO op_fldl_ST0_A0(void)
1675 { 1705 {
  1706 +#ifdef USE_FP_CONVERT
  1707 + FP_CONVERT.i64 = ldq((void *)A0);
  1708 + ST0 = FP_CONVERT.d;
  1709 +#else
1676 ST0 = ldfq((void *)A0); 1710 ST0 = ldfq((void *)A0);
  1711 +#endif
1677 } 1712 }
1678 1713
1679 #ifdef USE_X86LDOUBLE 1714 #ifdef USE_X86LDOUBLE
@@ -1738,17 +1773,32 @@ void OPPROTO op_fildll_ST0_A0(void) @@ -1738,17 +1773,32 @@ void OPPROTO op_fildll_ST0_A0(void)
1738 1773
1739 void OPPROTO op_fild_ST0_A0(void) 1774 void OPPROTO op_fild_ST0_A0(void)
1740 { 1775 {
  1776 +#ifdef USE_FP_CONVERT
  1777 + FP_CONVERT.i32 = ldsw((void *)A0);
  1778 + ST0 = (CPU86_LDouble)FP_CONVERT.i32;
  1779 +#else
1741 ST0 = (CPU86_LDouble)ldsw((void *)A0); 1780 ST0 = (CPU86_LDouble)ldsw((void *)A0);
  1781 +#endif
1742 } 1782 }
1743 1783
1744 void OPPROTO op_fildl_ST0_A0(void) 1784 void OPPROTO op_fildl_ST0_A0(void)
1745 { 1785 {
  1786 +#ifdef USE_FP_CONVERT
  1787 + FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
  1788 + ST0 = (CPU86_LDouble)FP_CONVERT.i32;
  1789 +#else
1746 ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); 1790 ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1791 +#endif
1747 } 1792 }
1748 1793
1749 void OPPROTO op_fildll_ST0_A0(void) 1794 void OPPROTO op_fildll_ST0_A0(void)
1750 { 1795 {
  1796 +#ifdef USE_FP_CONVERT
  1797 + FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
  1798 + ST0 = (CPU86_LDouble)FP_CONVERT.i64;
  1799 +#else
1751 ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); 1800 ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1801 +#endif
1752 } 1802 }
1753 1803
1754 #endif 1804 #endif
@@ -1757,7 +1807,12 @@ void OPPROTO op_fildll_ST0_A0(void) @@ -1757,7 +1807,12 @@ void OPPROTO op_fildll_ST0_A0(void)
1757 1807
1758 void OPPROTO op_fsts_ST0_A0(void) 1808 void OPPROTO op_fsts_ST0_A0(void)
1759 { 1809 {
  1810 +#ifdef USE_FP_CONVERT
  1811 + FP_CONVERT.d = ST0;
  1812 + stfl((void *)A0, FP_CONVERT.f);
  1813 +#else
1760 stfl((void *)A0, (float)ST0); 1814 stfl((void *)A0, (float)ST0);
  1815 +#endif
1761 } 1816 }
1762 1817
1763 void OPPROTO op_fstl_ST0_A0(void) 1818 void OPPROTO op_fstl_ST0_A0(void)
@@ -1792,22 +1847,43 @@ void OPPROTO op_fstt_ST0_A0(void) @@ -1792,22 +1847,43 @@ void OPPROTO op_fstt_ST0_A0(void)
1792 1847
1793 void OPPROTO op_fist_ST0_A0(void) 1848 void OPPROTO op_fist_ST0_A0(void)
1794 { 1849 {
  1850 +#if defined(__sparc__) && !defined(__sparc_v9__)
  1851 + register CPU86_LDouble d asm("o0");
  1852 +#else
  1853 + CPU86_LDouble d;
  1854 +#endif
1795 int val; 1855 int val;
1796 - val = lrint(ST0); 1856 +
  1857 + d = ST0;
  1858 + val = lrint(d);
1797 stw((void *)A0, val); 1859 stw((void *)A0, val);
1798 } 1860 }
1799 1861
1800 void OPPROTO op_fistl_ST0_A0(void) 1862 void OPPROTO op_fistl_ST0_A0(void)
1801 { 1863 {
  1864 +#if defined(__sparc__) && !defined(__sparc_v9__)
  1865 + register CPU86_LDouble d asm("o0");
  1866 +#else
  1867 + CPU86_LDouble d;
  1868 +#endif
1802 int val; 1869 int val;
1803 - val = lrint(ST0); 1870 +
  1871 + d = ST0;
  1872 + val = lrint(d);
1804 stl((void *)A0, val); 1873 stl((void *)A0, val);
1805 } 1874 }
1806 1875
1807 void OPPROTO op_fistll_ST0_A0(void) 1876 void OPPROTO op_fistll_ST0_A0(void)
1808 { 1877 {
  1878 +#if defined(__sparc__) && !defined(__sparc_v9__)
  1879 + register CPU86_LDouble d asm("o0");
  1880 +#else
  1881 + CPU86_LDouble d;
  1882 +#endif
1809 int64_t val; 1883 int64_t val;
1810 - val = llrint(ST0); 1884 +
  1885 + d = ST0;
  1886 + val = llrint(d);
1811 stq((void *)A0, val); 1887 stq((void *)A0, val);
1812 } 1888 }
1813 1889
translate-i386.c
@@ -89,6 +89,21 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop) @@ -89,6 +89,21 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
89 } 89 }
90 #endif 90 #endif
91 91
  92 +#ifdef __sparc__
  93 +
  94 +static void inline flush_icache_range(unsigned long start, unsigned long stop)
  95 +{
  96 + unsigned long p;
  97 +
  98 + p = start & ~(8UL - 1UL);
  99 + stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
  100 +
  101 + for (; p < stop; p += 8)
  102 + __asm__ __volatile__("flush\t%0" : : "r" (p));
  103 +}
  104 +
  105 +#endif
  106 +
92 extern FILE *logfile; 107 extern FILE *logfile;
93 extern int loglevel; 108 extern int loglevel;
94 109