📄 test.c
字号:
: "a" (p1), "0" (p), "d" (pe), "b" (p2) : "ecx" ); do_tick(); BAILR } while (!done); } }}void movinv32(int iter, ulong p1, ulong lb, ulong hb, int sval, int off){ int i, j, k=0, done; volatile ulong *pe; volatile ulong *start, *end; ulong pat = 0;/* CDH start * ulong p3 = sval << 31; * CDH end */ /* Display the current pattern */ hprint(LINE_PAT, COL_PAT, p1); /* Initialize memory with the initial pattern. */ for (j=0; j<segs; j++) { start = v->map[j].start; end = v->map[j].end; pe = start; p = start; done = 0; k = off; pat = p1; do { /* Check for overflow */ if (pe + SPINSZ > pe) { pe += SPINSZ; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; } /* Do a SPINSZ section of memory *//* Original C code replaced with hand tuned assembly code * while (p < pe) { * *p = pat; * if (++k >= 32) { * pat = lb; * k = 0; * } else { * pat = pat << 1; * pat |= sval; * } * p++; * } */ asm __volatile__ ( "jmp L20\n\t" ".p2align 4,,7\n\t"/* CDH start */ "L20:\n\t" "movl %%ecx,(%%edi)\n\t" "incb %%bl\n\t" "addl $4,%%edi\n\t" "roll $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "jb L20\n\t" "andb $31,%%bl\n\t" : "=b" (k), "=D" (p), "=c" (pat) : "D" (p),"d" (pe),"b" (k),"c" (pat)/* CDH end */ ); do_tick(); BAILR } while (!done); } /* Do moving inversions test. Check for initial pattern and then * write the complement for each memory location. Test from bottom * up and then from the top down. */ for (i=0; i<iter; i++) { for (j=0; j<segs; j++) { start = v->map[j].start; end = v->map[j].end; pe = start; p = start; done = 0; k = off; pat = p1; do { /* Check for overflow */ if (pe + SPINSZ > pe) { pe += SPINSZ; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; }/* Original C code replaced with hand tuned assembly code * while (p < pe) { * if ((bad=*p) != pat) { * error((ulong*)p, pat, bad); * } * *p = ~pat; * if (++k >= 32) { * pat = lb; * k = 0; * } else { * pat = pat << 1; * pat |= sval; * } * p++; * } */ asm __volatile__ ( "pushl %%ebp\n\t" "jmp L30\n\t" ".p2align 4,,7\n\t" "L30:\n\t" "movl (%%edi),%%ebp\n\t" "cmpl %%ecx,%%ebp\n\t" "jne L34\n\t"/* CDH start */ "L35:\n\t" "notl %%ecx\n\t" "movl %%ecx,(%%edi)\n\t" "notl %%ecx\n\t" "addl $4,%%edi\n\t" "incb %%bl\n\t" "roll $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "jb L30\n\t" "jmp L33\n\t"/* CDH end */ "L34:\n\t" \ "pushl %%esi\n\t" "pushl %%eax\n\t" "pushl %%ebx\n\t" "pushl %%edx\n\t" "pushl %%ebp\n\t" "pushl %%ecx\n\t" "pushl %%edi\n\t" "call error\n\t" "popl %%edi\n\t" "popl %%ecx\n\t" "popl %%ebp\n\t" "popl %%edx\n\t" "popl %%ebx\n\t" "popl %%eax\n\t" "popl %%esi\n\t" "jmp L35\n"/* CDH start */ "L33:\n\t" "andb $31,%%bl\n\t" "popl %%ebp\n\t" : "=b" (k), "=D" (p), "=c" (pat) : "D" (p),"d" (pe),"b" (k),"c" (pat)/* CDH end */ ); do_tick(); BAILR } while (!done); } /* Since we already adjusted k and the pattern this * code backs both up one step *//* CDH start *//* Original C code replaced with hand tuned assembly code * pat = lb; * if ( 0 != (k = (k-1) & 31) ) { * pat = (pat << k); * if ( sval ) * pat |= ((sval << k) - 1); * } * k++; */ asm __volatile__ ( "decl %%ecx\n\t" "andl $31,%%ecx\n\t" "roll %%cl,%%ebx\n\t" "incb %%cl\n\t" : "=c" (k), "=b" (pat) : "c" (k), "b" (lb) );/* CDH end */ for (j=segs-1; j>=0; j--) { start = v->map[j].start; end = v->map[j].end; p = end -1; pe = end -1; done = 0; do { /* Check for underflow */ if (pe - SPINSZ < pe) { pe -= SPINSZ; } else { pe = start; } if (pe <= start) { pe = start; done++; } if (p == pe ) { break; }/* Original C code replaced with hand tuned assembly code * do { * if ((bad=*p) != ~pat) { * error((ulong*)p, ~pat, bad); * } * *p = pat; * if (--k <= 0) { * pat = hb; * k = 32; * } else { * pat = pat >> 1; * pat |= p3; * } * } while (p-- > pe); */ asm __volatile__ ( "pushl %%ebp\n\t" "addl $4,%%edi\n\t" "jmp L40\n\t" ".p2align 4,,7\n\t" "L40:\n\t" "subl $4,%%edi\n\t" "movl (%%edi),%%ebp\n\t" "notl %%ecx\n\t" "cmpl %%ecx,%%ebp\n\t" "jne L44\n\t"/* CDH start */ "L45:\n\t" "notl %%ecx\n\t" "movl %%ecx,(%%edi)\n\t" "decb %%bl\n\t" "rorl $1,%%ecx\n\t" "cmpl %%edx,%%edi\n\t" "ja L40\n\t" "jmp L43\n\t"/* CDH end */ "L44:\n\t" \ "pushl %%esi\n\t" "pushl %%eax\n\t" "pushl %%ebx\n\t" "pushl %%edx\n\t" "pushl %%ebp\n\t" "pushl %%ecx\n\t" "pushl %%edi\n\t" "call error\n\t" "popl %%edi\n\t" "popl %%ecx\n\t" "popl %%ebp\n\t" "popl %%edx\n\t" "popl %%ebx\n\t" "popl %%eax\n\t" "popl %%esi\n\t" "jmp L45\n"/* CDH start */ "L43:\n\t" "andb $31,%%bl\n\t" "subl $4,%%edi\n\t" "popl %%ebp\n\t" : "=b" (k), "=D" (p), "=c" (pat) : "D" (p),"d" (pe),"b" (k),"c" (pat)/* CDH end */ ); do_tick(); BAILR } while (!done); } }}/* * Test all of memory using modulo X access pattern. */void modtst(int offset, int iter, ulong p1, ulong p2){ int j, k, l, done; volatile ulong *pe; volatile ulong *start, *end; /* Display the current pattern */ hprint(LINE_PAT, COL_PAT-2, p1); cprint(LINE_PAT, COL_PAT+6, "-"); dprint(LINE_PAT, COL_PAT+7, offset, 2, 1); /* Write every nth location with pattern */ for (j=0; j<segs; j++) { start = v->map[j].start; end = v->map[j].end; pe = (ulong *)start; p = start+offset; done = 0; do { /* Check for overflow */ if (pe + SPINSZ > pe) { pe += SPINSZ; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; }/* Original C code replaced with hand tuned assembly code * for (; p < pe; p += MOD_SZ) { * *p = p1; * } */ asm __volatile__ ( "jmp L60\n\t" \ ".p2align 4,,7\n\t" \ "L60:\n\t" \ "movl %%eax,(%%edi)\n\t" \ "addl $80,%%edi\n\t" \ "cmpl %%edx,%%edi\n\t" \ "jb L60\n\t" \ : "=D" (p) : "D" (p), "d" (pe), "a" (p1) ); do_tick(); BAILR } while (!done); } /* Write the rest of memory "iter" times with the pattern complement */ for (l=0; l<iter; l++) { for (j=0; j<segs; j++) { start = v->map[j].start; end = v->map[j].end; pe = (ulong *)start; p = start; done = 0; k = 0; do { /* Check for overflow */ if (pe + SPINSZ > pe) { pe += SPINSZ; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; }/* Original C code replaced with hand tuned assembly code * for (; p < pe; p++) { * if (k != offset) { * *p = p2; * } * if (++k > MOD_SZ-1) { * k = 0; * } * } */ asm __volatile__ ( "jmp L50\n\t" \ ".p2align 4,,7\n\t" \ "L50:\n\t" \ "cmpl %%ebx,%%ecx\n\t" \ "je L52\n\t" \ "movl %%eax,(%%edi)\n\t" \ "L52:\n\t" \ "incl %%ebx\n\t" \ "cmpl $19,%%ebx\n\t" \ "jle L53\n\t" \ "xorl %%ebx,%%ebx\n\t" \ "L53:\n\t" \ "addl $4,%%edi\n\t" \ "cmpl %%edx,%%edi\n\t" \ "jb L50\n\t" \ : "=D" (p), "=b" (k) : "D" (p), "d" (pe), "a" (p2), "b" (k), "c" (offset) ); do_tick(); BAILR } while (!done); } } /* Now check every nth location */ for (j=0; j<segs; j++) { start = v->map[j].start; end = v->map[j].end; pe = (ulong *)start; p = start+offset; done = 0; do { /* Check for overflow */ if (pe + SPINSZ > pe) { pe += SPINSZ; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; }/* Original C code replaced with hand tuned assembly code * for (; p < pe; p += MOD_SZ) { * if ((bad=*p) != p1) { * error((ulong*)p, p1, bad); * } * } */ asm __volatile__ ( "jmp L70\n\t" \ ".p2align 4,,7\n\t" \ "L70:\n\t" \ "movl (%%edi),%%ecx\n\t" \ "cmpl %%eax,%%ecx\n\t" \ "jne L71\n\t" \ "L72:\n\t" \ "addl $80,%%edi\n\t" \ "cmpl %%edx,%%edi\n\t" \ "jb L70\n\t" \ "jmp L73\n\t" \ "L71:\n\t" \ "pushl %%edx\n\t" "pushl %%ecx\n\t" "pushl %%eax\n\t" "pushl %%edi\n\t" "call error\n\t" "popl %%edi\n\t" "popl %%eax\n\t" "popl %%ecx\n\t" "popl %%edx\n\t" "jmp L72\n" "L73:\n\t" \ : "=D" (p) : "D" (p), "d" (pe), "a" (p1) : "ecx" ); do_tick(); BAILR } while (!done); } cprint(LINE_PAT, COL_PAT, " ");}/* * Test memory using block moves * Adapted from Robert Redelmeier's burnBX test */void block_move(int iter){ int i, j, done; ulong len; volatile ulong p, pe, pp; volatile ulong start, end; cprint(LINE_PAT, COL_PAT-2, " "); /* Initialize memory with the initial pattern. */ for (j=0; j<segs; j++) { start = (ulong)v->map[j].start;#ifdef USB_WAR /* We can't do the block move test on low memory beacuase * BIOS USB support clobbers location 0x410 and 0x4e0 */ if (start < 0x4f0) { start = 0x4f0; }#endif end = (ulong)v->map[j].end; pe = start; p = start; done = 0; do { /* Check for overflow */ if (pe + SPINSZ*4 > pe) { pe += SPINSZ*4; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break; } len = ((ulong)pe - (ulong)p) / 64; asm __volatile__ ( "jmp L100\n\t" ".p2align 4,,7\n\t" "L100:\n\t" "movl %%eax, %%edx\n\t" "notl %%edx\n\t" "movl %%eax,0(%%edi)\n\t" "movl %%eax,4(%%edi)\n\t" "movl %%eax,8(%%edi)\n\t" "movl %%eax,12(%%edi)\n\t" "movl %%edx,16(%%edi)\n\t" "movl %%edx,20(%%edi)\n\t" "movl %%eax,24(%%edi)\n\t" "movl %%eax,28(%%edi)\n\t" "movl %%eax,32(%%edi)\n\t" "movl %%eax,36(%%edi)\n\t" "movl %%edx,40(%%edi)\n\t" "movl %%edx,44(%%edi)\n\t" "movl %%eax,48(%%edi)\n\t" "movl %%eax,52(%%edi)\n\t" "movl %%edx,56(%%edi)\n\t" "movl %%edx,60(%%edi)\n\t" "rcll $1, %%eax\n\t" "leal 64(%%edi), %%edi\n\t" "decl %%ecx\n\t" "jnz L100\n\t" : "=D" (p) : "D" (p), "c" (len), "a" (1) : "edx" ); do_tick(); BAILR } while (!done); } /* Now move the data around * First move the data up half of the segment size we are testing * Then move the data to the original location + 32 bytes */ for (j=0; j<segs; j++) { start = (ulong)v->map[j].start;#ifdef USB_WAR /* We can't do the block move test on low memory beacuase * BIOS USB support clobbers location 0x410 and 0x4e0 */ if (start < 0x4f0) { start = 0x4f0; }#endif end = (ulong)v->map[j].end; pe = start; p = start; done = 0; do { /* Check for overflow */ if (pe + SPINSZ*4 > pe) { pe += SPINSZ*4; } else { pe = end; } if (pe >= end) { pe = end; done++; } if (p == pe ) { break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -