⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch06test.c

📁 这是学习arm汇编的一个非常好的源码
💻 C
字号:
/* ____________________________________________________________________
 *
 * Copyright (c) 2003, Andrew N. Sloss, Dominic Symes, Chris Wright
 * All rights reserved.
 * ____________________________________________________________________
 * 
 * NON-COMMERCIAL USE License
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 *
 * 1. For NON-COMMERCIAL USE only.
 * 
 * 2. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 3. Redistributions in binary form must reproduce the above 
 *    copyright notice, this list of conditions and the following 
 *    disclaimer in the documentation and/or other materials provided 
 *    with the distribution. 
 *
 * 4. All advertising materials mentioning features or use of this 
 *    software must display the following acknowledgement:
 *
 *    This product includes software developed by Andrew N. Sloss,
 *    Chris Wright and Dominic Symes. 
 *
 *  THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY 
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE 
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
 *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 *  OF SUCH DAMAGE. 
 *
 * If you have questions about this license or would like a different
 * license please email : andrew@sloss.net
 *
 * Test module for the example routines of Chapter 6
 */
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ch06test.h"

int main(void)
{
  int errors=0;
  
  printf("Testing examples for Chapter 6\n");

#if 1
  TEST_TOLOWER(str_tolower_preload);
  TEST_TOLOWER(str_tolower_unrolled);
  TEST_SHIFT(shift_bits);  
  TEST_SCALE(shift_right);
  TEST_MERGE(merge_images);
  TEST_MEMSET(my_memset);
  TEST_MATRIX_MUL(matrix_mul);
  TEST_BITSTREAM(bitstream_write_test, bitstream_read_test);
  TEST_SWITCH(switch_absolute);
  TEST_SWITCH(switch_relative);
  TEST_SWITCH(switch_hash);
#endif
  TEST_LOADSTORE(load_32_little, store_32_little, 0);
  TEST_LOADSTORE(load_32_big, store_32_big, 1);
  TEST_CHECKSUM(checksum_32_little);
  
  if (errors)
  {
    printf("Test finished with %d errors.\n", errors);
    return 1;
  }
  else
  {
    printf("Test passed.\n");
  }
  return 0;
}

#define TESTSIZE 1024
#define TESTOFF    64

int test_memset(
  char *name,           /* function name */
  fn_memset *fn         /* function to test */
)
{
  const int sizes[]={0,1,2,3,4,5,6,10,40,160,500};
  char workspace[TESTSIZE];
  int i,j,offset;
  int errors=0;
  
  printf("Testing function: %s\n", name);
  
  for (i=0; i<sizeof(sizes)/sizeof(sizes[0]); i++)
  {
    for (offset=0; offset<4; offset++)
    {
#if VERBOSE
      printf(" Memset size=%d Alignment=%d\n", sizes[i], offset);
#endif

      /* clear the workspace */
      for (j=0; j<TESTSIZE; j++)
      {
        workspace[j]=0x56;
      }
    
      /* run the memset */
#if 1
      (*fn)(workspace+TESTOFF+offset, 0xA4, sizes[i]);
#else
      { unsigned int t=*(volatile unsigned int*)0x12340000;
      (*fn)(workspace+TESTOFF+offset, 0xA4, sizes[i]);
       t-=*(volatile unsigned int*)0x12340000;
       printf("time = %d\n", t);
      }
#endif
    
      /* check the result */
      for (j=0; j<TESTSIZE; j++)
      {
        char c=0xA4;
      
        if (j<TESTOFF+offset || j>=TESTOFF+offset+sizes[i])
        {
          c=0x56;
        }
        if (workspace[j]!=c)
        {
          printf("Error offset[%d]=0x%02x (ref 0x%02x)\n", j-TESTOFF-offset, workspace[j], c);
          errors++;
        }
      }
    }
  }
  
  return errors;  
}

/* Test matrix multiply RxS by SxT to RxT */

#define R 40
#define S 40
#define T 40

int test_matrix_mul(
  char *name,           /* function name */
  fn_matrix_mul *fn         /* function to test */
)
{
  int a[R*T];
  int ref_a[R*T];
  int b[R*S];
  int c[S*T];
  int i, errors=0;

  printf("Testing function: %s\n", name);
  
  /* Fill matrices with some randomish values */
  for (i=0; i<R*S; i++)
  {
    b[i] = (5*i) % 23;
  }
  for (i=0; i<S*T; i++)
  {
    c[i] = (7*i) % 31;
  }
  
  /* call optimised and reference matrix multiplies */
  ref_matrix_mul(ref_a, b, c);
  (*fn)(a, b, c);
  
  /* compare outputs */
  for (i=0; i<R*T; i++)
  {
    if (a[i] != ref_a[i])
    {
      errors++;
      printf("Mismatch[%d]: %08x %08x\n", i, ref_a[i], a[i]);
    }
  }
  
  return errors;
}

#define NUM_BITS 1024

int test_shift(
  char *name,           /* function name */
  fn_shift *fn          /* function to test */
)
{
  unsigned int out[NUM_BITS/32];
  unsigned int ref_out[NUM_BITS/32];
  unsigned int in[NUM_BITS/32];
  int i, k, errors=0;
  unsigned int carry, ref_carry;
  

  printf("Testing function: %s\n", name);
  
  for (k=1; k<32; k++)
  {
#if VERBOSE
    //printf("Testing a shift of %d\n", k);
#endif

    for (i=0; i<NUM_BITS/32; i++)
    {
      in[i]=(unsigned)(i*0xA2345679+0x1234567f);
    }
    
    ref_carry = ref_shift_bits(ref_out, in, NUM_BITS, k);
    carry = (*fn)(out, in, NUM_BITS, k);
    
    for (i=0; i<NUM_BITS/32; i++)
    {
      if (out[i] != ref_out[i])
      {
        errors++;
        printf("Mismatch[%d]: %08x %08x\n", i, ref_out[i], out[i]);
      }
    }
    if (carry != ref_carry)
    {
      errors++;
      printf("Mismatch[carry]: %08x %08x\n", ref_carry, carry);
    }
  }

  return errors;
}

#define MAX_LEN 100

/* Test string to lower function */
int test_tolower(
  char *name,           /* function name */
  fn_tolower *fn          /* function to test */
)
{
  char out[MAX_LEN];
  char ref_out[MAX_LEN];
  char in[MAX_LEN];
  int len, errors=0;

  printf("Testing function: %s\n", name);
  
  for (len=0; len<MAX_LEN; len++)
  {
#if VERBOSE
    //printf("Testing tolower string of length %d\n", len);
#endif

    gen_str(in, len);
    
    str_tolower(ref_out, in);
    (*fn)(out, in);
    
    if (strcmp(ref_out, out))
    {
      errors++;
      printf("Mismatch: \"%s\" \"%s\"\n", ref_out, out);
    }
  }

  return errors;
}

#define SCALE_LEN 40

/* Test right shift/scaling function */
int test_scale(
  char *name,           /* function name */
  fn_scale *fn          /* function to test */
)
{
  int out[SCALE_LEN];
  int in[SCALE_LEN];
  int i, k, errors=0;
  
  printf("Testing function: %s\n", name);
  
  for (k=0; k<31; k++)
  {
#if VERBOSE
    //printf("Testing right shift of %d\n", k);
#endif

    for (i=0; i<SCALE_LEN; i++)
    {
      in[i] = 0xa5367898 * i + 0x23478909;
    }
    
    (*fn)(out, in, k);
    
    for (i=0; i<SCALE_LEN; i++)
    {
      if (out[i] != (in[i]>>k))
      {
        errors++;
        printf("Mismatch[%d]: %08x %08x\n", i, in[i]>>k, out[i]);    
      }
    }
  }
  
  return errors;
}

int test_merge(
  char *name,           /* function name */
  fn_merge *fn          /* function to test */
)
{
  char z[IMAGE_SIZE]; /* output */
  char ref_z[IMAGE_SIZE]; /* output */
  char x[IMAGE_SIZE];
  char y[IMAGE_SIZE];
  int i, a, errors=0;
  
  printf("Testing function: %s\n", name);
  
  for (a=0; a<=256; )
  {
#if VERBOSE
    printf("Testing merge of intensity %d\n", a);
#endif

    gen_bytes(x, IMAGE_SIZE);
    gen_bytes(y, IMAGE_SIZE);

    ref_merge_images(ref_z, x, y, a);
    (*fn)(z, x, y, a);
    
    for (i=0; i<IMAGE_SIZE; i++)
    {
      if (ref_z[i] != z[i])
      {
        errors++;
        printf("Mismatch[%d]: %02x %02x\n", i, ref_z[i], z[i]);    
      }
    }
    if (a==255) a=256;
    else a+=51;
  }
  
  return errors;  
}

#define N 8
#define MESSAGE_LENGTH 256

int test_bitstream(
  char *name_write,         /* function name */
  char *name_read,
  fn_bit_write *fn_write,
  fn_bit_read  *fn_read
)
{
  int look_code[1<<N];
  char look_codebits[1<<N];
  int message_codes[MESSAGE_LENGTH];
  char message_codebits[MESSAGE_LENGTH];
  char bitstream_buffer[MESSAGE_LENGTH+8];
  int received_codes[MESSAGE_LENGTH];
  int i, k, errors=0;
  int alignment;

  printf("Testing functions: %s %s\n", name_write, name_read);
  
  /* We test the bitstream functions with a very simple Huffman Code
   * For each k>=1 there is a code of length k bits consisting of
   * (k-1) 1's followed by a single 0 stop bit.
   */
  for (k=1; k<=N; k++)
  {
    int code = (1<<k)-2;  /* (k-1) 1's followed by 0 */
    
    /* fill in the lookup table for code length k */
    for (i=0; i<(1<<(N-k)); i++)
    {
      look_code    [ (code << (N-k)) + i ] = code;
      look_codebits[ (code << (N-k)) + i ] = (char)k;
    }
  }
  look_code    [(1<<N)-1] = -1;
  look_codebits[(1<<N)-1] = 0xFF; /* escape codes longer than N-bits */
  
  /* Now lets generate a message to send of codes <= N bits.
   * The message is terminated with an (N+1)-bit code
   */
  for (i=0; i<MESSAGE_LENGTH-1; i++)
  {
    k = (rand()%N)+1; /* randomish code length */
    message_codes[i] = (1<<k)-2;
    message_codebits[i] = (char)k;
  }
  message_codes[i] = (1<<(N+1))-2;
  message_codebits[i] = N+1;
  
  /* Now, for each byte alignment, encode and decode the message */
  for (alignment=0; alignment<4; alignment++)
  {
    char *bitstream = bitstream_buffer + 4 + alignment;
    int num_bytes, num_codes;

    bitstream[-1] = 0x59;
    num_bytes = (*fn_write)(bitstream, message_codes, message_codebits) - bitstream;
    if (bitstream[-1] != 0x59)
    {
      errors++;
      printf("Write bits corrupted initial memory %02x\n", bitstream[-1]);
    }
    
#if 0
    /* display the bitstream buffer contents */
    printf("bitstream = ");
    for (i=0; i<num_bytes; i++)
    {
      if ((i % 8)==0) putchar('\n');
      for (k=0x80; k!=0; k>>=1)
      {
        if (k & bitstream[i]) putchar('1');
        else putchar('0');
      }
      putchar(' ');
    }
    printf("\n");
#endif
    
#if VERBOSE
    printf("Alignment=%d Bytes written=%d\n", alignment, num_bytes);
#endif
    
    num_codes = (*fn_read)(bitstream, received_codes, look_code, look_codebits) - received_codes;
  
    if (num_codes!=MESSAGE_LENGTH-1)
    {
      errors++;
      printf("Message length incorrect: %d %d\n", MESSAGE_LENGTH-1, num_codes);
    }
    for (i=0; i<num_codes; i++)
    {
      if (message_codes[i]!=received_codes[i])
      {
        errors++;
        printf("Mismatch[%d]: %08x %08x\n", i, message_codes[i], received_codes[i]);
      }
    }

  }
  
  return errors;
}

/* Test switch functions */

int test_switch(
  char *name,           /* function name */
  fn_switch *ref,       /* ref */
  fn_switch *fn         /* fn to test */
)
{
  int i, j, k, errors=0;
  
  printf("Testing function: %s\n", name);
  
  for (k=0; k<512; k++)
  {
    i = (*ref)(k);
    j = (*fn)(k);
    
    if (i != j)
    {
      errors++;
      printf("Mismatch[%d]: %08x %08x\n", k, i, j);
    }
  }
  
  return errors;
}

/* Test unaligned checksum functions */

int test_checksum(
  char *name,           /* function name */
  fn_checksum *ref,       /* ref */
  fn_checksum *fn         /* fn to test */
)
{
  char data[]="16ygsy1gygdy3287484848df82hdun32dkj2nidjhid23";
  int i, j, a, errors=0;
  
  printf("Testing function: %s\n", name);
  
  for (a=0; a<4; a++)
  {
    /* for each alignment */
    i = (*ref)(&data[a], 3);
    j = (*fn)(&data[a], 3);
    
    if (i != j)
    {
      errors++;
      printf("Mismatch[%d]: %08x %08x\n", a, i, j);
    }
  }
  
  return errors;
}

int test_loadstore(
  char *load,          /* function name */
  char *store,         /* function name */
  fn_load *fload,
  fn_store *fstore,
  int big              /* big endian flag */
)
{
  char data[8];
  int a, errors=0;
  
  printf("Testings function: %s %s\n", load, store);
  
  for (a=0; a<4; a++)
  {
    int val;
  
    /* for each alignment */
    memset(data, 0, 8);
    
    (*fstore)(data+a, 0x01020304);
    if (big)
    {
      val = ref_read_32_big(data+a); 
    }
    else
    {
      val = ref_read_32_little(data+a); 
    }    
    
    if (val != 0x01020304)
    {
      errors++;
      printf("Mismatch[%d]: store %08x %08x\n", a, 0x01020304, val);
    }
    
    val = (*fload)(data+a);
    if (val != 0x01020304)
    {
      errors++;
      printf("Mismatch[%d]: load  %08x %08x\n", a, 0x01020304, val);
    }    
  }
  
  return errors;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -